@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
@@ -1,3 +1,4 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
1
2
  import * as React from 'react';
2
3
  import { InteractionContext } from '../context/InteractionProvider';
3
4
  import { CartesianContext } from '../context/CartesianContextProvider';
@@ -30,64 +31,47 @@ export var useAxisEvents = function useAxisEvents(disableAxisListener) {
30
31
  if (element === null || disableAxisListener) {
31
32
  return function () {};
32
33
  }
33
- var getUpdateY = function getUpdateY(y) {
34
- if (usedYAxis === null) {
35
- return null;
36
- }
37
- var _yAxis$usedYAxis = yAxis[usedYAxis],
38
- yScale = _yAxis$usedYAxis.scale,
39
- yAxisData = _yAxis$usedYAxis.data;
40
- if (!isBandScale(yScale)) {
41
- return {
42
- value: yScale.invert(y)
43
- };
44
- }
45
- var dataIndex = Math.floor((y - yScale.range()[0]) / yScale.step());
46
- if (dataIndex < 0 || dataIndex >= yAxisData.length) {
47
- return null;
48
- }
49
- return {
50
- index: dataIndex,
51
- value: yAxisData[dataIndex]
52
- };
53
- };
54
- var getUpdateX = function getUpdateX(x) {
34
+ var getUpdate = function getUpdate(axisConfig, mouseValue) {
55
35
  if (usedXAxis === null) {
56
36
  return null;
57
37
  }
58
- var _xAxis$usedXAxis = xAxis[usedXAxis],
59
- xScale = _xAxis$usedXAxis.scale,
60
- xAxisData = _xAxis$usedXAxis.data;
61
- if (!isBandScale(xScale)) {
62
- var value = xScale.invert(x);
63
- var closestIndex = xAxisData == null ? void 0 : xAxisData.findIndex(function (v, index) {
38
+ var scale = axisConfig.scale,
39
+ axisData = axisConfig.data;
40
+ if (!isBandScale(scale)) {
41
+ var value = scale.invert(mouseValue);
42
+ if (axisData === undefined) {
43
+ return {
44
+ value: value
45
+ };
46
+ }
47
+ var closestIndex = axisData == null ? void 0 : axisData.findIndex(function (v, index) {
64
48
  if (v > value) {
65
49
  // @ts-ignore
66
- if (index === 0 || Math.abs(value - v) <= Math.abs(value - xAxisData[index - 1])) {
50
+ if (index === 0 || Math.abs(value - v) <= Math.abs(value - axisData[index - 1])) {
67
51
  return true;
68
52
  }
69
53
  }
70
54
  if (v <= value) {
71
- if (index === xAxisData.length - 1 ||
55
+ if (index === axisData.length - 1 ||
72
56
  // @ts-ignore
73
- Math.abs(value - v) < Math.abs(value - xAxisData[index + 1])) {
57
+ Math.abs(value - v) < Math.abs(value - axisData[index + 1])) {
74
58
  return true;
75
59
  }
76
60
  }
77
61
  return false;
78
62
  });
79
63
  return {
80
- value: closestIndex !== undefined && closestIndex >= 0 ? xAxisData[closestIndex] : value,
64
+ value: closestIndex !== undefined && closestIndex >= 0 ? axisData[closestIndex] : value,
81
65
  index: closestIndex
82
66
  };
83
67
  }
84
- var dataIndex = xScale.bandwidth() === 0 ? Math.floor((x - xScale.range()[0] + xScale.step() / 2) / xScale.step()) : Math.floor((x - xScale.range()[0]) / xScale.step());
85
- if (dataIndex < 0 || dataIndex >= xAxisData.length) {
68
+ var dataIndex = scale.bandwidth() === 0 ? Math.floor((mouseValue - Math.min.apply(Math, _toConsumableArray(scale.range())) + scale.step() / 2) / scale.step()) : Math.floor((mouseValue - Math.min.apply(Math, _toConsumableArray(scale.range()))) / scale.step());
69
+ if (dataIndex < 0 || dataIndex >= axisData.length) {
86
70
  return null;
87
71
  }
88
72
  return {
89
73
  index: dataIndex,
90
- value: xAxisData[dataIndex]
74
+ value: axisData[dataIndex]
91
75
  };
92
76
  };
93
77
  var handleMouseOut = function handleMouseOut() {
@@ -125,8 +109,8 @@ export var useAxisEvents = function useAxisEvents(disableAxisListener) {
125
109
  });
126
110
  return;
127
111
  }
128
- var newStateX = getUpdateX(svgPt.x);
129
- var newStateY = getUpdateY(svgPt.y);
112
+ var newStateX = getUpdate(xAxis[usedXAxis], svgPt.x);
113
+ var newStateY = getUpdate(yAxis[usedYAxis], svgPt.y);
130
114
  dispatch({
131
115
  type: 'updateAxis',
132
116
  data: {
@@ -22,11 +22,11 @@ function useTicks(options) {
22
22
  var domain = scale.domain();
23
23
  if (scale.bandwidth() > 0) {
24
24
  // scale type = 'band'
25
- return [].concat(_toConsumableArray(domain.map(function (value, index) {
25
+ return [].concat(_toConsumableArray(domain.map(function (value) {
26
26
  var _valueFormatter;
27
27
  return {
28
28
  formattedValue: (_valueFormatter = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter : value,
29
- offset: index === 0 ? scale.range()[0] : scale(value) - (scale.step() - scale.bandwidth()) / 2,
29
+ offset: scale(value) - (scale.step() - scale.bandwidth()) / 2,
30
30
  labelOffset: scale.step() / 2
31
31
  };
32
32
  })), [{
package/legacy/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v6.0.0-alpha.7
2
+ * @mui/x-charts v6.0.0-alpha.9
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -11,6 +11,11 @@ export interface BarSeriesType extends CommonSeriesType<number>, CartesianSeries
11
11
  */
12
12
  dataKey?: string;
13
13
  label?: string;
14
+ /**
15
+ * Layout of the bars. All bar should have the same layout.
16
+ * @default 'vertical'
17
+ */
18
+ layout?: 'horizontal' | 'vertical';
14
19
  }
15
20
  /**
16
21
  * An object that allows to identify a single bar.
@@ -21,5 +26,5 @@ export type BarItemIdentifier = {
21
26
  seriesId: DefaultizedBarSeriesType['id'];
22
27
  dataIndex: number;
23
28
  };
24
- export interface DefaultizedBarSeriesType extends DefaultizedProps<BarSeriesType, CommonDefaultizedProps | 'color'> {
29
+ export interface DefaultizedBarSeriesType extends DefaultizedProps<BarSeriesType, CommonDefaultizedProps | 'color' | 'layout'> {
25
30
  }
@@ -1,6 +1,28 @@
1
1
  import { DefaultizedProps } from '../helpers';
2
2
  import { CartesianSeriesType, CommonDefaultizedProps, CommonSeriesType, StackableSeriesType } from './common';
3
3
  export type CurveType = 'catmullRom' | 'linear' | 'monotoneX' | 'monotoneY' | 'natural' | 'step' | 'stepBefore' | 'stepAfter';
4
+ export interface ShowMarkParams {
5
+ /**
6
+ * The item index.
7
+ */
8
+ index: number;
9
+ /**
10
+ * The x coordinate in the SVG.
11
+ */
12
+ x: number;
13
+ /**
14
+ * The y coordinate in the SVG.
15
+ */
16
+ y: number;
17
+ /**
18
+ * The item position value. It likely comes from the axis `data` property.
19
+ */
20
+ position: number | Date;
21
+ /**
22
+ * The item value. It comes from the series `data` property.
23
+ */
24
+ value: number;
25
+ }
4
26
  export interface LineSeriesType extends CommonSeriesType<number>, CartesianSeriesType, StackableSeriesType {
5
27
  type: 'line';
6
28
  /**
@@ -15,6 +37,17 @@ export interface LineSeriesType extends CommonSeriesType<number>, CartesianSerie
15
37
  area?: boolean;
16
38
  label?: string;
17
39
  curve?: CurveType;
40
+ /**
41
+ * Define which items of the series should display a mark.
42
+ * If can be a boolean that applies to all items.
43
+ * Or a callback that gets some item properties and returns true if the item should be displayed.
44
+ */
45
+ showMark?: boolean | ((params: ShowMarkParams) => boolean);
46
+ /**
47
+ * Do not render the line highlight item if set to `true`.
48
+ * @default false
49
+ */
50
+ disableHighlight?: boolean;
18
51
  }
19
52
  /**
20
53
  * An object that allows to identify a single line.
@@ -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,22 +37,34 @@ 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 => (s.data ?? dataset ?? []).length))
45
+ }, (_, index) => index)
46
+ };
47
+ const defaultizedAxisHighlight = _extends({}, hasHorizontalSeries ? {
48
+ y: 'band'
49
+ } : {
50
+ x: 'band'
51
+ }, axisHighlight);
39
52
  return /*#__PURE__*/_jsxs(ResponsiveChartContainer, {
40
53
  ref: ref,
41
54
  series: series.map(s => _extends({
42
55
  type: 'bar'
43
- }, s)),
56
+ }, s, {
57
+ layout: hasHorizontalSeries ? 'horizontal' : 'vertical'
58
+ })),
44
59
  width: width,
45
60
  height: height,
46
61
  margin: margin,
47
- xAxis: xAxis ?? [{
48
- id: DEFAULT_X_AXIS_KEY,
49
- scaleType: 'band',
50
- data: Array.from({
51
- length: Math.max(...series.map(s => (s.data ?? dataset ?? []).length))
52
- }, (_, index) => index)
53
- }],
54
- yAxis: yAxis,
62
+ xAxis: xAxis ?? (hasHorizontalSeries ? undefined : [_extends({
63
+ id: DEFAULT_X_AXIS_KEY
64
+ }, defaultAxisConfig)]),
65
+ yAxis: yAxis ?? (hasHorizontalSeries ? [_extends({
66
+ id: DEFAULT_Y_AXIS_KEY
67
+ }, defaultAxisConfig)] : undefined),
55
68
  colors: colors,
56
69
  dataset: dataset,
57
70
  sx: sx,
@@ -72,9 +85,7 @@ const BarChart = /*#__PURE__*/React.forwardRef(function BarChart(props, ref) {
72
85
  }), /*#__PURE__*/_jsx(ChartsLegend, _extends({}, legend, {
73
86
  slots: slots,
74
87
  slotProps: slotProps
75
- })), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({
76
- x: "band"
77
- }, axisHighlight)), /*#__PURE__*/_jsx(ChartsTooltip, _extends({}, tooltip, {
88
+ })), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, defaultizedAxisHighlight)), /*#__PURE__*/_jsx(ChartsTooltip, _extends({}, tooltip, {
78
89
  slots: slots,
79
90
  slotProps: slotProps
80
91
  })), /*#__PURE__*/_jsx(ChartsClipPath, {
@@ -89,7 +100,7 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
89
100
  // ----------------------------------------------------------------------
90
101
  axisHighlight: PropTypes.shape({
91
102
  x: PropTypes.oneOf(['band', 'line', 'none']),
92
- y: PropTypes.oneOf(['line', 'none'])
103
+ y: PropTypes.oneOf(['band', 'line', 'none'])
93
104
  }),
94
105
  /**
95
106
  * Indicate which axis to display the bottom of the charts.
@@ -124,6 +135,7 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
124
135
  desc: PropTypes.string,
125
136
  disableAxisListener: PropTypes.bool,
126
137
  height: PropTypes.number,
138
+ layout: PropTypes.oneOf(['horizontal', 'vertical']),
127
139
  /**
128
140
  * Indicate which axis to display the left of the charts.
129
141
  * Can be a string (the id of the axis) or an object `ChartsYAxisProps`.
@@ -204,6 +216,7 @@ process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
204
216
  }),
205
217
  id: PropTypes.string,
206
218
  label: PropTypes.string,
219
+ layout: PropTypes.oneOf(['horizontal', 'vertical']),
207
220
  stack: PropTypes.string,
208
221
  stackOffset: PropTypes.oneOf(['diverging', 'expand', 'none', 'silhouette', 'wiggle']),
209
222
  stackOrder: PropTypes.oneOf(['appearance', 'ascending', 'descending', 'insideOut', 'none', 'reverse']),
@@ -61,27 +61,37 @@ function BarPlot(props) {
61
61
  const yAxisKey = series[seriesId].yAxisKey ?? defaultYAxisId;
62
62
  const xAxisConfig = xAxis[xAxisKey];
63
63
  const yAxisConfig = yAxis[yAxisKey];
64
- if (!isBandScaleConfig(xAxisConfig)) {
65
- throw new Error(`Axis with id "${xAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
66
- }
67
- if (xAxis[xAxisKey].data === undefined) {
68
- throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
64
+ const verticalLayout = series[seriesId].layout === 'vertical';
65
+ let baseScaleConfig;
66
+ if (verticalLayout) {
67
+ if (!isBandScaleConfig(xAxisConfig)) {
68
+ throw new Error(`Axis with id "${xAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
69
+ }
70
+ if (xAxis[xAxisKey].data === undefined) {
71
+ throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
72
+ }
73
+ baseScaleConfig = xAxisConfig;
74
+ } else {
75
+ if (!isBandScaleConfig(yAxisConfig)) {
76
+ throw new Error(`Axis with id "${yAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
77
+ }
78
+ if (yAxis[yAxisKey].data === undefined) {
79
+ throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
80
+ }
81
+ baseScaleConfig = yAxisConfig;
69
82
  }
70
83
  const xScale = xAxisConfig.scale;
71
84
  const yScale = yAxisConfig.scale;
72
-
73
- // Currently assuming all bars are vertical
74
- const bandWidth = xScale.bandwidth();
85
+ const bandWidth = baseScaleConfig.scale.bandwidth();
75
86
  const {
76
87
  barWidth,
77
88
  offset
78
89
  } = getBandSize({
79
90
  bandWidth,
80
91
  numberOfGroups: stackingGroups.length,
81
- gapRatio: xAxisConfig.barGapRatio
92
+ gapRatio: baseScaleConfig.barGapRatio
82
93
  });
83
-
84
- // @ts-ignore TODO: fix when adding a correct API for customisation
94
+ const barOffset = groupIndex * (barWidth + offset);
85
95
  const {
86
96
  stackedData,
87
97
  color
@@ -92,10 +102,10 @@ function BarPlot(props) {
92
102
  return /*#__PURE__*/_jsx(BarElement, _extends({
93
103
  id: seriesId,
94
104
  dataIndex: dataIndex,
95
- x: xScale(xAxis[xAxisKey].data?.[dataIndex]) + groupIndex * (barWidth + offset),
96
- y: yScale(value),
97
- height: yScale(baseline) - yScale(value),
98
- width: barWidth,
105
+ x: verticalLayout ? xScale(xAxis[xAxisKey].data?.[dataIndex]) + barOffset : xScale(baseline),
106
+ y: verticalLayout ? yScale(value) : yScale(yAxis[yAxisKey].data?.[dataIndex]) + barOffset,
107
+ height: verticalLayout ? Math.abs(yScale(baseline) - yScale(value)) : barWidth,
108
+ width: verticalLayout ? barWidth : Math.abs(xScale(baseline) - xScale(value)),
99
109
  color: color,
100
110
  highlightScope: series[seriesId].highlightScope
101
111
  }, props), `${seriesId}-${dataIndex}`);
@@ -1,4 +1,4 @@
1
- export const getExtremumX = params => {
1
+ const getBaseExtremum = params => {
2
2
  const {
3
3
  axis
4
4
  } = params;
@@ -6,7 +6,7 @@ export const getExtremumX = params => {
6
6
  const maxX = Math.max(...(axis.data ?? []));
7
7
  return [minX, maxX];
8
8
  };
9
- export const getExtremumY = params => {
9
+ const getValueExtremum = params => {
10
10
  const {
11
11
  series,
12
12
  axis,
@@ -16,4 +16,20 @@ export const getExtremumY = params => {
16
16
  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]);
17
17
  return [acc[0] === null ? seriesMin : Math.min(seriesMin, acc[0]), acc[1] === null ? seriesMax : Math.max(seriesMax, acc[1])];
18
18
  }, [null, null]);
19
+ };
20
+ export const getExtremumX = params => {
21
+ // Notice that bar should be all horizontal or all vertical.
22
+ // Don't think it's a problem for now
23
+ const isHorizontal = Object.keys(params.series).some(seriesId => params.series[seriesId].layout === 'horizontal');
24
+ if (isHorizontal) {
25
+ return getValueExtremum(params);
26
+ }
27
+ return getBaseExtremum(params);
28
+ };
29
+ export const getExtremumY = params => {
30
+ const isHorizontal = Object.keys(params.series).some(seriesId => params.series[seriesId].layout === 'horizontal');
31
+ if (isHorizontal) {
32
+ return getBaseExtremum(params);
33
+ }
34
+ return getValueExtremum(params);
19
35
  };
@@ -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 };
@@ -71,29 +71,33 @@ export function ChartsAxisTooltipContent(props) {
71
71
  sx,
72
72
  classes
73
73
  } = props;
74
- const dataIndex = axisData.x && axisData.x.index;
75
- const axisValue = axisData.x && axisData.x.value;
74
+ const isXaxis = (axisData.x && axisData.x.index) !== undefined;
75
+ const dataIndex = isXaxis ? axisData.x && axisData.x.index : axisData.y && axisData.y.index;
76
+ const axisValue = isXaxis ? axisData.x && axisData.x.value : axisData.y && axisData.y.value;
76
77
  const {
77
78
  xAxisIds,
78
- xAxis
79
+ xAxis,
80
+ yAxisIds,
81
+ yAxis
79
82
  } = React.useContext(CartesianContext);
80
83
  const series = React.useContext(SeriesContext);
81
- const USED_X_AXIS_ID = xAxisIds[0];
84
+ const USED_AXIS_ID = isXaxis ? xAxisIds[0] : yAxisIds[0];
82
85
  const relevantSeries = React.useMemo(() => {
83
86
  const rep = [];
84
87
  Object.keys(series).filter(seriesType => ['bar', 'line', 'scatter'].includes(seriesType)).forEach(seriesType => {
85
88
  series[seriesType].seriesOrder.forEach(seriesId => {
86
- const axisKey = series[seriesType].series[seriesId].xAxisKey;
87
- if (axisKey === undefined || axisKey === USED_X_AXIS_ID) {
89
+ const item = series[seriesType].series[seriesId];
90
+ const axisKey = isXaxis ? item.xAxisKey : item.yAxisKey;
91
+ if (axisKey === undefined || axisKey === USED_AXIS_ID) {
88
92
  rep.push(series[seriesType].series[seriesId]);
89
93
  }
90
94
  });
91
95
  });
92
96
  return rep;
93
- }, [USED_X_AXIS_ID, series]);
97
+ }, [USED_AXIS_ID, isXaxis, series]);
94
98
  const relevantAxis = React.useMemo(() => {
95
- return xAxis[USED_X_AXIS_ID];
96
- }, [USED_X_AXIS_ID, xAxis]);
99
+ return isXaxis ? xAxis[USED_AXIS_ID] : yAxis[USED_AXIS_ID];
100
+ }, [USED_AXIS_ID, isXaxis, xAxis, yAxis]);
97
101
  const Content = content ?? DefaultChartsAxisContent;
98
102
  return /*#__PURE__*/_jsx(Content, {
99
103
  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,
@@ -76,13 +79,16 @@ const LineChart = /*#__PURE__*/React.forwardRef(function LineChart(props, ref) {
76
79
  bottomAxis: bottomAxis,
77
80
  slots: slots,
78
81
  slotProps: slotProps
79
- }), /*#__PURE__*/_jsx(MarkPlot, {
82
+ }), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, axisHighlight)), /*#__PURE__*/_jsx(MarkPlot, {
83
+ slots: slots,
84
+ slotProps: slotProps
85
+ }), /*#__PURE__*/_jsx(LineHighlightPlot, {
80
86
  slots: slots,
81
87
  slotProps: slotProps
82
88
  }), /*#__PURE__*/_jsx(ChartsLegend, _extends({}, legend, {
83
89
  slots: slots,
84
90
  slotProps: slotProps
85
- })), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, axisHighlight)), /*#__PURE__*/_jsx(ChartsTooltip, _extends({}, tooltip)), /*#__PURE__*/_jsx(ChartsClipPath, {
91
+ })), /*#__PURE__*/_jsx(ChartsTooltip, _extends({}, tooltip)), /*#__PURE__*/_jsx(ChartsClipPath, {
86
92
  id: clipPathId
87
93
  }), children]
88
94
  });
@@ -94,7 +100,7 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
94
100
  // ----------------------------------------------------------------------
95
101
  axisHighlight: PropTypes.shape({
96
102
  x: PropTypes.oneOf(['band', 'line', 'none']),
97
- y: PropTypes.oneOf(['line', 'none'])
103
+ y: PropTypes.oneOf(['band', 'line', 'none'])
98
104
  }),
99
105
  /**
100
106
  * Indicate which axis to display the bottom of the charts.
@@ -128,6 +134,10 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
128
134
  dataset: PropTypes.arrayOf(PropTypes.object),
129
135
  desc: PropTypes.string,
130
136
  disableAxisListener: PropTypes.bool,
137
+ /**
138
+ * If `true`, render the line highlight item.
139
+ */
140
+ disableLineItemHighlight: PropTypes.bool,
131
141
  height: PropTypes.number,
132
142
  /**
133
143
  * Indicate which axis to display the left of the charts.
@@ -205,12 +215,14 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
205
215
  curve: PropTypes.oneOf(['catmullRom', 'linear', 'monotoneX', 'monotoneY', 'natural', 'step', 'stepAfter', 'stepBefore']),
206
216
  data: PropTypes.arrayOf(PropTypes.number),
207
217
  dataKey: PropTypes.string,
218
+ disableHighlight: PropTypes.bool,
208
219
  highlightScope: PropTypes.shape({
209
220
  faded: PropTypes.oneOf(['global', 'none', 'series']),
210
221
  highlighted: PropTypes.oneOf(['item', 'none', 'series'])
211
222
  }),
212
223
  id: PropTypes.string,
213
224
  label: PropTypes.string,
225
+ showMark: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
214
226
  stack: PropTypes.string,
215
227
  stackOffset: PropTypes.oneOf(['diverging', 'expand', 'none', 'silhouette', 'wiggle']),
216
228
  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 };