@mui/x-charts 8.19.0 → 8.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/ChartsGrid/ChartsHorizontalGrid.js +5 -1
  3. package/ChartsGrid/ChartsVerticalGrid.js +5 -1
  4. package/ChartsTooltip/ChartsTooltipContainer.js +1 -1
  5. package/RadarChart/RadarSeriesPlot/RadarSeriesArea.js +2 -2
  6. package/RadarChart/RadarSeriesPlot/RadarSeriesPlot.js +2 -2
  7. package/RadarChart/RadarSeriesPlot/useInteractionAllItemProps.d.ts +7 -0
  8. package/RadarChart/RadarSeriesPlot/useInteractionAllItemProps.js +26 -0
  9. package/esm/ChartsGrid/ChartsHorizontalGrid.js +5 -1
  10. package/esm/ChartsGrid/ChartsVerticalGrid.js +5 -1
  11. package/esm/ChartsTooltip/ChartsTooltipContainer.js +1 -1
  12. package/esm/RadarChart/RadarSeriesPlot/RadarSeriesArea.js +1 -1
  13. package/esm/RadarChart/RadarSeriesPlot/RadarSeriesPlot.js +1 -1
  14. package/esm/RadarChart/RadarSeriesPlot/useInteractionAllItemProps.d.ts +7 -0
  15. package/esm/RadarChart/RadarSeriesPlot/useInteractionAllItemProps.js +18 -0
  16. package/esm/hooks/useInteractionItemProps.d.ts +0 -5
  17. package/esm/hooks/useInteractionItemProps.js +0 -11
  18. package/esm/hooks/useTicks.js +12 -3
  19. package/esm/index.js +1 -1
  20. package/esm/internals/plugins/corePlugins/useChartSeries/processSeries.d.ts +16 -10
  21. package/esm/internals/plugins/corePlugins/useChartSeries/processSeries.js +20 -12
  22. package/esm/internals/plugins/corePlugins/useChartSeries/useChartSeries.js +5 -7
  23. package/esm/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.d.ts +11 -4
  24. package/esm/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.js +13 -4
  25. package/esm/internals/plugins/corePlugins/useChartSeries/useChartSeries.types.d.ts +3 -2
  26. package/esm/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.js +16 -12
  27. package/esm/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.js +5 -5
  28. package/esm/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.types.d.ts +4 -0
  29. package/esm/internals/plugins/featurePlugins/useChartInteraction/useChartTooltip.selectors.d.ts +1 -1
  30. package/esm/internals/plugins/featurePlugins/useChartInteraction/useChartTooltip.selectors.js +1 -1
  31. package/esm/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.js +15 -10
  32. package/esm/internals/seriesSelectorOfType.d.ts +1 -1
  33. package/hooks/useInteractionItemProps.d.ts +0 -5
  34. package/hooks/useInteractionItemProps.js +1 -13
  35. package/hooks/useTicks.js +12 -3
  36. package/index.js +1 -1
  37. package/internals/plugins/corePlugins/useChartSeries/processSeries.d.ts +16 -10
  38. package/internals/plugins/corePlugins/useChartSeries/processSeries.js +23 -14
  39. package/internals/plugins/corePlugins/useChartSeries/useChartSeries.js +4 -6
  40. package/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.d.ts +11 -4
  41. package/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.js +13 -4
  42. package/internals/plugins/corePlugins/useChartSeries/useChartSeries.types.d.ts +3 -2
  43. package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.js +16 -12
  44. package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.js +5 -5
  45. package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.types.d.ts +4 -0
  46. package/internals/plugins/featurePlugins/useChartInteraction/useChartTooltip.selectors.d.ts +1 -1
  47. package/internals/plugins/featurePlugins/useChartInteraction/useChartTooltip.selectors.js +1 -1
  48. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.js +15 -10
  49. package/internals/seriesSelectorOfType.d.ts +1 -1
  50. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -5,6 +5,68 @@
5
5
  All notable changes to this project will be documented in this file.
6
6
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
7
7
 
8
+ ## 8.20.0
9
+
10
+ _Nov 26, 2025_
11
+
12
+ We'd like to extend a big thank you to the 8 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 🔃 Data Grid tree data now supports row reordering. See the [Drag-and-drop tree data reordering](https://mui.com/x/react-data-grid/tree-data/#drag-and-drop-tree-data-reordering) section for more details.
15
+ - 🐞 Bugfixes
16
+
17
+ The following team members contributed to this release:
18
+ @alexfauquette, @arminmeh, @bernardobelchior, @cherniavskii, @siriwatknp, @JCQuintas, @MBilalShafi, @prakhargupta1
19
+
20
+ ### Data Grid
21
+
22
+ #### `@mui/x-data-grid@8.20.0`
23
+
24
+ - [DataGrid] Fix RTL virtualization to display columns when viewport width is larger than the grid (#20409) @siriwatknp
25
+ - [DataGrid] Fix row range selection (#20442) @arminmeh
26
+ - [DataGrid] Initialize data grid core packages (#20276) @cherniavskii
27
+ - [DataGrid] Improve accessibility of the sort icon (#20430) @arminmeh
28
+ - [DataGrid] Use `viewport` as a boundary for the `BasePopper` flip (#20311) @arminmeh
29
+
30
+ #### `@mui/x-data-grid-pro@8.20.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
31
+
32
+ Same changes as in `@mui/x-data-grid@8.20.0`, plus:
33
+
34
+ - [DataGridPro] Avoid automatic scroll back to the focused header filter after it leaves the viewport (#20416) @arminmeh
35
+ - [DataGridPro] Tree data row reordering (#19401) @MBilalShafi
36
+
37
+ #### `@mui/x-data-grid-premium@8.20.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
38
+
39
+ Same changes as in `@mui/x-data-grid-pro@8.20.0`.
40
+
41
+ ### Charts
42
+
43
+ #### `@mui/x-charts@8.20.0`
44
+
45
+ - [charts] Fix item tooltip position with node anchor (#20421) @alexfauquette
46
+ - [charts] Fix radar item tooltip closing bug (#20429) @alexfauquette
47
+ - [charts] Move series processing to selector (#20388) @JCQuintas
48
+ - [charts] Prevent pointer out from removing controlled highlight (#20385) @alexfauquette
49
+
50
+ #### `@mui/x-charts-pro@8.20.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
51
+
52
+ Same changes as in `@mui/x-charts@8.20.0`, plus:
53
+
54
+ - [charts-pro] Fix Content-Security-Policy nonce not being correctly set on export (#20395) @bernardobelchior
55
+ - [charts-pro] Improve vertical zoom slider thumb on mobile (#20439) @bernardobelchior
56
+ - [charts-pro] Provide arguments to the `AreaPlotRoot` styled component (#20414) @arminmeh
57
+ - [charts-pro] Remove grid outside the drawing area (#20412) @alexfauquette
58
+
59
+ #### `@mui/x-charts-premium@8.20.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
60
+
61
+ Same changes as in `@mui/x-charts-pro@8.20.0`, plus:
62
+
63
+ - [charts-premium] Add explicit return type to `ChartsRenderer` for better compatibility with React 18 (#20413) @arminmeh
64
+
65
+ ### Docs
66
+
67
+ - [docs] Add `llms.txt` link to the sidebar (#20312) @siriwatknp
68
+ - [docs] Add a line chart demo for the Overview section (#20239) @prakhargupta1
69
+
8
70
  ## 8.19.0
9
71
 
10
72
  _Nov 20, 2025_
@@ -8,11 +8,15 @@ exports.ChartsGridHorizontal = ChartsGridHorizontal;
8
8
  var React = _interopRequireWildcard(require("react"));
9
9
  var _useTicks = require("../hooks/useTicks");
10
10
  var _styledComponents = require("./styledComponents");
11
+ var _ChartProvider = require("../context/ChartProvider");
11
12
  var _jsxRuntime = require("react/jsx-runtime");
12
13
  /**
13
14
  * @ignore - internal component.
14
15
  */
15
16
  function ChartsGridHorizontal(props) {
17
+ const {
18
+ instance
19
+ } = (0, _ChartProvider.useChartContext)();
16
20
  const {
17
21
  axis,
18
22
  start,
@@ -34,7 +38,7 @@ function ChartsGridHorizontal(props) {
34
38
  children: yTicks.map(({
35
39
  value,
36
40
  offset
37
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_styledComponents.GridLine, {
41
+ }) => !instance.isYInside(offset) ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_styledComponents.GridLine, {
38
42
  y1: offset,
39
43
  y2: offset,
40
44
  x1: start,
@@ -8,11 +8,15 @@ exports.ChartsGridVertical = ChartsGridVertical;
8
8
  var React = _interopRequireWildcard(require("react"));
9
9
  var _useTicks = require("../hooks/useTicks");
10
10
  var _styledComponents = require("./styledComponents");
11
+ var _ChartProvider = require("../context/ChartProvider");
11
12
  var _jsxRuntime = require("react/jsx-runtime");
12
13
  /**
13
14
  * @ignore - internal component.
14
15
  */
15
16
  function ChartsGridVertical(props) {
17
+ const {
18
+ instance
19
+ } = (0, _ChartProvider.useChartContext)();
16
20
  const {
17
21
  axis,
18
22
  start,
@@ -34,7 +38,7 @@ function ChartsGridVertical(props) {
34
38
  children: xTicks.map(({
35
39
  value,
36
40
  offset
37
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_styledComponents.GridLine, {
41
+ }) => !instance.isXInside(offset) ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_styledComponents.GridLine, {
38
42
  y1: start,
39
43
  y2: end,
40
44
  x1: offset,
@@ -92,7 +92,7 @@ function ChartsTooltipContainer(inProps) {
92
92
  const isOpen = (0, _useSelector.useSelector)(store, getIsOpenSelector(trigger, axisSystem, shouldPreventBecauseOfBrush));
93
93
  const lastInteraction = (0, _useSelector.useSelector)(store, _useChartInteraction.selectorChartsLastInteraction);
94
94
  const computedAnchor = lastInteraction === 'keyboard' ? 'node' : anchor;
95
- const itemPosition = (0, _useSelector.useSelector)(store, trigger === 'item' && computedAnchor === 'node' ? _useChartInteraction.selectorChartsTooltipItemPosition : () => null, [position]);
95
+ const itemPosition = (0, _useSelector.useSelector)(store, trigger === 'item' && computedAnchor === 'node' ? _useChartInteraction.selectorChartsTooltipItemPosition : () => null, position);
96
96
  React.useEffect(() => {
97
97
  const svgElement = svgRef.current;
98
98
  if (svgElement === null) {
@@ -16,7 +16,7 @@ var _useRadarSeriesData = require("./useRadarSeriesData");
16
16
  var _getAreaPath = require("./getAreaPath");
17
17
  var _radarSeriesPlotClasses = require("./radarSeriesPlotClasses");
18
18
  var _useItemHighlightedGetter = require("../../hooks/useItemHighlightedGetter");
19
- var _useInteractionItemProps = require("../../hooks/useInteractionItemProps");
19
+ var _useInteractionAllItemProps = require("./useInteractionAllItemProps");
20
20
  var _useRadarRotationIndex = require("./useRadarRotationIndex");
21
21
  var _jsxRuntime = require("react/jsx-runtime");
22
22
  const _excluded = ["seriesId", "onItemClick"];
@@ -54,7 +54,7 @@ function RadarSeriesArea(props) {
54
54
  other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
55
55
  const seriesCoordinates = (0, _useRadarSeriesData.useRadarSeriesData)(seriesId);
56
56
  const getRotationIndex = (0, _useRadarRotationIndex.useRadarRotationIndex)();
57
- const interactionProps = (0, _useInteractionItemProps.useInteractionAllItemProps)(seriesCoordinates);
57
+ const interactionProps = (0, _useInteractionAllItemProps.useInteractionAllItemProps)(seriesCoordinates);
58
58
  const {
59
59
  isFaded,
60
60
  isHighlighted
@@ -8,7 +8,7 @@ exports.RadarSeriesPlot = RadarSeriesPlot;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _propTypes = _interopRequireDefault(require("prop-types"));
10
10
  var _useRadarSeriesData = require("./useRadarSeriesData");
11
- var _useInteractionItemProps = require("../../hooks/useInteractionItemProps");
11
+ var _useInteractionAllItemProps = require("./useInteractionAllItemProps");
12
12
  var _useItemHighlightedGetter = require("../../hooks/useItemHighlightedGetter");
13
13
  var _radarSeriesPlotClasses = require("./radarSeriesPlotClasses");
14
14
  var _RadarSeriesArea = require("./RadarSeriesArea");
@@ -24,7 +24,7 @@ function RadarSeriesPlot(props) {
24
24
  } = props;
25
25
  const seriesCoordinates = (0, _useRadarSeriesData.useRadarSeriesData)(inSeriesId);
26
26
  const getRotationIndex = (0, _useRadarRotationIndex.useRadarRotationIndex)();
27
- const interactionProps = (0, _useInteractionItemProps.useInteractionAllItemProps)(seriesCoordinates);
27
+ const interactionProps = (0, _useInteractionAllItemProps.useInteractionAllItemProps)(seriesCoordinates);
28
28
  const {
29
29
  isFaded,
30
30
  isHighlighted
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ import { SeriesItemIdentifierWithData } from "../../models/seriesType/index.js";
3
+ export declare const useInteractionAllItemProps: (data: SeriesItemIdentifierWithData<"radar">[], skip?: boolean) => {
4
+ onPointerEnter?: () => void;
5
+ onPointerLeave?: () => void;
6
+ onPointerDown?: (event: React.PointerEvent) => void;
7
+ }[];
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useInteractionAllItemProps = void 0;
8
+ var React = _interopRequireWildcard(require("react"));
9
+ var _useChartContext = require("../../context/ChartProvider/useChartContext");
10
+ var _useInteractionItemProps = require("../../hooks/useInteractionItemProps");
11
+ const useInteractionAllItemProps = (data, skip) => {
12
+ const {
13
+ instance
14
+ } = (0, _useChartContext.useChartContext)();
15
+ const results = React.useMemo(() => {
16
+ return data.map(item => {
17
+ return skip ? {} : (0, _useInteractionItemProps.getInteractionItemProps)(instance, {
18
+ type: 'radar',
19
+ seriesId: item.seriesId,
20
+ dataIndex: item.dataIndex
21
+ });
22
+ });
23
+ }, [data, instance, skip]);
24
+ return results;
25
+ };
26
+ exports.useInteractionAllItemProps = useInteractionAllItemProps;
@@ -1,11 +1,15 @@
1
1
  import * as React from 'react';
2
2
  import { useTicks } from "../hooks/useTicks.js";
3
3
  import { GridLine } from "./styledComponents.js";
4
+ import { useChartContext } from "../context/ChartProvider/index.js";
4
5
  import { jsx as _jsx } from "react/jsx-runtime";
5
6
  /**
6
7
  * @ignore - internal component.
7
8
  */
8
9
  export function ChartsGridHorizontal(props) {
10
+ const {
11
+ instance
12
+ } = useChartContext();
9
13
  const {
10
14
  axis,
11
15
  start,
@@ -27,7 +31,7 @@ export function ChartsGridHorizontal(props) {
27
31
  children: yTicks.map(({
28
32
  value,
29
33
  offset
30
- }) => /*#__PURE__*/_jsx(GridLine, {
34
+ }) => !instance.isYInside(offset) ? null : /*#__PURE__*/_jsx(GridLine, {
31
35
  y1: offset,
32
36
  y2: offset,
33
37
  x1: start,
@@ -1,11 +1,15 @@
1
1
  import * as React from 'react';
2
2
  import { useTicks } from "../hooks/useTicks.js";
3
3
  import { GridLine } from "./styledComponents.js";
4
+ import { useChartContext } from "../context/ChartProvider/index.js";
4
5
  import { jsx as _jsx } from "react/jsx-runtime";
5
6
  /**
6
7
  * @ignore - internal component.
7
8
  */
8
9
  export function ChartsGridVertical(props) {
10
+ const {
11
+ instance
12
+ } = useChartContext();
9
13
  const {
10
14
  axis,
11
15
  start,
@@ -27,7 +31,7 @@ export function ChartsGridVertical(props) {
27
31
  children: xTicks.map(({
28
32
  value,
29
33
  offset
30
- }) => /*#__PURE__*/_jsx(GridLine, {
34
+ }) => !instance.isXInside(offset) ? null : /*#__PURE__*/_jsx(GridLine, {
31
35
  y1: start,
32
36
  y2: end,
33
37
  x1: offset,
@@ -85,7 +85,7 @@ function ChartsTooltipContainer(inProps) {
85
85
  const isOpen = useSelector(store, getIsOpenSelector(trigger, axisSystem, shouldPreventBecauseOfBrush));
86
86
  const lastInteraction = useSelector(store, selectorChartsLastInteraction);
87
87
  const computedAnchor = lastInteraction === 'keyboard' ? 'node' : anchor;
88
- const itemPosition = useSelector(store, trigger === 'item' && computedAnchor === 'node' ? selectorChartsTooltipItemPosition : () => null, [position]);
88
+ const itemPosition = useSelector(store, trigger === 'item' && computedAnchor === 'node' ? selectorChartsTooltipItemPosition : () => null, position);
89
89
  React.useEffect(() => {
90
90
  const svgElement = svgRef.current;
91
91
  if (svgElement === null) {
@@ -8,7 +8,7 @@ import { useRadarSeriesData } from "./useRadarSeriesData.js";
8
8
  import { getAreaPath } from "./getAreaPath.js";
9
9
  import { useUtilityClasses } from "./radarSeriesPlotClasses.js";
10
10
  import { useItemHighlightedGetter } from "../../hooks/useItemHighlightedGetter.js";
11
- import { useInteractionAllItemProps } from "../../hooks/useInteractionItemProps.js";
11
+ import { useInteractionAllItemProps } from "./useInteractionAllItemProps.js";
12
12
  import { useRadarRotationIndex } from "./useRadarRotationIndex.js";
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  export function getPathProps(params) {
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import PropTypes from 'prop-types';
3
3
  import { useRadarSeriesData } from "./useRadarSeriesData.js";
4
- import { useInteractionAllItemProps } from "../../hooks/useInteractionItemProps.js";
4
+ import { useInteractionAllItemProps } from "./useInteractionAllItemProps.js";
5
5
  import { useItemHighlightedGetter } from "../../hooks/useItemHighlightedGetter.js";
6
6
  import { useUtilityClasses } from "./radarSeriesPlotClasses.js";
7
7
  import { getPathProps } from "./RadarSeriesArea.js";
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ import { SeriesItemIdentifierWithData } from "../../models/seriesType/index.js";
3
+ export declare const useInteractionAllItemProps: (data: SeriesItemIdentifierWithData<"radar">[], skip?: boolean) => {
4
+ onPointerEnter?: () => void;
5
+ onPointerLeave?: () => void;
6
+ onPointerDown?: (event: React.PointerEvent) => void;
7
+ }[];
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ import { useChartContext } from "../../context/ChartProvider/useChartContext.js";
3
+ import { getInteractionItemProps } from "../../hooks/useInteractionItemProps.js";
4
+ export const useInteractionAllItemProps = (data, skip) => {
5
+ const {
6
+ instance
7
+ } = useChartContext();
8
+ const results = React.useMemo(() => {
9
+ return data.map(item => {
10
+ return skip ? {} : getInteractionItemProps(instance, {
11
+ type: 'radar',
12
+ seriesId: item.seriesId,
13
+ dataIndex: item.dataIndex
14
+ });
15
+ });
16
+ }, [data, instance, skip]);
17
+ return results;
18
+ };
@@ -9,11 +9,6 @@ export declare const useInteractionItemProps: (data: SeriesItemIdentifierWithDat
9
9
  onPointerLeave?: () => void;
10
10
  onPointerDown?: (event: React.PointerEvent) => void;
11
11
  };
12
- export declare const useInteractionAllItemProps: (data: SeriesItemIdentifierWithData[], skip?: boolean) => {
13
- onPointerEnter?: () => void;
14
- onPointerLeave?: () => void;
15
- onPointerDown?: (event: React.PointerEvent) => void;
16
- }[];
17
12
  export declare function getInteractionItemProps(instance: ChartInstance<[UseChartInteractionSignature, UseChartHighlightSignature]>, item: ChartItemIdentifierWithData<ChartSeriesType>): {
18
13
  onPointerEnter?: () => void;
19
14
  onPointerLeave?: () => void;
@@ -39,17 +39,6 @@ export const useInteractionItemProps = (data, skip) => {
39
39
  onPointerDown
40
40
  }, [skip, onPointerEnter, onPointerLeave]);
41
41
  };
42
- export const useInteractionAllItemProps = (data, skip) => {
43
- const {
44
- instance
45
- } = useChartContext();
46
- const results = React.useMemo(() => {
47
- return data.map(item => {
48
- return skip ? {} : getInteractionItemProps(instance, item);
49
- });
50
- }, [data, instance, skip]);
51
- return results;
52
- };
53
42
  export function getInteractionItemProps(instance, item) {
54
43
  function onPointerEnter() {
55
44
  if (!item) {
@@ -10,6 +10,9 @@ const offsetRatio = {
10
10
  end: 1,
11
11
  middle: 0.5
12
12
  };
13
+ function getTickPosition(scale, value, placement) {
14
+ return scale(value) - (scale.step() - scale.bandwidth()) / 2 + offsetRatio[placement] * scale.step();
15
+ }
13
16
  export function getTicks(options) {
14
17
  const {
15
18
  scale,
@@ -28,7 +31,13 @@ export function getTicks(options) {
28
31
  if (scale.bandwidth() > 0) {
29
32
  // scale type = 'band'
30
33
  const filteredDomain = typeof tickInterval === 'function' && domain.filter(tickInterval) || typeof tickInterval === 'object' && tickInterval || domain;
31
- return [...filteredDomain.map(value => {
34
+ const isReversed = scale.range()[0] > scale.range()[1];
35
+ // Indexes are inclusive regarding the entire band.
36
+ const startIndex = filteredDomain.findIndex(value => {
37
+ return isInside(getTickPosition(scale, value, isReversed ? 'start' : 'end'));
38
+ });
39
+ const endIndex = filteredDomain.findLastIndex(value => isInside(getTickPosition(scale, value, isReversed ? 'end' : 'start')));
40
+ return [...filteredDomain.slice(startIndex, endIndex + 1).map(value => {
32
41
  const defaultTickLabel = `${value}`;
33
42
  return {
34
43
  value,
@@ -38,10 +47,10 @@ export function getTicks(options) {
38
47
  tickNumber,
39
48
  defaultTickLabel
40
49
  }) ?? defaultTickLabel,
41
- offset: scale(value) - (scale.step() - scale.bandwidth()) / 2 + offsetRatio[tickPlacement] * scale.step(),
50
+ offset: getTickPosition(scale, value, tickPlacement),
42
51
  labelOffset: tickLabelPlacement === 'tick' ? 0 : scale.step() * (offsetRatio[tickLabelPlacement] - offsetRatio[tickPlacement])
43
52
  };
44
- }), ...(tickPlacement === 'extremities' ? [{
53
+ }), ...(tickPlacement === 'extremities' && endIndex === domain.length - 1 && isInside(scale.range()[1]) ? [{
45
54
  formattedValue: undefined,
46
55
  offset: scale.range()[1],
47
56
  labelOffset: 0
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v8.19.0
2
+ * @mui/x-charts v8.20.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -1,23 +1,29 @@
1
1
  import { AllSeriesType } from "../../../../models/seriesType/index.js";
2
2
  import { ChartSeriesType, DatasetType } from "../../../../models/seriesType/config.js";
3
3
  import { ChartSeriesConfig } from "../../models/seriesConfig/index.js";
4
- import { SeriesProcessorResult } from "../../models/seriesConfig/seriesProcessor.types.js";
4
+ import { DefaultizedSeriesGroups, ProcessedSeries } from "./useChartSeries.types.js";
5
5
  /**
6
- * This methods is the interface between what the developer is providing and what components receives
7
- * To simplify the components behaviors, it groups series by type, such that LinePlots props are not updated if some line data are modified
8
- * It also add defaultized values such as the ids, colors
6
+ * This method groups series by type and adds defaultized values such as the ids and colors.
7
+ * It does NOT apply the series processors - that happens in a selector.
9
8
  * @param series The array of series provided by the developer
10
9
  * @param colors The color palette used to defaultize series colors
11
- * @returns An object structuring all the series by type.
10
+ * @returns An object structuring all the series by type with default values.
12
11
  */
13
- export declare const preprocessSeries: <TSeriesType extends ChartSeriesType>({
12
+ export declare const defaultizeSeries: <TSeriesType extends ChartSeriesType>({
14
13
  series,
15
14
  colors,
16
- seriesConfig,
17
- dataset
15
+ seriesConfig
18
16
  }: {
19
17
  series: Readonly<AllSeriesType<TSeriesType>[]>;
20
18
  colors: readonly string[];
21
19
  seriesConfig: ChartSeriesConfig<TSeriesType>;
22
- dataset?: Readonly<DatasetType>;
23
- }) => { [type in TSeriesType]?: SeriesProcessorResult<TSeriesType> | undefined };
20
+ }) => DefaultizedSeriesGroups<TSeriesType>;
21
+ /**
22
+ * Applies series processors to the defaultized series groups.
23
+ * This should be called in a selector to compute processed series on-demand.
24
+ * @param defaultizedSeries The defaultized series groups
25
+ * @param seriesConfig The series configuration
26
+ * @param dataset The optional dataset
27
+ * @returns Processed series with all transformations applied
28
+ */
29
+ export declare const applySeriesProcessors: <TSeriesType extends ChartSeriesType>(defaultizedSeries: DefaultizedSeriesGroups<TSeriesType>, seriesConfig: ChartSeriesConfig<TSeriesType>, dataset?: Readonly<DatasetType>) => ProcessedSeries<TSeriesType>;
@@ -1,22 +1,17 @@
1
1
  /**
2
- * This methods is the interface between what the developer is providing and what components receives
3
- * To simplify the components behaviors, it groups series by type, such that LinePlots props are not updated if some line data are modified
4
- * It also add defaultized values such as the ids, colors
2
+ * This method groups series by type and adds defaultized values such as the ids and colors.
3
+ * It does NOT apply the series processors - that happens in a selector.
5
4
  * @param series The array of series provided by the developer
6
5
  * @param colors The color palette used to defaultize series colors
7
- * @returns An object structuring all the series by type.
6
+ * @returns An object structuring all the series by type with default values.
8
7
  */
9
- export const preprocessSeries = ({
8
+ export const defaultizeSeries = ({
10
9
  series,
11
10
  colors,
12
- seriesConfig,
13
- dataset
11
+ seriesConfig
14
12
  }) => {
15
13
  // Group series by type
16
14
  const seriesGroups = {};
17
- // Notice the line about uses `ChartSeriesType` instead of TSeriesType.
18
- // That's probably because the series.type is not propagated from the generic but hardcoded in the config.
19
-
20
15
  series.forEach((seriesData, seriesIndex) => {
21
16
  const seriesWithDefaultValues = seriesConfig[seriesData.type].getSeriesWithDefaultValues(seriesData, seriesIndex, colors);
22
17
  const id = seriesWithDefaultValues.id;
@@ -32,12 +27,25 @@ export const preprocessSeries = ({
32
27
  seriesGroups[seriesData.type].series[id] = seriesWithDefaultValues;
33
28
  seriesGroups[seriesData.type].seriesOrder.push(id);
34
29
  });
30
+ return seriesGroups;
31
+ };
32
+
33
+ /**
34
+ * Applies series processors to the defaultized series groups.
35
+ * This should be called in a selector to compute processed series on-demand.
36
+ * @param defaultizedSeries The defaultized series groups
37
+ * @param seriesConfig The series configuration
38
+ * @param dataset The optional dataset
39
+ * @returns Processed series with all transformations applied
40
+ */
41
+ export const applySeriesProcessors = (defaultizedSeries, seriesConfig, dataset) => {
35
42
  const processedSeries = {};
43
+
36
44
  // Apply formatter on a type group
37
45
  Object.keys(seriesConfig).forEach(type => {
38
- const group = seriesGroups[type];
46
+ const group = defaultizedSeries[type];
39
47
  if (group !== undefined) {
40
- processedSeries[type] = seriesConfig[type]?.seriesProcessor?.(group, dataset) ?? seriesGroups[type];
48
+ processedSeries[type] = seriesConfig[type]?.seriesProcessor?.(group, dataset) ?? group;
41
49
  }
42
50
  });
43
51
  return processedSeries;
@@ -3,7 +3,7 @@
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
5
  import { rainbowSurgePalette } from "../../../../colorPalettes/index.js";
6
- import { preprocessSeries } from "./processSeries.js";
6
+ import { defaultizeSeries } from "./processSeries.js";
7
7
  export const useChartSeries = ({
8
8
  params,
9
9
  store,
@@ -25,11 +25,10 @@ export const useChartSeries = ({
25
25
  return;
26
26
  }
27
27
  store.set('series', _extends({}, store.state.series, {
28
- processedSeries: preprocessSeries({
28
+ defaultizedSeries: defaultizeSeries({
29
29
  series,
30
30
  colors: typeof colors === 'function' ? colors(theme) : colors,
31
- seriesConfig,
32
- dataset
31
+ seriesConfig
33
32
  }),
34
33
  dataset
35
34
  }));
@@ -59,11 +58,10 @@ useChartSeries.getInitialState = ({
59
58
  return {
60
59
  series: {
61
60
  seriesConfig,
62
- processedSeries: preprocessSeries({
61
+ defaultizedSeries: defaultizeSeries({
63
62
  series,
64
63
  colors: typeof colors === 'function' ? colors(theme) : colors,
65
- seriesConfig,
66
- dataset
64
+ seriesConfig
67
65
  }),
68
66
  dataset
69
67
  }
@@ -1,17 +1,24 @@
1
1
  import { ChartRootSelector } from "../../utils/selectors.js";
2
2
  import { UseChartSeriesSignature } from "./useChartSeries.types.js";
3
3
  export declare const selectorChartSeriesState: ChartRootSelector<UseChartSeriesSignature>;
4
- export declare const selectorChartSeriesProcessed: (args_0: import("../useChartId/useChartId.types.js").UseChartIdState & import("../useChartExperimentalFeature/useChartExperimentalFeature.types.js").UseChartExperimentalFeaturesState & import("../useChartDimensions/useChartDimensions.types.js").UseChartDimensionsState & import("./useChartSeries.types.js").UseChartSeriesState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../useChartAnimation/useChartAnimation.types.js").UseChartAnimationState & import("../useChartInteractionListener/index.js").UseChartInteractionListenerState & Partial<{}> & {
4
+ export declare const selectorChartDefaultizedSeries: (args_0: import("../useChartId/useChartId.types.js").UseChartIdState & import("../useChartExperimentalFeature/useChartExperimentalFeature.types.js").UseChartExperimentalFeaturesState & import("../useChartDimensions/useChartDimensions.types.js").UseChartDimensionsState & import("./useChartSeries.types.js").UseChartSeriesState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../useChartAnimation/useChartAnimation.types.js").UseChartAnimationState & import("../useChartInteractionListener/index.js").UseChartInteractionListenerState & Partial<{}> & {
5
5
  cacheKey: import("../../models/index.js").ChartStateCacheKey;
6
- }) => import("./useChartSeries.types.js").ProcessedSeries<keyof import("../../../index.js").ChartsSeriesConfig>;
6
+ }) => import("./useChartSeries.types.js").DefaultizedSeriesGroups<keyof import("../../../index.js").ChartsSeriesConfig>;
7
7
  export declare const selectorChartSeriesConfig: (args_0: import("../useChartId/useChartId.types.js").UseChartIdState & import("../useChartExperimentalFeature/useChartExperimentalFeature.types.js").UseChartExperimentalFeaturesState & import("../useChartDimensions/useChartDimensions.types.js").UseChartDimensionsState & import("./useChartSeries.types.js").UseChartSeriesState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../useChartAnimation/useChartAnimation.types.js").UseChartAnimationState & import("../useChartInteractionListener/index.js").UseChartInteractionListenerState & Partial<{}> & {
8
8
  cacheKey: import("../../models/index.js").ChartStateCacheKey;
9
9
  }) => import("../../models/index.js").ChartSeriesConfig<keyof import("../../../index.js").ChartsSeriesConfig>;
10
10
  /**
11
11
  * Get the dataset from the series state.
12
- * @param {ChartState<[UseChartSeriesSignature]>} state The state of the chart.
13
12
  * @returns {DatasetType | undefined} The dataset.
14
13
  */
15
14
  export declare const selectorChartDataset: (args_0: import("../useChartId/useChartId.types.js").UseChartIdState & import("../useChartExperimentalFeature/useChartExperimentalFeature.types.js").UseChartExperimentalFeaturesState & import("../useChartDimensions/useChartDimensions.types.js").UseChartDimensionsState & import("./useChartSeries.types.js").UseChartSeriesState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../useChartAnimation/useChartAnimation.types.js").UseChartAnimationState & import("../useChartInteractionListener/index.js").UseChartInteractionListenerState & Partial<{}> & {
16
15
  cacheKey: import("../../models/index.js").ChartStateCacheKey;
17
- }) => readonly import("../../../index.js").DatasetElementType<unknown>[] | undefined;
16
+ }) => readonly import("../../../index.js").DatasetElementType<unknown>[] | undefined;
17
+ /**
18
+ * Get the processed series after applying series processors.
19
+ * This selector computes the processed series on-demand from the defaultized series.
20
+ * @returns {ProcessedSeries} The processed series.
21
+ */
22
+ export declare const selectorChartSeriesProcessed: (args_0: import("../useChartId/useChartId.types.js").UseChartIdState & import("../useChartExperimentalFeature/useChartExperimentalFeature.types.js").UseChartExperimentalFeaturesState & import("../useChartDimensions/useChartDimensions.types.js").UseChartDimensionsState & import("./useChartSeries.types.js").UseChartSeriesState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../useChartAnimation/useChartAnimation.types.js").UseChartAnimationState & import("../useChartInteractionListener/index.js").UseChartInteractionListenerState & Partial<{}> & {
23
+ cacheKey: import("../../models/index.js").ChartStateCacheKey;
24
+ }) => import("./useChartSeries.types.js").ProcessedSeries<keyof import("../../../index.js").ChartsSeriesConfig>;
@@ -1,11 +1,20 @@
1
- import { createSelector } from '@mui/x-internals/store';
1
+ import { createSelectorMemoized, createSelector } from '@mui/x-internals/store';
2
+ import { applySeriesProcessors } from "./processSeries.js";
2
3
  export const selectorChartSeriesState = state => state.series;
3
- export const selectorChartSeriesProcessed = createSelector(selectorChartSeriesState, seriesState => seriesState.processedSeries);
4
+ export const selectorChartDefaultizedSeries = createSelector(selectorChartSeriesState, seriesState => seriesState.defaultizedSeries);
4
5
  export const selectorChartSeriesConfig = createSelector(selectorChartSeriesState, seriesState => seriesState.seriesConfig);
5
6
 
6
7
  /**
7
8
  * Get the dataset from the series state.
8
- * @param {ChartState<[UseChartSeriesSignature]>} state The state of the chart.
9
9
  * @returns {DatasetType | undefined} The dataset.
10
10
  */
11
- export const selectorChartDataset = createSelector(selectorChartSeriesState, seriesState => seriesState.dataset);
11
+ export const selectorChartDataset = createSelector(selectorChartSeriesState, seriesState => seriesState.dataset);
12
+
13
+ /**
14
+ * Get the processed series after applying series processors.
15
+ * This selector computes the processed series on-demand from the defaultized series.
16
+ * @returns {ProcessedSeries} The processed series.
17
+ */
18
+ export const selectorChartSeriesProcessed = createSelectorMemoized(selectorChartDefaultizedSeries, selectorChartSeriesConfig, selectorChartDataset, function selectorChartSeriesProcessed(defaultizedSeries, seriesConfig, dataset) {
19
+ return applySeriesProcessors(defaultizedSeries, seriesConfig, dataset);
20
+ });
@@ -2,7 +2,7 @@ import { AllSeriesType } from "../../../../models/seriesType/index.js";
2
2
  import { ChartsColorPalette } from "../../../../colorPalettes/index.js";
3
3
  import { ChartPluginSignature, ChartSeriesConfig } from "../../models/index.js";
4
4
  import { ChartSeriesType, DatasetType } from "../../../../models/seriesType/config.js";
5
- import { SeriesProcessorResult } from "../../models/seriesConfig/seriesProcessor.types.js";
5
+ import { SeriesProcessorParams, SeriesProcessorResult } from "../../models/seriesConfig/seriesProcessor.types.js";
6
6
  export interface UseChartSeriesParameters<T extends ChartSeriesType = ChartSeriesType> {
7
7
  /**
8
8
  * An array of objects that can be used to populate series and axes data using their `dataKey` property.
@@ -36,9 +36,10 @@ export type UseChartSeriesDefaultizedParameters<T extends ChartSeriesType = Char
36
36
  theme: 'light' | 'dark';
37
37
  };
38
38
  export type ProcessedSeries<TSeriesTypes extends ChartSeriesType = ChartSeriesType> = { [type in TSeriesTypes]?: SeriesProcessorResult<type> };
39
+ export type DefaultizedSeriesGroups<TSeriesTypes extends ChartSeriesType = ChartSeriesType> = { [type in TSeriesTypes]?: SeriesProcessorParams<type> };
39
40
  export interface UseChartSeriesState<T extends ChartSeriesType = ChartSeriesType> {
40
41
  series: {
41
- processedSeries: ProcessedSeries<T>;
42
+ defaultizedSeries: DefaultizedSeriesGroups<T>;
42
43
  seriesConfig: ChartSeriesConfig<T>;
43
44
  dataset?: Readonly<DatasetType>;
44
45
  };