@mui/x-charts 7.0.0-beta.4 → 7.0.0-beta.6

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 (52) hide show
  1. package/BarChart/BarChart.js +12 -0
  2. package/CHANGELOG.md +271 -61
  3. package/ChartContainer/ChartContainer.js +4 -0
  4. package/ChartsAxis/ChartsAxis.js +8 -0
  5. package/ChartsGrid/ChartsGrid.js +2 -2
  6. package/ChartsLegend/DefaultChartsLegend.js +20 -27
  7. package/ChartsTooltip/DefaultChartsAxisTooltipContent.js +3 -1
  8. package/ChartsXAxis/ChartsXAxis.js +18 -2
  9. package/ChartsYAxis/ChartsYAxis.js +18 -2
  10. package/LineChart/LineChart.js +12 -0
  11. package/PieChart/PieChart.js +29 -8
  12. package/ResponsiveChartContainer/ResponsiveChartContainer.js +4 -0
  13. package/ScatterChart/ScatterChart.js +12 -0
  14. package/SparkLineChart/SparkLineChart.js +2 -0
  15. package/esm/BarChart/BarChart.js +12 -0
  16. package/esm/ChartContainer/ChartContainer.js +4 -0
  17. package/esm/ChartsAxis/ChartsAxis.js +8 -0
  18. package/esm/ChartsGrid/ChartsGrid.js +2 -2
  19. package/esm/ChartsLegend/DefaultChartsLegend.js +20 -27
  20. package/esm/ChartsTooltip/DefaultChartsAxisTooltipContent.js +3 -1
  21. package/esm/ChartsXAxis/ChartsXAxis.js +18 -2
  22. package/esm/ChartsYAxis/ChartsYAxis.js +18 -2
  23. package/esm/LineChart/LineChart.js +12 -0
  24. package/esm/PieChart/PieChart.js +29 -8
  25. package/esm/ResponsiveChartContainer/ResponsiveChartContainer.js +4 -0
  26. package/esm/ScatterChart/ScatterChart.js +12 -0
  27. package/esm/SparkLineChart/SparkLineChart.js +2 -0
  28. package/esm/hooks/useTicks.js +23 -9
  29. package/esm/internals/useIsRTL.js +5 -0
  30. package/hooks/useTicks.d.ts +15 -3
  31. package/hooks/useTicks.js +23 -9
  32. package/index.js +1 -1
  33. package/internals/useIsRTL.d.ts +1 -0
  34. package/internals/useIsRTL.js +12 -0
  35. package/models/axis.d.ts +11 -2
  36. package/modern/BarChart/BarChart.js +12 -0
  37. package/modern/ChartContainer/ChartContainer.js +4 -0
  38. package/modern/ChartsAxis/ChartsAxis.js +8 -0
  39. package/modern/ChartsGrid/ChartsGrid.js +2 -2
  40. package/modern/ChartsLegend/DefaultChartsLegend.js +20 -27
  41. package/modern/ChartsTooltip/DefaultChartsAxisTooltipContent.js +3 -1
  42. package/modern/ChartsXAxis/ChartsXAxis.js +18 -2
  43. package/modern/ChartsYAxis/ChartsYAxis.js +18 -2
  44. package/modern/LineChart/LineChart.js +12 -0
  45. package/modern/PieChart/PieChart.js +29 -8
  46. package/modern/ResponsiveChartContainer/ResponsiveChartContainer.js +4 -0
  47. package/modern/ScatterChart/ScatterChart.js +12 -0
  48. package/modern/SparkLineChart/SparkLineChart.js +2 -0
  49. package/modern/hooks/useTicks.js +23 -9
  50. package/modern/index.js +1 -1
  51. package/modern/internals/useIsRTL.js +5 -0
  52. package/package.json +2 -2
@@ -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
  })
@@ -13,12 +13,20 @@ export function getTickNumber(params) {
13
13
  const defaultizedTickNumber = tickNumber != null ? 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
@@ -30,15 +38,17 @@ export function useTicks(options) {
30
38
  var _valueFormatter;
31
39
  return {
32
40
  value,
33
- formattedValue: (_valueFormatter = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter : `${value}`,
34
- offset: scale(value) - (scale.step() - scale.bandwidth()) / 2,
35
- labelOffset: scale.step() / 2
41
+ formattedValue: (_valueFormatter = valueFormatter == null ? void 0 : valueFormatter(value, {
42
+ location: 'tick'
43
+ })) != null ? _valueFormatter : `${value}`,
44
+ offset: scale(value) - (scale.step() - scale.bandwidth()) / 2 + offsetRatio[tickPlacement] * scale.step(),
45
+ labelOffset: tickLabelPlacement === 'tick' ? 0 : scale.step() * (offsetRatio[tickLabelPlacement] - offsetRatio[tickPlacement])
36
46
  };
37
- }), {
47
+ }), ...(tickPlacement === 'extremities' ? [{
38
48
  formattedValue: undefined,
39
49
  offset: scale.range()[1],
40
50
  labelOffset: 0
41
- }];
51
+ }] : [])];
42
52
  }
43
53
 
44
54
  // scale type = 'point'
@@ -47,7 +57,9 @@ export function useTicks(options) {
47
57
  var _valueFormatter2;
48
58
  return {
49
59
  value,
50
- formattedValue: (_valueFormatter2 = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter2 : `${value}`,
60
+ formattedValue: (_valueFormatter2 = valueFormatter == null ? void 0 : valueFormatter(value, {
61
+ location: 'tick'
62
+ })) != null ? _valueFormatter2 : `${value}`,
51
63
  offset: scale(value),
52
64
  labelOffset: 0
53
65
  };
@@ -58,10 +70,12 @@ export function useTicks(options) {
58
70
  var _valueFormatter3;
59
71
  return {
60
72
  value,
61
- formattedValue: (_valueFormatter3 = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter3 : scale.tickFormat(tickNumber)(value),
73
+ formattedValue: (_valueFormatter3 = valueFormatter == null ? void 0 : valueFormatter(value, {
74
+ location: 'tick'
75
+ })) != null ? _valueFormatter3 : scale.tickFormat(tickNumber)(value),
62
76
  offset: scale(value),
63
77
  labelOffset: 0
64
78
  };
65
79
  });
66
- }, [tickNumber, scale, valueFormatter, tickInterval]);
80
+ }, [scale, tickInterval, tickNumber, valueFormatter, tickPlacement, tickLabelPlacement]);
67
81
  }
@@ -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
+ };
@@ -1,4 +1,4 @@
1
- import { D3Scale } from '../models/axis';
1
+ import { AxisConfig, D3Scale } from '../models/axis';
2
2
  export interface TickParams {
3
3
  /**
4
4
  * Maximal step between two ticks.
@@ -25,6 +25,18 @@ export interface TickParams {
25
25
  * @default 'auto'
26
26
  */
27
27
  tickInterval?: 'auto' | ((value: any, index: number) => boolean) | any[];
28
+ /**
29
+ * The placement of ticks in regard to the band interval.
30
+ * Only used if scale is 'band'.
31
+ * @default 'extremities'
32
+ */
33
+ tickPlacement?: 'start' | 'end' | 'middle' | 'extremities';
34
+ /**
35
+ * The placement of ticks label. Can be the middle of the band, or the tick position.
36
+ * Only used if scale is 'band'.
37
+ * @default 'middle'
38
+ */
39
+ tickLabelPlacement?: 'middle' | 'tick';
28
40
  }
29
41
  export declare function getTickNumber(params: TickParams & {
30
42
  range: any[];
@@ -41,5 +53,5 @@ export type TickItemType = {
41
53
  };
42
54
  export declare function useTicks(options: {
43
55
  scale: D3Scale;
44
- valueFormatter?: (value: any) => string;
45
- } & Pick<TickParams, 'tickNumber' | 'tickInterval'>): TickItemType[];
56
+ valueFormatter?: AxisConfig['valueFormatter'];
57
+ } & Pick<TickParams, 'tickNumber' | 'tickInterval' | 'tickPlacement' | 'tickLabelPlacement'>): TickItemType[];
package/hooks/useTicks.js CHANGED
@@ -22,12 +22,20 @@ function getTickNumber(params) {
22
22
  const defaultizedTickNumber = tickNumber ?? Math.floor(Math.abs(range[1] - range[0]) / 50);
23
23
  return Math.min(maxTicks, Math.max(minTicks, defaultizedTickNumber));
24
24
  }
25
+ const offsetRatio = {
26
+ start: 0,
27
+ extremities: 0,
28
+ end: 1,
29
+ middle: 0.5
30
+ };
25
31
  function useTicks(options) {
26
32
  const {
27
33
  scale,
28
34
  tickNumber,
29
35
  valueFormatter,
30
- tickInterval
36
+ tickInterval,
37
+ tickPlacement = 'extremities',
38
+ tickLabelPlacement = 'middle'
31
39
  } = options;
32
40
  return React.useMemo(() => {
33
41
  // band scale
@@ -37,21 +45,25 @@ function useTicks(options) {
37
45
  // scale type = 'band'
38
46
  return [...domain.map(value => ({
39
47
  value,
40
- formattedValue: valueFormatter?.(value) ?? `${value}`,
41
- offset: scale(value) - (scale.step() - scale.bandwidth()) / 2,
42
- labelOffset: scale.step() / 2
43
- })), {
48
+ formattedValue: valueFormatter?.(value, {
49
+ location: 'tick'
50
+ }) ?? `${value}`,
51
+ offset: scale(value) - (scale.step() - scale.bandwidth()) / 2 + offsetRatio[tickPlacement] * scale.step(),
52
+ labelOffset: tickLabelPlacement === 'tick' ? 0 : scale.step() * (offsetRatio[tickLabelPlacement] - offsetRatio[tickPlacement])
53
+ })), ...(tickPlacement === 'extremities' ? [{
44
54
  formattedValue: undefined,
45
55
  offset: scale.range()[1],
46
56
  labelOffset: 0
47
- }];
57
+ }] : [])];
48
58
  }
49
59
 
50
60
  // scale type = 'point'
51
61
  const filteredDomain = typeof tickInterval === 'function' && domain.filter(tickInterval) || typeof tickInterval === 'object' && tickInterval || domain;
52
62
  return filteredDomain.map(value => ({
53
63
  value,
54
- formattedValue: valueFormatter?.(value) ?? `${value}`,
64
+ formattedValue: valueFormatter?.(value, {
65
+ location: 'tick'
66
+ }) ?? `${value}`,
55
67
  offset: scale(value),
56
68
  labelOffset: 0
57
69
  }));
@@ -59,9 +71,11 @@ function useTicks(options) {
59
71
  const ticks = typeof tickInterval === 'object' ? tickInterval : scale.ticks(tickNumber);
60
72
  return ticks.map(value => ({
61
73
  value,
62
- formattedValue: valueFormatter?.(value) ?? scale.tickFormat(tickNumber)(value),
74
+ formattedValue: valueFormatter?.(value, {
75
+ location: 'tick'
76
+ }) ?? scale.tickFormat(tickNumber)(value),
63
77
  offset: scale(value),
64
78
  labelOffset: 0
65
79
  }));
66
- }, [tickNumber, scale, valueFormatter, tickInterval]);
80
+ }, [scale, tickInterval, tickNumber, valueFormatter, tickPlacement, tickLabelPlacement]);
67
81
  }
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v7.0.0-beta.4
2
+ * @mui/x-charts v7.0.0-beta.6
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -0,0 +1 @@
1
+ export declare const useIsRTL: () => boolean;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useIsRTL = void 0;
7
+ var _styles = require("@mui/material/styles");
8
+ const useIsRTL = () => {
9
+ const theme = (0, _styles.useTheme)();
10
+ return theme.direction === 'rtl';
11
+ };
12
+ exports.useIsRTL = useIsRTL;
package/models/axis.d.ts CHANGED
@@ -127,7 +127,7 @@ interface AxisScaleConfig {
127
127
  * @default 0.1
128
128
  */
129
129
  barGapRatio: number;
130
- };
130
+ } & Pick<TickParams, 'tickPlacement' | 'tickLabelPlacement'>;
131
131
  point: {
132
132
  scaleType: 'point';
133
133
  scale: ScalePoint<number | Date | string>;
@@ -157,6 +157,9 @@ interface AxisScaleConfig {
157
157
  scale: ScaleLinear<number, number>;
158
158
  };
159
159
  }
160
+ export type AxisValueFormatterContext = {
161
+ location: 'tick' | 'tooltip';
162
+ };
160
163
  export type AxisConfig<S extends ScaleName = ScaleName, V = any> = {
161
164
  /**
162
165
  * Id used to identify the axis.
@@ -180,7 +183,13 @@ export type AxisConfig<S extends ScaleName = ScaleName, V = any> = {
180
183
  * The key used to retrieve `data` from the `dataset` prop.
181
184
  */
182
185
  dataKey?: string;
183
- valueFormatter?: (value: V) => string;
186
+ /**
187
+ * Formats the axis value.
188
+ * @param {V} value The value to format.
189
+ * @param {AxisValueFormatterContext} context The rendering context of the value.
190
+ * @returns {string} The string to display.
191
+ */
192
+ valueFormatter?: (value: V, context: AxisValueFormatterContext) => string;
184
193
  /**
185
194
  * If `true`, hide this value in the tooltip
186
195
  */
@@ -153,10 +153,12 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
153
153
  tickFontSize: PropTypes.number,
154
154
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
155
155
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
156
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
156
157
  tickLabelStyle: PropTypes.object,
157
158
  tickMaxStep: PropTypes.number,
158
159
  tickMinStep: PropTypes.number,
159
160
  tickNumber: PropTypes.number,
161
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
160
162
  tickSize: PropTypes.number
161
163
  }), PropTypes.string]),
162
164
  children: PropTypes.node,
@@ -214,10 +216,12 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
214
216
  tickFontSize: PropTypes.number,
215
217
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
216
218
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
219
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
217
220
  tickLabelStyle: PropTypes.object,
218
221
  tickMaxStep: PropTypes.number,
219
222
  tickMinStep: PropTypes.number,
220
223
  tickNumber: PropTypes.number,
224
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
221
225
  tickSize: PropTypes.number
222
226
  }), PropTypes.string]),
223
227
  /**
@@ -280,10 +284,12 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
280
284
  tickFontSize: PropTypes.number,
281
285
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
282
286
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
287
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
283
288
  tickLabelStyle: PropTypes.object,
284
289
  tickMaxStep: PropTypes.number,
285
290
  tickMinStep: PropTypes.number,
286
291
  tickNumber: PropTypes.number,
292
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
287
293
  tickSize: PropTypes.number
288
294
  }), PropTypes.string]),
289
295
  /**
@@ -340,10 +346,12 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
340
346
  tickFontSize: PropTypes.number,
341
347
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
342
348
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
349
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
343
350
  tickLabelStyle: PropTypes.object,
344
351
  tickMaxStep: PropTypes.number,
345
352
  tickMinStep: PropTypes.number,
346
353
  tickNumber: PropTypes.number,
354
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
347
355
  tickSize: PropTypes.number
348
356
  }), PropTypes.string]),
349
357
  viewBox: PropTypes.shape({
@@ -384,10 +392,12 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
384
392
  tickFontSize: PropTypes.number,
385
393
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
386
394
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
395
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
387
396
  tickLabelStyle: PropTypes.object,
388
397
  tickMaxStep: PropTypes.number,
389
398
  tickMinStep: PropTypes.number,
390
399
  tickNumber: PropTypes.number,
400
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
391
401
  tickSize: PropTypes.number,
392
402
  valueFormatter: PropTypes.func
393
403
  })),
@@ -419,10 +429,12 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
419
429
  tickFontSize: PropTypes.number,
420
430
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
421
431
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
432
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
422
433
  tickLabelStyle: PropTypes.object,
423
434
  tickMaxStep: PropTypes.number,
424
435
  tickMinStep: PropTypes.number,
425
436
  tickNumber: PropTypes.number,
437
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
426
438
  tickSize: PropTypes.number,
427
439
  valueFormatter: PropTypes.func
428
440
  }))
@@ -145,10 +145,12 @@ process.env.NODE_ENV !== "production" ? ChartContainer.propTypes = {
145
145
  tickFontSize: PropTypes.number,
146
146
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
147
147
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
148
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
148
149
  tickLabelStyle: PropTypes.object,
149
150
  tickMaxStep: PropTypes.number,
150
151
  tickMinStep: PropTypes.number,
151
152
  tickNumber: PropTypes.number,
153
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
152
154
  tickSize: PropTypes.number,
153
155
  valueFormatter: PropTypes.func
154
156
  })),
@@ -180,10 +182,12 @@ process.env.NODE_ENV !== "production" ? ChartContainer.propTypes = {
180
182
  tickFontSize: PropTypes.number,
181
183
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
182
184
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
185
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
183
186
  tickLabelStyle: PropTypes.object,
184
187
  tickMaxStep: PropTypes.number,
185
188
  tickMinStep: PropTypes.number,
186
189
  tickNumber: PropTypes.number,
190
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
187
191
  tickSize: PropTypes.number,
188
192
  valueFormatter: PropTypes.func
189
193
  }))
@@ -115,10 +115,12 @@ process.env.NODE_ENV !== "production" ? ChartsAxis.propTypes = {
115
115
  tickFontSize: PropTypes.number,
116
116
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
117
117
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
118
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
118
119
  tickLabelStyle: PropTypes.object,
119
120
  tickMaxStep: PropTypes.number,
120
121
  tickMinStep: PropTypes.number,
121
122
  tickNumber: PropTypes.number,
123
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
122
124
  tickSize: PropTypes.number
123
125
  }), PropTypes.string]),
124
126
  /**
@@ -142,10 +144,12 @@ process.env.NODE_ENV !== "production" ? ChartsAxis.propTypes = {
142
144
  tickFontSize: PropTypes.number,
143
145
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
144
146
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
147
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
145
148
  tickLabelStyle: PropTypes.object,
146
149
  tickMaxStep: PropTypes.number,
147
150
  tickMinStep: PropTypes.number,
148
151
  tickNumber: PropTypes.number,
152
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
149
153
  tickSize: PropTypes.number
150
154
  }), PropTypes.string]),
151
155
  /**
@@ -169,10 +173,12 @@ process.env.NODE_ENV !== "production" ? ChartsAxis.propTypes = {
169
173
  tickFontSize: PropTypes.number,
170
174
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
171
175
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
176
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
172
177
  tickLabelStyle: PropTypes.object,
173
178
  tickMaxStep: PropTypes.number,
174
179
  tickMinStep: PropTypes.number,
175
180
  tickNumber: PropTypes.number,
181
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
176
182
  tickSize: PropTypes.number
177
183
  }), PropTypes.string]),
178
184
  /**
@@ -206,10 +212,12 @@ process.env.NODE_ENV !== "production" ? ChartsAxis.propTypes = {
206
212
  tickFontSize: PropTypes.number,
207
213
  tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
208
214
  tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
215
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
209
216
  tickLabelStyle: PropTypes.object,
210
217
  tickMaxStep: PropTypes.number,
211
218
  tickMinStep: PropTypes.number,
212
219
  tickNumber: PropTypes.number,
220
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
213
221
  tickSize: PropTypes.number
214
222
  }), PropTypes.string])
215
223
  } : void 0;
@@ -88,7 +88,7 @@ function ChartsGrid(props) {
88
88
  x1: offset,
89
89
  x2: offset,
90
90
  className: classes.verticalLine
91
- }, formattedValue)), horizontal && yTicks.map(({
91
+ }, `vertical-${formattedValue}`)), horizontal && yTicks.map(({
92
92
  formattedValue,
93
93
  offset
94
94
  }) => /*#__PURE__*/_jsx("line", {
@@ -97,7 +97,7 @@ function ChartsGrid(props) {
97
97
  x1: xScale.range()[0],
98
98
  x2: xScale.range()[1],
99
99
  className: classes.horizontalLine
100
- }, formattedValue))]
100
+ }, `horizontal-${formattedValue}`))]
101
101
  }));
102
102
  }
103
103
  process.env.NODE_ENV !== "production" ? ChartsGrid.propTypes = {
@@ -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))
@@ -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