@mui/x-charts 7.5.1 → 7.6.1

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 (133) hide show
  1. package/BarChart/BarChart.js +18 -1
  2. package/BarChart/BarElement.d.ts +0 -3
  3. package/BarChart/BarElement.js +7 -18
  4. package/BarChart/BarLabel/BarLabelItem.js +5 -16
  5. package/BarChart/BarLabel/BarLabelPlot.js +0 -4
  6. package/BarChart/BarPlot.js +4 -30
  7. package/BarChart/checkScaleErrors.d.ts +11 -0
  8. package/BarChart/checkScaleErrors.js +33 -0
  9. package/BarChart/types.d.ts +0 -2
  10. package/CHANGELOG.md +112 -1
  11. package/ChartContainer/ChartContainer.d.ts +3 -2
  12. package/ChartContainer/ChartContainer.js +19 -2
  13. package/ChartsVoronoiHandler/ChartsVoronoiHandler.js +13 -1
  14. package/LineChart/AreaElement.d.ts +0 -2
  15. package/LineChart/AreaElement.js +7 -17
  16. package/LineChart/AreaPlot.js +0 -2
  17. package/LineChart/LineChart.js +18 -1
  18. package/LineChart/LineElement.d.ts +0 -2
  19. package/LineChart/LineElement.js +7 -17
  20. package/LineChart/LinePlot.js +0 -2
  21. package/LineChart/MarkElement.d.ts +0 -2
  22. package/LineChart/MarkElement.js +10 -17
  23. package/LineChart/MarkPlot.js +0 -1
  24. package/PieChart/PieArc.d.ts +4 -1
  25. package/PieChart/PieArc.js +7 -3
  26. package/PieChart/PieArcLabelPlot.d.ts +1 -1
  27. package/PieChart/PieArcLabelPlot.js +1 -7
  28. package/PieChart/PieArcPlot.d.ts +1 -1
  29. package/PieChart/PieArcPlot.js +5 -7
  30. package/PieChart/PieChart.js +18 -1
  31. package/PieChart/PiePlot.js +2 -6
  32. package/PieChart/dataTransform/useTransformData.d.ts +1 -1
  33. package/PieChart/dataTransform/useTransformData.js +10 -25
  34. package/ResponsiveChartContainer/ResponsiveChartContainer.js +13 -0
  35. package/ScatterChart/Scatter.js +14 -10
  36. package/ScatterChart/ScatterChart.js +18 -1
  37. package/SparkLineChart/SparkLineChart.js +13 -0
  38. package/context/HighlightedProvider/HighlightedContext.d.ts +65 -0
  39. package/context/HighlightedProvider/HighlightedContext.js +36 -0
  40. package/context/HighlightedProvider/HighlightedProvider.d.ts +20 -0
  41. package/context/HighlightedProvider/HighlightedProvider.js +97 -0
  42. package/context/HighlightedProvider/createIsFaded.d.ts +2 -0
  43. package/context/HighlightedProvider/createIsFaded.js +19 -0
  44. package/context/HighlightedProvider/createIsHighlighted.d.ts +2 -0
  45. package/context/HighlightedProvider/createIsHighlighted.js +19 -0
  46. package/context/HighlightedProvider/index.d.ts +4 -0
  47. package/context/HighlightedProvider/index.js +49 -0
  48. package/context/HighlightedProvider/useHighlighted.d.ts +9 -0
  49. package/context/HighlightedProvider/useHighlighted.js +24 -0
  50. package/context/HighlightedProvider/useItemHighlighted.d.ts +21 -0
  51. package/context/HighlightedProvider/useItemHighlighted.js +37 -0
  52. package/context/index.d.ts +1 -1
  53. package/context/index.js +15 -0
  54. package/esm/BarChart/BarChart.js +18 -1
  55. package/esm/BarChart/BarElement.js +8 -19
  56. package/esm/BarChart/BarLabel/BarLabelItem.js +5 -16
  57. package/esm/BarChart/BarLabel/BarLabelPlot.js +0 -4
  58. package/esm/BarChart/BarPlot.js +4 -30
  59. package/esm/BarChart/checkScaleErrors.js +27 -0
  60. package/esm/ChartContainer/ChartContainer.js +19 -2
  61. package/esm/ChartsVoronoiHandler/ChartsVoronoiHandler.js +13 -1
  62. package/esm/LineChart/AreaElement.js +8 -18
  63. package/esm/LineChart/AreaPlot.js +0 -2
  64. package/esm/LineChart/LineChart.js +18 -1
  65. package/esm/LineChart/LineElement.js +8 -18
  66. package/esm/LineChart/LinePlot.js +0 -2
  67. package/esm/LineChart/MarkElement.js +11 -18
  68. package/esm/LineChart/MarkPlot.js +0 -1
  69. package/esm/PieChart/PieArc.js +7 -3
  70. package/esm/PieChart/PieArcLabelPlot.js +1 -7
  71. package/esm/PieChart/PieArcPlot.js +5 -7
  72. package/esm/PieChart/PieChart.js +18 -1
  73. package/esm/PieChart/PiePlot.js +2 -6
  74. package/esm/PieChart/dataTransform/useTransformData.js +10 -25
  75. package/esm/ResponsiveChartContainer/ResponsiveChartContainer.js +13 -0
  76. package/esm/ScatterChart/Scatter.js +15 -11
  77. package/esm/ScatterChart/ScatterChart.js +18 -1
  78. package/esm/SparkLineChart/SparkLineChart.js +13 -0
  79. package/esm/context/HighlightedProvider/HighlightedContext.js +29 -0
  80. package/esm/context/HighlightedProvider/HighlightedProvider.js +89 -0
  81. package/esm/context/HighlightedProvider/createIsFaded.js +12 -0
  82. package/esm/context/HighlightedProvider/createIsHighlighted.js +12 -0
  83. package/esm/context/HighlightedProvider/index.js +4 -0
  84. package/esm/context/HighlightedProvider/useHighlighted.js +17 -0
  85. package/esm/context/HighlightedProvider/useItemHighlighted.js +29 -0
  86. package/esm/context/index.js +1 -0
  87. package/esm/hooks/useInteractionItemProps.js +9 -41
  88. package/hooks/useInteractionItemProps.d.ts +1 -4
  89. package/hooks/useInteractionItemProps.js +11 -45
  90. package/index.js +1 -1
  91. package/internals/colorScale.d.ts +1 -1
  92. package/internals/defaultizeColor.d.ts +13 -13
  93. package/models/seriesType/common.d.ts +4 -1
  94. package/modern/BarChart/BarChart.js +18 -1
  95. package/modern/BarChart/BarElement.js +8 -19
  96. package/modern/BarChart/BarLabel/BarLabelItem.js +5 -16
  97. package/modern/BarChart/BarLabel/BarLabelPlot.js +0 -4
  98. package/modern/BarChart/BarPlot.js +4 -30
  99. package/modern/BarChart/checkScaleErrors.js +27 -0
  100. package/modern/ChartContainer/ChartContainer.js +19 -2
  101. package/modern/ChartsVoronoiHandler/ChartsVoronoiHandler.js +13 -1
  102. package/modern/LineChart/AreaElement.js +8 -18
  103. package/modern/LineChart/AreaPlot.js +0 -2
  104. package/modern/LineChart/LineChart.js +18 -1
  105. package/modern/LineChart/LineElement.js +8 -18
  106. package/modern/LineChart/LinePlot.js +0 -2
  107. package/modern/LineChart/MarkElement.js +11 -18
  108. package/modern/LineChart/MarkPlot.js +0 -1
  109. package/modern/PieChart/PieArc.js +7 -3
  110. package/modern/PieChart/PieArcLabelPlot.js +1 -7
  111. package/modern/PieChart/PieArcPlot.js +5 -7
  112. package/modern/PieChart/PieChart.js +18 -1
  113. package/modern/PieChart/PiePlot.js +2 -6
  114. package/modern/PieChart/dataTransform/useTransformData.js +10 -25
  115. package/modern/ResponsiveChartContainer/ResponsiveChartContainer.js +13 -0
  116. package/modern/ScatterChart/Scatter.js +15 -11
  117. package/modern/ScatterChart/ScatterChart.js +18 -1
  118. package/modern/SparkLineChart/SparkLineChart.js +13 -0
  119. package/modern/context/HighlightedProvider/HighlightedContext.js +29 -0
  120. package/modern/context/HighlightedProvider/HighlightedProvider.js +89 -0
  121. package/modern/context/HighlightedProvider/createIsFaded.js +12 -0
  122. package/modern/context/HighlightedProvider/createIsHighlighted.js +12 -0
  123. package/modern/context/HighlightedProvider/index.js +4 -0
  124. package/modern/context/HighlightedProvider/useHighlighted.js +17 -0
  125. package/modern/context/HighlightedProvider/useItemHighlighted.js +29 -0
  126. package/modern/context/index.js +1 -0
  127. package/modern/hooks/useInteractionItemProps.js +9 -41
  128. package/modern/index.js +1 -1
  129. package/package.json +3 -3
  130. package/context/HighlightProvider.d.ts +0 -45
  131. package/context/HighlightProvider.js +0 -60
  132. package/esm/context/HighlightProvider.js +0 -51
  133. package/modern/context/HighlightProvider.js +0 -51
@@ -3,19 +3,20 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.useInteractionItemProps = exports.getIsHighlighted = exports.getIsFaded = void 0;
6
+ exports.useInteractionItemProps = void 0;
7
7
  var React = _interopRequireWildcard(require("react"));
8
8
  var _InteractionProvider = require("../context/InteractionProvider");
9
- var _HighlightProvider = require("../context/HighlightProvider");
9
+ var _context = require("../context");
10
10
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
11
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
- const useInteractionItemProps = (scope, skip) => {
12
+ const useInteractionItemProps = skip => {
13
13
  const {
14
14
  dispatch: dispatchInteraction
15
15
  } = React.useContext(_InteractionProvider.InteractionContext);
16
16
  const {
17
- dispatch: dispatchHighlight
18
- } = React.useContext(_HighlightProvider.HighlighContext);
17
+ setHighlighted,
18
+ clearHighlighted
19
+ } = React.useContext(_context.HighlightedContext);
19
20
  if (skip) {
20
21
  return () => ({});
21
22
  }
@@ -25,10 +26,9 @@ const useInteractionItemProps = (scope, skip) => {
25
26
  type: 'enterItem',
26
27
  data
27
28
  });
28
- dispatchHighlight({
29
- type: 'enterItem',
30
- item: data,
31
- scope
29
+ setHighlighted({
30
+ seriesId: data.seriesId,
31
+ dataIndex: data.dataIndex
32
32
  });
33
33
  };
34
34
  const onMouseLeave = () => {
@@ -36,10 +36,7 @@ const useInteractionItemProps = (scope, skip) => {
36
36
  type: 'leaveItem',
37
37
  data
38
38
  });
39
- dispatchHighlight({
40
- type: 'leaveItem',
41
- item: data
42
- });
39
+ clearHighlighted();
43
40
  };
44
41
  return {
45
42
  onMouseEnter,
@@ -48,35 +45,4 @@ const useInteractionItemProps = (scope, skip) => {
48
45
  };
49
46
  return getInteractionItemProps;
50
47
  };
51
- exports.useInteractionItemProps = useInteractionItemProps;
52
- const getIsHighlighted = (selectedItem, currentItem, highlightScope) => {
53
- if (!highlightScope?.highlighted || highlightScope.highlighted === 'none' || selectedItem === null) {
54
- return false;
55
- }
56
- const isSeriesSelected = selectedItem.type === currentItem.type && selectedItem.seriesId === currentItem.seriesId;
57
- if (!isSeriesSelected) {
58
- return false;
59
- }
60
- if (highlightScope.highlighted === 'series') {
61
- return isSeriesSelected;
62
- }
63
- return selectedItem.dataIndex !== undefined && selectedItem.dataIndex === currentItem.dataIndex;
64
- };
65
- exports.getIsHighlighted = getIsHighlighted;
66
- const getIsFaded = (selectedItem, currentItem, highlightScope) => {
67
- if (!highlightScope?.faded || highlightScope.faded === 'none' || selectedItem === null) {
68
- return false;
69
- }
70
- const isSeriesSelected = selectedItem.type === currentItem.type && selectedItem.seriesId === currentItem.seriesId;
71
- if (highlightScope.faded === 'series') {
72
- return isSeriesSelected && selectedItem.dataIndex !== currentItem.dataIndex;
73
- }
74
- if (highlightScope.faded === 'global') {
75
- if (!isSeriesSelected) {
76
- return true;
77
- }
78
- return selectedItem.dataIndex !== undefined && selectedItem.dataIndex !== currentItem.dataIndex;
79
- }
80
- return false;
81
- };
82
- exports.getIsFaded = getIsFaded;
48
+ exports.useInteractionItemProps = useInteractionItemProps;
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v7.5.1
2
+ * @mui/x-charts v7.6.1
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -2,4 +2,4 @@ import { ScaleOrdinal } from 'd3-scale';
2
2
  import { ContinuousColorConfig, PiecewiseColorConfig, OrdinalColorConfig } from '../models/colorMapping';
3
3
  export declare function getSequentialColorScale<Value extends number | Date>(config: ContinuousColorConfig<Value> | PiecewiseColorConfig<Value>): import("d3-scale").ScaleThreshold<Value, string, never> | import("d3-scale").ScaleSequential<string, never>;
4
4
  export declare function getOrdinalColorScale<Value extends number | Date | string>(config: OrdinalColorConfig<Value>): ScaleOrdinal<Value, string, null | string> | ScaleOrdinal<number, string, null | string>;
5
- export declare function getColorScale(config: ContinuousColorConfig | PiecewiseColorConfig | OrdinalColorConfig): ScaleOrdinal<string | number | Date, string, string | null> | ScaleOrdinal<number, string, string | null> | import("d3-scale").ScaleSequential<string, never> | import("d3-scale").ScaleThreshold<number | Date, string, never>;
5
+ export declare function getColorScale(config: ContinuousColorConfig | PiecewiseColorConfig | OrdinalColorConfig): import("d3-scale").ScaleSequential<string, never> | ScaleOrdinal<number, string, string | null> | ScaleOrdinal<string | number | Date, string, string | null> | import("d3-scale").ScaleThreshold<number | Date, string, never>;
@@ -58,19 +58,6 @@ export declare function defaultizeColor(series: AllSeriesType, seriesIndex: numb
58
58
  yAxisKey?: string | undefined;
59
59
  stack?: string | undefined;
60
60
  stackOrder?: import("..").StackOrderType | undefined;
61
- } | {
62
- type: "scatter";
63
- data: import("../models/seriesType").ScatterValueType[];
64
- markerSize?: number | undefined;
65
- label?: string | ((location: "tooltip" | "legend") => string) | undefined;
66
- disableHover?: boolean | undefined;
67
- zAxisKey?: string | undefined;
68
- id?: import("../models/seriesType/common").SeriesId | undefined;
69
- color: string;
70
- valueFormatter?: import("../models/seriesType/common").SeriesValueFormatter<import("../models/seriesType").ScatterValueType> | undefined;
71
- highlightScope?: Partial<import("..").HighlightScope> | undefined;
72
- xAxisKey?: string | undefined;
73
- yAxisKey?: string | undefined;
74
61
  } | {
75
62
  type: "line";
76
63
  data?: (number | null)[] | undefined;
@@ -90,4 +77,17 @@ export declare function defaultizeColor(series: AllSeriesType, seriesIndex: numb
90
77
  xAxisKey?: string | undefined;
91
78
  yAxisKey?: string | undefined;
92
79
  stackOrder?: import("..").StackOrderType | undefined;
80
+ } | {
81
+ type: "scatter";
82
+ data: import("../models/seriesType").ScatterValueType[];
83
+ markerSize?: number | undefined;
84
+ label?: string | ((location: "tooltip" | "legend") => string) | undefined;
85
+ disableHover?: boolean | undefined;
86
+ zAxisKey?: string | undefined;
87
+ id?: import("../models/seriesType/common").SeriesId | undefined;
88
+ color: string;
89
+ valueFormatter?: import("../models/seriesType/common").SeriesValueFormatter<import("../models/seriesType").ScatterValueType> | undefined;
90
+ highlightScope?: Partial<import("..").HighlightScope> | undefined;
91
+ xAxisKey?: string | undefined;
92
+ yAxisKey?: string | undefined;
93
93
  };
@@ -1,4 +1,4 @@
1
- import type { HighlightScope } from '../../context/HighlightProvider';
1
+ import type { HighlightScope } from '../../context';
2
2
  import type { StackOffsetType, StackOrderType } from '../stacking';
3
3
  export type SeriesId = number | string;
4
4
  export type SeriesValueFormatterContext = {
@@ -18,6 +18,9 @@ export type CommonSeriesType<TValue> = {
18
18
  * @returns {string} The string to display.
19
19
  */
20
20
  valueFormatter?: SeriesValueFormatter<TValue>;
21
+ /**
22
+ * The scope to apply when the series is highlighted.
23
+ */
21
24
  highlightScope?: Partial<HighlightScope>;
22
25
  };
23
26
  export type CommonDefaultizedProps = 'id' | 'valueFormatter' | 'data';
@@ -53,7 +53,9 @@ const BarChart = /*#__PURE__*/React.forwardRef(function BarChart(props, ref) {
53
53
  slots,
54
54
  slotProps,
55
55
  loading,
56
- barLabel
56
+ barLabel,
57
+ highlightedItem,
58
+ onHighlightChange
57
59
  } = props;
58
60
  const id = useId();
59
61
  const clipPathId = `${id}-clip-path`;
@@ -89,6 +91,8 @@ const BarChart = /*#__PURE__*/React.forwardRef(function BarChart(props, ref) {
89
91
  dataset: dataset,
90
92
  sx: sx,
91
93
  disableAxisListener: tooltip?.trigger !== 'axis' && axisHighlight?.x === 'none' && axisHighlight?.y === 'none' && !onAxisClick,
94
+ highlightedItem: highlightedItem,
95
+ onHighlightChange: onHighlightChange,
92
96
  children: [onAxisClick && /*#__PURE__*/_jsx(ChartsOnAxisClickHandler, {
93
97
  onAxisClick: onAxisClick
94
98
  }), grid && /*#__PURE__*/_jsx(ChartsGrid, {
@@ -188,6 +192,13 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
188
192
  * The height of the chart in px. If not defined, it takes the height of the parent element.
189
193
  */
190
194
  height: PropTypes.number,
195
+ /**
196
+ * The item currently highlighted. Turns highlighting into a controlled prop.
197
+ */
198
+ highlightedItem: PropTypes.shape({
199
+ dataIndex: PropTypes.number,
200
+ seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
201
+ }),
191
202
  /**
192
203
  * The direction of the bar elements.
193
204
  * @default 'vertical'
@@ -237,6 +248,12 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
237
248
  * @param {null | AxisData} data The data about the clicked axis and items associated with it.
238
249
  */
239
250
  onAxisClick: PropTypes.func,
251
+ /**
252
+ * The callback fired when the highlighted item changes.
253
+ *
254
+ * @param {HighlightItemData | null} highlightedItem The newly highlighted item.
255
+ */
256
+ onHighlightChange: PropTypes.func,
240
257
  /**
241
258
  * Callback fired when a bar item is clicked.
242
259
  * @param {React.MouseEvent<SVGElement, MouseEvent>} event The event source of the callback.
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["id", "dataIndex", "classes", "color", "highlightScope", "slots", "slotProps", "style", "onClick"];
3
+ const _excluded = ["id", "dataIndex", "classes", "color", "slots", "slotProps", "style", "onClick"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import composeClasses from '@mui/utils/composeClasses';
@@ -10,8 +10,8 @@ import { styled } from '@mui/material/styles';
10
10
  import { color as d3Color } from 'd3-color';
11
11
  import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
12
12
  import { animated } from '@react-spring/web';
13
- import { getIsFaded, getIsHighlighted, useInteractionItemProps } from '../hooks/useInteractionItemProps';
14
- import { InteractionContext } from '../context/InteractionProvider';
13
+ import { useInteractionItemProps } from '../hooks/useInteractionItemProps';
14
+ import { useItemHighlighted } from '../context';
15
15
  import { jsx as _jsx } from "react/jsx-runtime";
16
16
  export function getBarElementUtilityClass(slot) {
17
17
  return generateUtilityClass('MuiBarElement', slot);
@@ -45,27 +45,20 @@ function BarElement(props) {
45
45
  dataIndex,
46
46
  classes: innerClasses,
47
47
  color,
48
- highlightScope,
49
48
  slots,
50
49
  slotProps,
51
50
  style,
52
51
  onClick
53
52
  } = props,
54
53
  other = _objectWithoutPropertiesLoose(props, _excluded);
55
- const getInteractionItemProps = useInteractionItemProps(highlightScope);
54
+ const getInteractionItemProps = useInteractionItemProps();
56
55
  const {
57
- item
58
- } = React.useContext(InteractionContext);
59
- const isHighlighted = getIsHighlighted(item, {
60
- type: 'bar',
61
- seriesId: id,
62
- dataIndex
63
- }, highlightScope);
64
- const isFaded = !isHighlighted && getIsFaded(item, {
65
- type: 'bar',
56
+ isFaded,
57
+ isHighlighted
58
+ } = useItemHighlighted({
66
59
  seriesId: id,
67
60
  dataIndex
68
- }, highlightScope);
61
+ });
69
62
  const ownerState = {
70
63
  id,
71
64
  dataIndex,
@@ -101,10 +94,6 @@ process.env.NODE_ENV !== "production" ? BarElement.propTypes = {
101
94
  // ----------------------------------------------------------------------
102
95
  classes: PropTypes.object,
103
96
  dataIndex: PropTypes.number.isRequired,
104
- highlightScope: PropTypes.shape({
105
- faded: PropTypes.oneOf(['global', 'none', 'series']),
106
- highlighted: PropTypes.oneOf(['item', 'none', 'series'])
107
- }),
108
97
  id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
109
98
  /**
110
99
  * The props used for each component slot.
@@ -5,12 +5,10 @@ const _excluded = ["seriesId", "classes", "color", "style", "dataIndex", "barLab
5
5
  import * as React from 'react';
6
6
  import { useSlotProps } from '@mui/base/utils';
7
7
  import PropTypes from 'prop-types';
8
- import { InteractionContext } from '../../context/InteractionProvider';
9
- import { getIsFaded, getIsHighlighted } from '../../hooks/useInteractionItemProps';
10
8
  import { useUtilityClasses } from './barLabelClasses';
11
- import { HighlighContext } from '../../context/HighlightProvider';
12
9
  import { getBarLabel } from './getBarLabel';
13
10
  import { BarLabel } from './BarLabel';
11
+ import { useItemHighlighted } from '../../context';
14
12
  import { jsx as _jsx } from "react/jsx-runtime";
15
13
  /**
16
14
  * @ignore - internal component.
@@ -31,21 +29,12 @@ function BarLabelItem(props) {
31
29
  } = props,
32
30
  other = _objectWithoutPropertiesLoose(props, _excluded);
33
31
  const {
34
- item
35
- } = React.useContext(InteractionContext);
36
- const {
37
- scope
38
- } = React.useContext(HighlighContext);
39
- const isHighlighted = getIsHighlighted(item, {
40
- type: 'bar',
41
- seriesId,
42
- dataIndex
43
- }, scope);
44
- const isFaded = !isHighlighted && getIsFaded(item, {
45
- type: 'bar',
32
+ isFaded,
33
+ isHighlighted
34
+ } = useItemHighlighted({
46
35
  seriesId,
47
36
  dataIndex
48
- }, scope);
37
+ });
49
38
  const ownerState = {
50
39
  seriesId,
51
40
  classes: innerClasses,
@@ -83,10 +83,6 @@ process.env.NODE_ENV !== "production" ? BarLabelPlot.propTypes = {
83
83
  color: PropTypes.string.isRequired,
84
84
  dataIndex: PropTypes.number.isRequired,
85
85
  height: PropTypes.number.isRequired,
86
- highlightScope: PropTypes.shape({
87
- faded: PropTypes.oneOf(['global', 'none', 'series']),
88
- highlighted: PropTypes.oneOf(['item', 'none', 'series'])
89
- }),
90
86
  layout: PropTypes.oneOf(['horizontal', 'vertical']),
91
87
  maskId: PropTypes.string.isRequired,
92
88
  seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
@@ -7,12 +7,11 @@ import { useTransition } from '@react-spring/web';
7
7
  import { SeriesContext } from '../context/SeriesContextProvider';
8
8
  import { CartesianContext } from '../context/CartesianContextProvider';
9
9
  import { BarElement } from './BarElement';
10
- import { isBandScaleConfig, isPointScaleConfig } from '../models/axis';
11
- import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../constants';
12
10
  import getColor from './getColor';
13
11
  import { useChartId } from '../hooks';
14
12
  import { BarClipPath } from './BarClipPath';
15
13
  import { BarLabelPlot } from './BarLabel/BarLabelPlot';
14
+ import { checkScaleErrors } from './checkScaleErrors';
16
15
 
17
16
  /**
18
17
  * Solution of the equations
@@ -72,30 +71,8 @@ const useAggregatedData = () => {
72
71
  const xAxisConfig = xAxis[xAxisKey];
73
72
  const yAxisConfig = yAxis[yAxisKey];
74
73
  const verticalLayout = series[seriesId].layout === 'vertical';
75
- let baseScaleConfig;
76
- if (verticalLayout) {
77
- if (!isBandScaleConfig(xAxisConfig)) {
78
- throw new Error(`MUI X Charts: ${xAxisKey === DEFAULT_X_AXIS_KEY ? 'The first `xAxis`' : `The x-axis with id "${xAxisKey}"`} should be of type "band" to display the bar series of id "${seriesId}".`);
79
- }
80
- if (xAxis[xAxisKey].data === undefined) {
81
- throw new Error(`MUI X Charts: ${xAxisKey === DEFAULT_X_AXIS_KEY ? 'The first `xAxis`' : `The x-axis with id "${xAxisKey}"`} should have data property.`);
82
- }
83
- baseScaleConfig = xAxisConfig;
84
- if (isBandScaleConfig(yAxisConfig) || isPointScaleConfig(yAxisConfig)) {
85
- throw new Error(`MUI X Charts: ${yAxisKey === DEFAULT_Y_AXIS_KEY ? 'The first `yAxis`' : `The y-axis with id "${yAxisKey}"`} should be a continuous type to display the bar series of id "${seriesId}".`);
86
- }
87
- } else {
88
- if (!isBandScaleConfig(yAxisConfig)) {
89
- throw new Error(`MUI X Charts: ${yAxisKey === DEFAULT_Y_AXIS_KEY ? 'The first `yAxis`' : `The y-axis with id "${yAxisKey}"`} should be of type "band" to display the bar series of id "${seriesId}".`);
90
- }
91
- if (yAxis[yAxisKey].data === undefined) {
92
- throw new Error(`MUI X Charts: ${yAxisKey === DEFAULT_Y_AXIS_KEY ? 'The first `yAxis`' : `The y-axis with id "${yAxisKey}"`} should have data property.`);
93
- }
94
- baseScaleConfig = yAxisConfig;
95
- if (isBandScaleConfig(xAxisConfig) || isPointScaleConfig(xAxisConfig)) {
96
- throw new Error(`MUI X Charts: ${xAxisKey === DEFAULT_X_AXIS_KEY ? 'The first `xAxis`' : `The x-axis with id "${xAxisKey}"`} should be a continuous type to display the bar series of id "${seriesId}".`);
97
- }
98
- }
74
+ checkScaleErrors(verticalLayout, seriesId, xAxisKey, xAxis, yAxisKey, yAxis);
75
+ const baseScaleConfig = verticalLayout ? xAxisConfig : yAxisConfig;
99
76
  const xScale = xAxisConfig.scale;
100
77
  const yScale = yAxisConfig.scale;
101
78
  const colorGetter = getColor(series[seriesId], xAxis[xAxisKey], yAxis[yAxisKey]);
@@ -128,7 +105,6 @@ const useAggregatedData = () => {
128
105
  height: verticalLayout ? maxValueCoord - minValueCoord : barWidth,
129
106
  width: verticalLayout ? barWidth : maxValueCoord - minValueCoord,
130
107
  color: colorGetter(dataIndex),
131
- highlightScope: series[seriesId].highlightScope,
132
108
  value: series[seriesId].data[dataIndex],
133
109
  maskId: `${chartId}_${stackId || seriesId}_${groupIndex}_${dataIndex}`
134
110
  };
@@ -251,14 +227,12 @@ function BarPlot(props) {
251
227
  seriesId,
252
228
  dataIndex,
253
229
  color,
254
- highlightScope,
255
230
  maskId
256
231
  }) => {
257
232
  const barElement = /*#__PURE__*/_jsx(BarElement, _extends({
258
233
  id: seriesId,
259
234
  dataIndex: dataIndex,
260
- color: color,
261
- highlightScope: highlightScope
235
+ color: color
262
236
  }, other, {
263
237
  onClick: onItemClick && (event => {
264
238
  onItemClick(event, {
@@ -0,0 +1,27 @@
1
+ import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../constants';
2
+ import { isBandScaleConfig, isPointScaleConfig } from '../models/axis';
3
+ const getAxisMessage = (axisDirection, axisKey) => {
4
+ const axisName = `${axisDirection}-axis`;
5
+ const axisKeyName = `${axisDirection}Axis`;
6
+ const axisDefaultKey = axisDirection === 'x' ? DEFAULT_X_AXIS_KEY : DEFAULT_Y_AXIS_KEY;
7
+ return axisKey === axisDefaultKey ? `The first \`${axisKeyName}\`` : `The ${axisName} with id "${axisKey}"`;
8
+ };
9
+ export function checkScaleErrors(verticalLayout, seriesId, xAxisKey, xAxis, yAxisKey, yAxis) {
10
+ const xAxisConfig = xAxis[xAxisKey];
11
+ const yAxisConfig = yAxis[yAxisKey];
12
+ const discreteAxisConfig = verticalLayout ? xAxisConfig : yAxisConfig;
13
+ const continuousAxisConfig = verticalLayout ? yAxisConfig : xAxisConfig;
14
+ const discreteAxisKey = verticalLayout ? xAxisKey : yAxisKey;
15
+ const continuousAxisKey = verticalLayout ? yAxisKey : xAxisKey;
16
+ const discreteAxisDirection = verticalLayout ? 'x' : 'y';
17
+ const continuousAxisDirection = verticalLayout ? 'y' : 'x';
18
+ if (!isBandScaleConfig(discreteAxisConfig)) {
19
+ throw new Error(`MUI X Charts: ${getAxisMessage(discreteAxisDirection, discreteAxisKey)} should be of type "band" to display the bar series of id "${seriesId}".`);
20
+ }
21
+ if (discreteAxisConfig.data === undefined) {
22
+ throw new Error(`MUI X Charts: ${getAxisMessage(discreteAxisDirection, discreteAxisKey)} should have data property.`);
23
+ }
24
+ if (isBandScaleConfig(continuousAxisConfig) || isPointScaleConfig(continuousAxisConfig)) {
25
+ throw new Error(`MUI X Charts: ${getAxisMessage(continuousAxisDirection, continuousAxisKey)} should be a continuous type to display the bar series of id "${seriesId}".`);
26
+ }
27
+ }
@@ -7,8 +7,8 @@ import { InteractionProvider } from '../context/InteractionProvider';
7
7
  import { useReducedMotion } from '../hooks/useReducedMotion';
8
8
  import { ChartsSurface } from '../ChartsSurface';
9
9
  import { CartesianContextProvider } from '../context/CartesianContextProvider';
10
- import { HighlightProvider } from '../context/HighlightProvider';
11
10
  import { ChartsAxesGradients } from '../internals/components/ChartsAxesGradients';
11
+ import { HighlightedProvider } from '../context';
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  const ChartContainer = /*#__PURE__*/React.forwardRef(function ChartContainer(props, ref) {
14
14
  const {
@@ -24,6 +24,8 @@ const ChartContainer = /*#__PURE__*/React.forwardRef(function ChartContainer(pro
24
24
  title,
25
25
  desc,
26
26
  disableAxisListener,
27
+ highlightedItem,
28
+ onHighlightChange,
27
29
  children
28
30
  } = props;
29
31
  const svgRef = React.useRef(null);
@@ -44,7 +46,9 @@ const ChartContainer = /*#__PURE__*/React.forwardRef(function ChartContainer(pro
44
46
  yAxis: yAxis,
45
47
  dataset: dataset,
46
48
  children: /*#__PURE__*/_jsx(InteractionProvider, {
47
- children: /*#__PURE__*/_jsx(HighlightProvider, {
49
+ children: /*#__PURE__*/_jsx(HighlightedProvider, {
50
+ highlightedItem: highlightedItem,
51
+ onHighlightChange: onHighlightChange,
48
52
  children: /*#__PURE__*/_jsxs(ChartsSurface, {
49
53
  width: width,
50
54
  height: height,
@@ -88,6 +92,13 @@ process.env.NODE_ENV !== "production" ? ChartContainer.propTypes = {
88
92
  * The height of the chart in px.
89
93
  */
90
94
  height: PropTypes.number.isRequired,
95
+ /**
96
+ * The item currently highlighted. Turns highlighting into a controlled prop.
97
+ */
98
+ highlightedItem: PropTypes.shape({
99
+ dataIndex: PropTypes.number,
100
+ seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
101
+ }),
91
102
  /**
92
103
  * The margin between the SVG and the drawing area.
93
104
  * It's used for leaving some space for extra information such as the x- and y-axis or legend.
@@ -100,6 +111,12 @@ process.env.NODE_ENV !== "production" ? ChartContainer.propTypes = {
100
111
  right: PropTypes.number,
101
112
  top: PropTypes.number
102
113
  }),
114
+ /**
115
+ * The callback fired when the highlighted item changes.
116
+ *
117
+ * @param {HighlightItemData | null} highlightedItem The newly highlighted item.
118
+ */
119
+ onHighlightChange: PropTypes.func,
103
120
  /**
104
121
  * The array of series to display.
105
122
  * Each type of series has its own specificity.
@@ -8,6 +8,7 @@ import { SeriesContext } from '../context/SeriesContextProvider';
8
8
  import { getValueToPositionMapper } from '../hooks/useScale';
9
9
  import { getSVGPoint } from '../internals/utils';
10
10
  import { useDrawingArea, useSvgRef } from '../hooks';
11
+ import { useHighlighted } from '../context';
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  function ChartsVoronoiHandler(props) {
13
14
  const {
@@ -36,6 +37,10 @@ function ChartsVoronoiHandler(props) {
36
37
  } = React.useContext(SeriesContext).scatter ?? {};
37
38
  const voronoiRef = React.useRef({});
38
39
  const delauneyRef = React.useRef(undefined);
40
+ const {
41
+ setHighlighted,
42
+ clearHighlighted
43
+ } = useHighlighted();
39
44
  const defaultXAxisId = xAxisIds[0];
40
45
  const defaultYAxisId = yAxisIds[0];
41
46
  useEnhancedEffect(() => {
@@ -129,6 +134,7 @@ function ChartsVoronoiHandler(props) {
129
134
  dispatch({
130
135
  type: 'exitChart'
131
136
  });
137
+ clearHighlighted();
132
138
  };
133
139
  const handleMouseMove = event => {
134
140
  const closestPoint = getClosestPoint(event);
@@ -136,6 +142,7 @@ function ChartsVoronoiHandler(props) {
136
142
  dispatch({
137
143
  type: 'exitChart'
138
144
  });
145
+ clearHighlighted();
139
146
  return;
140
147
  }
141
148
  if (closestPoint === 'outside-voronoi-max-radius' || closestPoint === 'no-point-found') {
@@ -145,6 +152,7 @@ function ChartsVoronoiHandler(props) {
145
152
  type: 'scatter'
146
153
  }
147
154
  });
155
+ clearHighlighted();
148
156
  return;
149
157
  }
150
158
  const {
@@ -159,6 +167,10 @@ function ChartsVoronoiHandler(props) {
159
167
  dataIndex
160
168
  }
161
169
  });
170
+ setHighlighted({
171
+ seriesId,
172
+ dataIndex
173
+ });
162
174
  };
163
175
  const handleMouseClick = event => {
164
176
  if (!onItemClick) {
@@ -187,7 +199,7 @@ function ChartsVoronoiHandler(props) {
187
199
  element.removeEventListener('mousemove', handleMouseMove);
188
200
  element.removeEventListener('click', handleMouseClick);
189
201
  };
190
- }, [svgRef, dispatch, left, width, top, height, yAxis, xAxis, voronoiMaxRadius, onItemClick]);
202
+ }, [svgRef, dispatch, left, width, top, height, yAxis, xAxis, voronoiMaxRadius, onItemClick, setHighlighted, clearHighlighted]);
191
203
 
192
204
  // eslint-disable-next-line react/jsx-no-useless-fragment
193
205
  return /*#__PURE__*/_jsx(React.Fragment, {});
@@ -1,15 +1,15 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["id", "classes", "color", "gradientId", "highlightScope", "slots", "slotProps", "onClick"];
3
+ const _excluded = ["id", "classes", "color", "gradientId", "slots", "slotProps", "onClick"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import composeClasses from '@mui/utils/composeClasses';
7
7
  import { useSlotProps } from '@mui/base/utils';
8
8
  import generateUtilityClass from '@mui/utils/generateUtilityClass';
9
9
  import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
10
- import { getIsFaded, getIsHighlighted, useInteractionItemProps } from '../hooks/useInteractionItemProps';
11
- import { InteractionContext } from '../context/InteractionProvider';
10
+ import { useInteractionItemProps } from '../hooks/useInteractionItemProps';
12
11
  import { AnimatedArea } from './AnimatedArea';
12
+ import { useItemHighlighted } from '../context';
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  export function getAreaElementUtilityClass(slot) {
15
15
  return generateUtilityClass('MuiAreaElement', slot);
@@ -43,24 +43,18 @@ function AreaElement(props) {
43
43
  classes: innerClasses,
44
44
  color,
45
45
  gradientId,
46
- highlightScope,
47
46
  slots,
48
47
  slotProps,
49
48
  onClick
50
49
  } = props,
51
50
  other = _objectWithoutPropertiesLoose(props, _excluded);
52
- const getInteractionItemProps = useInteractionItemProps(highlightScope);
51
+ const getInteractionItemProps = useInteractionItemProps();
53
52
  const {
54
- item
55
- } = React.useContext(InteractionContext);
56
- const isHighlighted = getIsHighlighted(item, {
57
- type: 'line',
58
- seriesId: id
59
- }, highlightScope);
60
- const isFaded = !isHighlighted && getIsFaded(item, {
61
- type: 'line',
53
+ isFaded,
54
+ isHighlighted
55
+ } = useItemHighlighted({
62
56
  seriesId: id
63
- }, highlightScope);
57
+ });
64
58
  const ownerState = {
65
59
  id,
66
60
  classes: innerClasses,
@@ -95,10 +89,6 @@ process.env.NODE_ENV !== "production" ? AreaElement.propTypes = {
95
89
  color: PropTypes.string.isRequired,
96
90
  d: PropTypes.string.isRequired,
97
91
  gradientId: PropTypes.string,
98
- highlightScope: PropTypes.shape({
99
- faded: PropTypes.oneOf(['global', 'none', 'series']),
100
- highlighted: PropTypes.oneOf(['item', 'none', 'series'])
101
- }),
102
92
  id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
103
93
  /**
104
94
  * If `true`, animations are skipped.
@@ -97,7 +97,6 @@ function AreaPlot(props) {
97
97
  d,
98
98
  seriesId,
99
99
  color,
100
- highlightScope,
101
100
  area,
102
101
  gradientUsed
103
102
  }) => !!area && /*#__PURE__*/_jsx(AreaElement, {
@@ -105,7 +104,6 @@ function AreaPlot(props) {
105
104
  d: d,
106
105
  color: color,
107
106
  gradientId: gradientUsed && getGradientId(...gradientUsed),
108
- highlightScope: highlightScope,
109
107
  slots: slots,
110
108
  slotProps: slotProps,
111
109
  onClick: onItemClick && (event => onItemClick(event, {
@@ -57,7 +57,9 @@ const LineChart = /*#__PURE__*/React.forwardRef(function LineChart(props, ref) {
57
57
  slots,
58
58
  slotProps,
59
59
  skipAnimation,
60
- loading
60
+ loading,
61
+ highlightedItem,
62
+ onHighlightChange
61
63
  } = props;
62
64
  const id = useId();
63
65
  const clipPathId = `${id}-clip-path`;
@@ -82,6 +84,8 @@ const LineChart = /*#__PURE__*/React.forwardRef(function LineChart(props, ref) {
82
84
  dataset: dataset,
83
85
  sx: sx,
84
86
  disableAxisListener: tooltip?.trigger !== 'axis' && axisHighlight?.x === 'none' && axisHighlight?.y === 'none' && !onAxisClick,
87
+ highlightedItem: highlightedItem,
88
+ onHighlightChange: onHighlightChange,
85
89
  children: [onAxisClick && /*#__PURE__*/_jsx(ChartsOnAxisClickHandler, {
86
90
  onAxisClick: onAxisClick
87
91
  }), grid && /*#__PURE__*/_jsx(ChartsGrid, {
@@ -183,6 +187,13 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
183
187
  * The height of the chart in px. If not defined, it takes the height of the parent element.
184
188
  */
185
189
  height: PropTypes.number,
190
+ /**
191
+ * The item currently highlighted. Turns highlighting into a controlled prop.
192
+ */
193
+ highlightedItem: PropTypes.shape({
194
+ dataIndex: PropTypes.number,
195
+ seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
196
+ }),
186
197
  /**
187
198
  * Indicate which axis to display the left of the charts.
188
199
  * Can be a string (the id of the axis) or an object `ChartsYAxisProps`.
@@ -231,6 +242,12 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
231
242
  * @param {null | AxisData} data The data about the clicked axis and items associated with it.
232
243
  */
233
244
  onAxisClick: PropTypes.func,
245
+ /**
246
+ * The callback fired when the highlighted item changes.
247
+ *
248
+ * @param {HighlightItemData | null} highlightedItem The newly highlighted item.
249
+ */
250
+ onHighlightChange: PropTypes.func,
234
251
  /**
235
252
  * Callback fired when a line element is clicked.
236
253
  */