@mui/x-charts 8.5.2 → 8.6.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 (188) hide show
  1. package/BarChart/AnimatedBarElement.js +3 -1
  2. package/BarChart/BarLabel/BarLabelPlot.d.ts +2 -2
  3. package/BarChart/BarLabel/BarLabelPlot.js +33 -25
  4. package/BarChart/BarPlot.js +55 -40
  5. package/BarChart/barClasses.d.ts +12 -0
  6. package/BarChart/barClasses.js +25 -0
  7. package/BarChart/index.d.ts +3 -1
  8. package/BarChart/index.js +23 -1
  9. package/BarChart/types.d.ts +5 -1
  10. package/CHANGELOG.md +203 -11
  11. package/ChartsLegend/ChartsLegend.d.ts +1 -0
  12. package/ChartsLegend/ChartsLegend.js +2 -0
  13. package/ChartsLegend/ContinuousColorLegend.d.ts +1 -0
  14. package/ChartsLegend/PiecewiseColorLegend.d.ts +1 -0
  15. package/ChartsLegend/chartsLegendClasses.d.ts +3 -1
  16. package/ChartsLegend/chartsLegendClasses.js +2 -1
  17. package/ChartsSurface/ChartsSurface.d.ts +1 -1
  18. package/ChartsXAxis/ChartsXAxis.js +4 -108
  19. package/ChartsXAxis/getVisibleLabels.d.ts +14 -0
  20. package/ChartsXAxis/getVisibleLabels.js +71 -0
  21. package/ChartsXAxis/shortenLabels.d.ts +4 -0
  22. package/ChartsXAxis/shortenLabels.js +48 -0
  23. package/ChartsYAxis/ChartsYAxis.js +2 -39
  24. package/ChartsYAxis/shortenLabels.d.ts +4 -0
  25. package/ChartsYAxis/shortenLabels.js +46 -0
  26. package/LineChart/AnimatedArea.js +4 -1
  27. package/LineChart/AnimatedLine.js +4 -1
  28. package/LineChart/CircleMarkElement.js +4 -1
  29. package/LineChart/MarkElement.js +4 -1
  30. package/LineChart/MarkPlot.js +1 -0
  31. package/PieChart/PieArc.js +3 -1
  32. package/PieChart/PiePlot.js +6 -0
  33. package/PieChart/index.d.ts +3 -1
  34. package/PieChart/index.js +18 -1
  35. package/PieChart/pieClasses.d.ts +12 -0
  36. package/PieChart/pieClasses.js +24 -0
  37. package/ScatterChart/Scatter.d.ts +2 -0
  38. package/ScatterChart/Scatter.js +9 -1
  39. package/ScatterChart/index.d.ts +3 -1
  40. package/ScatterChart/index.js +16 -1
  41. package/ScatterChart/scatterClasses.d.ts +8 -0
  42. package/ScatterChart/scatterClasses.js +22 -0
  43. package/Toolbar/ToolbarButton.js +2 -0
  44. package/esm/BarChart/AnimatedBarElement.js +3 -1
  45. package/esm/BarChart/BarLabel/BarLabelPlot.d.ts +2 -2
  46. package/esm/BarChart/BarLabel/BarLabelPlot.js +33 -25
  47. package/esm/BarChart/BarPlot.js +55 -40
  48. package/esm/BarChart/barClasses.d.ts +12 -0
  49. package/esm/BarChart/barClasses.js +15 -0
  50. package/esm/BarChart/index.d.ts +3 -1
  51. package/esm/BarChart/index.js +2 -1
  52. package/esm/BarChart/types.d.ts +5 -1
  53. package/esm/ChartsLegend/ChartsLegend.d.ts +1 -0
  54. package/esm/ChartsLegend/ChartsLegend.js +2 -0
  55. package/esm/ChartsLegend/ContinuousColorLegend.d.ts +1 -0
  56. package/esm/ChartsLegend/PiecewiseColorLegend.d.ts +1 -0
  57. package/esm/ChartsLegend/chartsLegendClasses.d.ts +3 -1
  58. package/esm/ChartsLegend/chartsLegendClasses.js +2 -1
  59. package/esm/ChartsSurface/ChartsSurface.d.ts +1 -1
  60. package/esm/ChartsXAxis/ChartsXAxis.js +2 -106
  61. package/esm/ChartsXAxis/getVisibleLabels.d.ts +14 -0
  62. package/esm/ChartsXAxis/getVisibleLabels.js +67 -0
  63. package/esm/ChartsXAxis/shortenLabels.d.ts +4 -0
  64. package/esm/ChartsXAxis/shortenLabels.js +42 -0
  65. package/esm/ChartsYAxis/ChartsYAxis.js +1 -38
  66. package/esm/ChartsYAxis/shortenLabels.d.ts +4 -0
  67. package/esm/ChartsYAxis/shortenLabels.js +41 -0
  68. package/esm/LineChart/AnimatedArea.js +4 -1
  69. package/esm/LineChart/AnimatedLine.js +4 -1
  70. package/esm/LineChart/CircleMarkElement.js +4 -1
  71. package/esm/LineChart/MarkElement.js +4 -1
  72. package/esm/LineChart/MarkPlot.js +1 -0
  73. package/esm/PieChart/PieArc.js +3 -1
  74. package/esm/PieChart/PiePlot.js +6 -0
  75. package/esm/PieChart/index.d.ts +3 -1
  76. package/esm/PieChart/index.js +2 -1
  77. package/esm/PieChart/pieClasses.d.ts +12 -0
  78. package/esm/PieChart/pieClasses.js +15 -0
  79. package/esm/ScatterChart/Scatter.d.ts +2 -0
  80. package/esm/ScatterChart/Scatter.js +9 -1
  81. package/esm/ScatterChart/index.d.ts +3 -1
  82. package/esm/ScatterChart/index.js +2 -1
  83. package/esm/ScatterChart/scatterClasses.d.ts +8 -0
  84. package/esm/ScatterChart/scatterClasses.js +13 -0
  85. package/esm/Toolbar/ToolbarButton.js +2 -0
  86. package/esm/hooks/useItemHighlighted.js +2 -2
  87. package/esm/index.js +1 -1
  88. package/esm/internals/components/NotRendered.d.ts +9 -0
  89. package/esm/internals/components/NotRendered.js +10 -0
  90. package/esm/internals/createSeriesSelectorOfType.js +2 -2
  91. package/esm/internals/index.d.ts +1 -0
  92. package/esm/internals/index.js +1 -0
  93. package/esm/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.selectors.d.ts +3 -29
  94. package/esm/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.selectors.js +1 -1
  95. package/esm/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.js +30 -2
  96. package/esm/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.selectors.d.ts +14 -724
  97. package/esm/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.selectors.js +10 -10
  98. package/esm/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.types.d.ts +8 -2
  99. package/esm/internals/plugins/corePlugins/useChartId/useChartId.selectors.d.ts +3 -29
  100. package/esm/internals/plugins/corePlugins/useChartId/useChartId.selectors.js +1 -1
  101. package/esm/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.d.ts +6 -54
  102. package/esm/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.js +2 -2
  103. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartAxisSize.selectors.d.ts +12 -208
  104. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors.d.ts +7 -66
  105. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors.js +2 -3
  106. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.d.ts +21 -6222
  107. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.js +4 -6
  108. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianInteraction.selectors.d.ts +50 -5
  109. package/esm/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.d.ts +18 -622
  110. package/esm/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.js +3 -3
  111. package/esm/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.selectors.d.ts +18 -230
  112. package/esm/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.selectors.js +6 -6
  113. package/esm/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.js +20 -4
  114. package/esm/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.selectors.d.ts +17 -2012
  115. package/esm/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.selectors.js +2 -2
  116. package/esm/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarInteraction.selectors.d.ts +39 -4
  117. package/esm/internals/plugins/featurePlugins/useChartVoronoi/useChartVoronoi.selectors.d.ts +3 -27
  118. package/esm/internals/plugins/featurePlugins/useChartVoronoi/useChartVoronoi.selectors.js +1 -1
  119. package/esm/internals/plugins/featurePlugins/useChartZAxis/useChartZAxis.selectors.d.ts +5 -40
  120. package/esm/internals/plugins/utils/selectors.d.ts +18 -6
  121. package/esm/internals/plugins/utils/selectors.js +3 -3
  122. package/esm/internals/store/useSelector.d.ts +2 -2
  123. package/esm/internals/store/useSelector.js +2 -2
  124. package/esm/locales/enUS.d.ts +3 -0
  125. package/esm/locales/enUS.js +8 -2
  126. package/esm/locales/frFR.d.ts +3 -0
  127. package/esm/locales/frFR.js +7 -0
  128. package/esm/locales/ptBR.d.ts +3 -0
  129. package/esm/locales/ptBR.js +7 -1
  130. package/esm/locales/ptPT.d.ts +3 -0
  131. package/esm/locales/ptPT.js +7 -1
  132. package/esm/locales/utils/chartsLocaleTextApi.d.ts +17 -0
  133. package/esm/locales/utils/getChartsLocalization.d.ts +3 -0
  134. package/esm/locales/utils/imageMimeTypes.d.ts +2 -0
  135. package/esm/locales/utils/imageMimeTypes.js +5 -0
  136. package/esm/models/slots/chartsBaseSlotProps.d.ts +4 -0
  137. package/hooks/useItemHighlighted.js +2 -2
  138. package/index.js +1 -1
  139. package/internals/components/NotRendered.d.ts +9 -0
  140. package/internals/components/NotRendered.js +16 -0
  141. package/internals/createSeriesSelectorOfType.js +2 -2
  142. package/internals/index.d.ts +1 -0
  143. package/internals/index.js +12 -0
  144. package/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.selectors.d.ts +3 -29
  145. package/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.selectors.js +1 -1
  146. package/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.js +30 -2
  147. package/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.selectors.d.ts +14 -724
  148. package/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.selectors.js +11 -10
  149. package/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.types.d.ts +8 -2
  150. package/internals/plugins/corePlugins/useChartId/useChartId.selectors.d.ts +3 -29
  151. package/internals/plugins/corePlugins/useChartId/useChartId.selectors.js +1 -1
  152. package/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.d.ts +6 -54
  153. package/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.js +2 -2
  154. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartAxisSize.selectors.d.ts +12 -208
  155. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors.d.ts +7 -66
  156. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors.js +4 -3
  157. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.d.ts +21 -6222
  158. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.js +4 -6
  159. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianInteraction.selectors.d.ts +50 -5
  160. package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.d.ts +18 -622
  161. package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.js +3 -3
  162. package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.selectors.d.ts +18 -230
  163. package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.selectors.js +6 -6
  164. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.js +20 -4
  165. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.selectors.d.ts +17 -2012
  166. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.selectors.js +2 -2
  167. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarInteraction.selectors.d.ts +39 -4
  168. package/internals/plugins/featurePlugins/useChartVoronoi/useChartVoronoi.selectors.d.ts +3 -27
  169. package/internals/plugins/featurePlugins/useChartVoronoi/useChartVoronoi.selectors.js +1 -1
  170. package/internals/plugins/featurePlugins/useChartZAxis/useChartZAxis.selectors.d.ts +5 -40
  171. package/internals/plugins/utils/selectors.d.ts +18 -6
  172. package/internals/plugins/utils/selectors.js +3 -3
  173. package/internals/store/useSelector.d.ts +2 -2
  174. package/internals/store/useSelector.js +2 -2
  175. package/locales/enUS.d.ts +3 -0
  176. package/locales/enUS.js +8 -2
  177. package/locales/frFR.d.ts +3 -0
  178. package/locales/frFR.js +7 -0
  179. package/locales/ptBR.d.ts +3 -0
  180. package/locales/ptBR.js +7 -1
  181. package/locales/ptPT.d.ts +3 -0
  182. package/locales/ptPT.js +7 -1
  183. package/locales/utils/chartsLocaleTextApi.d.ts +17 -0
  184. package/locales/utils/getChartsLocalization.d.ts +3 -0
  185. package/locales/utils/imageMimeTypes.d.ts +2 -0
  186. package/locales/utils/imageMimeTypes.js +11 -0
  187. package/models/slots/chartsBaseSlotProps.d.ts +4 -0
  188. package/package.json +3 -3
@@ -9,24 +9,22 @@ import useSlotProps from '@mui/utils/useSlotProps';
9
9
  import composeClasses from '@mui/utils/composeClasses';
10
10
  import { useThemeProps, useTheme, styled } from '@mui/material/styles';
11
11
  import { useRtl } from '@mui/system/RtlProvider';
12
- import { clampAngle } from "../internals/clampAngle.js";
13
12
  import { useIsHydrated } from "../hooks/useIsHydrated.js";
14
- import { doesTextFitInRect, ellipsize } from "../internals/ellipsize.js";
15
13
  import { getStringSize } from "../internals/domUtils.js";
16
14
  import { useTicks } from "../hooks/useTicks.js";
17
15
  import { getAxisUtilityClass } from "../ChartsAxis/axisClasses.js";
18
16
  import { AxisRoot } from "../internals/components/AxisSharedComponents.js";
19
17
  import { ChartsText } from "../ChartsText/index.js";
20
- import { getMinXTranslation } from "../internals/geometry.js";
21
18
  import { useMounted } from "../hooks/useMounted.js";
22
19
  import { useDrawingArea } from "../hooks/useDrawingArea.js";
23
- import { getWordsByLines } from "../internals/getWordsByLines.js";
24
20
  import { isInfinity } from "../internals/isInfinity.js";
25
21
  import { isBandScale } from "../internals/isBandScale.js";
26
22
  import { useChartContext } from "../context/ChartProvider/useChartContext.js";
27
23
  import { useXAxes } from "../hooks/useAxis.js";
28
24
  import { getDefaultBaseline, getDefaultTextAnchor } from "../ChartsText/defaultTextPlacement.js";
29
25
  import { invertTextAnchor } from "../internals/invertTextAnchor.js";
26
+ import { shortenLabels } from "./shortenLabels.js";
27
+ import { getVisibleLabels } from "./getVisibleLabels.js";
30
28
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
31
29
  const useUtilityClasses = ownerState => {
32
30
  const {
@@ -49,108 +47,6 @@ const useUtilityClasses = ownerState => {
49
47
  const TICK_LABEL_GAP = 3;
50
48
  /* Gap between the axis label and tick labels. */
51
49
  const AXIS_LABEL_TICK_LABEL_GAP = 4;
52
-
53
- /* Returns a set of indices of the tick labels that should be visible. */
54
- function getVisibleLabels(xTicks, {
55
- tickLabelStyle: style,
56
- tickLabelInterval,
57
- tickLabelMinGap,
58
- reverse,
59
- isMounted,
60
- isXInside
61
- }) {
62
- const getTickLabelSize = tick => {
63
- if (!isMounted || tick.formattedValue === undefined) {
64
- return {
65
- width: 0,
66
- height: 0
67
- };
68
- }
69
- const tickSizes = getWordsByLines({
70
- style,
71
- needsComputation: true,
72
- text: tick.formattedValue
73
- });
74
- return {
75
- width: Math.max(...tickSizes.map(size => size.width)),
76
- height: Math.max(tickSizes.length * tickSizes[0].height)
77
- };
78
- };
79
- if (typeof tickLabelInterval === 'function') {
80
- return new Set(xTicks.filter((item, index) => tickLabelInterval(item.value, index)));
81
- }
82
-
83
- // Filter label to avoid overlap
84
- let previousTextLimit = 0;
85
- const direction = reverse ? -1 : 1;
86
- return new Set(xTicks.filter((item, labelIndex) => {
87
- const {
88
- offset,
89
- labelOffset
90
- } = item;
91
- const textPosition = offset + labelOffset;
92
- if (labelIndex > 0 && direction * textPosition < direction * (previousTextLimit + tickLabelMinGap)) {
93
- return false;
94
- }
95
- if (!isXInside(textPosition)) {
96
- return false;
97
- }
98
-
99
- /* Measuring text width is expensive, so we need to delay it as much as possible to improve performance. */
100
- const {
101
- width,
102
- height
103
- } = getTickLabelSize(item);
104
- const distance = getMinXTranslation(width, height, style?.angle);
105
- const currentTextLimit = textPosition - direction * distance / 2;
106
- if (labelIndex > 0 && direction * currentTextLimit < direction * (previousTextLimit + tickLabelMinGap)) {
107
- // Except for the first label, we skip all label that overlap with the last accepted.
108
- // Notice that the early return prevents `previousTextLimit` from being updated.
109
- return false;
110
- }
111
- previousTextLimit = textPosition + direction * distance / 2;
112
- return true;
113
- }));
114
- }
115
- function shortenLabels(visibleLabels, drawingArea, maxHeight, isRtl, tickLabelStyle) {
116
- const shortenedLabels = new Map();
117
- const angle = clampAngle(tickLabelStyle?.angle ?? 0);
118
-
119
- // Multiplying the space available to the left of the text position by leftBoundFactor returns the max width of the text.
120
- // Same for rightBoundFactor
121
- let leftBoundFactor = 1;
122
- let rightBoundFactor = 1;
123
- if (tickLabelStyle?.textAnchor === 'start') {
124
- leftBoundFactor = Infinity;
125
- rightBoundFactor = 1;
126
- } else if (tickLabelStyle?.textAnchor === 'end') {
127
- leftBoundFactor = 1;
128
- rightBoundFactor = Infinity;
129
- } else {
130
- leftBoundFactor = 2;
131
- rightBoundFactor = 2;
132
- }
133
- if (angle > 90 && angle < 270) {
134
- [leftBoundFactor, rightBoundFactor] = [rightBoundFactor, leftBoundFactor];
135
- }
136
- if (isRtl) {
137
- [leftBoundFactor, rightBoundFactor] = [rightBoundFactor, leftBoundFactor];
138
- }
139
- for (const item of visibleLabels) {
140
- if (item.formattedValue) {
141
- // That maximum width of the tick depends on its proximity to the axis bounds.
142
- const width = Math.min((item.offset + item.labelOffset) * leftBoundFactor, (drawingArea.left + drawingArea.width + drawingArea.right - item.offset - item.labelOffset) * rightBoundFactor);
143
- const doesTextFit = text => doesTextFitInRect(text, {
144
- width,
145
- height: maxHeight,
146
- angle,
147
- measureText: string => getStringSize(string, tickLabelStyle)
148
- });
149
- shortenedLabels.set(item, ellipsize(item.formattedValue.toString(), doesTextFit));
150
- }
151
- }
152
- return shortenedLabels;
153
- }
154
50
  const XAxisRoot = styled(AxisRoot, {
155
51
  name: 'MuiChartsXAxis',
156
52
  slot: 'Root'
@@ -0,0 +1,14 @@
1
+ import { TickItemType } from "../hooks/useTicks.js";
2
+ import { ChartsXAxisProps, ComputedXAxis } from "../models/axis.js";
3
+ export declare function getVisibleLabels(xTicks: TickItemType[], {
4
+ tickLabelStyle: style,
5
+ tickLabelInterval,
6
+ tickLabelMinGap,
7
+ reverse,
8
+ isMounted,
9
+ isXInside
10
+ }: Pick<ChartsXAxisProps, 'tickLabelInterval' | 'tickLabelStyle'> & Pick<ComputedXAxis, 'reverse'> & {
11
+ isMounted: boolean;
12
+ tickLabelMinGap: NonNullable<ChartsXAxisProps['tickLabelMinGap']>;
13
+ isXInside: (x: number) => boolean;
14
+ }): Set<TickItemType>;
@@ -0,0 +1,67 @@
1
+ 'use client';
2
+
3
+ import { getMinXTranslation } from "../internals/geometry.js";
4
+ import { getWordsByLines } from "../internals/getWordsByLines.js";
5
+
6
+ /* Returns a set of indices of the tick labels that should be visible. */
7
+ export function getVisibleLabels(xTicks, {
8
+ tickLabelStyle: style,
9
+ tickLabelInterval,
10
+ tickLabelMinGap,
11
+ reverse,
12
+ isMounted,
13
+ isXInside
14
+ }) {
15
+ const getTickLabelSize = tick => {
16
+ if (!isMounted || tick.formattedValue === undefined) {
17
+ return {
18
+ width: 0,
19
+ height: 0
20
+ };
21
+ }
22
+ const tickSizes = getWordsByLines({
23
+ style,
24
+ needsComputation: true,
25
+ text: tick.formattedValue
26
+ });
27
+ return {
28
+ width: Math.max(...tickSizes.map(size => size.width)),
29
+ height: Math.max(tickSizes.length * tickSizes[0].height)
30
+ };
31
+ };
32
+ if (typeof tickLabelInterval === 'function') {
33
+ return new Set(xTicks.filter((item, index) => tickLabelInterval(item.value, index)));
34
+ }
35
+
36
+ // Filter label to avoid overlap
37
+ let previousTextLimit = 0;
38
+ const direction = reverse ? -1 : 1;
39
+ return new Set(xTicks.filter((item, labelIndex) => {
40
+ const {
41
+ offset,
42
+ labelOffset
43
+ } = item;
44
+ const textPosition = offset + labelOffset;
45
+ if (labelIndex > 0 && direction * textPosition < direction * (previousTextLimit + tickLabelMinGap)) {
46
+ return false;
47
+ }
48
+ if (!isXInside(textPosition)) {
49
+ return false;
50
+ }
51
+
52
+ /* Measuring text width is expensive, so we need to delay it as much as possible to improve performance. */
53
+ const {
54
+ width,
55
+ height
56
+ } = getTickLabelSize(item);
57
+ const distance = getMinXTranslation(width, height, style?.angle);
58
+ const currentTextLimit = textPosition - direction * distance / 2;
59
+ if (labelIndex > 0 && direction * currentTextLimit < direction * (previousTextLimit + tickLabelMinGap)) {
60
+ // Except for the first label, we skip all label that overlap with the last accepted.
61
+ // Notice that the early return prevents `previousTextLimit` from being updated.
62
+ return false;
63
+ }
64
+ previousTextLimit = textPosition + direction * distance / 2;
65
+ return true;
66
+ }));
67
+ }
@@ -0,0 +1,4 @@
1
+ import { TickItemType } from "../hooks/useTicks.js";
2
+ import { ChartsXAxisProps } from "../models/axis.js";
3
+ import { ChartDrawingArea } from "../hooks/useDrawingArea.js";
4
+ export declare function shortenLabels(visibleLabels: Set<TickItemType>, drawingArea: Pick<ChartDrawingArea, 'left' | 'width' | 'right'>, maxHeight: number, isRtl: boolean, tickLabelStyle: ChartsXAxisProps['tickLabelStyle']): Map<TickItemType, string>;
@@ -0,0 +1,42 @@
1
+ import { clampAngle } from "../internals/clampAngle.js";
2
+ import { doesTextFitInRect, ellipsize } from "../internals/ellipsize.js";
3
+ import { getStringSize } from "../internals/domUtils.js";
4
+ export function shortenLabels(visibleLabels, drawingArea, maxHeight, isRtl, tickLabelStyle) {
5
+ const shortenedLabels = new Map();
6
+ const angle = clampAngle(tickLabelStyle?.angle ?? 0);
7
+
8
+ // Multiplying the space available to the left of the text position by leftBoundFactor returns the max width of the text.
9
+ // Same for rightBoundFactor
10
+ let leftBoundFactor = 1;
11
+ let rightBoundFactor = 1;
12
+ if (tickLabelStyle?.textAnchor === 'start') {
13
+ leftBoundFactor = Infinity;
14
+ rightBoundFactor = 1;
15
+ } else if (tickLabelStyle?.textAnchor === 'end') {
16
+ leftBoundFactor = 1;
17
+ rightBoundFactor = Infinity;
18
+ } else {
19
+ leftBoundFactor = 2;
20
+ rightBoundFactor = 2;
21
+ }
22
+ if (angle > 90 && angle < 270) {
23
+ [leftBoundFactor, rightBoundFactor] = [rightBoundFactor, leftBoundFactor];
24
+ }
25
+ if (isRtl) {
26
+ [leftBoundFactor, rightBoundFactor] = [rightBoundFactor, leftBoundFactor];
27
+ }
28
+ for (const item of visibleLabels) {
29
+ if (item.formattedValue) {
30
+ // That maximum width of the tick depends on its proximity to the axis bounds.
31
+ const width = Math.min((item.offset + item.labelOffset) * leftBoundFactor, (drawingArea.left + drawingArea.width + drawingArea.right - item.offset - item.labelOffset) * rightBoundFactor);
32
+ const doesTextFit = text => doesTextFitInRect(text, {
33
+ width,
34
+ height: maxHeight,
35
+ angle,
36
+ measureText: string => getStringSize(string, tickLabelStyle)
37
+ });
38
+ shortenedLabels.set(item, ellipsize(item.formattedValue.toString(), doesTextFit));
39
+ }
40
+ }
41
+ return shortenedLabels;
42
+ }
@@ -11,7 +11,6 @@ import { useThemeProps, styled, useTheme } from '@mui/material/styles';
11
11
  import { useRtl } from '@mui/system/RtlProvider';
12
12
  import { useIsHydrated } from "../hooks/useIsHydrated.js";
13
13
  import { getDefaultBaseline, getDefaultTextAnchor } from "../ChartsText/defaultTextPlacement.js";
14
- import { doesTextFitInRect, ellipsize } from "../internals/ellipsize.js";
15
14
  import { getStringSize } from "../internals/domUtils.js";
16
15
  import { useTicks } from "../hooks/useTicks.js";
17
16
  import { useDrawingArea } from "../hooks/useDrawingArea.js";
@@ -22,8 +21,8 @@ import { isInfinity } from "../internals/isInfinity.js";
22
21
  import { isBandScale } from "../internals/isBandScale.js";
23
22
  import { useChartContext } from "../context/ChartProvider/index.js";
24
23
  import { useYAxes } from "../hooks/index.js";
25
- import { clampAngle } from "../internals/clampAngle.js";
26
24
  import { invertTextAnchor } from "../internals/invertTextAnchor.js";
25
+ import { shortenLabels } from "./shortenLabels.js";
27
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
28
27
  const useUtilityClasses = ownerState => {
29
28
  const {
@@ -46,42 +45,6 @@ const useUtilityClasses = ownerState => {
46
45
  const TICK_LABEL_GAP = 2;
47
46
  /* Gap between the axis label and tick labels. */
48
47
  const AXIS_LABEL_TICK_LABEL_GAP = 2;
49
- function shortenLabels(visibleLabels, drawingArea, maxWidth, isRtl, tickLabelStyle) {
50
- const shortenedLabels = new Map();
51
- const angle = clampAngle(tickLabelStyle?.angle ?? 0);
52
- let topBoundFactor = 1;
53
- let bottomBoundFactor = 1;
54
- if (tickLabelStyle?.textAnchor === 'start') {
55
- topBoundFactor = Infinity;
56
- bottomBoundFactor = 1;
57
- } else if (tickLabelStyle?.textAnchor === 'end') {
58
- topBoundFactor = 1;
59
- bottomBoundFactor = Infinity;
60
- } else {
61
- topBoundFactor = 2;
62
- bottomBoundFactor = 2;
63
- }
64
- if (angle > 180) {
65
- [topBoundFactor, bottomBoundFactor] = [bottomBoundFactor, topBoundFactor];
66
- }
67
- if (isRtl) {
68
- [topBoundFactor, bottomBoundFactor] = [bottomBoundFactor, topBoundFactor];
69
- }
70
- for (const item of visibleLabels) {
71
- if (item.formattedValue) {
72
- // That maximum height of the tick depends on its proximity to the axis bounds.
73
- const height = Math.min((item.offset + item.labelOffset) * topBoundFactor, (drawingArea.top + drawingArea.height + drawingArea.bottom - item.offset - item.labelOffset) * bottomBoundFactor);
74
- const doesTextFit = text => doesTextFitInRect(text, {
75
- width: maxWidth,
76
- height,
77
- angle,
78
- measureText: string => getStringSize(string, tickLabelStyle)
79
- });
80
- shortenedLabels.set(item, ellipsize(item.formattedValue.toString(), doesTextFit));
81
- }
82
- }
83
- return shortenedLabels;
84
- }
85
48
  const YAxisRoot = styled(AxisRoot, {
86
49
  name: 'MuiChartsYAxis',
87
50
  slot: 'Root'
@@ -0,0 +1,4 @@
1
+ import { ChartDrawingArea } from "../hooks/index.js";
2
+ import { TickItemType } from "../hooks/useTicks.js";
3
+ import { ChartsYAxisProps } from "../models/index.js";
4
+ export declare function shortenLabels(visibleLabels: TickItemType[], drawingArea: Pick<ChartDrawingArea, 'top' | 'height' | 'bottom'>, maxWidth: number, isRtl: boolean, tickLabelStyle: ChartsYAxisProps['tickLabelStyle']): Map<TickItemType, string>;
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+
3
+ import { clampAngle } from "../internals/clampAngle.js";
4
+ import { doesTextFitInRect, ellipsize } from "../internals/ellipsize.js";
5
+ import { getStringSize } from "../internals/domUtils.js";
6
+ export function shortenLabels(visibleLabels, drawingArea, maxWidth, isRtl, tickLabelStyle) {
7
+ const shortenedLabels = new Map();
8
+ const angle = clampAngle(tickLabelStyle?.angle ?? 0);
9
+ let topBoundFactor = 1;
10
+ let bottomBoundFactor = 1;
11
+ if (tickLabelStyle?.textAnchor === 'start') {
12
+ topBoundFactor = Infinity;
13
+ bottomBoundFactor = 1;
14
+ } else if (tickLabelStyle?.textAnchor === 'end') {
15
+ topBoundFactor = 1;
16
+ bottomBoundFactor = Infinity;
17
+ } else {
18
+ topBoundFactor = 2;
19
+ bottomBoundFactor = 2;
20
+ }
21
+ if (angle > 180) {
22
+ [topBoundFactor, bottomBoundFactor] = [bottomBoundFactor, topBoundFactor];
23
+ }
24
+ if (isRtl) {
25
+ [topBoundFactor, bottomBoundFactor] = [bottomBoundFactor, topBoundFactor];
26
+ }
27
+ for (const item of visibleLabels) {
28
+ if (item.formattedValue) {
29
+ // That maximum height of the tick depends on its proximity to the axis bounds.
30
+ const height = Math.min((item.offset + item.labelOffset) * topBoundFactor, (drawingArea.top + drawingArea.height + drawingArea.bottom - item.offset - item.labelOffset) * bottomBoundFactor);
31
+ const doesTextFit = text => doesTextFitInRect(text, {
32
+ width: maxWidth,
33
+ height,
34
+ angle,
35
+ measureText: string => getStringSize(string, tickLabelStyle)
36
+ });
37
+ shortenedLabels.set(item, ellipsize(item.formattedValue.toString(), doesTextFit));
38
+ }
39
+ }
40
+ return shortenedLabels;
41
+ }
@@ -34,7 +34,10 @@ function AnimatedArea(props) {
34
34
  // eslint-disable-next-line no-nested-ternary
35
35
  ownerState.isHighlighted ? 'brightness(140%)' : ownerState.gradientId ? undefined : 'brightness(120%)',
36
36
  opacity: ownerState.isFaded ? 0.3 : 1,
37
- stroke: "none"
37
+ stroke: "none",
38
+ "data-series": ownerState.id,
39
+ "data-highlighted": ownerState.isHighlighted || undefined,
40
+ "data-faded": ownerState.isFaded || undefined
38
41
  }, other, animatedProps))
39
42
  });
40
43
  }
@@ -36,7 +36,10 @@ const AnimatedLine = /*#__PURE__*/React.forwardRef(function AnimatedLine(props,
36
36
  strokeLinejoin: "round",
37
37
  fill: "none",
38
38
  filter: ownerState.isHighlighted ? 'brightness(120%)' : undefined,
39
- opacity: ownerState.isFaded ? 0.3 : 1
39
+ opacity: ownerState.isFaded ? 0.3 : 1,
40
+ "data-series": ownerState.id,
41
+ "data-highlighted": ownerState.isHighlighted || undefined,
42
+ "data-faded": ownerState.isFaded || undefined
40
43
  }, other, animateProps))
41
44
  });
42
45
  });
@@ -69,7 +69,10 @@ function CircleMarkElement(props) {
69
69
  className: classes.root,
70
70
  onClick: onClick,
71
71
  cursor: onClick ? 'pointer' : 'unset'
72
- }, interactionProps));
72
+ }, interactionProps, {
73
+ "data-highlighted": isHighlighted || undefined,
74
+ "data-faded": isFaded || undefined
75
+ }));
73
76
  }
74
77
  process.env.NODE_ENV !== "production" ? CircleMarkElement.propTypes = {
75
78
  // ----------------------------- Warning --------------------------------
@@ -77,7 +77,10 @@ function MarkElement(props) {
77
77
  d: d3Symbol(d3SymbolsFill[getSymbol(shape)])(),
78
78
  onClick: onClick,
79
79
  cursor: onClick ? 'pointer' : 'unset'
80
- }, interactionProps));
80
+ }, interactionProps, {
81
+ "data-highlighted": isHighlighted || undefined,
82
+ "data-faded": isFaded || undefined
83
+ }));
81
84
  }
82
85
  process.env.NODE_ENV !== "production" ? MarkElement.propTypes = {
83
86
  // ----------------------------- Warning --------------------------------
@@ -102,6 +102,7 @@ function MarkPlot(props) {
102
102
  });
103
103
  return /*#__PURE__*/_jsx("g", {
104
104
  clipPath: `url(#${clipId})`,
105
+ "data-series": seriesId,
105
106
  children: xData?.map((x, index) => {
106
107
  const value = data[index] == null ? null : stackedData[index][1];
107
108
  return {
@@ -94,7 +94,9 @@ const PieArc = /*#__PURE__*/React.forwardRef(function PieArc(props, ref) {
94
94
  opacity: ownerState.isFaded ? 0.3 : 1,
95
95
  filter: ownerState.isHighlighted ? 'brightness(120%)' : 'none',
96
96
  strokeWidth: 1,
97
- strokeLinejoin: "round"
97
+ strokeLinejoin: "round",
98
+ "data-highlighted": ownerState.isHighlighted || undefined,
99
+ "data-faded": ownerState.isFaded || undefined
98
100
  }, other, interactionProps, animatedProps));
99
101
  });
100
102
  if (process.env.NODE_ENV !== "production") PieArc.displayName = "PieArc";
@@ -9,6 +9,7 @@ import { getPieCoordinates } from "./getPieCoordinates.js";
9
9
  import { usePieSeriesContext } from "../hooks/usePieSeries.js";
10
10
  import { useSkipAnimation } from "../hooks/useSkipAnimation.js";
11
11
  import { useDrawingArea } from "../hooks/index.js";
12
+ import { useUtilityClasses } from "./pieClasses.js";
12
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
14
  /**
14
15
  * Demos:
@@ -35,6 +36,7 @@ function PiePlot(props) {
35
36
  height
36
37
  } = useDrawingArea();
37
38
  const skipAnimation = useSkipAnimation(inSkipAnimation);
39
+ const classes = useUtilityClasses();
38
40
  if (seriesData === undefined) {
39
41
  return null;
40
42
  }
@@ -69,7 +71,9 @@ function PiePlot(props) {
69
71
  const outerRadius = getPercentageValue(outerRadiusParam ?? availableRadius, availableRadius);
70
72
  const innerRadius = getPercentageValue(innerRadiusParam ?? 0, availableRadius);
71
73
  return /*#__PURE__*/_jsx("g", {
74
+ className: classes.series,
72
75
  transform: `translate(${left + cx}, ${top + cy})`,
76
+ "data-series": seriesId,
73
77
  children: /*#__PURE__*/_jsx(PieArcPlot, {
74
78
  innerRadius: innerRadius,
75
79
  outerRadius: outerRadius,
@@ -113,7 +117,9 @@ function PiePlot(props) {
113
117
  const innerRadius = getPercentageValue(innerRadiusParam ?? 0, availableRadius);
114
118
  const arcLabelRadius = arcLabelRadiusParam === undefined ? (outerRadius + innerRadius) / 2 : getPercentageValue(arcLabelRadiusParam, availableRadius);
115
119
  return /*#__PURE__*/_jsx("g", {
120
+ className: classes.seriesLabels,
116
121
  transform: `translate(${left + cx}, ${top + cy})`,
122
+ "data-series": seriesId,
117
123
  children: /*#__PURE__*/_jsx(PieArcLabelPlot, {
118
124
  innerRadius: innerRadius,
119
125
  outerRadius: outerRadius ?? availableRadius,
@@ -4,4 +4,6 @@ export * from "./PieArcPlot.js";
4
4
  export * from "./PieArcLabelPlot.js";
5
5
  export * from "./PieArc.js";
6
6
  export * from "./PieArcLabel.js";
7
- export * from "./getPieCoordinates.js";
7
+ export * from "./getPieCoordinates.js";
8
+ export { pieClasses } from "./pieClasses.js";
9
+ export type { PieClasses, PieClassKey } from "./pieClasses.js";
@@ -4,4 +4,5 @@ export * from "./PieArcPlot.js";
4
4
  export * from "./PieArcLabelPlot.js";
5
5
  export * from "./PieArc.js";
6
6
  export * from "./PieArcLabel.js";
7
- export * from "./getPieCoordinates.js";
7
+ export * from "./getPieCoordinates.js";
8
+ export { pieClasses } from "./pieClasses.js";
@@ -0,0 +1,12 @@
1
+ export interface PieClasses {
2
+ /** Styles applied to the root element. */
3
+ root: string;
4
+ /** Styles applied to the `g` element that contains all pie arcs of a series. */
5
+ series: string;
6
+ /** Styles applied to the `g` element that contains all pie arc labels of a series. */
7
+ seriesLabels: string;
8
+ }
9
+ export type PieClassKey = keyof PieClasses;
10
+ export declare function getPieUtilityClass(slot: string): string;
11
+ export declare const pieClasses: PieClasses;
12
+ export declare const useUtilityClasses: (classes?: Partial<PieClasses>) => Record<"root" | "series" | "seriesLabels", string>;
@@ -0,0 +1,15 @@
1
+ import generateUtilityClass from '@mui/utils/generateUtilityClass';
2
+ import composeClasses from '@mui/utils/composeClasses';
3
+ import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
4
+ export function getPieUtilityClass(slot) {
5
+ return generateUtilityClass('MuiPieChart', slot);
6
+ }
7
+ export const pieClasses = generateUtilityClasses('MuiPieChart', ['root', 'series', 'seriesLabels']);
8
+ export const useUtilityClasses = classes => {
9
+ const slots = {
10
+ root: ['root'],
11
+ series: ['series'],
12
+ seriesLabels: ['seriesLabels']
13
+ };
14
+ return composeClasses(slots, getPieUtilityClass, classes);
15
+ };
@@ -3,6 +3,7 @@ import { ScatterMarkerSlotProps, ScatterMarkerSlots } from "./ScatterMarker.type
3
3
  import { DefaultizedScatterSeriesType, ScatterItemIdentifier } from "../models/seriesType/scatter.js";
4
4
  import { D3Scale } from "../models/axis.js";
5
5
  import { ColorGetter } from "../internals/plugins/models/seriesConfig/index.js";
6
+ import { ScatterClasses } from "./scatterClasses.js";
6
7
  export interface ScatterProps {
7
8
  series: DefaultizedScatterSeriesType;
8
9
  xScale: D3Scale;
@@ -15,6 +16,7 @@ export interface ScatterProps {
15
16
  * @param {ScatterItemIdentifier} scatterItemIdentifier The scatter item identifier.
16
17
  */
17
18
  onItemClick?: (event: React.MouseEvent<SVGElement, MouseEvent>, scatterItemIdentifier: ScatterItemIdentifier) => void;
19
+ classes?: Partial<ScatterClasses>;
18
20
  slots?: ScatterSlots;
19
21
  slotProps?: ScatterSlotProps;
20
22
  }
@@ -14,6 +14,7 @@ import { useItemHighlightedGetter } from "../hooks/useItemHighlightedGetter.js";
14
14
  import { selectorChartsVoronoiIsVoronoiEnabled } from "../internals/plugins/featurePlugins/useChartVoronoi/index.js";
15
15
  import { useChartContext } from "../context/ChartProvider/index.js";
16
16
  import { ScatterMarker } from "./ScatterMarker.js";
17
+ import { useUtilityClasses } from "./scatterClasses.js";
17
18
  import { jsx as _jsx } from "react/jsx-runtime";
18
19
  /**
19
20
  * Demos:
@@ -33,6 +34,7 @@ function Scatter(props) {
33
34
  color,
34
35
  colorGetter,
35
36
  onItemClick,
37
+ classes: inClasses,
36
38
  slots,
37
39
  slotProps
38
40
  } = props;
@@ -88,7 +90,10 @@ function Scatter(props) {
88
90
  ownerState: {}
89
91
  }),
90
92
  markerProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded);
93
+ const classes = useUtilityClasses(inClasses);
91
94
  return /*#__PURE__*/_jsx("g", {
95
+ "data-series": series.id,
96
+ className: classes.root,
92
97
  children: cleanData.map((dataPoint, i) => /*#__PURE__*/_jsx(Marker, _extends({
93
98
  dataIndex: dataPoint.dataIndex,
94
99
  color: dataPoint.color,
@@ -100,7 +105,9 @@ function Scatter(props) {
100
105
  type: 'scatter',
101
106
  seriesId: series.id,
102
107
  dataIndex: dataPoint.dataIndex
103
- }))
108
+ })),
109
+ "data-highlighted": dataPoint.isHighlighted || undefined,
110
+ "data-faded": dataPoint.isFaded || undefined
104
111
  }, interactionItemProps[i], markerProps), dataPoint.id ?? dataPoint.dataIndex))
105
112
  });
106
113
  }
@@ -109,6 +116,7 @@ process.env.NODE_ENV !== "production" ? Scatter.propTypes = {
109
116
  // | These PropTypes are generated from the TypeScript type definitions |
110
117
  // | To update them edit the TypeScript types and run "pnpm proptypes" |
111
118
  // ----------------------------------------------------------------------
119
+ classes: PropTypes.object,
112
120
  color: PropTypes.string.isRequired,
113
121
  colorGetter: PropTypes.func,
114
122
  /**
@@ -2,4 +2,6 @@ export * from "./ScatterChart.js";
2
2
  export * from "./ScatterPlot.js";
3
3
  export * from "./Scatter.js";
4
4
  export * from "./ScatterMarker.types.js";
5
- export * from "./ScatterMarker.js";
5
+ export * from "./ScatterMarker.js";
6
+ export type { ScatterClasses } from "./scatterClasses.js";
7
+ export { scatterClasses } from "./scatterClasses.js";
@@ -2,4 +2,5 @@ export * from "./ScatterChart.js";
2
2
  export * from "./ScatterPlot.js";
3
3
  export * from "./Scatter.js";
4
4
  export * from "./ScatterMarker.types.js";
5
- export * from "./ScatterMarker.js";
5
+ export * from "./ScatterMarker.js";
6
+ export { scatterClasses } from "./scatterClasses.js";
@@ -0,0 +1,8 @@
1
+ export interface ScatterClasses {
2
+ /** Styles applied to the root element. */
3
+ root: string;
4
+ }
5
+ export type ScatterClassKey = keyof ScatterClasses;
6
+ export declare function getScatterUtilityClass(slot: string): string;
7
+ export declare const scatterClasses: ScatterClasses;
8
+ export declare const useUtilityClasses: (classes?: Partial<ScatterClasses>) => Record<"root", string>;
@@ -0,0 +1,13 @@
1
+ import generateUtilityClass from '@mui/utils/generateUtilityClass';
2
+ import composeClasses from '@mui/utils/composeClasses';
3
+ import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
4
+ export function getScatterUtilityClass(slot) {
5
+ return generateUtilityClass('MuiScatter', slot);
6
+ }
7
+ export const scatterClasses = generateUtilityClasses('MuiScatter', ['root']);
8
+ export const useUtilityClasses = classes => {
9
+ const slots = {
10
+ root: ['root']
11
+ };
12
+ return composeClasses(slots, getScatterUtilityClass, classes);
13
+ };
@@ -44,10 +44,12 @@ process.env.NODE_ENV !== "production" ? ToolbarButton.propTypes = {
44
44
  // ----------------------------------------------------------------------
45
45
  className: PropTypes.string,
46
46
  disabled: PropTypes.bool,
47
+ id: PropTypes.string,
47
48
  /**
48
49
  * A function to customize the rendering of the component.
49
50
  */
50
51
  render: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
52
+ size: PropTypes.oneOf(['large', 'medium', 'small']),
51
53
  style: PropTypes.object,
52
54
  tabIndex: PropTypes.number
53
55
  } : void 0;