@mui/x-charts 7.12.1 → 7.14.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 (128) hide show
  1. package/BarChart/BarChart.js +2 -0
  2. package/BarChart/BarPlot.js +4 -3
  3. package/BarChart/extremums.js +46 -9
  4. package/CHANGELOG.md +162 -1
  5. package/ChartContainer/ChartContainer.d.ts +3 -3
  6. package/ChartContainer/ChartContainer.js +4 -2
  7. package/ChartContainer/useChartContainerProps.d.ts +4 -2
  8. package/ChartContainer/useChartContainerProps.js +3 -3
  9. package/ChartContainer/useDefaultizeAxis.d.ts +3 -1
  10. package/ChartContainer/useDefaultizeAxis.js +16 -5
  11. package/ChartsAxisHighlight/ChartsAxisHighlight.js +23 -9
  12. package/ChartsGrid/ChartsGrid.js +6 -4
  13. package/ChartsTooltip/utils.js +4 -2
  14. package/ChartsXAxis/ChartsXAxis.js +25 -8
  15. package/ChartsYAxis/ChartsYAxis.js +19 -7
  16. package/LineChart/AreaPlot.js +11 -1
  17. package/LineChart/LineChart.js +2 -0
  18. package/LineChart/extremums.js +23 -18
  19. package/PieChart/PieChart.js +2 -0
  20. package/ResponsiveChartContainer/ResponsiveChartContainer.js +2 -0
  21. package/ResponsiveChartContainer/useResponsiveChartContainerProps.d.ts +1 -1
  22. package/ScatterChart/ScatterChart.js +2 -0
  23. package/ScatterChart/extremums.js +30 -22
  24. package/SparkLineChart/SparkLineChart.js +2 -0
  25. package/context/CartesianProvider/Cartesian.types.d.ts +59 -0
  26. package/context/CartesianProvider/Cartesian.types.js +5 -0
  27. package/context/CartesianProvider/CartesianContext.d.ts +1 -22
  28. package/context/CartesianProvider/CartesianProvider.d.ts +3 -23
  29. package/context/CartesianProvider/CartesianProvider.js +4 -7
  30. package/context/CartesianProvider/computeValue.d.ts +18 -31
  31. package/context/CartesianProvider/computeValue.js +20 -23
  32. package/context/CartesianProvider/defaultizeAxis.d.ts +1 -0
  33. package/context/CartesianProvider/getAxisExtremum.d.ts +3 -2
  34. package/context/CartesianProvider/getAxisExtremum.js +10 -11
  35. package/context/CartesianProvider/index.d.ts +1 -0
  36. package/context/CartesianProvider/index.js +12 -0
  37. package/context/CartesianProvider/useCartesianContext.d.ts +1 -1
  38. package/context/CartesianProvider/zoom.d.ts +10 -0
  39. package/context/CartesianProvider/zoom.js +26 -0
  40. package/context/DrawingProvider.d.ts +7 -2
  41. package/context/DrawingProvider.js +11 -3
  42. package/context/PluginProvider/ExtremumGetter.types.d.ts +12 -2
  43. package/esm/BarChart/BarChart.js +2 -0
  44. package/esm/BarChart/BarPlot.js +4 -3
  45. package/esm/BarChart/extremums.js +46 -9
  46. package/esm/ChartContainer/ChartContainer.js +5 -3
  47. package/esm/ChartContainer/useChartContainerProps.js +3 -3
  48. package/esm/ChartContainer/useDefaultizeAxis.js +16 -5
  49. package/esm/ChartsAxisHighlight/ChartsAxisHighlight.js +23 -9
  50. package/esm/ChartsGrid/ChartsGrid.js +6 -4
  51. package/esm/ChartsTooltip/utils.js +4 -2
  52. package/esm/ChartsXAxis/ChartsXAxis.js +25 -8
  53. package/esm/ChartsYAxis/ChartsYAxis.js +19 -7
  54. package/esm/LineChart/AreaPlot.js +11 -1
  55. package/esm/LineChart/LineChart.js +2 -0
  56. package/esm/LineChart/extremums.js +23 -18
  57. package/esm/PieChart/PieChart.js +2 -0
  58. package/esm/ResponsiveChartContainer/ResponsiveChartContainer.js +2 -0
  59. package/esm/ScatterChart/ScatterChart.js +2 -0
  60. package/esm/ScatterChart/extremums.js +30 -22
  61. package/esm/SparkLineChart/SparkLineChart.js +2 -0
  62. package/esm/context/CartesianProvider/Cartesian.types.js +1 -0
  63. package/esm/context/CartesianProvider/CartesianProvider.js +4 -7
  64. package/esm/context/CartesianProvider/computeValue.js +20 -23
  65. package/esm/context/CartesianProvider/getAxisExtremum.js +10 -11
  66. package/esm/context/CartesianProvider/index.js +1 -0
  67. package/esm/context/CartesianProvider/zoom.js +19 -0
  68. package/esm/context/DrawingProvider.js +11 -3
  69. package/esm/hooks/useAxisEvents.js +3 -1
  70. package/esm/hooks/useTicks.js +5 -2
  71. package/esm/internals/domUtils.js +16 -3
  72. package/esm/internals/index.js +3 -0
  73. package/esm/internals/isInfinity.js +3 -0
  74. package/esm/models/axis.js +5 -0
  75. package/esm/tests/firePointerEvent.js +35 -0
  76. package/hooks/useAxisEvents.js +3 -1
  77. package/hooks/useTicks.js +5 -2
  78. package/index.js +1 -1
  79. package/internals/defaultizeColor.d.ts +1 -0
  80. package/internals/domUtils.d.ts +2 -0
  81. package/internals/domUtils.js +19 -5
  82. package/internals/index.d.ts +2 -0
  83. package/internals/index.js +17 -1
  84. package/internals/isInfinity.d.ts +1 -0
  85. package/internals/isInfinity.js +9 -0
  86. package/models/axis.d.ts +6 -0
  87. package/models/axis.js +5 -0
  88. package/models/seriesType/line.d.ts +10 -0
  89. package/modern/BarChart/BarChart.js +2 -0
  90. package/modern/BarChart/BarPlot.js +4 -3
  91. package/modern/BarChart/extremums.js +46 -9
  92. package/modern/ChartContainer/ChartContainer.js +5 -3
  93. package/modern/ChartContainer/useChartContainerProps.js +3 -3
  94. package/modern/ChartContainer/useDefaultizeAxis.js +16 -5
  95. package/modern/ChartsAxisHighlight/ChartsAxisHighlight.js +23 -9
  96. package/modern/ChartsGrid/ChartsGrid.js +6 -4
  97. package/modern/ChartsTooltip/utils.js +4 -2
  98. package/modern/ChartsXAxis/ChartsXAxis.js +25 -8
  99. package/modern/ChartsYAxis/ChartsYAxis.js +19 -7
  100. package/modern/LineChart/AreaPlot.js +11 -1
  101. package/modern/LineChart/LineChart.js +2 -0
  102. package/modern/LineChart/extremums.js +23 -18
  103. package/modern/PieChart/PieChart.js +2 -0
  104. package/modern/ResponsiveChartContainer/ResponsiveChartContainer.js +2 -0
  105. package/modern/ScatterChart/ScatterChart.js +2 -0
  106. package/modern/ScatterChart/extremums.js +30 -22
  107. package/modern/SparkLineChart/SparkLineChart.js +2 -0
  108. package/modern/context/CartesianProvider/Cartesian.types.js +1 -0
  109. package/modern/context/CartesianProvider/CartesianProvider.js +4 -7
  110. package/modern/context/CartesianProvider/computeValue.js +20 -23
  111. package/modern/context/CartesianProvider/getAxisExtremum.js +10 -11
  112. package/modern/context/CartesianProvider/index.js +1 -0
  113. package/modern/context/CartesianProvider/zoom.js +19 -0
  114. package/modern/context/DrawingProvider.js +11 -3
  115. package/modern/hooks/useAxisEvents.js +3 -1
  116. package/modern/hooks/useTicks.js +5 -2
  117. package/modern/index.js +1 -1
  118. package/modern/internals/domUtils.js +16 -3
  119. package/modern/internals/index.js +3 -0
  120. package/modern/internals/isInfinity.js +3 -0
  121. package/modern/models/axis.js +5 -0
  122. package/modern/tests/firePointerEvent.js +35 -0
  123. package/package.json +4 -4
  124. package/tests/firePointerEvent.js +42 -0
  125. package/context/CartesianProvider/normalizeAxis.d.ts +0 -5
  126. package/context/CartesianProvider/normalizeAxis.js +0 -23
  127. package/esm/context/CartesianProvider/normalizeAxis.js +0 -15
  128. package/modern/context/CartesianProvider/normalizeAxis.js +0 -15
@@ -25,16 +25,30 @@ export const ChartsAxisHighlightPath = styled('path', {
25
25
  slot: 'Root',
26
26
  overridesResolver: (_, styles) => styles.root
27
27
  })(({
28
- ownerState,
29
28
  theme
30
- }) => _extends({
31
- pointerEvents: 'none'
32
- }, ownerState.axisHighlight === 'band' && {
33
- fill: theme.palette.mode === 'light' ? 'gray' : 'white',
34
- fillOpacity: 0.1
35
- }, ownerState.axisHighlight === 'line' && {
36
- strokeDasharray: '5 2',
37
- stroke: theme.palette.mode === 'light' ? '#000000' : '#ffffff'
29
+ }) => ({
30
+ pointerEvents: 'none',
31
+ variants: [{
32
+ props: {
33
+ axisHighlight: 'band'
34
+ },
35
+ style: _extends({
36
+ fill: 'white',
37
+ fillOpacity: 0.1
38
+ }, theme.applyStyles('light', {
39
+ fill: 'gray'
40
+ }))
41
+ }, {
42
+ props: {
43
+ axisHighlight: 'line'
44
+ },
45
+ style: _extends({
46
+ strokeDasharray: '5 2',
47
+ stroke: '#ffffff'
48
+ }, theme.applyStyles('light', {
49
+ stroke: '#000000'
50
+ }))
51
+ }]
38
52
  }));
39
53
  /**
40
54
  * Demos:
@@ -8,6 +8,7 @@ import { styled, useThemeProps } from '@mui/material/styles';
8
8
  import { useCartesianContext } from '../context/CartesianProvider';
9
9
  import { useTicks } from '../hooks/useTicks';
10
10
  import { getChartsGridUtilityClass, chartsGridClasses } from './chartsGridClasses';
11
+ import { useDrawingArea } from '../hooks/useDrawingArea';
11
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
13
  const GridRoot = styled('g', {
13
14
  name: 'MuiChartsGrid',
@@ -53,6 +54,7 @@ function ChartsGrid(props) {
53
54
  props,
54
55
  name: 'MuiChartsGrid'
55
56
  });
57
+ const drawingArea = useDrawingArea();
56
58
  const {
57
59
  vertical,
58
60
  horizontal
@@ -93,8 +95,8 @@ function ChartsGrid(props) {
93
95
  formattedValue,
94
96
  offset
95
97
  }) => /*#__PURE__*/_jsx(GridLine, {
96
- y1: yScale.range()[0],
97
- y2: yScale.range()[1],
98
+ y1: drawingArea.top,
99
+ y2: drawingArea.top + drawingArea.height,
98
100
  x1: offset,
99
101
  x2: offset,
100
102
  className: classes.verticalLine
@@ -104,8 +106,8 @@ function ChartsGrid(props) {
104
106
  }) => /*#__PURE__*/_jsx(GridLine, {
105
107
  y1: offset,
106
108
  y2: offset,
107
- x1: xScale.range()[0],
108
- x2: xScale.range()[1],
109
+ x1: drawingArea.left,
110
+ x2: drawingArea.left + drawingArea.width,
109
111
  className: classes.horizontalLine
110
112
  }, `horizontal-${formattedValue}`))]
111
113
  }));
@@ -47,8 +47,10 @@ export function useMouseTracker() {
47
47
  if (element === null) {
48
48
  return () => {};
49
49
  }
50
- const handleOut = () => {
51
- setMousePosition(null);
50
+ const handleOut = event => {
51
+ if (event.pointerType !== 'mouse') {
52
+ setMousePosition(null);
53
+ }
52
54
  };
53
55
  const handleMove = event => {
54
56
  setMousePosition({
@@ -15,6 +15,8 @@ import { getMinXTranslation } from '../internals/geometry';
15
15
  import { useMounted } from '../hooks/useMounted';
16
16
  import { useDrawingArea } from '../hooks/useDrawingArea';
17
17
  import { getWordsByLines } from '../internals/getWordsByLines';
18
+ import { isInfinity } from '../internals/isInfinity';
19
+ import { isBandScale } from '../internals/isBandScale';
18
20
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
21
  const useUtilityClasses = ownerState => {
20
22
  const {
@@ -137,7 +139,8 @@ function ChartsXAxis(inProps) {
137
139
  tickInterval,
138
140
  tickLabelInterval,
139
141
  tickPlacement,
140
- tickLabelPlacement
142
+ tickLabelPlacement,
143
+ sx
141
144
  } = defaultizedProps;
142
145
  const theme = useTheme();
143
146
  const classes = useUtilityClasses(_extends({}, defaultizedProps, {
@@ -147,7 +150,8 @@ function ChartsXAxis(inProps) {
147
150
  left,
148
151
  top,
149
152
  width,
150
- height
153
+ height,
154
+ isPointInside
151
155
  } = useDrawingArea();
152
156
  const tickSize = disableTicks ? 4 : tickSizeProp;
153
157
  const positionSign = position === 'bottom' ? 1 : -1;
@@ -199,15 +203,17 @@ function ChartsXAxis(inProps) {
199
203
  ownerState: {}
200
204
  });
201
205
  const domain = xScale.domain();
202
- if (domain.length === 0 || domain[0] === domain[1]) {
203
- // Skip axis rendering if
204
- // - the data is empty (for band and point axis)
205
- // - No data is associated to the axis (other scale types)
206
+ const ordinalAxis = isBandScale(xScale);
207
+ // Skip axis rendering if no data is available
208
+ // - The domain is an empty array for band/point scales.
209
+ // - The domains contains Infinity for continuous scales.
210
+ if (ordinalAxis && domain.length === 0 || !ordinalAxis && domain.some(isInfinity)) {
206
211
  return null;
207
212
  }
208
213
  return /*#__PURE__*/_jsxs(AxisRoot, {
209
214
  transform: `translate(0, ${position === 'bottom' ? top + height : top})`,
210
215
  className: classes.root,
216
+ sx: sx,
211
217
  children: [!disableLine && /*#__PURE__*/_jsx(Line, _extends({
212
218
  x1: left,
213
219
  x2: left + width,
@@ -220,8 +226,18 @@ function ChartsXAxis(inProps) {
220
226
  }, index) => {
221
227
  const xTickLabel = labelOffset ?? 0;
222
228
  const yTickLabel = positionSign * (tickSize + 3);
223
- const showTick = offset >= left - 1 && offset <= left + width + 1;
224
- const showTickLabel = offset + xTickLabel >= left - 1 && offset + xTickLabel <= left + width + 1;
229
+ const showTick = isPointInside({
230
+ x: offset,
231
+ y: -1
232
+ }, {
233
+ direction: 'x'
234
+ });
235
+ const showTickLabel = isPointInside({
236
+ x: offset + xTickLabel,
237
+ y: -1
238
+ }, {
239
+ direction: 'x'
240
+ });
225
241
  return /*#__PURE__*/_jsxs("g", {
226
242
  transform: `translate(${offset}, 0)`,
227
243
  className: classes.tickContainer,
@@ -305,6 +321,7 @@ process.env.NODE_ENV !== "production" ? ChartsXAxis.propTypes = {
305
321
  * @default 'currentColor'
306
322
  */
307
323
  stroke: PropTypes.string,
324
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
308
325
  /**
309
326
  * The font size of the axis ticks text.
310
327
  * @default 12
@@ -12,6 +12,8 @@ import { useDrawingArea } from '../hooks/useDrawingArea';
12
12
  import { AxisRoot } from '../internals/components/AxisSharedComponents';
13
13
  import { ChartsText } from '../ChartsText';
14
14
  import { getAxisUtilityClass } from '../ChartsAxis/axisClasses';
15
+ import { isInfinity } from '../internals/isInfinity';
16
+ import { isBandScale } from '../internals/isBandScale';
15
17
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
18
  const useUtilityClasses = ownerState => {
17
19
  const {
@@ -78,7 +80,8 @@ function ChartsYAxis(inProps) {
78
80
  tickPlacement,
79
81
  tickLabelPlacement,
80
82
  tickInterval,
81
- tickLabelInterval
83
+ tickLabelInterval,
84
+ sx
82
85
  } = defaultizedProps;
83
86
  const theme = useTheme();
84
87
  const isRTL = theme.direction === 'rtl';
@@ -89,7 +92,8 @@ function ChartsYAxis(inProps) {
89
92
  left,
90
93
  top,
91
94
  width,
92
- height
95
+ height,
96
+ isPointInside
93
97
  } = useDrawingArea();
94
98
  const tickSize = disableTicks ? 4 : tickSizeProp;
95
99
  const yTicks = useTicks({
@@ -145,15 +149,17 @@ function ChartsYAxis(inProps) {
145
149
  ownerState: {}
146
150
  });
147
151
  const domain = yScale.domain();
148
- if (domain.length === 0 || domain[0] === domain[1]) {
149
- // Skip axis rendering if
150
- // - the data is empty (for band and point axis)
151
- // - No data is associated to the axis (other scale types)
152
+ const ordinalAxis = isBandScale(yScale);
153
+ // Skip axis rendering if no data is available
154
+ // - The domain is an empty array for band/point scales.
155
+ // - The domains contains Infinity for continuous scales.
156
+ if (ordinalAxis && domain.length === 0 || !ordinalAxis && domain.some(isInfinity)) {
152
157
  return null;
153
158
  }
154
159
  return /*#__PURE__*/_jsxs(AxisRoot, {
155
160
  transform: `translate(${position === 'right' ? left + width : left}, 0)`,
156
161
  className: classes.root,
162
+ sx: sx,
157
163
  children: [!disableLine && /*#__PURE__*/_jsx(Line, _extends({
158
164
  y1: top,
159
165
  y2: top + height,
@@ -167,7 +173,12 @@ function ChartsYAxis(inProps) {
167
173
  const xTickLabel = positionSign * (tickSize + 2);
168
174
  const yTickLabel = labelOffset;
169
175
  const skipLabel = typeof tickLabelInterval === 'function' && !tickLabelInterval?.(value, index);
170
- const showLabel = offset >= top - 1 && offset <= height + top + 1;
176
+ const showLabel = isPointInside({
177
+ x: -1,
178
+ y: offset
179
+ }, {
180
+ direction: 'y'
181
+ });
171
182
  if (!showLabel) {
172
183
  return null;
173
184
  }
@@ -253,6 +264,7 @@ process.env.NODE_ENV !== "production" ? ChartsYAxis.propTypes = {
253
264
  * @default 'currentColor'
254
265
  */
255
266
  stroke: PropTypes.string,
267
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
256
268
  /**
257
269
  * The font size of the axis ticks text.
258
270
  * @default 12
@@ -42,7 +42,8 @@ const useAggregatedData = () => {
42
42
  yAxisKey = defaultYAxisId,
43
43
  stackedData,
44
44
  data,
45
- connectNulls
45
+ connectNulls,
46
+ baseline
46
47
  } = series[seriesId];
47
48
  const xAxisId = xAxisIdProp ?? xAxisKey;
48
49
  const yAxisId = yAxisIdProp ?? yAxisKey;
@@ -59,6 +60,15 @@ const useAggregatedData = () => {
59
60
  }
60
61
  }
61
62
  const areaPath = d3Area().x(d => xScale(d.x)).defined((_, i) => connectNulls || data[i] != null).y0(d => {
63
+ if (typeof baseline === 'number') {
64
+ return yScale(baseline);
65
+ }
66
+ if (baseline === 'max') {
67
+ return yScale.range()[1];
68
+ }
69
+ if (baseline === 'min') {
70
+ return yScale.range()[0];
71
+ }
62
72
  const value = d.y && yScale(d.y[0]);
63
73
  if (Number.isNaN(value)) {
64
74
  return yScale.range()[0];
@@ -274,6 +274,7 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
274
274
  slotProps: PropTypes.object,
275
275
  slots: PropTypes.object,
276
276
  stroke: PropTypes.string,
277
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
277
278
  tickFontSize: PropTypes.number,
278
279
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
279
280
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -326,6 +327,7 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
326
327
  slotProps: PropTypes.object,
327
328
  slots: PropTypes.object,
328
329
  stroke: PropTypes.string,
330
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
329
331
  tickFontSize: PropTypes.number,
330
332
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
331
333
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -6,23 +6,27 @@ export const getExtremumX = params => {
6
6
  const maxX = Math.max(...(axis.data ?? []));
7
7
  return [minX, maxX];
8
8
  };
9
- function getSeriesExtremums(getValues, stackedData) {
10
- if (stackedData.length === 0) {
11
- return [null, null];
12
- }
13
- return stackedData.reduce((seriesAcc, stackedValue) => {
9
+ function getSeriesExtremums(getValues, stackedData, filter) {
10
+ return stackedData.reduce((seriesAcc, stackedValue, index) => {
14
11
  const [base, value] = getValues(stackedValue);
15
- if (seriesAcc[0] === null) {
16
- return [Math.min(base, value), Math.max(base, value)];
12
+ if (filter && (!filter({
13
+ y: base,
14
+ x: null
15
+ }, index) || !filter({
16
+ y: value,
17
+ x: null
18
+ }, index))) {
19
+ return seriesAcc;
17
20
  }
18
21
  return [Math.min(base, value, seriesAcc[0]), Math.max(base, value, seriesAcc[1])];
19
- }, getValues(stackedData[0]));
22
+ }, [Infinity, -Infinity]);
20
23
  }
21
24
  export const getExtremumY = params => {
22
25
  const {
23
26
  series,
24
27
  axis,
25
- isDefaultAxis
28
+ isDefaultAxis,
29
+ getFilters
26
30
  } = params;
27
31
  return Object.keys(series).filter(seriesId => {
28
32
  const yAxisId = series[seriesId].yAxisId ?? series[seriesId].yAxisKey;
@@ -33,16 +37,17 @@ export const getExtremumY = params => {
33
37
  stackedData
34
38
  } = series[seriesId];
35
39
  const isArea = area !== undefined;
36
- const getValues = isArea && axis.scaleType !== 'log' ? d => d : d => [d[1], d[1]]; // Since this series is not used to display an area, we do not consider the base (the d[0]).
40
+ const filter = getFilters?.({
41
+ currentAxisId: axis.id,
42
+ isDefaultAxis,
43
+ seriesXAxisId: series[seriesId].xAxisId ?? series[seriesId].xAxisKey,
44
+ seriesYAxisId: series[seriesId].yAxisId ?? series[seriesId].yAxisKey
45
+ });
37
46
 
38
- const seriesExtremums = getSeriesExtremums(getValues, stackedData);
39
- if (acc[0] === null) {
40
- return seriesExtremums;
41
- }
42
- if (seriesExtremums[0] === null) {
43
- return acc;
44
- }
47
+ // Since this series is not used to display an area, we do not consider the base (the d[0]).
48
+ const getValues = isArea && axis.scaleType !== 'log' && typeof series[seriesId].baseline !== 'string' ? d => d : d => [d[1], d[1]];
49
+ const seriesExtremums = getSeriesExtremums(getValues, stackedData, filter);
45
50
  const [seriesMin, seriesMax] = seriesExtremums;
46
51
  return [Math.min(seriesMin, acc[0]), Math.max(seriesMax, acc[1])];
47
- }, [null, null]);
52
+ }, [Infinity, -Infinity]);
48
53
  };
@@ -318,6 +318,7 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
318
318
  slotProps: PropTypes.object,
319
319
  slots: PropTypes.object,
320
320
  stroke: PropTypes.string,
321
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
321
322
  tickFontSize: PropTypes.number,
322
323
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
323
324
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -370,6 +371,7 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
370
371
  slotProps: PropTypes.object,
371
372
  slots: PropTypes.object,
372
373
  stroke: PropTypes.string,
374
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
373
375
  tickFontSize: PropTypes.number,
374
376
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
375
377
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -130,6 +130,7 @@ process.env.NODE_ENV !== "production" ? ResponsiveChartContainer.propTypes = {
130
130
  slotProps: PropTypes.object,
131
131
  slots: PropTypes.object,
132
132
  stroke: PropTypes.string,
133
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
133
134
  tickFontSize: PropTypes.number,
134
135
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
135
136
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -182,6 +183,7 @@ process.env.NODE_ENV !== "production" ? ResponsiveChartContainer.propTypes = {
182
183
  slotProps: PropTypes.object,
183
184
  slots: PropTypes.object,
184
185
  stroke: PropTypes.string,
186
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
185
187
  tickFontSize: PropTypes.number,
186
188
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
187
189
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -255,6 +255,7 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
255
255
  slotProps: PropTypes.object,
256
256
  slots: PropTypes.object,
257
257
  stroke: PropTypes.string,
258
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
258
259
  tickFontSize: PropTypes.number,
259
260
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
260
261
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -307,6 +308,7 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
307
308
  slotProps: PropTypes.object,
308
309
  slots: PropTypes.object,
309
310
  stroke: PropTypes.string,
311
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
310
312
  tickFontSize: PropTypes.number,
311
313
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
312
314
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -1,47 +1,55 @@
1
1
  const mergeMinMax = (acc, val) => {
2
- if (acc[0] === null || acc[1] === null) {
3
- return val;
4
- }
5
- if (val[0] === null || val[1] === null) {
6
- return acc;
7
- }
8
2
  return [Math.min(acc[0], val[0]), Math.max(acc[1], val[1])];
9
3
  };
10
4
  export const getExtremumX = params => {
11
5
  const {
12
6
  series,
13
7
  axis,
14
- isDefaultAxis
8
+ isDefaultAxis,
9
+ getFilters
15
10
  } = params;
16
11
  return Object.keys(series).filter(seriesId => {
17
12
  const axisId = series[seriesId].xAxisId ?? series[seriesId].xAxisKey;
18
13
  return axisId === axis.id || axisId === undefined && isDefaultAxis;
19
14
  }).reduce((acc, seriesId) => {
20
- const seriesMinMax = series[seriesId].data.reduce((accSeries, {
21
- x
22
- }) => {
23
- const val = [x, x];
24
- return mergeMinMax(accSeries, val);
25
- }, [null, null]);
15
+ const filter = getFilters?.({
16
+ currentAxisId: axis.id,
17
+ isDefaultAxis,
18
+ seriesXAxisId: series[seriesId].xAxisId ?? series[seriesId].xAxisKey,
19
+ seriesYAxisId: series[seriesId].yAxisId ?? series[seriesId].yAxisKey
20
+ });
21
+ const seriesMinMax = series[seriesId].data.reduce((accSeries, d, dataIndex) => {
22
+ if (filter && !filter(d, dataIndex)) {
23
+ return accSeries;
24
+ }
25
+ return mergeMinMax(accSeries, [d.x, d.x]);
26
+ }, [Infinity, -Infinity]);
26
27
  return mergeMinMax(acc, seriesMinMax);
27
- }, [null, null]);
28
+ }, [Infinity, -Infinity]);
28
29
  };
29
30
  export const getExtremumY = params => {
30
31
  const {
31
32
  series,
32
33
  axis,
33
- isDefaultAxis
34
+ isDefaultAxis,
35
+ getFilters
34
36
  } = params;
35
37
  return Object.keys(series).filter(seriesId => {
36
38
  const axisId = series[seriesId].yAxisId ?? series[seriesId].yAxisKey;
37
39
  return axisId === axis.id || axisId === undefined && isDefaultAxis;
38
40
  }).reduce((acc, seriesId) => {
39
- const seriesMinMax = series[seriesId].data.reduce((accSeries, {
40
- y
41
- }) => {
42
- const val = [y, y];
43
- return mergeMinMax(accSeries, val);
44
- }, [null, null]);
41
+ const filter = getFilters?.({
42
+ currentAxisId: axis.id,
43
+ isDefaultAxis,
44
+ seriesXAxisId: series[seriesId].xAxisId ?? series[seriesId].xAxisKey,
45
+ seriesYAxisId: series[seriesId].yAxisId ?? series[seriesId].yAxisKey
46
+ });
47
+ const seriesMinMax = series[seriesId].data.reduce((accSeries, d, dataIndex) => {
48
+ if (filter && !filter(d, dataIndex)) {
49
+ return accSeries;
50
+ }
51
+ return mergeMinMax(accSeries, [d.y, d.y]);
52
+ }, [Infinity, -Infinity]);
45
53
  return mergeMinMax(acc, seriesMinMax);
46
- }, [null, null]);
54
+ }, [Infinity, -Infinity]);
47
55
  };
@@ -279,6 +279,7 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes = {
279
279
  slotProps: PropTypes.object,
280
280
  slots: PropTypes.object,
281
281
  stroke: PropTypes.string,
282
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
282
283
  tickFontSize: PropTypes.number,
283
284
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
284
285
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -330,6 +331,7 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes = {
330
331
  slotProps: PropTypes.object,
331
332
  slots: PropTypes.object,
332
333
  stroke: PropTypes.string,
334
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
333
335
  tickFontSize: PropTypes.number,
334
336
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
335
337
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
@@ -6,11 +6,10 @@ import { computeValue } from './computeValue';
6
6
  import { useXExtremumGetter } from '../PluginProvider/useXExtremumGetter';
7
7
  import { useYExtremumGetter } from '../PluginProvider';
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
- function CartesianContextProvider(props) {
9
+ function CartesianProvider(props) {
10
10
  const {
11
11
  xAxis,
12
12
  yAxis,
13
- dataset,
14
13
  children
15
14
  } = props;
16
15
  const formattedSeries = useSeries();
@@ -22,17 +21,15 @@ function CartesianContextProvider(props) {
22
21
  formattedSeries,
23
22
  axis: xAxis,
24
23
  extremumGetters: xExtremumGetters,
25
- dataset,
26
24
  axisDirection: 'x'
27
- }), [drawingArea, formattedSeries, xAxis, xExtremumGetters, dataset]);
25
+ }), [drawingArea, formattedSeries, xAxis, xExtremumGetters]);
28
26
  const yValues = React.useMemo(() => computeValue({
29
27
  drawingArea,
30
28
  formattedSeries,
31
29
  axis: yAxis,
32
30
  extremumGetters: yExtremumGetters,
33
- dataset,
34
31
  axisDirection: 'y'
35
- }), [drawingArea, formattedSeries, yAxis, yExtremumGetters, dataset]);
32
+ }), [drawingArea, formattedSeries, yAxis, yExtremumGetters]);
36
33
  const value = React.useMemo(() => ({
37
34
  isInitialized: true,
38
35
  data: {
@@ -47,4 +44,4 @@ function CartesianContextProvider(props) {
47
44
  children: children
48
45
  });
49
46
  }
50
- export { CartesianContextProvider };
47
+ export { CartesianProvider };
@@ -4,22 +4,12 @@ import { isBandScaleConfig, isPointScaleConfig } from '../../models/axis';
4
4
  import { getColorScale, getOrdinalColorScale } from '../../internals/colorScale';
5
5
  import { getTickNumber } from '../../hooks/useTicks';
6
6
  import { getScale } from '../../internals/getScale';
7
+ import { zoomScaleRange } from './zoom';
7
8
  import { getAxisExtremum } from './getAxisExtremum';
8
- import { normalizeAxis } from './normalizeAxis';
9
9
  const getRange = (drawingArea, axisDirection, isReverse) => {
10
10
  const range = axisDirection === 'x' ? [drawingArea.left, drawingArea.left + drawingArea.width] : [drawingArea.top + drawingArea.height, drawingArea.top];
11
11
  return isReverse ? range.reverse() : range;
12
12
  };
13
- const zoomedScaleRange = (scaleRange, zoomRange) => {
14
- const rangeGap = scaleRange[1] - scaleRange[0];
15
- const zoomGap = zoomRange[1] - zoomRange[0];
16
-
17
- // If current zoom show the scale between p1 and p2 percents
18
- // The range should be extended by adding [0, p1] and [p2, 100] segments
19
- const min = scaleRange[0] - zoomRange[0] * rangeGap / zoomGap;
20
- const max = scaleRange[1] + (100 - zoomRange[1]) * rangeGap / zoomGap;
21
- return [min, max];
22
- };
23
13
  const isDateData = data => data?.[0] instanceof Date;
24
14
  function createDateFormatter(axis, range) {
25
15
  const timeScale = scaleTime(axis.data, range);
@@ -32,32 +22,37 @@ const DEFAULT_BAR_GAP_RATIO = 0.1;
32
22
  export function computeValue({
33
23
  drawingArea,
34
24
  formattedSeries,
35
- axis: inAxis,
25
+ axis: allAxis,
36
26
  extremumGetters,
37
- dataset,
38
27
  axisDirection,
39
- zoomData
28
+ zoomData,
29
+ zoomOptions,
30
+ getFilters
40
31
  }) {
41
- const allAxis = normalizeAxis(inAxis, dataset, axisDirection);
42
32
  const completeAxis = {};
43
- allAxis.forEach((axis, axisIndex) => {
33
+ allAxis.forEach((eachAxis, axisIndex) => {
34
+ const axis = eachAxis;
44
35
  const isDefaultAxis = axisIndex === 0;
45
- const [minData, maxData] = getAxisExtremum(axis, extremumGetters, isDefaultAxis, formattedSeries);
36
+ const zoomOption = zoomOptions?.[axis.id];
46
37
  const zoom = zoomData?.find(({
47
38
  axisId
48
39
  }) => axisId === axis.id);
49
40
  const zoomRange = zoom ? [zoom.start, zoom.end] : [0, 100];
50
41
  const range = getRange(drawingArea, axisDirection, axis.reverse);
42
+ const [minData, maxData] = getAxisExtremum(axis, extremumGetters, isDefaultAxis, formattedSeries, zoom === undefined && !zoomOption ? getFilters : undefined // Do not apply filtering if zoom is already defined.
43
+ );
44
+ const data = axis.data ?? [];
51
45
  if (isBandScaleConfig(axis)) {
52
46
  const categoryGapRatio = axis.categoryGapRatio ?? DEFAULT_CATEGORY_GAP_RATIO;
53
47
  const barGapRatio = axis.barGapRatio ?? DEFAULT_BAR_GAP_RATIO;
54
48
  // Reverse range because ordinal scales are presented from top to bottom on y-axis
55
49
  const scaleRange = axisDirection === 'x' ? range : [range[1], range[0]];
56
- const zoomedRange = zoomedScaleRange(scaleRange, zoomRange);
50
+ const zoomedRange = zoomScaleRange(scaleRange, zoomRange);
57
51
  completeAxis[axis.id] = _extends({
58
52
  categoryGapRatio,
59
53
  barGapRatio
60
54
  }, axis, {
55
+ data,
61
56
  scale: scaleBand(axis.data, zoomedRange).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
62
57
  tickNumber: axis.data.length,
63
58
  colorScale: axis.colorMap && (axis.colorMap.type === 'ordinal' ? getOrdinalColorScale(_extends({
@@ -71,8 +66,9 @@ export function computeValue({
71
66
  }
72
67
  if (isPointScaleConfig(axis)) {
73
68
  const scaleRange = axisDirection === 'x' ? range : [...range].reverse();
74
- const zoomedRange = zoomedScaleRange(scaleRange, zoomRange);
69
+ const zoomedRange = zoomScaleRange(scaleRange, zoomRange);
75
70
  completeAxis[axis.id] = _extends({}, axis, {
71
+ data,
76
72
  scale: scalePoint(axis.data, zoomedRange),
77
73
  tickNumber: axis.data.length,
78
74
  colorScale: axis.colorMap && (axis.colorMap.type === 'ordinal' ? getOrdinalColorScale(_extends({
@@ -89,19 +85,20 @@ export function computeValue({
89
85
  return;
90
86
  }
91
87
  const scaleType = axis.scaleType ?? 'linear';
92
- const extremums = [axis.min ?? minData, axis.max ?? maxData];
88
+ const axisExtremums = [axis.min ?? minData, axis.max ?? maxData];
93
89
  const rawTickNumber = getTickNumber(_extends({}, axis, {
94
90
  range,
95
- domain: extremums
91
+ domain: axisExtremums
96
92
  }));
97
93
  const tickNumber = rawTickNumber / ((zoomRange[1] - zoomRange[0]) / 100);
98
- const zoomedRange = zoomedScaleRange(range, zoomRange);
94
+ const zoomedRange = zoomScaleRange(range, zoomRange);
99
95
 
100
96
  // TODO: move nice to prop? Disable when there is zoom?
101
- const scale = getScale(scaleType, extremums, zoomedRange).nice(rawTickNumber);
97
+ const scale = getScale(scaleType, axisExtremums, zoomedRange).nice(rawTickNumber);
102
98
  const [minDomain, maxDomain] = scale.domain();
103
99
  const domain = [axis.min ?? minDomain, axis.max ?? maxDomain];
104
100
  completeAxis[axis.id] = _extends({}, axis, {
101
+ data,
105
102
  scaleType: scaleType,
106
103
  scale: scale.domain(domain),
107
104
  tickNumber,