@mui/x-charts 7.0.0-beta.5 → 7.0.0-beta.7

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 (57) hide show
  1. package/BarChart/BarChart.js +12 -0
  2. package/CHANGELOG.md +252 -50
  3. package/ChartContainer/ChartContainer.js +4 -0
  4. package/ChartsAxis/ChartsAxis.js +8 -0
  5. package/ChartsLegend/ChartsLegend.d.ts +3 -0
  6. package/ChartsLegend/ChartsLegend.js +3 -0
  7. package/ChartsLegend/DefaultChartsLegend.js +23 -27
  8. package/ChartsTooltip/ChartsTooltip.d.ts +12 -0
  9. package/ChartsTooltip/DefaultChartsAxisTooltipContent.js +3 -1
  10. package/ChartsXAxis/ChartsXAxis.js +18 -2
  11. package/ChartsYAxis/ChartsYAxis.js +18 -2
  12. package/LineChart/LineChart.js +12 -0
  13. package/PieChart/PieChart.js +29 -8
  14. package/ResponsiveChartContainer/ResponsiveChartContainer.js +4 -0
  15. package/ScatterChart/ScatterChart.js +12 -0
  16. package/SparkLineChart/SparkLineChart.js +2 -0
  17. package/esm/BarChart/BarChart.js +12 -0
  18. package/esm/ChartContainer/ChartContainer.js +4 -0
  19. package/esm/ChartsAxis/ChartsAxis.js +8 -0
  20. package/esm/ChartsLegend/ChartsLegend.js +3 -0
  21. package/esm/ChartsLegend/DefaultChartsLegend.js +23 -27
  22. package/esm/ChartsTooltip/DefaultChartsAxisTooltipContent.js +3 -1
  23. package/esm/ChartsXAxis/ChartsXAxis.js +18 -2
  24. package/esm/ChartsYAxis/ChartsYAxis.js +18 -2
  25. package/esm/LineChart/LineChart.js +12 -0
  26. package/esm/PieChart/PieChart.js +29 -8
  27. package/esm/ResponsiveChartContainer/ResponsiveChartContainer.js +4 -0
  28. package/esm/ScatterChart/ScatterChart.js +12 -0
  29. package/esm/SparkLineChart/SparkLineChart.js +2 -0
  30. package/esm/hooks/useAxisEvents.js +9 -1
  31. package/esm/hooks/useTicks.js +23 -9
  32. package/esm/internals/useIsRTL.js +5 -0
  33. package/hooks/useAxisEvents.js +9 -1
  34. package/hooks/useTicks.d.ts +15 -3
  35. package/hooks/useTicks.js +23 -9
  36. package/index.js +1 -1
  37. package/internals/useIsRTL.d.ts +1 -0
  38. package/internals/useIsRTL.js +12 -0
  39. package/models/axis.d.ts +27 -2
  40. package/modern/BarChart/BarChart.js +12 -0
  41. package/modern/ChartContainer/ChartContainer.js +4 -0
  42. package/modern/ChartsAxis/ChartsAxis.js +8 -0
  43. package/modern/ChartsLegend/ChartsLegend.js +3 -0
  44. package/modern/ChartsLegend/DefaultChartsLegend.js +23 -27
  45. package/modern/ChartsTooltip/DefaultChartsAxisTooltipContent.js +3 -1
  46. package/modern/ChartsXAxis/ChartsXAxis.js +18 -2
  47. package/modern/ChartsYAxis/ChartsYAxis.js +18 -2
  48. package/modern/LineChart/LineChart.js +12 -0
  49. package/modern/PieChart/PieChart.js +29 -8
  50. package/modern/ResponsiveChartContainer/ResponsiveChartContainer.js +4 -0
  51. package/modern/ScatterChart/ScatterChart.js +12 -0
  52. package/modern/SparkLineChart/SparkLineChart.js +2 -0
  53. package/modern/hooks/useAxisEvents.js +9 -1
  54. package/modern/hooks/useTicks.js +23 -9
  55. package/modern/index.js +1 -1
  56. package/modern/internals/useIsRTL.js +5 -0
  57. package/package.json +2 -2
@@ -50,6 +50,7 @@ function DefaultChartsLegend(props) {
50
50
  labelStyle: inLabelStyle
51
51
  } = props;
52
52
  const theme = useTheme();
53
+ const isRTL = theme.direction === 'rtl';
53
54
  const labelStyle = React.useMemo(() => _extends({}, theme.typography.subtitle1, {
54
55
  color: 'inherit',
55
56
  dominantBaseline: 'central',
@@ -80,7 +81,7 @@ function DefaultChartsLegend(props) {
80
81
  const totalHeight = drawingArea.top + drawingArea.height + drawingArea.bottom;
81
82
  const availableWidth = totalWidth - padding.left - padding.right;
82
83
  const availableHeight = totalHeight - padding.top - padding.bottom;
83
- const seriesWithPosition = React.useMemo(() => {
84
+ const [seriesWithPosition, legendWidth, legendHeight] = React.useMemo(() => {
84
85
  // Start at 0, 0. Will be modified later by padding and position.
85
86
  let x = 0;
86
87
  let y = 0;
@@ -144,40 +145,31 @@ function DefaultChartsLegend(props) {
144
145
  }
145
146
  return rep;
146
147
  });
147
-
148
- // Move the legend according to padding and position
149
- let gapX = 0;
150
- let gapY = 0;
148
+ return [seriesWithRawPosition.map(item => _extends({}, item, {
149
+ positionY: item.positionY + (direction === 'row' ? rowMaxHeight[item.rowIndex] / 2 // Get the center of the entire row
150
+ : item.outerHeight / 2) // Get the center of the item
151
+ })), totalWidthUsed, totalHeightUsed];
152
+ }, [seriesToDisplay, getItemSpace, labelStyle, direction, availableWidth, availableHeight, itemGap]);
153
+ const gapX = React.useMemo(() => {
151
154
  switch (position.horizontal) {
152
155
  case 'left':
153
- gapX = padding.left;
154
- break;
156
+ return padding.left;
155
157
  case 'right':
156
- gapX = totalWidth - padding.right - totalWidthUsed;
157
- break;
158
+ return totalWidth - padding.right - legendWidth;
158
159
  default:
159
- gapX = (totalWidth - totalWidthUsed) / 2;
160
- break;
160
+ return (totalWidth - legendWidth) / 2;
161
161
  }
162
+ }, [position.horizontal, padding.left, padding.right, totalWidth, legendWidth]);
163
+ const gapY = React.useMemo(() => {
162
164
  switch (position.vertical) {
163
165
  case 'top':
164
- gapY = padding.top;
165
- break;
166
+ return padding.top;
166
167
  case 'bottom':
167
- gapY = totalHeight - padding.bottom - totalHeightUsed;
168
- break;
168
+ return totalHeight - padding.bottom - legendHeight;
169
169
  default:
170
- gapY = (totalHeight - totalHeightUsed) / 2;
171
- break;
170
+ return (totalHeight - legendHeight) / 2;
172
171
  }
173
- return seriesWithRawPosition.map(item => _extends({}, item, {
174
- // Add the gap due to the position
175
- positionX: item.positionX + gapX,
176
- // Add the gap due to the position
177
- positionY: item.positionY + gapY + (direction === 'row' ? rowMaxHeight[item.rowIndex] / 2 // Get the center of the entire row
178
- : item.outerHeight / 2) // Get the center of the item
179
- }));
180
- }, [seriesToDisplay, position.horizontal, position.vertical, getItemSpace, labelStyle, direction, availableWidth, availableHeight, itemGap, padding.left, padding.right, padding.top, padding.bottom, totalWidth, totalHeight]);
172
+ }, [position.vertical, padding.top, padding.bottom, totalHeight, legendHeight]);
181
173
  if (hidden) {
182
174
  return null;
183
175
  }
@@ -192,9 +184,10 @@ function DefaultChartsLegend(props) {
192
184
  positionY
193
185
  }) => /*#__PURE__*/_jsxs("g", {
194
186
  className: classes.series,
195
- transform: `translate(${positionX} ${positionY})`,
187
+ transform: `translate(${gapX + (isRTL ? legendWidth - positionX : positionX)} ${gapY + positionY})`,
196
188
  children: [/*#__PURE__*/_jsx("rect", {
197
189
  className: classes.mark,
190
+ x: isRTL ? -itemMarkWidth : 0,
198
191
  y: -itemMarkHeight / 2,
199
192
  width: itemMarkWidth,
200
193
  height: itemMarkHeight,
@@ -202,7 +195,7 @@ function DefaultChartsLegend(props) {
202
195
  }), /*#__PURE__*/_jsx(ChartsText, {
203
196
  style: labelStyle,
204
197
  text: label,
205
- x: itemMarkWidth + markGap,
198
+ x: (isRTL ? -1 : 1) * (itemMarkWidth + markGap),
206
199
  y: 0
207
200
  })]
208
201
  }, id))
@@ -272,6 +265,9 @@ process.env.NODE_ENV !== "production" ? DefaultChartsLegend.propTypes = {
272
265
  right: PropTypes.number,
273
266
  top: PropTypes.number
274
267
  })]),
268
+ /**
269
+ * The position of the legend.
270
+ */
275
271
  position: PropTypes.shape({
276
272
  horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired,
277
273
  vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired
@@ -29,7 +29,9 @@ function DefaultChartsAxisTooltipContent(props) {
29
29
  children: /*#__PURE__*/_jsx(ChartsTooltipCell, {
30
30
  colSpan: 3,
31
31
  children: /*#__PURE__*/_jsx(Typography, {
32
- children: axisFormatter(axisValue)
32
+ children: axisFormatter(axisValue, {
33
+ location: 'tooltip'
34
+ })
33
35
  })
34
36
  })
35
37
  })
@@ -140,7 +140,9 @@ function ChartsXAxis(inProps) {
140
140
  slots,
141
141
  slotProps,
142
142
  tickInterval,
143
- tickLabelInterval
143
+ tickLabelInterval,
144
+ tickPlacement,
145
+ tickLabelPlacement
144
146
  } = defaultizedProps;
145
147
  const theme = useTheme();
146
148
  const classes = useUtilityClasses(_extends({}, defaultizedProps, {
@@ -176,7 +178,9 @@ function ChartsXAxis(inProps) {
176
178
  scale: xScale,
177
179
  tickNumber,
178
180
  valueFormatter,
179
- tickInterval
181
+ tickInterval,
182
+ tickPlacement,
183
+ tickLabelPlacement
180
184
  });
181
185
  const xTicksWithDimension = addLabelDimension(xTicks, {
182
186
  tickLabelStyle: axisTickLabelProps.style,
@@ -319,6 +323,12 @@ process.env.NODE_ENV !== "production" ? ChartsXAxis.propTypes = {
319
323
  * @default 'auto'
320
324
  */
321
325
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
326
+ /**
327
+ * The placement of ticks label. Can be the middle of the band, or the tick position.
328
+ * Only used if scale is 'band'.
329
+ * @default 'middle'
330
+ */
331
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
322
332
  /**
323
333
  * The style applied to ticks text.
324
334
  */
@@ -340,6 +350,12 @@ process.env.NODE_ENV !== "production" ? ChartsXAxis.propTypes = {
340
350
  * Not supported by categorical axis (band, points).
341
351
  */
342
352
  tickNumber: PropTypes.number,
353
+ /**
354
+ * The placement of ticks in regard to the band interval.
355
+ * Only used if scale is 'band'.
356
+ * @default 'extremities'
357
+ */
358
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
343
359
  /**
344
360
  * The size of the ticks.
345
361
  * @default 6
@@ -79,7 +79,9 @@ function ChartsYAxis(inProps) {
79
79
  tickSize: tickSizeProp,
80
80
  valueFormatter,
81
81
  slots,
82
- slotProps
82
+ slotProps,
83
+ tickPlacement,
84
+ tickLabelPlacement
83
85
  } = defaultizedProps;
84
86
  const theme = useTheme();
85
87
  const classes = useUtilityClasses(_extends({}, defaultizedProps, {
@@ -95,7 +97,9 @@ function ChartsYAxis(inProps) {
95
97
  const yTicks = useTicks({
96
98
  scale: yScale,
97
99
  tickNumber,
98
- valueFormatter
100
+ valueFormatter,
101
+ tickPlacement,
102
+ tickLabelPlacement
99
103
  });
100
104
  const positionSign = position === 'right' ? 1 : -1;
101
105
  const labelRefPoint = {
@@ -249,6 +253,12 @@ process.env.NODE_ENV !== "production" ? ChartsYAxis.propTypes = {
249
253
  * @default 'auto'
250
254
  */
251
255
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
256
+ /**
257
+ * The placement of ticks label. Can be the middle of the band, or the tick position.
258
+ * Only used if scale is 'band'.
259
+ * @default 'middle'
260
+ */
261
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
252
262
  /**
253
263
  * The style applied to ticks text.
254
264
  */
@@ -270,6 +280,12 @@ process.env.NODE_ENV !== "production" ? ChartsYAxis.propTypes = {
270
280
  * Not supported by categorical axis (band, points).
271
281
  */
272
282
  tickNumber: PropTypes.number,
283
+ /**
284
+ * The placement of ticks in regard to the band interval.
285
+ * Only used if scale is 'band'.
286
+ * @default 'extremities'
287
+ */
288
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
273
289
  /**
274
290
  * The size of the ticks.
275
291
  * @default 6
@@ -160,10 +160,12 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
160
160
  tickFontSize: PropTypes.number,
161
161
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
162
162
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
163
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
163
164
  tickLabelStyle: PropTypes.object,
164
165
  tickMaxStep: PropTypes.number,
165
166
  tickMinStep: PropTypes.number,
166
167
  tickNumber: PropTypes.number,
168
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
167
169
  tickSize: PropTypes.number
168
170
  }), PropTypes.string]),
169
171
  children: PropTypes.node,
@@ -220,10 +222,12 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
220
222
  tickFontSize: PropTypes.number,
221
223
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
222
224
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
225
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
223
226
  tickLabelStyle: PropTypes.object,
224
227
  tickMaxStep: PropTypes.number,
225
228
  tickMinStep: PropTypes.number,
226
229
  tickNumber: PropTypes.number,
230
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
227
231
  tickSize: PropTypes.number
228
232
  }), PropTypes.string]),
229
233
  /**
@@ -292,10 +296,12 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
292
296
  tickFontSize: PropTypes.number,
293
297
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
294
298
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
299
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
295
300
  tickLabelStyle: PropTypes.object,
296
301
  tickMaxStep: PropTypes.number,
297
302
  tickMinStep: PropTypes.number,
298
303
  tickNumber: PropTypes.number,
304
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
299
305
  tickSize: PropTypes.number
300
306
  }), PropTypes.string]),
301
307
  /**
@@ -353,10 +359,12 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
353
359
  tickFontSize: PropTypes.number,
354
360
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
355
361
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
362
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
356
363
  tickLabelStyle: PropTypes.object,
357
364
  tickMaxStep: PropTypes.number,
358
365
  tickMinStep: PropTypes.number,
359
366
  tickNumber: PropTypes.number,
367
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
360
368
  tickSize: PropTypes.number
361
369
  }), PropTypes.string]),
362
370
  viewBox: PropTypes.shape({
@@ -397,10 +405,12 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
397
405
  tickFontSize: PropTypes.number,
398
406
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
399
407
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
408
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
400
409
  tickLabelStyle: PropTypes.object,
401
410
  tickMaxStep: PropTypes.number,
402
411
  tickMinStep: PropTypes.number,
403
412
  tickNumber: PropTypes.number,
413
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
404
414
  tickSize: PropTypes.number,
405
415
  valueFormatter: PropTypes.func
406
416
  })),
@@ -432,10 +442,12 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
432
442
  tickFontSize: PropTypes.number,
433
443
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
434
444
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
445
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
435
446
  tickLabelStyle: PropTypes.object,
436
447
  tickMaxStep: PropTypes.number,
437
448
  tickMinStep: PropTypes.number,
438
449
  tickNumber: PropTypes.number,
450
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
439
451
  tickSize: PropTypes.number,
440
452
  valueFormatter: PropTypes.func
441
453
  }))
@@ -8,6 +8,7 @@ import { ChartsTooltip } from '../ChartsTooltip';
8
8
  import { ChartsLegend } from '../ChartsLegend';
9
9
  import { ChartsAxisHighlight } from '../ChartsAxisHighlight';
10
10
  import { PiePlot } from './PiePlot';
11
+ import { useIsRTL } from '../internals/useIsRTL';
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
14
  const defaultMargin = {
@@ -16,6 +17,12 @@ const defaultMargin = {
16
17
  left: 5,
17
18
  right: 100
18
19
  };
20
+ const defaultRTLMargin = {
21
+ top: 5,
22
+ bottom: 5,
23
+ left: 100,
24
+ right: 5
25
+ };
19
26
 
20
27
  /**
21
28
  * Demos:
@@ -45,13 +52,7 @@ function PieChart(props) {
45
52
  y: 'none'
46
53
  },
47
54
  skipAnimation,
48
- legend = {
49
- direction: 'column',
50
- position: {
51
- vertical: 'middle',
52
- horizontal: 'right'
53
- }
54
- },
55
+ legend: legendProps,
55
56
  topAxis = null,
56
57
  leftAxis = null,
57
58
  rightAxis = null,
@@ -61,7 +62,15 @@ function PieChart(props) {
61
62
  slotProps,
62
63
  onItemClick
63
64
  } = props;
64
- const margin = _extends({}, defaultMargin, marginProps);
65
+ const isRTL = useIsRTL();
66
+ const margin = _extends({}, isRTL ? defaultRTLMargin : defaultMargin, marginProps);
67
+ const legend = _extends({
68
+ direction: 'column',
69
+ position: {
70
+ vertical: 'middle',
71
+ horizontal: isRTL ? 'left' : 'right'
72
+ }
73
+ }, legendProps);
65
74
  return /*#__PURE__*/_jsxs(ResponsiveChartContainer, {
66
75
  series: series.map(s => _extends({
67
76
  type: 'pie'
@@ -131,10 +140,12 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
131
140
  tickFontSize: PropTypes.number,
132
141
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
133
142
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
143
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
134
144
  tickLabelStyle: PropTypes.object,
135
145
  tickMaxStep: PropTypes.number,
136
146
  tickMinStep: PropTypes.number,
137
147
  tickNumber: PropTypes.number,
148
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
138
149
  tickSize: PropTypes.number
139
150
  }), PropTypes.string]),
140
151
  children: PropTypes.node,
@@ -180,10 +191,12 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
180
191
  tickFontSize: PropTypes.number,
181
192
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
182
193
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
194
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
183
195
  tickLabelStyle: PropTypes.object,
184
196
  tickMaxStep: PropTypes.number,
185
197
  tickMinStep: PropTypes.number,
186
198
  tickNumber: PropTypes.number,
199
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
187
200
  tickSize: PropTypes.number
188
201
  }), PropTypes.string]),
189
202
  /**
@@ -239,10 +252,12 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
239
252
  tickFontSize: PropTypes.number,
240
253
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
241
254
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
255
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
242
256
  tickLabelStyle: PropTypes.object,
243
257
  tickMaxStep: PropTypes.number,
244
258
  tickMinStep: PropTypes.number,
245
259
  tickNumber: PropTypes.number,
260
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
246
261
  tickSize: PropTypes.number
247
262
  }), PropTypes.string]),
248
263
  /**
@@ -300,10 +315,12 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
300
315
  tickFontSize: PropTypes.number,
301
316
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
302
317
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
318
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
303
319
  tickLabelStyle: PropTypes.object,
304
320
  tickMaxStep: PropTypes.number,
305
321
  tickMinStep: PropTypes.number,
306
322
  tickNumber: PropTypes.number,
323
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
307
324
  tickSize: PropTypes.number
308
325
  }), PropTypes.string]),
309
326
  viewBox: PropTypes.shape({
@@ -344,10 +361,12 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
344
361
  tickFontSize: PropTypes.number,
345
362
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
346
363
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
364
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
347
365
  tickLabelStyle: PropTypes.object,
348
366
  tickMaxStep: PropTypes.number,
349
367
  tickMinStep: PropTypes.number,
350
368
  tickNumber: PropTypes.number,
369
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
351
370
  tickSize: PropTypes.number,
352
371
  valueFormatter: PropTypes.func
353
372
  })),
@@ -379,10 +398,12 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
379
398
  tickFontSize: PropTypes.number,
380
399
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
381
400
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
401
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
382
402
  tickLabelStyle: PropTypes.object,
383
403
  tickMaxStep: PropTypes.number,
384
404
  tickMinStep: PropTypes.number,
385
405
  tickNumber: PropTypes.number,
406
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
386
407
  tickSize: PropTypes.number,
387
408
  valueFormatter: PropTypes.func
388
409
  }))
@@ -132,10 +132,12 @@ process.env.NODE_ENV !== "production" ? ResponsiveChartContainer.propTypes = {
132
132
  tickFontSize: PropTypes.number,
133
133
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
134
134
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
135
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
135
136
  tickLabelStyle: PropTypes.object,
136
137
  tickMaxStep: PropTypes.number,
137
138
  tickMinStep: PropTypes.number,
138
139
  tickNumber: PropTypes.number,
140
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
139
141
  tickSize: PropTypes.number,
140
142
  valueFormatter: PropTypes.func
141
143
  })),
@@ -167,10 +169,12 @@ process.env.NODE_ENV !== "production" ? ResponsiveChartContainer.propTypes = {
167
169
  tickFontSize: PropTypes.number,
168
170
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
169
171
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
172
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
170
173
  tickLabelStyle: PropTypes.object,
171
174
  tickMaxStep: PropTypes.number,
172
175
  tickMinStep: PropTypes.number,
173
176
  tickNumber: PropTypes.number,
177
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
174
178
  tickSize: PropTypes.number,
175
179
  valueFormatter: PropTypes.func
176
180
  }))
@@ -121,10 +121,12 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
121
121
  tickFontSize: PropTypes.number,
122
122
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
123
123
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
124
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
124
125
  tickLabelStyle: PropTypes.object,
125
126
  tickMaxStep: PropTypes.number,
126
127
  tickMinStep: PropTypes.number,
127
128
  tickNumber: PropTypes.number,
129
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
128
130
  tickSize: PropTypes.number
129
131
  }), PropTypes.string]),
130
132
  children: PropTypes.node,
@@ -182,10 +184,12 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
182
184
  tickFontSize: PropTypes.number,
183
185
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
184
186
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
187
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
185
188
  tickLabelStyle: PropTypes.object,
186
189
  tickMaxStep: PropTypes.number,
187
190
  tickMinStep: PropTypes.number,
188
191
  tickNumber: PropTypes.number,
192
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
189
193
  tickSize: PropTypes.number
190
194
  }), PropTypes.string]),
191
195
  /**
@@ -241,10 +245,12 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
241
245
  tickFontSize: PropTypes.number,
242
246
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
243
247
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
248
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
244
249
  tickLabelStyle: PropTypes.object,
245
250
  tickMaxStep: PropTypes.number,
246
251
  tickMinStep: PropTypes.number,
247
252
  tickNumber: PropTypes.number,
253
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
248
254
  tickSize: PropTypes.number
249
255
  }), PropTypes.string]),
250
256
  /**
@@ -297,10 +303,12 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
297
303
  tickFontSize: PropTypes.number,
298
304
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
299
305
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
306
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
300
307
  tickLabelStyle: PropTypes.object,
301
308
  tickMaxStep: PropTypes.number,
302
309
  tickMinStep: PropTypes.number,
303
310
  tickNumber: PropTypes.number,
311
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
304
312
  tickSize: PropTypes.number
305
313
  }), PropTypes.string]),
306
314
  viewBox: PropTypes.shape({
@@ -346,10 +354,12 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
346
354
  tickFontSize: PropTypes.number,
347
355
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
348
356
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
357
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
349
358
  tickLabelStyle: PropTypes.object,
350
359
  tickMaxStep: PropTypes.number,
351
360
  tickMinStep: PropTypes.number,
352
361
  tickNumber: PropTypes.number,
362
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
353
363
  tickSize: PropTypes.number,
354
364
  valueFormatter: PropTypes.func
355
365
  })),
@@ -381,10 +391,12 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
381
391
  tickFontSize: PropTypes.number,
382
392
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
383
393
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
394
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
384
395
  tickLabelStyle: PropTypes.object,
385
396
  tickMaxStep: PropTypes.number,
386
397
  tickMinStep: PropTypes.number,
387
398
  tickNumber: PropTypes.number,
399
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
388
400
  tickSize: PropTypes.number,
389
401
  valueFormatter: PropTypes.func
390
402
  }))
@@ -247,10 +247,12 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes = {
247
247
  tickFontSize: PropTypes.number,
248
248
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
249
249
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
250
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
250
251
  tickLabelStyle: PropTypes.object,
251
252
  tickMaxStep: PropTypes.number,
252
253
  tickMinStep: PropTypes.number,
253
254
  tickNumber: PropTypes.number,
255
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
254
256
  tickSize: PropTypes.number,
255
257
  valueFormatter: PropTypes.func
256
258
  })
@@ -43,7 +43,8 @@ export const useAxisEvents = disableAxisListener => {
43
43
  }
44
44
  const {
45
45
  scale,
46
- data: axisData
46
+ data: axisData,
47
+ reverse
47
48
  } = axisConfig;
48
49
  if (!isBandScale(scale)) {
49
50
  const value = scale.invert(mouseValue);
@@ -76,6 +77,13 @@ export const useAxisEvents = disableAxisListener => {
76
77
  if (dataIndex < 0 || dataIndex >= axisData.length) {
77
78
  return null;
78
79
  }
80
+ if (reverse) {
81
+ const reverseIndex = axisData.length - 1 - dataIndex;
82
+ return {
83
+ index: reverseIndex,
84
+ value: axisData[reverseIndex]
85
+ };
86
+ }
79
87
  return {
80
88
  index: dataIndex,
81
89
  value: axisData[dataIndex]
@@ -13,12 +13,20 @@ export function getTickNumber(params) {
13
13
  const defaultizedTickNumber = tickNumber ?? Math.floor(Math.abs(range[1] - range[0]) / 50);
14
14
  return Math.min(maxTicks, Math.max(minTicks, defaultizedTickNumber));
15
15
  }
16
+ const offsetRatio = {
17
+ start: 0,
18
+ extremities: 0,
19
+ end: 1,
20
+ middle: 0.5
21
+ };
16
22
  export function useTicks(options) {
17
23
  const {
18
24
  scale,
19
25
  tickNumber,
20
26
  valueFormatter,
21
- tickInterval
27
+ tickInterval,
28
+ tickPlacement = 'extremities',
29
+ tickLabelPlacement = 'middle'
22
30
  } = options;
23
31
  return React.useMemo(() => {
24
32
  // band scale
@@ -28,21 +36,25 @@ export function useTicks(options) {
28
36
  // scale type = 'band'
29
37
  return [...domain.map(value => ({
30
38
  value,
31
- formattedValue: valueFormatter?.(value) ?? `${value}`,
32
- offset: scale(value) - (scale.step() - scale.bandwidth()) / 2,
33
- labelOffset: scale.step() / 2
34
- })), {
39
+ formattedValue: valueFormatter?.(value, {
40
+ location: 'tick'
41
+ }) ?? `${value}`,
42
+ offset: scale(value) - (scale.step() - scale.bandwidth()) / 2 + offsetRatio[tickPlacement] * scale.step(),
43
+ labelOffset: tickLabelPlacement === 'tick' ? 0 : scale.step() * (offsetRatio[tickLabelPlacement] - offsetRatio[tickPlacement])
44
+ })), ...(tickPlacement === 'extremities' ? [{
35
45
  formattedValue: undefined,
36
46
  offset: scale.range()[1],
37
47
  labelOffset: 0
38
- }];
48
+ }] : [])];
39
49
  }
40
50
 
41
51
  // scale type = 'point'
42
52
  const filteredDomain = typeof tickInterval === 'function' && domain.filter(tickInterval) || typeof tickInterval === 'object' && tickInterval || domain;
43
53
  return filteredDomain.map(value => ({
44
54
  value,
45
- formattedValue: valueFormatter?.(value) ?? `${value}`,
55
+ formattedValue: valueFormatter?.(value, {
56
+ location: 'tick'
57
+ }) ?? `${value}`,
46
58
  offset: scale(value),
47
59
  labelOffset: 0
48
60
  }));
@@ -50,9 +62,11 @@ export function useTicks(options) {
50
62
  const ticks = typeof tickInterval === 'object' ? tickInterval : scale.ticks(tickNumber);
51
63
  return ticks.map(value => ({
52
64
  value,
53
- formattedValue: valueFormatter?.(value) ?? scale.tickFormat(tickNumber)(value),
65
+ formattedValue: valueFormatter?.(value, {
66
+ location: 'tick'
67
+ }) ?? scale.tickFormat(tickNumber)(value),
54
68
  offset: scale(value),
55
69
  labelOffset: 0
56
70
  }));
57
- }, [tickNumber, scale, valueFormatter, tickInterval]);
71
+ }, [scale, tickInterval, tickNumber, valueFormatter, tickPlacement, tickLabelPlacement]);
58
72
  }
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v7.0.0-beta.5
2
+ * @mui/x-charts v7.0.0-beta.7
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -0,0 +1,5 @@
1
+ import { useTheme } from '@mui/material/styles';
2
+ export const useIsRTL = () => {
3
+ const theme = useTheme();
4
+ return theme.direction === 'rtl';
5
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-charts",
3
- "version": "7.0.0-beta.5",
3
+ "version": "7.0.0-beta.7",
4
4
  "description": "The community edition of the charts components (MUI X).",
5
5
  "author": "MUI Team",
6
6
  "main": "./index.js",
@@ -28,7 +28,7 @@
28
28
  "directory": "packages/x-charts"
29
29
  },
30
30
  "dependencies": {
31
- "@babel/runtime": "^7.23.9",
31
+ "@babel/runtime": "^7.24.0",
32
32
  "@mui/base": "^5.0.0-beta.36",
33
33
  "@mui/system": "^5.15.9",
34
34
  "@mui/utils": "^5.15.9",