@mui/x-charts 9.11.1 → 9.13.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 (124) hide show
  1. package/BarChart/BarChart.js +8 -1
  2. package/BarChart/BarChart.mjs +8 -1
  3. package/CHANGELOG.md +278 -0
  4. package/ChartsContainer/ChartsContainer.js +8 -1
  5. package/ChartsContainer/ChartsContainer.mjs +8 -1
  6. package/ChartsContainer/useChartsContainerProps.js +3 -1
  7. package/ChartsContainer/useChartsContainerProps.mjs +3 -1
  8. package/ChartsTooltip/ChartsAxisTooltipContent.js +2 -9
  9. package/ChartsTooltip/ChartsAxisTooltipContent.mjs +2 -9
  10. package/ChartsTooltip/ChartsItemTooltipContent.js +2 -2
  11. package/ChartsTooltip/ChartsItemTooltipContent.mjs +2 -2
  12. package/ChartsTooltip/ChartsTooltipContainer.js +6 -2
  13. package/ChartsTooltip/ChartsTooltipContainer.mjs +6 -2
  14. package/ChartsXAxis/useAxisTicksProps.js +2 -1
  15. package/ChartsXAxis/useAxisTicksProps.mjs +2 -1
  16. package/ChartsYAxis/shortenLabels.js +16 -26
  17. package/ChartsYAxis/shortenLabels.mjs +17 -27
  18. package/ChartsYAxis/useAxisTicksProps.js +2 -1
  19. package/ChartsYAxis/useAxisTicksProps.mjs +2 -1
  20. package/LineChart/CircleMarkElement.js +0 -4
  21. package/LineChart/CircleMarkElement.mjs +0 -4
  22. package/LineChart/LineChart.js +8 -1
  23. package/LineChart/LineChart.mjs +8 -1
  24. package/LineChart/MarkElement.js +13 -6
  25. package/LineChart/MarkElement.mjs +13 -6
  26. package/PieChart/PieChart.js +7 -0
  27. package/PieChart/PieChart.mjs +7 -0
  28. package/RadarChart/RadarChart.js +8 -1
  29. package/RadarChart/RadarChart.mjs +8 -1
  30. package/RadarChart/RadarSeriesPlot/RadarSeriesMarks.js +6 -2
  31. package/RadarChart/RadarSeriesPlot/RadarSeriesMarks.mjs +6 -2
  32. package/RadarChart/RadarSeriesPlot/RadarSeriesPlot.js +2 -1
  33. package/RadarChart/RadarSeriesPlot/RadarSeriesPlot.mjs +2 -1
  34. package/RadarChart/useRadarChartProps.js +3 -1
  35. package/RadarChart/useRadarChartProps.mjs +3 -1
  36. package/ScatterChart/ScatterChart.js +8 -1
  37. package/ScatterChart/ScatterChart.mjs +8 -1
  38. package/SparkLineChart/SparkLineChart.js +8 -1
  39. package/SparkLineChart/SparkLineChart.mjs +8 -1
  40. package/constants/index.d.mts +3 -1
  41. package/constants/index.d.ts +3 -1
  42. package/constants/index.js +5 -2
  43. package/constants/index.mjs +4 -1
  44. package/hooks/animation/index.d.mts +1 -0
  45. package/hooks/animation/index.d.ts +1 -0
  46. package/hooks/animation/index.js +11 -0
  47. package/hooks/animation/index.mjs +1 -0
  48. package/hooks/animation/useAnimateMark.d.mts +25 -0
  49. package/hooks/animation/useAnimateMark.d.ts +25 -0
  50. package/hooks/animation/useAnimateMark.js +45 -0
  51. package/hooks/animation/useAnimateMark.mjs +39 -0
  52. package/hooks/useInteractionItemProps.js +4 -0
  53. package/hooks/useInteractionItemProps.mjs +4 -0
  54. package/index.js +1 -1
  55. package/index.mjs +1 -1
  56. package/internals/components/ChartsAccessibilityProxy/ChartsAccessibilityProxy.js +13 -3
  57. package/internals/components/ChartsAccessibilityProxy/ChartsAccessibilityProxy.mjs +12 -3
  58. package/internals/components/ChartsAccessibilityProxy/focusAccessibilityProxy.d.mts +8 -0
  59. package/internals/components/ChartsAccessibilityProxy/focusAccessibilityProxy.d.ts +8 -0
  60. package/internals/components/ChartsAccessibilityProxy/focusAccessibilityProxy.js +25 -0
  61. package/internals/components/ChartsAccessibilityProxy/focusAccessibilityProxy.mjs +19 -0
  62. package/internals/components/ChartsAccessibilityProxy/index.d.mts +2 -1
  63. package/internals/components/ChartsAccessibilityProxy/index.d.ts +2 -1
  64. package/internals/components/ChartsAccessibilityProxy/index.js +11 -0
  65. package/internals/components/ChartsAccessibilityProxy/index.mjs +2 -1
  66. package/internals/domUtils.js +17 -16
  67. package/internals/domUtils.mjs +17 -15
  68. package/internals/ellipsize.d.mts +30 -0
  69. package/internals/ellipsize.d.ts +30 -0
  70. package/internals/ellipsize.js +60 -0
  71. package/internals/ellipsize.mjs +59 -0
  72. package/internals/index.d.mts +1 -0
  73. package/internals/index.d.ts +1 -0
  74. package/internals/index.js +8 -0
  75. package/internals/index.mjs +1 -0
  76. package/internals/plugins/corePlugins/useChartElementRef/useChartElementRef.js +3 -1
  77. package/internals/plugins/corePlugins/useChartElementRef/useChartElementRef.mjs +3 -1
  78. package/internals/plugins/corePlugins/useChartElementRef/useChartElementRef.types.d.mts +5 -0
  79. package/internals/plugins/corePlugins/useChartElementRef/useChartElementRef.types.d.ts +5 -0
  80. package/internals/plugins/featurePlugins/shared/useRegisterPointerInteractions.js +10 -0
  81. package/internals/plugins/featurePlugins/shared/useRegisterPointerInteractions.mjs +10 -0
  82. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisAutoSize.d.mts +3 -0
  83. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisAutoSize.d.ts +3 -0
  84. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisAutoSize.js +9 -5
  85. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisAutoSize.mjs +9 -5
  86. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartAxisAutoSize.selectors.js +9 -4
  87. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartAxisAutoSize.selectors.mjs +9 -4
  88. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.js +75 -3
  89. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.mjs +76 -3
  90. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.types.d.mts +6 -2
  91. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.types.d.ts +6 -2
  92. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors.d.mts +1 -0
  93. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors.d.ts +1 -0
  94. package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.js +22 -0
  95. package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.mjs +22 -0
  96. package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.js +27 -1
  97. package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.mjs +27 -1
  98. package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types.d.mts +20 -0
  99. package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types.d.ts +20 -0
  100. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.js +242 -35
  101. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.mjs +244 -36
  102. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.d.mts +3 -0
  103. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.d.ts +3 -0
  104. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.js +12 -5
  105. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.mjs +11 -4
  106. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.types.d.mts +29 -0
  107. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.types.d.ts +29 -0
  108. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtAxisPosition.d.mts +28 -0
  109. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtAxisPosition.d.ts +28 -0
  110. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtAxisPosition.js +81 -0
  111. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtAxisPosition.mjs +76 -0
  112. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtRotationIndex.d.mts +18 -0
  113. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtRotationIndex.d.ts +18 -0
  114. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtRotationIndex.js +65 -0
  115. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtRotationIndex.mjs +60 -0
  116. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.js +43 -1
  117. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.mjs +43 -1
  118. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.types.d.mts +3 -2
  119. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.types.d.ts +3 -2
  120. package/internals/useDefaultTickLabelStyle.d.mts +7 -0
  121. package/internals/useDefaultTickLabelStyle.d.ts +7 -0
  122. package/internals/useDefaultTickLabelStyle.js +34 -0
  123. package/internals/useDefaultTickLabelStyle.mjs +28 -0
  124. package/package.json +6 -6
@@ -10,6 +10,7 @@ exports.useChartCartesianAxis = void 0;
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
11
  var React = _interopRequireWildcard(require("react"));
12
12
  var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
13
+ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
13
14
  var _store = require("@mui/x-internals/store");
14
15
  var _useAssertModelConsistency = require("@mui/x-internals/useAssertModelConsistency");
15
16
  var _warning = require("@mui/x-internals/warning");
@@ -23,6 +24,15 @@ var _useChartInteraction = require("../useChartInteraction");
23
24
  var _useChartCartesianInteraction = require("./useChartCartesianInteraction.selectors");
24
25
  var _checkHasInteractionPlugin = require("../useChartInteraction/checkHasInteractionPlugin");
25
26
  var _getAxisClickPayload = require("./getAxisClickPayload");
27
+ var _useDefaultTickLabelStyle = require("../../../useDefaultTickLabelStyle");
28
+ var _useChartKeyboardNavigation = require("../useChartKeyboardNavigation");
29
+ /**
30
+ * Narrows an axis item to one the axis actually has a value for.
31
+ * Axes unrelated to the focused series can exist with empty data, so the index must resolve.
32
+ */
33
+ function hasAxisValueAt(axes, item) {
34
+ return item !== undefined && item.dataIndex !== undefined && axes[item.axisId]?.data?.[item.dataIndex] !== undefined;
35
+ }
26
36
  const useChartCartesianAxis = ({
27
37
  params,
28
38
  store,
@@ -39,6 +49,12 @@ const useChartCartesianAxis = ({
39
49
  onTooltipAxisChange,
40
50
  axesGap
41
51
  } = params;
52
+ const defaultTickLabelStyle = (0, _useDefaultTickLabelStyle.useDefaultTickLabelStyle)();
53
+ (0, _useEnhancedEffect.default)(() => {
54
+ store.set('cartesianAxis', (0, _extends2.default)({}, store.state.cartesianAxis, {
55
+ defaultTickLabelStyle
56
+ }));
57
+ }, [defaultTickLabelStyle, store]);
42
58
  if (process.env.NODE_ENV !== 'production') {
43
59
  const ids = [...(xAxis ?? []), ...(yAxis ?? [])].filter(axis => axis.id).map(axis => axis.id);
44
60
  const duplicates = new Set(ids.filter((id, index) => ids.indexOf(id) !== index));
@@ -92,9 +108,10 @@ const useChartCartesianAxis = ({
92
108
  store.set('cartesianAxis', {
93
109
  axesGap,
94
110
  x: (0, _defaultizeAxis.defaultizeXAxis)(xAxis, dataset, axesGap),
95
- y: (0, _defaultizeAxis.defaultizeYAxis)(yAxis, dataset, axesGap)
111
+ y: (0, _defaultizeAxis.defaultizeYAxis)(yAxis, dataset, axesGap),
112
+ defaultTickLabelStyle
96
113
  });
97
- }, [xAxis, yAxis, dataset, axesGap, store]);
114
+ }, [xAxis, yAxis, dataset, axesGap, defaultTickLabelStyle, store]);
98
115
  const usedXAxis = xAxisIds[0];
99
116
  const usedYAxis = yAxisIds[0];
100
117
  (0, _store.useStoreEffect)(store, _useChartCartesianInteraction.selectorChartAxisInteraction, (prevAxisInteraction, nextAxisInteraction) => {
@@ -197,7 +214,62 @@ const useChartCartesianAxis = ({
197
214
  return () => {
198
215
  axisClickHandler.cleanup();
199
216
  };
200
- }, [params.onAxisClick, processedSeries, chartsLayerContainerRef, xAxisWithScale, xAxisIds, yAxisWithScale, yAxisIds, usedXAxis, usedYAxis, instance]);
217
+ }, [params.onAxisClick, processedSeries, store, chartsLayerContainerRef, xAxisWithScale, xAxisIds, yAxisWithScale, yAxisIds, usedXAxis, usedYAxis, instance]);
218
+
219
+ /**
220
+ * Kept separate from the pointer effect: this listener must survive re-renders, so it reads the
221
+ * axes and the callback when the key is pressed rather than closing over them. Re-subscribing per
222
+ * render would drop keystrokes landing between a keyboard navigation update and its commit.
223
+ */
224
+ const handleKeyboardActivation = (0, _useEventCallback.default)(event => {
225
+ const onAxisClick = params.onAxisClick;
226
+ if (!onAxisClick ||
227
+ // Ignore the auto-repeat while the key is held: a pointer click does not repeat either.
228
+ event.repeat || !(0, _useChartKeyboardNavigation.isItemActivationKey)(event) || !(0, _useChartKeyboardNavigation.selectorChartsIsKeyboardActivationEnabled)(store.state)) {
229
+ return;
230
+ }
231
+ const {
232
+ axis: xAxes
233
+ } = (0, _useChartCartesianAxisRendering.selectorChartXAxis)(store.state);
234
+ const {
235
+ axis: yAxes
236
+ } = (0, _useChartCartesianAxisRendering.selectorChartYAxis)(store.state);
237
+ const xAxisItem = (0, _useChartKeyboardNavigation.selectorChartsKeyboardXAxisIndex)(store.state);
238
+ const yAxisItem = (0, _useChartKeyboardNavigation.selectorChartsKeyboardYAxisIndex)(store.state);
239
+ const focusedAxisItem = hasAxisValueAt(xAxes, xAxisItem) ? {
240
+ item: xAxisItem,
241
+ isXAxis: true
242
+ } : hasAxisValueAt(yAxes, yAxisItem) && {
243
+ item: yAxisItem,
244
+ isXAxis: false
245
+ };
246
+ if (!focusedAxisItem) {
247
+ return;
248
+ }
249
+ const payload = (0, _getAxisClickPayload.getAxisClickPayload)({
250
+ axisId: focusedAxisItem.item.axisId,
251
+ dataIndex: focusedAxisItem.item.dataIndex,
252
+ isXAxis: focusedAxisItem.isXAxis,
253
+ axes: focusedAxisItem.isXAxis ? xAxes : yAxes,
254
+ processedSeries: (0, _useChartSeries.selectorChartSeriesProcessed)(store.state)
255
+ });
256
+ if (payload === null) {
257
+ return;
258
+ }
259
+ event.preventDefault();
260
+ // The callback only describes the pointer event unless the user augments the types.
261
+ onAxisClick(event, payload);
262
+ });
263
+ React.useEffect(() => {
264
+ const element = chartsLayerContainerRef.current;
265
+ if (element === null) {
266
+ return undefined;
267
+ }
268
+ element.addEventListener('keydown', handleKeyboardActivation);
269
+ return () => {
270
+ element.removeEventListener('keydown', handleKeyboardActivation);
271
+ };
272
+ }, [chartsLayerContainerRef, handleKeyboardActivation]);
201
273
  return {};
202
274
  };
203
275
  exports.useChartCartesianAxis = useChartCartesianAxis;
@@ -3,6 +3,7 @@
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
5
  import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
6
+ import useEventCallback from '@mui/utils/useEventCallback';
6
7
  import { useStoreEffect } from '@mui/x-internals/store';
7
8
  import { useAssertModelConsistency } from '@mui/x-internals/useAssertModelConsistency';
8
9
  import { warnOnce } from '@mui/x-internals/warning';
@@ -16,6 +17,16 @@ import { selectorChartsInteractionIsInitialized } from "../useChartInteraction/i
16
17
  import { selectorChartAxisInteraction } from "./useChartCartesianInteraction.selectors.mjs";
17
18
  import { checkHasInteractionPlugin } from "../useChartInteraction/checkHasInteractionPlugin.mjs";
18
19
  import { getAxisClickPayload } from "./getAxisClickPayload.mjs";
20
+ import { useDefaultTickLabelStyle } from "../../../useDefaultTickLabelStyle.mjs";
21
+ import { isItemActivationKey, selectorChartsIsKeyboardActivationEnabled, selectorChartsKeyboardXAxisIndex, selectorChartsKeyboardYAxisIndex } from "../useChartKeyboardNavigation/index.mjs";
22
+
23
+ /**
24
+ * Narrows an axis item to one the axis actually has a value for.
25
+ * Axes unrelated to the focused series can exist with empty data, so the index must resolve.
26
+ */
27
+ function hasAxisValueAt(axes, item) {
28
+ return item !== undefined && item.dataIndex !== undefined && axes[item.axisId]?.data?.[item.dataIndex] !== undefined;
29
+ }
19
30
  export const useChartCartesianAxis = ({
20
31
  params,
21
32
  store,
@@ -32,6 +43,12 @@ export const useChartCartesianAxis = ({
32
43
  onTooltipAxisChange,
33
44
  axesGap
34
45
  } = params;
46
+ const defaultTickLabelStyle = useDefaultTickLabelStyle();
47
+ useEnhancedEffect(() => {
48
+ store.set('cartesianAxis', _extends({}, store.state.cartesianAxis, {
49
+ defaultTickLabelStyle
50
+ }));
51
+ }, [defaultTickLabelStyle, store]);
35
52
  if (process.env.NODE_ENV !== 'production') {
36
53
  const ids = [...(xAxis ?? []), ...(yAxis ?? [])].filter(axis => axis.id).map(axis => axis.id);
37
54
  const duplicates = new Set(ids.filter((id, index) => ids.indexOf(id) !== index));
@@ -85,9 +102,10 @@ export const useChartCartesianAxis = ({
85
102
  store.set('cartesianAxis', {
86
103
  axesGap,
87
104
  x: defaultizeXAxis(xAxis, dataset, axesGap),
88
- y: defaultizeYAxis(yAxis, dataset, axesGap)
105
+ y: defaultizeYAxis(yAxis, dataset, axesGap),
106
+ defaultTickLabelStyle
89
107
  });
90
- }, [xAxis, yAxis, dataset, axesGap, store]);
108
+ }, [xAxis, yAxis, dataset, axesGap, defaultTickLabelStyle, store]);
91
109
  const usedXAxis = xAxisIds[0];
92
110
  const usedYAxis = yAxisIds[0];
93
111
  useStoreEffect(store, selectorChartAxisInteraction, (prevAxisInteraction, nextAxisInteraction) => {
@@ -190,7 +208,62 @@ export const useChartCartesianAxis = ({
190
208
  return () => {
191
209
  axisClickHandler.cleanup();
192
210
  };
193
- }, [params.onAxisClick, processedSeries, chartsLayerContainerRef, xAxisWithScale, xAxisIds, yAxisWithScale, yAxisIds, usedXAxis, usedYAxis, instance]);
211
+ }, [params.onAxisClick, processedSeries, store, chartsLayerContainerRef, xAxisWithScale, xAxisIds, yAxisWithScale, yAxisIds, usedXAxis, usedYAxis, instance]);
212
+
213
+ /**
214
+ * Kept separate from the pointer effect: this listener must survive re-renders, so it reads the
215
+ * axes and the callback when the key is pressed rather than closing over them. Re-subscribing per
216
+ * render would drop keystrokes landing between a keyboard navigation update and its commit.
217
+ */
218
+ const handleKeyboardActivation = useEventCallback(event => {
219
+ const onAxisClick = params.onAxisClick;
220
+ if (!onAxisClick ||
221
+ // Ignore the auto-repeat while the key is held: a pointer click does not repeat either.
222
+ event.repeat || !isItemActivationKey(event) || !selectorChartsIsKeyboardActivationEnabled(store.state)) {
223
+ return;
224
+ }
225
+ const {
226
+ axis: xAxes
227
+ } = selectorChartXAxis(store.state);
228
+ const {
229
+ axis: yAxes
230
+ } = selectorChartYAxis(store.state);
231
+ const xAxisItem = selectorChartsKeyboardXAxisIndex(store.state);
232
+ const yAxisItem = selectorChartsKeyboardYAxisIndex(store.state);
233
+ const focusedAxisItem = hasAxisValueAt(xAxes, xAxisItem) ? {
234
+ item: xAxisItem,
235
+ isXAxis: true
236
+ } : hasAxisValueAt(yAxes, yAxisItem) && {
237
+ item: yAxisItem,
238
+ isXAxis: false
239
+ };
240
+ if (!focusedAxisItem) {
241
+ return;
242
+ }
243
+ const payload = getAxisClickPayload({
244
+ axisId: focusedAxisItem.item.axisId,
245
+ dataIndex: focusedAxisItem.item.dataIndex,
246
+ isXAxis: focusedAxisItem.isXAxis,
247
+ axes: focusedAxisItem.isXAxis ? xAxes : yAxes,
248
+ processedSeries: selectorChartSeriesProcessed(store.state)
249
+ });
250
+ if (payload === null) {
251
+ return;
252
+ }
253
+ event.preventDefault();
254
+ // The callback only describes the pointer event unless the user augments the types.
255
+ onAxisClick(event, payload);
256
+ });
257
+ React.useEffect(() => {
258
+ const element = chartsLayerContainerRef.current;
259
+ if (element === null) {
260
+ return undefined;
261
+ }
262
+ element.addEventListener('keydown', handleKeyboardActivation);
263
+ return () => {
264
+ element.removeEventListener('keydown', handleKeyboardActivation);
265
+ };
266
+ }, [chartsLayerContainerRef, handleKeyboardActivation]);
194
267
  return {};
195
268
  };
196
269
  useChartCartesianAxis.params = {
@@ -7,6 +7,8 @@ import type { UseChartInteractionSignature } from "../useChartInteraction/index.
7
7
  import type { ChartsAxisProps } from "../../../../ChartsAxis/index.mjs";
8
8
  import type { UseChartBrushSignature } from "../useChartBrush/index.mjs";
9
9
  import type { SamplingState } from "./sampling.types.mjs";
10
+ import type { ChartsActivationEvent } from "../../../../models/events.mjs";
11
+ import type { ChartsTextStyle } from "../../../getWordsByLines.mjs";
10
12
  /**
11
13
  * The axes' configuration after computing.
12
14
  * An axis in this state already contains a scale function and all the necessary properties to be rendered.
@@ -34,10 +36,10 @@ export interface UseChartCartesianAxisParameters<S extends ScaleName = ScaleName
34
36
  /**
35
37
  * The function called for onClick events.
36
38
  * The second argument contains information about all line/bar elements at the current mouse position.
37
- * @param {MouseEvent} event The mouse event recorded on the `<svg/>` element.
39
+ * @param {ChartsActivationEvent} event The event recorded on the `<svg/>` element.
38
40
  * @param {null | ChartsAxisData} data The data about the clicked axis and items associated with it.
39
41
  */
40
- onAxisClick?: (event: MouseEvent, data: null | ChartsAxisData) => void;
42
+ onAxisClick?: (event: ChartsActivationEvent, data: null | ChartsAxisData) => void;
41
43
  /**
42
44
  * The function called when the pointer position corresponds to a new axis data item.
43
45
  * This update can either be caused by a pointer movement, or an axis update.
@@ -106,6 +108,8 @@ export interface UseChartCartesianAxisState {
106
108
  axesGap: number;
107
109
  x: DefaultedXAxis[];
108
110
  y: DefaultedYAxis[];
111
+ /** Only used to measure tick labels. Never merged into the rendered tick style. */
112
+ defaultTickLabelStyle?: ChartsTextStyle;
109
113
  };
110
114
  /**
111
115
  * The controlled axis item highlighted.
@@ -7,6 +7,8 @@ import type { UseChartInteractionSignature } from "../useChartInteraction/index.
7
7
  import type { ChartsAxisProps } from "../../../../ChartsAxis/index.js";
8
8
  import type { UseChartBrushSignature } from "../useChartBrush/index.js";
9
9
  import type { SamplingState } from "./sampling.types.js";
10
+ import type { ChartsActivationEvent } from "../../../../models/events.js";
11
+ import type { ChartsTextStyle } from "../../../getWordsByLines.js";
10
12
  /**
11
13
  * The axes' configuration after computing.
12
14
  * An axis in this state already contains a scale function and all the necessary properties to be rendered.
@@ -34,10 +36,10 @@ export interface UseChartCartesianAxisParameters<S extends ScaleName = ScaleName
34
36
  /**
35
37
  * The function called for onClick events.
36
38
  * The second argument contains information about all line/bar elements at the current mouse position.
37
- * @param {MouseEvent} event The mouse event recorded on the `<svg/>` element.
39
+ * @param {ChartsActivationEvent} event The event recorded on the `<svg/>` element.
38
40
  * @param {null | ChartsAxisData} data The data about the clicked axis and items associated with it.
39
41
  */
40
- onAxisClick?: (event: MouseEvent, data: null | ChartsAxisData) => void;
42
+ onAxisClick?: (event: ChartsActivationEvent, data: null | ChartsAxisData) => void;
41
43
  /**
42
44
  * The function called when the pointer position corresponds to a new axis data item.
43
45
  * This update can either be caused by a pointer movement, or an axis update.
@@ -106,6 +108,8 @@ export interface UseChartCartesianAxisState {
106
108
  axesGap: number;
107
109
  x: DefaultedXAxis[];
108
110
  y: DefaultedYAxis[];
111
+ /** Only used to measure tick labels. Never merged into the rendered tick style. */
112
+ defaultTickLabelStyle?: ChartsTextStyle;
109
113
  };
110
114
  /**
111
115
  * The controlled axis item highlighted.
@@ -5,6 +5,7 @@ export declare const selectorChartCartesianAxisState: (state: ChartState<[], [Us
5
5
  axesGap: number;
6
6
  x: DefaultedXAxis[];
7
7
  y: DefaultedYAxis[];
8
+ defaultTickLabelStyle?: import("../../../getWordsByLines.mjs").ChartsTextStyle;
8
9
  } | undefined;
9
10
  export type SelectorChartRawXAxisType = <State extends ChartState<[], [UseChartCartesianAxisSignature]>>(state: State) => DefaultedXAxis[] | undefined;
10
11
  export declare const selectorChartRawXAxis: SelectorChartRawXAxisType;
@@ -5,6 +5,7 @@ export declare const selectorChartCartesianAxisState: (state: ChartState<[], [Us
5
5
  axesGap: number;
6
6
  x: DefaultedXAxis[];
7
7
  y: DefaultedYAxis[];
8
+ defaultTickLabelStyle?: import("../../../getWordsByLines.js").ChartsTextStyle;
8
9
  } | undefined;
9
10
  export type SelectorChartRawXAxisType = <State extends ChartState<[], [UseChartCartesianAxisSignature]>>(state: State) => DefaultedXAxis[] | undefined;
10
11
  export declare const selectorChartRawXAxis: SelectorChartRawXAxisType;
@@ -144,6 +144,7 @@ const useChartClosestPoint = ({
144
144
  const moveEndHandler = instance.addInteractionListener('moveEnd', event => {
145
145
  if (!event.detail.activeGestures.pan) {
146
146
  instance.cleanInteraction?.();
147
+ instance.clearHoveredItem?.();
147
148
  instance.clearHighlight?.();
148
149
  instance.removeTooltipItem?.();
149
150
  }
@@ -151,6 +152,7 @@ const useChartClosestPoint = ({
151
152
  const panEndHandler = instance.addInteractionListener('panEnd', event => {
152
153
  if (!event.detail.activeGestures.move) {
153
154
  instance.cleanInteraction?.();
155
+ instance.clearHoveredItem?.();
154
156
  instance.clearHighlight?.();
155
157
  instance.removeTooltipItem?.();
156
158
  }
@@ -158,6 +160,7 @@ const useChartClosestPoint = ({
158
160
  const pressEndHandler = instance.addInteractionListener('quickPressEnd', event => {
159
161
  if (!event.detail.activeGestures.move && !event.detail.activeGestures.pan) {
160
162
  instance.cleanInteraction?.();
163
+ instance.clearHoveredItem?.();
161
164
  instance.clearHighlight?.();
162
165
  instance.removeTooltipItem?.();
163
166
  }
@@ -166,12 +169,14 @@ const useChartClosestPoint = ({
166
169
  const closestPoint = getClosestPoint(event.detail.srcEvent);
167
170
  if (closestPoint === 'outside-chart') {
168
171
  instance.cleanInteraction?.();
172
+ instance.clearHoveredItem?.();
169
173
  instance.clearHighlight?.();
170
174
  instance.removeTooltipItem?.();
171
175
  return;
172
176
  }
173
177
  if (closestPoint === 'outside-voronoi-max-radius' || closestPoint === 'no-point-found') {
174
178
  instance.removeTooltipItem?.();
179
+ instance.clearHoveredItem?.();
175
180
  instance.clearHighlight?.();
176
181
  instance.removeTooltipItem?.();
177
182
  return;
@@ -180,6 +185,11 @@ const useChartClosestPoint = ({
180
185
  seriesId,
181
186
  dataIndex
182
187
  } = closestPoint;
188
+ instance.setHoveredItem?.({
189
+ type: 'scatter',
190
+ seriesId,
191
+ dataIndex
192
+ });
183
193
  instance.setTooltipItem?.({
184
194
  type: 'scatter',
185
195
  seriesId,
@@ -192,6 +202,17 @@ const useChartClosestPoint = ({
192
202
  dataIndex
193
203
  });
194
204
  };
205
+
206
+ // A tap resolves nothing without a preceding move, and touch has no hover phase, so the
207
+ // pointer item is also resolved on `pointerdown`.
208
+ const onPointerDown = function onPointerDown(event) {
209
+ gestureHandler({
210
+ detail: {
211
+ srcEvent: event
212
+ }
213
+ });
214
+ };
215
+ element.addEventListener('pointerdown', onPointerDown);
195
216
  const tapHandler = instance.addInteractionListener('tap', event => {
196
217
  const closestPoint = getClosestPoint(event.detail.srcEvent);
197
218
  if (typeof closestPoint !== 'string' && onItemClick) {
@@ -210,6 +231,7 @@ const useChartClosestPoint = ({
210
231
  const panHandler = instance.addInteractionListener('pan', gestureHandler);
211
232
  const pressHandler = instance.addInteractionListener('quickPress', gestureHandler);
212
233
  return () => {
234
+ element.removeEventListener('pointerdown', onPointerDown);
213
235
  tapHandler.cleanup();
214
236
  moveHandler.cleanup();
215
237
  moveEndHandler.cleanup();
@@ -137,6 +137,7 @@ export const useChartClosestPoint = ({
137
137
  const moveEndHandler = instance.addInteractionListener('moveEnd', event => {
138
138
  if (!event.detail.activeGestures.pan) {
139
139
  instance.cleanInteraction?.();
140
+ instance.clearHoveredItem?.();
140
141
  instance.clearHighlight?.();
141
142
  instance.removeTooltipItem?.();
142
143
  }
@@ -144,6 +145,7 @@ export const useChartClosestPoint = ({
144
145
  const panEndHandler = instance.addInteractionListener('panEnd', event => {
145
146
  if (!event.detail.activeGestures.move) {
146
147
  instance.cleanInteraction?.();
148
+ instance.clearHoveredItem?.();
147
149
  instance.clearHighlight?.();
148
150
  instance.removeTooltipItem?.();
149
151
  }
@@ -151,6 +153,7 @@ export const useChartClosestPoint = ({
151
153
  const pressEndHandler = instance.addInteractionListener('quickPressEnd', event => {
152
154
  if (!event.detail.activeGestures.move && !event.detail.activeGestures.pan) {
153
155
  instance.cleanInteraction?.();
156
+ instance.clearHoveredItem?.();
154
157
  instance.clearHighlight?.();
155
158
  instance.removeTooltipItem?.();
156
159
  }
@@ -159,12 +162,14 @@ export const useChartClosestPoint = ({
159
162
  const closestPoint = getClosestPoint(event.detail.srcEvent);
160
163
  if (closestPoint === 'outside-chart') {
161
164
  instance.cleanInteraction?.();
165
+ instance.clearHoveredItem?.();
162
166
  instance.clearHighlight?.();
163
167
  instance.removeTooltipItem?.();
164
168
  return;
165
169
  }
166
170
  if (closestPoint === 'outside-voronoi-max-radius' || closestPoint === 'no-point-found') {
167
171
  instance.removeTooltipItem?.();
172
+ instance.clearHoveredItem?.();
168
173
  instance.clearHighlight?.();
169
174
  instance.removeTooltipItem?.();
170
175
  return;
@@ -173,6 +178,11 @@ export const useChartClosestPoint = ({
173
178
  seriesId,
174
179
  dataIndex
175
180
  } = closestPoint;
181
+ instance.setHoveredItem?.({
182
+ type: 'scatter',
183
+ seriesId,
184
+ dataIndex
185
+ });
176
186
  instance.setTooltipItem?.({
177
187
  type: 'scatter',
178
188
  seriesId,
@@ -185,6 +195,17 @@ export const useChartClosestPoint = ({
185
195
  dataIndex
186
196
  });
187
197
  };
198
+
199
+ // A tap resolves nothing without a preceding move, and touch has no hover phase, so the
200
+ // pointer item is also resolved on `pointerdown`.
201
+ const onPointerDown = function onPointerDown(event) {
202
+ gestureHandler({
203
+ detail: {
204
+ srcEvent: event
205
+ }
206
+ });
207
+ };
208
+ element.addEventListener('pointerdown', onPointerDown);
188
209
  const tapHandler = instance.addInteractionListener('tap', event => {
189
210
  const closestPoint = getClosestPoint(event.detail.srcEvent);
190
211
  if (typeof closestPoint !== 'string' && onItemClick) {
@@ -203,6 +224,7 @@ export const useChartClosestPoint = ({
203
224
  const panHandler = instance.addInteractionListener('pan', gestureHandler);
204
225
  const pressHandler = instance.addInteractionListener('quickPress', gestureHandler);
205
226
  return () => {
227
+ element.removeEventListener('pointerdown', onPointerDown);
206
228
  tapHandler.cleanup();
207
229
  moveHandler.cleanup();
208
230
  moveEndHandler.cleanup();
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.useChartInteraction = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
10
+ var _fastObjectShallowCompare = require("@mui/x-internals/fastObjectShallowCompare");
10
11
  const useChartInteraction = ({
11
12
  store
12
13
  }) => {
@@ -24,6 +25,28 @@ const useChartInteraction = ({
24
25
  }));
25
26
  }
26
27
  });
28
+ const setHoveredItem = (0, _useEventCallback.default)(function setHoveredItem(item) {
29
+ const previousItem = store.state.interaction.hoveredItem;
30
+ if (previousItem !== null && (0, _fastObjectShallowCompare.fastObjectShallowCompare)(previousItem, item)) {
31
+ return;
32
+ }
33
+ store.set('interaction', (0, _extends2.default)({}, store.state.interaction, {
34
+ hoveredItem: item
35
+ }));
36
+ });
37
+ const clearHoveredItem = (0, _useEventCallback.default)(function clearHoveredItem(itemToRemove) {
38
+ const previousItem = store.state.interaction.hoveredItem;
39
+ if (previousItem === null) {
40
+ return;
41
+ }
42
+ if (itemToRemove !== undefined && !(0, _fastObjectShallowCompare.fastObjectShallowCompare)(previousItem, itemToRemove)) {
43
+ // Another item took over already.
44
+ return;
45
+ }
46
+ store.set('interaction', (0, _extends2.default)({}, store.state.interaction, {
47
+ hoveredItem: null
48
+ }));
49
+ });
27
50
  const setPointerCoordinate = (0, _useEventCallback.default)(function setPointerCoordinate(coordinate) {
28
51
  store.set('interaction', (0, _extends2.default)({}, store.state.interaction, {
29
52
  pointer: coordinate,
@@ -44,6 +67,8 @@ const useChartInteraction = ({
44
67
  instance: {
45
68
  cleanInteraction,
46
69
  setLastUpdateSource,
70
+ setHoveredItem,
71
+ clearHoveredItem,
47
72
  setPointerCoordinate,
48
73
  handlePointerEnter,
49
74
  handlePointerLeave
@@ -56,7 +81,8 @@ useChartInteraction.getInitialState = () => ({
56
81
  item: null,
57
82
  pointer: null,
58
83
  lastUpdate: 'pointer',
59
- pointerType: null
84
+ pointerType: null,
85
+ hoveredItem: null
60
86
  }
61
87
  });
62
88
  useChartInteraction.params = {};
@@ -1,5 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import useEventCallback from '@mui/utils/useEventCallback';
3
+ import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowCompare';
3
4
  export const useChartInteraction = ({
4
5
  store
5
6
  }) => {
@@ -17,6 +18,28 @@ export const useChartInteraction = ({
17
18
  }));
18
19
  }
19
20
  });
21
+ const setHoveredItem = useEventCallback(function setHoveredItem(item) {
22
+ const previousItem = store.state.interaction.hoveredItem;
23
+ if (previousItem !== null && fastObjectShallowCompare(previousItem, item)) {
24
+ return;
25
+ }
26
+ store.set('interaction', _extends({}, store.state.interaction, {
27
+ hoveredItem: item
28
+ }));
29
+ });
30
+ const clearHoveredItem = useEventCallback(function clearHoveredItem(itemToRemove) {
31
+ const previousItem = store.state.interaction.hoveredItem;
32
+ if (previousItem === null) {
33
+ return;
34
+ }
35
+ if (itemToRemove !== undefined && !fastObjectShallowCompare(previousItem, itemToRemove)) {
36
+ // Another item took over already.
37
+ return;
38
+ }
39
+ store.set('interaction', _extends({}, store.state.interaction, {
40
+ hoveredItem: null
41
+ }));
42
+ });
20
43
  const setPointerCoordinate = useEventCallback(function setPointerCoordinate(coordinate) {
21
44
  store.set('interaction', _extends({}, store.state.interaction, {
22
45
  pointer: coordinate,
@@ -37,6 +60,8 @@ export const useChartInteraction = ({
37
60
  instance: {
38
61
  cleanInteraction,
39
62
  setLastUpdateSource,
63
+ setHoveredItem,
64
+ clearHoveredItem,
40
65
  setPointerCoordinate,
41
66
  handlePointerEnter,
42
67
  handlePointerLeave
@@ -48,7 +73,8 @@ useChartInteraction.getInitialState = () => ({
48
73
  item: null,
49
74
  pointer: null,
50
75
  lastUpdate: 'pointer',
51
- pointerType: null
76
+ pointerType: null,
77
+ hoveredItem: null
52
78
  }
53
79
  });
54
80
  useChartInteraction.params = {};
@@ -1,4 +1,6 @@
1
1
  import type { ChartPluginSignature } from "../../models/index.mjs";
2
+ import type { SeriesItemIdentifierWithType } from "../../../../models/seriesType/index.mjs";
3
+ import type { ChartSeriesType } from "../../../../models/seriesType/config.mjs";
2
4
  export type Coordinate = {
3
5
  x: number;
4
6
  y: number;
@@ -21,6 +23,17 @@ export interface UseChartInteractionInstance {
21
23
  * @returns {void}
22
24
  */
23
25
  setLastUpdateSource: (interaction: InteractionUpdateSource) => void;
26
+ /**
27
+ * Set the item the pointer is over.
28
+ * @param {SeriesItemIdentifierWithType} item The item under the pointer.
29
+ */
30
+ setHoveredItem: (item: SeriesItemIdentifierWithType<ChartSeriesType>) => void;
31
+ /**
32
+ * Remove the item the pointer was over.
33
+ * @param {SeriesItemIdentifierWithType} itemToRemove Only clears the item when it is the current
34
+ * one. Omit to clear unconditionally.
35
+ */
36
+ clearHoveredItem: (itemToRemove?: SeriesItemIdentifierWithType<ChartSeriesType>) => void;
24
37
  /**
25
38
  * Handle pointer enter event on the chart Surface.
26
39
  */
@@ -46,6 +59,13 @@ export interface UseChartInteractionState {
46
59
  * Used to decide if highlight should be based on pointer position or keyboard navigation.
47
60
  */
48
61
  lastUpdate: InteractionUpdateSource;
62
+ /**
63
+ * The item the pointer is currently over.
64
+ *
65
+ * Unlike the highlighted and the tooltip items, this one is never controlled, so it always
66
+ * reflects the pointer. That is what makes it usable to resolve what a click landed on.
67
+ */
68
+ hoveredItem: SeriesItemIdentifierWithType<ChartSeriesType> | null;
49
69
  };
50
70
  }
51
71
  export type UseChartInteractionSignature = ChartPluginSignature<{
@@ -1,4 +1,6 @@
1
1
  import type { ChartPluginSignature } from "../../models/index.js";
2
+ import type { SeriesItemIdentifierWithType } from "../../../../models/seriesType/index.js";
3
+ import type { ChartSeriesType } from "../../../../models/seriesType/config.js";
2
4
  export type Coordinate = {
3
5
  x: number;
4
6
  y: number;
@@ -21,6 +23,17 @@ export interface UseChartInteractionInstance {
21
23
  * @returns {void}
22
24
  */
23
25
  setLastUpdateSource: (interaction: InteractionUpdateSource) => void;
26
+ /**
27
+ * Set the item the pointer is over.
28
+ * @param {SeriesItemIdentifierWithType} item The item under the pointer.
29
+ */
30
+ setHoveredItem: (item: SeriesItemIdentifierWithType<ChartSeriesType>) => void;
31
+ /**
32
+ * Remove the item the pointer was over.
33
+ * @param {SeriesItemIdentifierWithType} itemToRemove Only clears the item when it is the current
34
+ * one. Omit to clear unconditionally.
35
+ */
36
+ clearHoveredItem: (itemToRemove?: SeriesItemIdentifierWithType<ChartSeriesType>) => void;
24
37
  /**
25
38
  * Handle pointer enter event on the chart Surface.
26
39
  */
@@ -46,6 +59,13 @@ export interface UseChartInteractionState {
46
59
  * Used to decide if highlight should be based on pointer position or keyboard navigation.
47
60
  */
48
61
  lastUpdate: InteractionUpdateSource;
62
+ /**
63
+ * The item the pointer is currently over.
64
+ *
65
+ * Unlike the highlighted and the tooltip items, this one is never controlled, so it always
66
+ * reflects the pointer. That is what makes it usable to resolve what a click landed on.
67
+ */
68
+ hoveredItem: SeriesItemIdentifierWithType<ChartSeriesType> | null;
49
69
  };
50
70
  }
51
71
  export type UseChartInteractionSignature = ChartPluginSignature<{