@mui/x-charts 6.0.0-alpha.7 → 6.0.0-alpha.9

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 (92) hide show
  1. package/BarChart/BarChart.d.ts +1 -0
  2. package/BarChart/BarChart.js +26 -13
  3. package/BarChart/BarPlot.js +25 -15
  4. package/BarChart/extremums.js +19 -3
  5. package/BarChart/formatter.js +3 -1
  6. package/CHANGELOG.md +212 -31
  7. package/ChartsAxisHighlight/ChartsAxisHighlight.d.ts +3 -2
  8. package/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
  9. package/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
  10. package/LineChart/AreaElement.d.ts +1 -1
  11. package/LineChart/LineChart.d.ts +7 -2
  12. package/LineChart/LineChart.js +15 -3
  13. package/LineChart/LineElement.d.ts +1 -1
  14. package/LineChart/LineHighlightElement.d.ts +21 -0
  15. package/LineChart/LineHighlightElement.js +79 -0
  16. package/LineChart/LineHighlightPlot.d.ts +25 -0
  17. package/LineChart/LineHighlightPlot.js +99 -0
  18. package/LineChart/MarkElement.d.ts +1 -1
  19. package/LineChart/MarkElement.js +1 -4
  20. package/LineChart/MarkPlot.js +34 -15
  21. package/LineChart/index.d.ts +2 -0
  22. package/LineChart/index.js +20 -0
  23. package/PieChart/PieArc.d.ts +1 -1
  24. package/PieChart/PieArcLabel.d.ts +1 -1
  25. package/PieChart/PieChart.js +1 -1
  26. package/ScatterChart/ScatterChart.js +1 -1
  27. package/SparkLineChart/SparkLineChart.d.ts +3 -2
  28. package/SparkLineChart/SparkLineChart.js +7 -12
  29. package/context/CartesianContextProvider.js +4 -4
  30. package/esm/BarChart/BarChart.js +30 -17
  31. package/esm/BarChart/BarPlot.js +26 -16
  32. package/esm/BarChart/extremums.js +18 -2
  33. package/esm/BarChart/formatter.js +3 -1
  34. package/esm/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
  35. package/esm/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
  36. package/esm/LineChart/LineChart.js +15 -3
  37. package/esm/LineChart/LineHighlightElement.js +68 -0
  38. package/esm/LineChart/LineHighlightPlot.js +92 -0
  39. package/esm/LineChart/MarkElement.js +1 -4
  40. package/esm/LineChart/MarkPlot.js +34 -15
  41. package/esm/LineChart/index.js +3 -1
  42. package/esm/PieChart/PieChart.js +1 -1
  43. package/esm/ScatterChart/ScatterChart.js +1 -1
  44. package/esm/SparkLineChart/SparkLineChart.js +8 -13
  45. package/esm/context/CartesianContextProvider.js +4 -4
  46. package/esm/hooks/useAxisEvents.js +21 -38
  47. package/esm/hooks/useTicks.js +2 -2
  48. package/hooks/useAxisEvents.js +21 -38
  49. package/hooks/useTicks.js +2 -2
  50. package/index.js +1 -1
  51. package/internals/defaultizeColor.d.ts +3 -0
  52. package/legacy/BarChart/BarChart.js +35 -20
  53. package/legacy/BarChart/BarPlot.js +26 -16
  54. package/legacy/BarChart/extremums.js +22 -2
  55. package/legacy/BarChart/formatter.js +3 -1
  56. package/legacy/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
  57. package/legacy/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
  58. package/legacy/LineChart/LineChart.js +15 -3
  59. package/legacy/LineChart/LineHighlightElement.js +67 -0
  60. package/legacy/LineChart/LineHighlightPlot.js +85 -0
  61. package/legacy/LineChart/MarkElement.js +1 -4
  62. package/legacy/LineChart/MarkPlot.js +24 -6
  63. package/legacy/LineChart/index.js +3 -1
  64. package/legacy/PieChart/PieChart.js +1 -1
  65. package/legacy/ScatterChart/ScatterChart.js +1 -1
  66. package/legacy/SparkLineChart/SparkLineChart.js +8 -11
  67. package/legacy/context/CartesianContextProvider.js +4 -4
  68. package/legacy/hooks/useAxisEvents.js +21 -37
  69. package/legacy/hooks/useTicks.js +2 -2
  70. package/legacy/index.js +1 -1
  71. package/models/seriesType/bar.d.ts +6 -1
  72. package/models/seriesType/line.d.ts +33 -0
  73. package/modern/BarChart/BarChart.js +27 -14
  74. package/modern/BarChart/BarPlot.js +25 -15
  75. package/modern/BarChart/extremums.js +18 -2
  76. package/modern/BarChart/formatter.js +3 -1
  77. package/modern/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
  78. package/modern/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
  79. package/modern/LineChart/LineChart.js +15 -3
  80. package/modern/LineChart/LineHighlightElement.js +68 -0
  81. package/modern/LineChart/LineHighlightPlot.js +91 -0
  82. package/modern/LineChart/MarkElement.js +1 -4
  83. package/modern/LineChart/MarkPlot.js +34 -15
  84. package/modern/LineChart/index.js +3 -1
  85. package/modern/PieChart/PieChart.js +1 -1
  86. package/modern/ScatterChart/ScatterChart.js +1 -1
  87. package/modern/SparkLineChart/SparkLineChart.js +8 -13
  88. package/modern/context/CartesianContextProvider.js +4 -4
  89. package/modern/hooks/useAxisEvents.js +21 -38
  90. package/modern/hooks/useTicks.js +2 -2
  91. package/modern/index.js +1 -1
  92. package/package.json +4 -4
@@ -8,10 +8,11 @@ import { LineSeriesType } from '../models/seriesType/line';
8
8
  import { AreaPlotSlotsComponent, AreaPlotSlotComponentProps } from '../LineChart/AreaPlot';
9
9
  import { LinePlotSlotsComponent, LinePlotSlotComponentProps } from '../LineChart/LinePlot';
10
10
  import { MarkPlotSlotsComponent, MarkPlotSlotComponentProps } from '../LineChart/MarkPlot';
11
+ import { LineHighlightPlotSlotsComponent, LineHighlightPlotSlotComponentProps } from '../LineChart/LineHighlightPlot';
11
12
  import { BarPlotSlotsComponent, BarPlotSlotComponentProps } from '../BarChart/BarPlot';
12
- export interface SparkLineChartSlotsComponent extends AreaPlotSlotsComponent, LinePlotSlotsComponent, MarkPlotSlotsComponent, BarPlotSlotsComponent {
13
+ export interface SparkLineChartSlotsComponent extends AreaPlotSlotsComponent, LinePlotSlotsComponent, MarkPlotSlotsComponent, LineHighlightPlotSlotsComponent, BarPlotSlotsComponent {
13
14
  }
14
- export interface SparkLineChartSlotComponentProps extends AreaPlotSlotComponentProps, LinePlotSlotComponentProps, MarkPlotSlotComponentProps, BarPlotSlotComponentProps {
15
+ export interface SparkLineChartSlotComponentProps extends AreaPlotSlotComponentProps, LinePlotSlotComponentProps, MarkPlotSlotComponentProps, LineHighlightPlotSlotComponentProps, BarPlotSlotComponentProps {
15
16
  }
16
17
  export interface SparkLineChartProps extends Omit<ResponsiveChartContainerProps, 'series' | 'xAxis' | 'yAxis'> {
17
18
  /**
@@ -8,7 +8,6 @@ exports.SparkLineChart = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var React = _interopRequireWildcard(require("react"));
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
- var _styles = require("@mui/material/styles");
12
11
  var _BarChart = require("../BarChart");
13
12
  var _LineChart = require("../LineChart");
14
13
  var _ResponsiveChartContainer = require("../ResponsiveChartContainer");
@@ -18,14 +17,6 @@ var _ChartsAxisHighlight = require("../ChartsAxisHighlight");
18
17
  var _jsxRuntime = require("react/jsx-runtime");
19
18
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
20
19
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
- const SparkLineMarkPlot = (0, _styles.styled)(_LineChart.MarkPlot)({
22
- [`& .${_LineChart.markElementClasses.root}`]: {
23
- display: 'none',
24
- [`&.${_LineChart.markElementClasses.highlighted}`]: {
25
- display: 'inherit'
26
- }
27
- }
28
- });
29
20
  const SPARKLINE_DEFAULT_MARGIN = {
30
21
  top: 5,
31
22
  bottom: 5,
@@ -67,7 +58,8 @@ const SparkLineChart = /*#__PURE__*/React.forwardRef(function SparkLineChart(pro
67
58
  valueFormatter
68
59
  }, plotType === 'bar' ? {} : {
69
60
  area,
70
- curve
61
+ curve,
62
+ disableHighlight: !showHighlight
71
63
  })],
72
64
  width: width,
73
65
  height: height,
@@ -93,7 +85,10 @@ const SparkLineChart = /*#__PURE__*/React.forwardRef(function SparkLineChart(pro
93
85
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_LineChart.LinePlot, {
94
86
  slots: slots,
95
87
  slotProps: slotProps
96
- }), showHighlight && /*#__PURE__*/(0, _jsxRuntime.jsx)(SparkLineMarkPlot, {})]
88
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_LineChart.LineHighlightPlot, {
89
+ slots: slots,
90
+ slotProps: slotProps
91
+ })]
97
92
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ChartsAxisHighlight.ChartsAxisHighlight, (0, _extends2.default)({}, axisHighlight)), showTooltip && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ChartsTooltip.ChartsTooltip, (0, _extends2.default)({}, tooltip)), children]
98
93
  });
99
94
  });
@@ -111,7 +106,7 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes = {
111
106
  area: _propTypes.default.bool,
112
107
  axisHighlight: _propTypes.default.shape({
113
108
  x: _propTypes.default.oneOf(['band', 'line', 'none']),
114
- y: _propTypes.default.oneOf(['line', 'none'])
109
+ y: _propTypes.default.oneOf(['band', 'line', 'none'])
115
110
  }),
116
111
  children: _propTypes.default.node,
117
112
  className: _propTypes.default.string,
@@ -161,17 +161,17 @@ function CartesianContextProvider({
161
161
  const range = [drawingArea.top + drawingArea.height, drawingArea.top];
162
162
  if ((0, _axis.isBandScaleConfig)(axis)) {
163
163
  const categoryGapRatio = axis.categoryGapRatio ?? DEFAULT_CATEGORY_GAP_RATIO;
164
- completedXAxis[axis.id] = (0, _extends2.default)({
164
+ completedYAxis[axis.id] = (0, _extends2.default)({
165
165
  categoryGapRatio,
166
166
  barGapRatio: 0
167
167
  }, axis, {
168
- scale: (0, _d3Scale.scaleBand)(axis.data, range).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
168
+ scale: (0, _d3Scale.scaleBand)(axis.data, [range[1], range[0]]).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
169
169
  ticksNumber: axis.data.length
170
170
  });
171
171
  }
172
172
  if ((0, _axis.isPointScaleConfig)(axis)) {
173
- completedXAxis[axis.id] = (0, _extends2.default)({}, axis, {
174
- scale: (0, _d3Scale.scalePoint)(axis.data, range),
173
+ completedYAxis[axis.id] = (0, _extends2.default)({}, axis, {
174
+ scale: (0, _d3Scale.scalePoint)(axis.data, [range[1], range[0]]),
175
175
  ticksNumber: axis.data.length
176
176
  });
177
177
  }
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
5
5
  import { BarPlot } from './BarPlot';
6
6
  import { ResponsiveChartContainer } from '../ResponsiveChartContainer';
7
7
  import { ChartsAxis } from '../ChartsAxis';
8
- import { DEFAULT_X_AXIS_KEY } from '../constants';
8
+ import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../constants';
9
9
  import { ChartsTooltip } from '../ChartsTooltip';
10
10
  import { ChartsLegend } from '../ChartsLegend';
11
11
  import { ChartsAxisHighlight } from '../ChartsAxisHighlight';
@@ -23,6 +23,7 @@ const BarChart = /*#__PURE__*/React.forwardRef(function BarChart(props, ref) {
23
23
  colors,
24
24
  dataset,
25
25
  sx,
26
+ layout,
26
27
  tooltip,
27
28
  axisHighlight,
28
29
  legend,
@@ -36,25 +37,37 @@ const BarChart = /*#__PURE__*/React.forwardRef(function BarChart(props, ref) {
36
37
  } = props;
37
38
  const id = useId();
38
39
  const clipPathId = `${id}-clip-path`;
40
+ const hasHorizontalSeries = layout === 'horizontal' || layout === undefined && series.some(item => item.layout === 'horizontal');
41
+ const defaultAxisConfig = {
42
+ scaleType: 'band',
43
+ data: Array.from({
44
+ length: Math.max(...series.map(s => {
45
+ var _ref, _s$data;
46
+ return ((_ref = (_s$data = s.data) != null ? _s$data : dataset) != null ? _ref : []).length;
47
+ }))
48
+ }, (_, index) => index)
49
+ };
50
+ const defaultizedAxisHighlight = _extends({}, hasHorizontalSeries ? {
51
+ y: 'band'
52
+ } : {
53
+ x: 'band'
54
+ }, axisHighlight);
39
55
  return /*#__PURE__*/_jsxs(ResponsiveChartContainer, {
40
56
  ref: ref,
41
57
  series: series.map(s => _extends({
42
58
  type: 'bar'
43
- }, s)),
59
+ }, s, {
60
+ layout: hasHorizontalSeries ? 'horizontal' : 'vertical'
61
+ })),
44
62
  width: width,
45
63
  height: height,
46
64
  margin: margin,
47
- xAxis: xAxis != null ? xAxis : [{
48
- id: DEFAULT_X_AXIS_KEY,
49
- scaleType: 'band',
50
- data: Array.from({
51
- length: Math.max(...series.map(s => {
52
- var _ref, _s$data;
53
- return ((_ref = (_s$data = s.data) != null ? _s$data : dataset) != null ? _ref : []).length;
54
- }))
55
- }, (_, index) => index)
56
- }],
57
- yAxis: yAxis,
65
+ xAxis: xAxis != null ? xAxis : hasHorizontalSeries ? undefined : [_extends({
66
+ id: DEFAULT_X_AXIS_KEY
67
+ }, defaultAxisConfig)],
68
+ yAxis: yAxis != null ? yAxis : hasHorizontalSeries ? [_extends({
69
+ id: DEFAULT_Y_AXIS_KEY
70
+ }, defaultAxisConfig)] : undefined,
58
71
  colors: colors,
59
72
  dataset: dataset,
60
73
  sx: sx,
@@ -75,9 +88,7 @@ const BarChart = /*#__PURE__*/React.forwardRef(function BarChart(props, ref) {
75
88
  }), /*#__PURE__*/_jsx(ChartsLegend, _extends({}, legend, {
76
89
  slots: slots,
77
90
  slotProps: slotProps
78
- })), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({
79
- x: "band"
80
- }, axisHighlight)), /*#__PURE__*/_jsx(ChartsTooltip, _extends({}, tooltip, {
91
+ })), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, defaultizedAxisHighlight)), /*#__PURE__*/_jsx(ChartsTooltip, _extends({}, tooltip, {
81
92
  slots: slots,
82
93
  slotProps: slotProps
83
94
  })), /*#__PURE__*/_jsx(ChartsClipPath, {
@@ -92,7 +103,7 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
92
103
  // ----------------------------------------------------------------------
93
104
  axisHighlight: PropTypes.shape({
94
105
  x: PropTypes.oneOf(['band', 'line', 'none']),
95
- y: PropTypes.oneOf(['line', 'none'])
106
+ y: PropTypes.oneOf(['band', 'line', 'none'])
96
107
  }),
97
108
  /**
98
109
  * Indicate which axis to display the bottom of the charts.
@@ -127,6 +138,7 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
127
138
  desc: PropTypes.string,
128
139
  disableAxisListener: PropTypes.bool,
129
140
  height: PropTypes.number,
141
+ layout: PropTypes.oneOf(['horizontal', 'vertical']),
130
142
  /**
131
143
  * Indicate which axis to display the left of the charts.
132
144
  * Can be a string (the id of the axis) or an object `ChartsYAxisProps`.
@@ -207,6 +219,7 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
207
219
  }),
208
220
  id: PropTypes.string,
209
221
  label: PropTypes.string,
222
+ layout: PropTypes.oneOf(['horizontal', 'vertical']),
210
223
  stack: PropTypes.string,
211
224
  stackOffset: PropTypes.oneOf(['diverging', 'expand', 'none', 'silhouette', 'wiggle']),
212
225
  stackOrder: PropTypes.oneOf(['appearance', 'ascending', 'descending', 'insideOut', 'none', 'reverse']),
@@ -62,42 +62,52 @@ function BarPlot(props) {
62
62
  const yAxisKey = (_series$seriesId$yAxi = series[seriesId].yAxisKey) != null ? _series$seriesId$yAxi : defaultYAxisId;
63
63
  const xAxisConfig = xAxis[xAxisKey];
64
64
  const yAxisConfig = yAxis[yAxisKey];
65
- if (!isBandScaleConfig(xAxisConfig)) {
66
- throw new Error(`Axis with id "${xAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
67
- }
68
- if (xAxis[xAxisKey].data === undefined) {
69
- throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
65
+ const verticalLayout = series[seriesId].layout === 'vertical';
66
+ let baseScaleConfig;
67
+ if (verticalLayout) {
68
+ if (!isBandScaleConfig(xAxisConfig)) {
69
+ throw new Error(`Axis with id "${xAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
70
+ }
71
+ if (xAxis[xAxisKey].data === undefined) {
72
+ throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
73
+ }
74
+ baseScaleConfig = xAxisConfig;
75
+ } else {
76
+ if (!isBandScaleConfig(yAxisConfig)) {
77
+ throw new Error(`Axis with id "${yAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
78
+ }
79
+ if (yAxis[yAxisKey].data === undefined) {
80
+ throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
81
+ }
82
+ baseScaleConfig = yAxisConfig;
70
83
  }
71
84
  const xScale = xAxisConfig.scale;
72
85
  const yScale = yAxisConfig.scale;
73
-
74
- // Currently assuming all bars are vertical
75
- const bandWidth = xScale.bandwidth();
86
+ const bandWidth = baseScaleConfig.scale.bandwidth();
76
87
  const {
77
88
  barWidth,
78
89
  offset
79
90
  } = getBandSize({
80
91
  bandWidth,
81
92
  numberOfGroups: stackingGroups.length,
82
- gapRatio: xAxisConfig.barGapRatio
93
+ gapRatio: baseScaleConfig.barGapRatio
83
94
  });
84
-
85
- // @ts-ignore TODO: fix when adding a correct API for customisation
95
+ const barOffset = groupIndex * (barWidth + offset);
86
96
  const {
87
97
  stackedData,
88
98
  color
89
99
  } = series[seriesId];
90
100
  return stackedData.map((values, dataIndex) => {
91
- var _xAxis$xAxisKey$data;
101
+ var _xAxis$xAxisKey$data, _yAxis$yAxisKey$data;
92
102
  const baseline = Math.min(...values);
93
103
  const value = Math.max(...values);
94
104
  return /*#__PURE__*/_jsx(BarElement, _extends({
95
105
  id: seriesId,
96
106
  dataIndex: dataIndex,
97
- x: xScale((_xAxis$xAxisKey$data = xAxis[xAxisKey].data) == null ? void 0 : _xAxis$xAxisKey$data[dataIndex]) + groupIndex * (barWidth + offset),
98
- y: yScale(value),
99
- height: yScale(baseline) - yScale(value),
100
- width: barWidth,
107
+ x: verticalLayout ? xScale((_xAxis$xAxisKey$data = xAxis[xAxisKey].data) == null ? void 0 : _xAxis$xAxisKey$data[dataIndex]) + barOffset : xScale(baseline),
108
+ y: verticalLayout ? yScale(value) : yScale((_yAxis$yAxisKey$data = yAxis[yAxisKey].data) == null ? void 0 : _yAxis$yAxisKey$data[dataIndex]) + barOffset,
109
+ height: verticalLayout ? Math.abs(yScale(baseline) - yScale(value)) : barWidth,
110
+ width: verticalLayout ? barWidth : Math.abs(xScale(baseline) - xScale(value)),
101
111
  color: color,
102
112
  highlightScope: series[seriesId].highlightScope
103
113
  }, props), `${seriesId}-${dataIndex}`);
@@ -1,4 +1,4 @@
1
- export const getExtremumX = params => {
1
+ const getBaseExtremum = params => {
2
2
  var _axis$data, _axis$data2;
3
3
  const {
4
4
  axis
@@ -7,7 +7,7 @@ export const getExtremumX = params => {
7
7
  const maxX = Math.max(...((_axis$data2 = axis.data) != null ? _axis$data2 : []));
8
8
  return [minX, maxX];
9
9
  };
10
- export const getExtremumY = params => {
10
+ const getValueExtremum = params => {
11
11
  const {
12
12
  series,
13
13
  axis,
@@ -17,4 +17,20 @@ export const getExtremumY = params => {
17
17
  const [seriesMin, seriesMax] = series[seriesId].stackedData.reduce((seriesAcc, values) => [Math.min(...values, ...(seriesAcc[0] === null ? [] : [seriesAcc[0]])), Math.max(...values, ...(seriesAcc[1] === null ? [] : [seriesAcc[1]]))], series[seriesId].stackedData[0]);
18
18
  return [acc[0] === null ? seriesMin : Math.min(seriesMin, acc[0]), acc[1] === null ? seriesMax : Math.max(seriesMax, acc[1])];
19
19
  }, [null, null]);
20
+ };
21
+ export const getExtremumX = params => {
22
+ // Notice that bar should be all horizontal or all vertical.
23
+ // Don't think it's a problem for now
24
+ const isHorizontal = Object.keys(params.series).some(seriesId => params.series[seriesId].layout === 'horizontal');
25
+ if (isHorizontal) {
26
+ return getValueExtremum(params);
27
+ }
28
+ return getBaseExtremum(params);
29
+ };
30
+ export const getExtremumY = params => {
31
+ const isHorizontal = Object.keys(params.series).some(seriesId => params.series[seriesId].layout === 'horizontal');
32
+ if (isHorizontal) {
33
+ return getBaseExtremum(params);
34
+ }
35
+ return getValueExtremum(params);
20
36
  };
@@ -42,7 +42,9 @@ const formatter = (params, dataset) => {
42
42
  })).order(stackingOrder).offset(stackingOffset)(d3Dataset);
43
43
  ids.forEach((id, index) => {
44
44
  const dataKey = series[id].dataKey;
45
- completedSeries[id] = _extends({}, series[id], {
45
+ completedSeries[id] = _extends({
46
+ layout: 'vertical'
47
+ }, series[id], {
46
48
  data: dataKey ? dataset.map(d => d[dataKey]) : series[id].data,
47
49
  stackedData: stackedSeries[index].map(([a, b]) => [a, b])
48
50
  });
@@ -25,6 +25,7 @@ function ChartsAxisHighlight(props) {
25
25
  axis
26
26
  } = React.useContext(InteractionContext);
27
27
  const getXPosition = getValueToPositionMapper(xScale);
28
+ const getYPosition = getValueToPositionMapper(yScale);
28
29
  return /*#__PURE__*/_jsxs(React.Fragment, {
29
30
  children: [xAxisHighlight === 'band' && axis.x !== null && isBandScale(xScale) && /*#__PURE__*/_jsx("path", {
30
31
  d: `M ${xScale(axis.x.value) - (xScale.step() - xScale.bandwidth()) / 2} ${yScale.range()[0]} l ${xScale.step()} 0 l 0 ${yScale.range()[1] - yScale.range()[0]} l ${-xScale.step()} 0 Z`,
@@ -33,15 +34,22 @@ function ChartsAxisHighlight(props) {
33
34
  style: {
34
35
  pointerEvents: 'none'
35
36
  }
37
+ }), yAxisHighlight === 'band' && axis.y !== null && isBandScale(yScale) && /*#__PURE__*/_jsx("path", {
38
+ d: `M ${xScale.range()[0]} ${yScale(axis.y.value) - (yScale.step() - yScale.bandwidth()) / 2} l 0 ${yScale.step()} l ${xScale.range()[1] - xScale.range()[0]} 0 l 0 ${-yScale.step()} Z`,
39
+ fill: "gray",
40
+ fillOpacity: 0.1,
41
+ style: {
42
+ pointerEvents: 'none'
43
+ }
36
44
  }), xAxisHighlight === 'line' && axis.x !== null && /*#__PURE__*/_jsx("path", {
37
- d: `M ${getXPosition(axis.x.value)} ${yScale(yScale.domain()[0])} L ${getXPosition(axis.x.value)} ${yScale(yScale.domain().at(-1))}`,
45
+ d: `M ${getXPosition(axis.x.value)} ${yScale.range()[0]} L ${getXPosition(axis.x.value)} ${yScale.range()[1]}`,
38
46
  stroke: "black",
39
47
  strokeDasharray: "5 2",
40
48
  style: {
41
49
  pointerEvents: 'none'
42
50
  }
43
51
  }), yAxisHighlight === 'line' && axis.y !== null && /*#__PURE__*/_jsx("path", {
44
- d: `M ${xScale.range()[0]} ${yScale(axis.y.value)} L ${xScale.range()[1]} ${yScale(axis.y.value)}`,
52
+ d: `M ${xScale.range()[0]} ${getYPosition(axis.y.value)} L ${xScale.range()[1]} ${getYPosition(axis.y.value)}`,
45
53
  stroke: "black",
46
54
  strokeDasharray: "5 2",
47
55
  style: {
@@ -56,6 +64,6 @@ process.env.NODE_ENV !== "production" ? ChartsAxisHighlight.propTypes = {
56
64
  // | To update them edit the TypeScript types and run "yarn proptypes" |
57
65
  // ----------------------------------------------------------------------
58
66
  x: PropTypes.oneOf(['band', 'line', 'none']),
59
- y: PropTypes.oneOf(['line', 'none'])
67
+ y: PropTypes.oneOf(['band', 'line', 'none'])
60
68
  } : void 0;
61
69
  export { ChartsAxisHighlight };
@@ -72,29 +72,33 @@ export function ChartsAxisTooltipContent(props) {
72
72
  sx,
73
73
  classes
74
74
  } = props;
75
- const dataIndex = axisData.x && axisData.x.index;
76
- const axisValue = axisData.x && axisData.x.value;
75
+ const isXaxis = (axisData.x && axisData.x.index) !== undefined;
76
+ const dataIndex = isXaxis ? axisData.x && axisData.x.index : axisData.y && axisData.y.index;
77
+ const axisValue = isXaxis ? axisData.x && axisData.x.value : axisData.y && axisData.y.value;
77
78
  const {
78
79
  xAxisIds,
79
- xAxis
80
+ xAxis,
81
+ yAxisIds,
82
+ yAxis
80
83
  } = React.useContext(CartesianContext);
81
84
  const series = React.useContext(SeriesContext);
82
- const USED_X_AXIS_ID = xAxisIds[0];
85
+ const USED_AXIS_ID = isXaxis ? xAxisIds[0] : yAxisIds[0];
83
86
  const relevantSeries = React.useMemo(() => {
84
87
  const rep = [];
85
88
  Object.keys(series).filter(seriesType => ['bar', 'line', 'scatter'].includes(seriesType)).forEach(seriesType => {
86
89
  series[seriesType].seriesOrder.forEach(seriesId => {
87
- const axisKey = series[seriesType].series[seriesId].xAxisKey;
88
- if (axisKey === undefined || axisKey === USED_X_AXIS_ID) {
90
+ const item = series[seriesType].series[seriesId];
91
+ const axisKey = isXaxis ? item.xAxisKey : item.yAxisKey;
92
+ if (axisKey === undefined || axisKey === USED_AXIS_ID) {
89
93
  rep.push(series[seriesType].series[seriesId]);
90
94
  }
91
95
  });
92
96
  });
93
97
  return rep;
94
- }, [USED_X_AXIS_ID, series]);
98
+ }, [USED_AXIS_ID, isXaxis, series]);
95
99
  const relevantAxis = React.useMemo(() => {
96
- return xAxis[USED_X_AXIS_ID];
97
- }, [USED_X_AXIS_ID, xAxis]);
100
+ return isXaxis ? xAxis[USED_AXIS_ID] : yAxis[USED_AXIS_ID];
101
+ }, [USED_AXIS_ID, isXaxis, xAxis, yAxis]);
98
102
  const Content = content != null ? content : DefaultChartsAxisContent;
99
103
  return /*#__PURE__*/_jsx(Content, {
100
104
  axisData: axisData,
@@ -12,6 +12,7 @@ import { ChartsTooltip } from '../ChartsTooltip';
12
12
  import { ChartsLegend } from '../ChartsLegend';
13
13
  import { ChartsAxisHighlight } from '../ChartsAxisHighlight';
14
14
  import { ChartsClipPath } from '../ChartsClipPath';
15
+ import { LineHighlightPlot } from './LineHighlightPlot';
15
16
  import { jsx as _jsx } from "react/jsx-runtime";
16
17
  import { jsxs as _jsxs } from "react/jsx-runtime";
17
18
  const LineChart = /*#__PURE__*/React.forwardRef(function LineChart(props, ref) {
@@ -29,6 +30,7 @@ const LineChart = /*#__PURE__*/React.forwardRef(function LineChart(props, ref) {
29
30
  axisHighlight = {
30
31
  x: 'line'
31
32
  },
33
+ disableLineItemHighlight,
32
34
  legend,
33
35
  topAxis,
34
36
  leftAxis,
@@ -43,6 +45,7 @@ const LineChart = /*#__PURE__*/React.forwardRef(function LineChart(props, ref) {
43
45
  return /*#__PURE__*/_jsxs(ResponsiveChartContainer, {
44
46
  ref: ref,
45
47
  series: series.map(s => _extends({
48
+ disableHighlight: !!disableLineItemHighlight,
46
49
  type: 'line'
47
50
  }, s)),
48
51
  width: width,
@@ -79,13 +82,16 @@ const LineChart = /*#__PURE__*/React.forwardRef(function LineChart(props, ref) {
79
82
  bottomAxis: bottomAxis,
80
83
  slots: slots,
81
84
  slotProps: slotProps
82
- }), /*#__PURE__*/_jsx(MarkPlot, {
85
+ }), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, axisHighlight)), /*#__PURE__*/_jsx(MarkPlot, {
86
+ slots: slots,
87
+ slotProps: slotProps
88
+ }), /*#__PURE__*/_jsx(LineHighlightPlot, {
83
89
  slots: slots,
84
90
  slotProps: slotProps
85
91
  }), /*#__PURE__*/_jsx(ChartsLegend, _extends({}, legend, {
86
92
  slots: slots,
87
93
  slotProps: slotProps
88
- })), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, axisHighlight)), /*#__PURE__*/_jsx(ChartsTooltip, _extends({}, tooltip)), /*#__PURE__*/_jsx(ChartsClipPath, {
94
+ })), /*#__PURE__*/_jsx(ChartsTooltip, _extends({}, tooltip)), /*#__PURE__*/_jsx(ChartsClipPath, {
89
95
  id: clipPathId
90
96
  }), children]
91
97
  });
@@ -97,7 +103,7 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
97
103
  // ----------------------------------------------------------------------
98
104
  axisHighlight: PropTypes.shape({
99
105
  x: PropTypes.oneOf(['band', 'line', 'none']),
100
- y: PropTypes.oneOf(['line', 'none'])
106
+ y: PropTypes.oneOf(['band', 'line', 'none'])
101
107
  }),
102
108
  /**
103
109
  * Indicate which axis to display the bottom of the charts.
@@ -131,6 +137,10 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
131
137
  dataset: PropTypes.arrayOf(PropTypes.object),
132
138
  desc: PropTypes.string,
133
139
  disableAxisListener: PropTypes.bool,
140
+ /**
141
+ * If `true`, render the line highlight item.
142
+ */
143
+ disableLineItemHighlight: PropTypes.bool,
134
144
  height: PropTypes.number,
135
145
  /**
136
146
  * Indicate which axis to display the left of the charts.
@@ -208,12 +218,14 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
208
218
  curve: PropTypes.oneOf(['catmullRom', 'linear', 'monotoneX', 'monotoneY', 'natural', 'step', 'stepAfter', 'stepBefore']),
209
219
  data: PropTypes.arrayOf(PropTypes.number),
210
220
  dataKey: PropTypes.string,
221
+ disableHighlight: PropTypes.bool,
211
222
  highlightScope: PropTypes.shape({
212
223
  faded: PropTypes.oneOf(['global', 'none', 'series']),
213
224
  highlighted: PropTypes.oneOf(['item', 'none', 'series'])
214
225
  }),
215
226
  id: PropTypes.string,
216
227
  label: PropTypes.string,
228
+ showMark: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
217
229
  stack: PropTypes.string,
218
230
  stackOffset: PropTypes.oneOf(['diverging', 'expand', 'none', 'silhouette', 'wiggle']),
219
231
  stackOrder: PropTypes.oneOf(['appearance', 'ascending', 'descending', 'insideOut', 'none', 'reverse']),
@@ -0,0 +1,68 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["x", "y", "id", "classes", "color"];
4
+ import * as React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import composeClasses from '@mui/utils/composeClasses';
7
+ import generateUtilityClass from '@mui/utils/generateUtilityClass';
8
+ import { styled } from '@mui/material/styles';
9
+ import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ export function getHighlightElementUtilityClass(slot) {
12
+ return generateUtilityClass('MuiHighlightElement', slot);
13
+ }
14
+ export const lineHighlightElementClasses = generateUtilityClasses('MuiHighlightElement', ['root']);
15
+ const useUtilityClasses = ownerState => {
16
+ const {
17
+ classes,
18
+ id
19
+ } = ownerState;
20
+ const slots = {
21
+ root: ['root', `series-${id}`]
22
+ };
23
+ return composeClasses(slots, getHighlightElementUtilityClass, classes);
24
+ };
25
+ const HighlightElement = styled('circle', {
26
+ name: 'MuiHighlightElement',
27
+ slot: 'Root',
28
+ overridesResolver: (_, styles) => styles.root
29
+ })(({
30
+ ownerState
31
+ }) => ({
32
+ transform: `translate(${ownerState.x}px, ${ownerState.y}px)`,
33
+ transformOrigin: `${ownerState.x}px ${ownerState.y}px`,
34
+ fill: ownerState.color
35
+ }));
36
+ function LineHighlightElement(props) {
37
+ const {
38
+ x,
39
+ y,
40
+ id,
41
+ classes: innerClasses,
42
+ color
43
+ } = props,
44
+ other = _objectWithoutPropertiesLoose(props, _excluded);
45
+ const ownerState = {
46
+ id,
47
+ classes: innerClasses,
48
+ color,
49
+ x,
50
+ y
51
+ };
52
+ const classes = useUtilityClasses(ownerState);
53
+ return /*#__PURE__*/_jsx(HighlightElement, _extends({}, other, {
54
+ ownerState: ownerState,
55
+ className: classes.root,
56
+ cx: 0,
57
+ cy: 0,
58
+ r: other.r === undefined ? 5 : other.r
59
+ }));
60
+ }
61
+ process.env.NODE_ENV !== "production" ? LineHighlightElement.propTypes = {
62
+ // ----------------------------- Warning --------------------------------
63
+ // | These PropTypes are generated from the TypeScript type definitions |
64
+ // | To update them edit the TypeScript types and run "yarn proptypes" |
65
+ // ----------------------------------------------------------------------
66
+ classes: PropTypes.object
67
+ } : void 0;
68
+ export { LineHighlightElement };
@@ -0,0 +1,92 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["slots", "slotProps"];
4
+ import * as React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import { SeriesContext } from '../context/SeriesContextProvider';
7
+ import { CartesianContext } from '../context/CartesianContextProvider';
8
+ import { LineHighlightElement } from './LineHighlightElement';
9
+ import { getValueToPositionMapper } from '../hooks/useScale';
10
+ import { InteractionContext } from '../context/InteractionProvider';
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ function LineHighlightPlot(props) {
13
+ var _axis$x, _slots$lineHighlight;
14
+ const {
15
+ slots,
16
+ slotProps
17
+ } = props,
18
+ other = _objectWithoutPropertiesLoose(props, _excluded);
19
+ const seriesData = React.useContext(SeriesContext).line;
20
+ const axisData = React.useContext(CartesianContext);
21
+ const {
22
+ axis
23
+ } = React.useContext(InteractionContext);
24
+ const highlightedIndex = (_axis$x = axis.x) == null ? void 0 : _axis$x.index;
25
+ if (highlightedIndex === undefined) {
26
+ return null;
27
+ }
28
+ if (seriesData === undefined) {
29
+ return null;
30
+ }
31
+ const {
32
+ series,
33
+ stackingGroups
34
+ } = seriesData;
35
+ const {
36
+ xAxis,
37
+ yAxis,
38
+ xAxisIds,
39
+ yAxisIds
40
+ } = axisData;
41
+ const defaultXAxisId = xAxisIds[0];
42
+ const defaultYAxisId = yAxisIds[0];
43
+ const Element = (_slots$lineHighlight = slots == null ? void 0 : slots.lineHighlight) != null ? _slots$lineHighlight : LineHighlightElement;
44
+ return /*#__PURE__*/_jsx("g", _extends({}, other, {
45
+ children: stackingGroups.flatMap(({
46
+ ids: groupIds
47
+ }) => {
48
+ return groupIds.flatMap(seriesId => {
49
+ const {
50
+ xAxisKey = defaultXAxisId,
51
+ yAxisKey = defaultYAxisId,
52
+ stackedData,
53
+ disableHighlight
54
+ } = series[seriesId];
55
+ if (disableHighlight) {
56
+ return null;
57
+ }
58
+ const xScale = getValueToPositionMapper(xAxis[xAxisKey].scale);
59
+ const yScale = yAxis[yAxisKey].scale;
60
+ const xData = xAxis[xAxisKey].data;
61
+ if (xData === undefined) {
62
+ throw new Error(`Axis of id "${xAxisKey}" should have data property to be able to display a line plot.`);
63
+ }
64
+ const x = xScale(xData[highlightedIndex]);
65
+ const y = yScale(stackedData[highlightedIndex][1]);
66
+ return /*#__PURE__*/_jsx(Element, _extends({
67
+ id: seriesId,
68
+ color: series[seriesId].color,
69
+ x: x,
70
+ y: y
71
+ }, slotProps == null ? void 0 : slotProps.lineHighlight), `${seriesId}`);
72
+ });
73
+ })
74
+ }));
75
+ }
76
+ process.env.NODE_ENV !== "production" ? LineHighlightPlot.propTypes = {
77
+ // ----------------------------- Warning --------------------------------
78
+ // | These PropTypes are generated from the TypeScript type definitions |
79
+ // | To update them edit the TypeScript types and run "yarn proptypes" |
80
+ // ----------------------------------------------------------------------
81
+ /**
82
+ * The props used for each component slot.
83
+ * @default {}
84
+ */
85
+ slotProps: PropTypes.object,
86
+ /**
87
+ * Overridable component slots.
88
+ * @default {}
89
+ */
90
+ slots: PropTypes.object
91
+ } : void 0;
92
+ export { LineHighlightPlot };
@@ -40,10 +40,7 @@ const MarkElementPath = styled('path', {
40
40
  transformOrigin: `${ownerState.x}px ${ownerState.y}px`,
41
41
  fill: theme.palette.background.paper,
42
42
  stroke: ownerState.color,
43
- strokeWidth: 2,
44
- '&.MuiMarkElement-highlighted': {
45
- fill: ownerState.color
46
- }
43
+ strokeWidth: 2
47
44
  }));
48
45
  MarkElementPath.propTypes = {
49
46
  // ----------------------------- Warning --------------------------------