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

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 (65) 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 +154 -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/LineChart.js +1 -1
  11. package/LineChart/MarkPlot.js +7 -4
  12. package/PieChart/PieChart.js +1 -1
  13. package/ScatterChart/ScatterChart.js +1 -1
  14. package/SparkLineChart/SparkLineChart.js +1 -1
  15. package/context/CartesianContextProvider.js +4 -4
  16. package/esm/BarChart/BarChart.js +30 -17
  17. package/esm/BarChart/BarPlot.js +26 -16
  18. package/esm/BarChart/extremums.js +18 -2
  19. package/esm/BarChart/formatter.js +3 -1
  20. package/esm/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
  21. package/esm/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
  22. package/esm/LineChart/LineChart.js +1 -1
  23. package/esm/LineChart/MarkPlot.js +7 -4
  24. package/esm/PieChart/PieChart.js +1 -1
  25. package/esm/ScatterChart/ScatterChart.js +1 -1
  26. package/esm/SparkLineChart/SparkLineChart.js +1 -1
  27. package/esm/context/CartesianContextProvider.js +4 -4
  28. package/esm/hooks/useAxisEvents.js +21 -38
  29. package/esm/hooks/useTicks.js +2 -2
  30. package/hooks/useAxisEvents.js +21 -38
  31. package/hooks/useTicks.js +2 -2
  32. package/index.js +1 -1
  33. package/internals/defaultizeColor.d.ts +1 -0
  34. package/legacy/BarChart/BarChart.js +35 -20
  35. package/legacy/BarChart/BarPlot.js +26 -16
  36. package/legacy/BarChart/extremums.js +22 -2
  37. package/legacy/BarChart/formatter.js +3 -1
  38. package/legacy/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
  39. package/legacy/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
  40. package/legacy/LineChart/LineChart.js +1 -1
  41. package/legacy/LineChart/MarkPlot.js +5 -2
  42. package/legacy/PieChart/PieChart.js +1 -1
  43. package/legacy/ScatterChart/ScatterChart.js +1 -1
  44. package/legacy/SparkLineChart/SparkLineChart.js +1 -1
  45. package/legacy/context/CartesianContextProvider.js +4 -4
  46. package/legacy/hooks/useAxisEvents.js +21 -37
  47. package/legacy/hooks/useTicks.js +2 -2
  48. package/legacy/index.js +1 -1
  49. package/models/seriesType/bar.d.ts +6 -1
  50. package/modern/BarChart/BarChart.js +27 -14
  51. package/modern/BarChart/BarPlot.js +25 -15
  52. package/modern/BarChart/extremums.js +18 -2
  53. package/modern/BarChart/formatter.js +3 -1
  54. package/modern/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
  55. package/modern/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
  56. package/modern/LineChart/LineChart.js +1 -1
  57. package/modern/LineChart/MarkPlot.js +7 -4
  58. package/modern/PieChart/PieChart.js +1 -1
  59. package/modern/ScatterChart/ScatterChart.js +1 -1
  60. package/modern/SparkLineChart/SparkLineChart.js +1 -1
  61. package/modern/context/CartesianContextProvider.js +4 -4
  62. package/modern/hooks/useAxisEvents.js +21 -38
  63. package/modern/hooks/useTicks.js +2 -2
  64. package/modern/index.js +1 -1
  65. package/package.json +4 -4
@@ -80,29 +80,33 @@ function ChartsAxisTooltipContent(props) {
80
80
  sx,
81
81
  classes
82
82
  } = props;
83
- const dataIndex = axisData.x && axisData.x.index;
84
- const axisValue = axisData.x && axisData.x.value;
83
+ const isXaxis = (axisData.x && axisData.x.index) !== undefined;
84
+ const dataIndex = isXaxis ? axisData.x && axisData.x.index : axisData.y && axisData.y.index;
85
+ const axisValue = isXaxis ? axisData.x && axisData.x.value : axisData.y && axisData.y.value;
85
86
  const {
86
87
  xAxisIds,
87
- xAxis
88
+ xAxis,
89
+ yAxisIds,
90
+ yAxis
88
91
  } = React.useContext(_CartesianContextProvider.CartesianContext);
89
92
  const series = React.useContext(_SeriesContextProvider.SeriesContext);
90
- const USED_X_AXIS_ID = xAxisIds[0];
93
+ const USED_AXIS_ID = isXaxis ? xAxisIds[0] : yAxisIds[0];
91
94
  const relevantSeries = React.useMemo(() => {
92
95
  const rep = [];
93
96
  Object.keys(series).filter(seriesType => ['bar', 'line', 'scatter'].includes(seriesType)).forEach(seriesType => {
94
97
  series[seriesType].seriesOrder.forEach(seriesId => {
95
- const axisKey = series[seriesType].series[seriesId].xAxisKey;
96
- if (axisKey === undefined || axisKey === USED_X_AXIS_ID) {
98
+ const item = series[seriesType].series[seriesId];
99
+ const axisKey = isXaxis ? item.xAxisKey : item.yAxisKey;
100
+ if (axisKey === undefined || axisKey === USED_AXIS_ID) {
97
101
  rep.push(series[seriesType].series[seriesId]);
98
102
  }
99
103
  });
100
104
  });
101
105
  return rep;
102
- }, [USED_X_AXIS_ID, series]);
106
+ }, [USED_AXIS_ID, isXaxis, series]);
103
107
  const relevantAxis = React.useMemo(() => {
104
- return xAxis[USED_X_AXIS_ID];
105
- }, [USED_X_AXIS_ID, xAxis]);
108
+ return isXaxis ? xAxis[USED_AXIS_ID] : yAxis[USED_AXIS_ID];
109
+ }, [USED_AXIS_ID, isXaxis, xAxis, yAxis]);
106
110
  const Content = content ?? DefaultChartsAxisContent;
107
111
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Content, {
108
112
  axisData: axisData,
@@ -103,7 +103,7 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
103
103
  // ----------------------------------------------------------------------
104
104
  axisHighlight: _propTypes.default.shape({
105
105
  x: _propTypes.default.oneOf(['band', 'line', 'none']),
106
- y: _propTypes.default.oneOf(['line', 'none'])
106
+ y: _propTypes.default.oneOf(['band', 'line', 'none'])
107
107
  }),
108
108
  /**
109
109
  * Indicate which axis to display the bottom of the charts.
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.MarkPlot = MarkPlot;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
9
10
  var React = _interopRequireWildcard(require("react"));
10
11
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
12
  var _SeriesContextProvider = require("../context/SeriesContextProvider");
@@ -13,13 +14,15 @@ var _CartesianContextProvider = require("../context/CartesianContextProvider");
13
14
  var _MarkElement = require("./MarkElement");
14
15
  var _useScale = require("../hooks/useScale");
15
16
  var _jsxRuntime = require("react/jsx-runtime");
17
+ const _excluded = ["slots", "slotProps"];
16
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); }
17
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; }
18
20
  function MarkPlot(props) {
19
21
  const {
20
- slots,
21
- slotProps
22
- } = props;
22
+ slots,
23
+ slotProps
24
+ } = props,
25
+ other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
23
26
  const seriesData = React.useContext(_SeriesContextProvider.SeriesContext).line;
24
27
  const axisData = React.useContext(_CartesianContextProvider.CartesianContext);
25
28
  const Mark = slots?.mark ?? _MarkElement.MarkElement;
@@ -38,7 +41,7 @@ function MarkPlot(props) {
38
41
  } = axisData;
39
42
  const defaultXAxisId = xAxisIds[0];
40
43
  const defaultYAxisId = yAxisIds[0];
41
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("g", (0, _extends2.default)({}, props, {
44
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("g", (0, _extends2.default)({}, other, {
42
45
  children: stackingGroups.flatMap(({
43
46
  ids: groupIds
44
47
  }) => {
@@ -96,7 +96,7 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
96
96
  // ----------------------------------------------------------------------
97
97
  axisHighlight: _propTypes.default.shape({
98
98
  x: _propTypes.default.oneOf(['band', 'line', 'none']),
99
- y: _propTypes.default.oneOf(['line', 'none'])
99
+ y: _propTypes.default.oneOf(['band', 'line', 'none'])
100
100
  }),
101
101
  /**
102
102
  * Indicate which axis to display the bottom of the charts.
@@ -79,7 +79,7 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
79
79
  // ----------------------------------------------------------------------
80
80
  axisHighlight: _propTypes.default.shape({
81
81
  x: _propTypes.default.oneOf(['band', 'line', 'none']),
82
- y: _propTypes.default.oneOf(['line', 'none'])
82
+ y: _propTypes.default.oneOf(['band', 'line', 'none'])
83
83
  }),
84
84
  /**
85
85
  * Indicate which axis to display the bottom of the charts.
@@ -111,7 +111,7 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes = {
111
111
  area: _propTypes.default.bool,
112
112
  axisHighlight: _propTypes.default.shape({
113
113
  x: _propTypes.default.oneOf(['band', 'line', 'none']),
114
- y: _propTypes.default.oneOf(['line', 'none'])
114
+ y: _propTypes.default.oneOf(['band', 'line', 'none'])
115
115
  }),
116
116
  children: _propTypes.default.node,
117
117
  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,
@@ -97,7 +97,7 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
97
97
  // ----------------------------------------------------------------------
98
98
  axisHighlight: PropTypes.shape({
99
99
  x: PropTypes.oneOf(['band', 'line', 'none']),
100
- y: PropTypes.oneOf(['line', 'none'])
100
+ y: PropTypes.oneOf(['band', 'line', 'none'])
101
101
  }),
102
102
  /**
103
103
  * Indicate which axis to display the bottom of the charts.
@@ -1,4 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["slots", "slotProps"];
2
4
  import * as React from 'react';
3
5
  import PropTypes from 'prop-types';
4
6
  import { SeriesContext } from '../context/SeriesContextProvider';
@@ -9,9 +11,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
9
11
  function MarkPlot(props) {
10
12
  var _slots$mark;
11
13
  const {
12
- slots,
13
- slotProps
14
- } = props;
14
+ slots,
15
+ slotProps
16
+ } = props,
17
+ other = _objectWithoutPropertiesLoose(props, _excluded);
15
18
  const seriesData = React.useContext(SeriesContext).line;
16
19
  const axisData = React.useContext(CartesianContext);
17
20
  const Mark = (_slots$mark = slots == null ? void 0 : slots.mark) != null ? _slots$mark : MarkElement;
@@ -30,7 +33,7 @@ function MarkPlot(props) {
30
33
  } = axisData;
31
34
  const defaultXAxisId = xAxisIds[0];
32
35
  const defaultYAxisId = yAxisIds[0];
33
- return /*#__PURE__*/_jsx("g", _extends({}, props, {
36
+ return /*#__PURE__*/_jsx("g", _extends({}, other, {
34
37
  children: stackingGroups.flatMap(({
35
38
  ids: groupIds
36
39
  }) => {
@@ -88,7 +88,7 @@ process.env.NODE_ENV !== "production" ? PieChart.propTypes = {
88
88
  // ----------------------------------------------------------------------
89
89
  axisHighlight: PropTypes.shape({
90
90
  x: PropTypes.oneOf(['band', 'line', 'none']),
91
- y: PropTypes.oneOf(['line', 'none'])
91
+ y: PropTypes.oneOf(['band', 'line', 'none'])
92
92
  }),
93
93
  /**
94
94
  * Indicate which axis to display the bottom of the charts.
@@ -70,7 +70,7 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
70
70
  // ----------------------------------------------------------------------
71
71
  axisHighlight: PropTypes.shape({
72
72
  x: PropTypes.oneOf(['band', 'line', 'none']),
73
- y: PropTypes.oneOf(['line', 'none'])
73
+ y: PropTypes.oneOf(['band', 'line', 'none'])
74
74
  }),
75
75
  /**
76
76
  * Indicate which axis to display the bottom of the charts.
@@ -102,7 +102,7 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes = {
102
102
  area: PropTypes.bool,
103
103
  axisHighlight: PropTypes.shape({
104
104
  x: PropTypes.oneOf(['band', 'line', 'none']),
105
- y: PropTypes.oneOf(['line', 'none'])
105
+ y: PropTypes.oneOf(['band', 'line', 'none'])
106
106
  }),
107
107
  children: PropTypes.node,
108
108
  className: PropTypes.string,
@@ -156,17 +156,17 @@ function CartesianContextProvider({
156
156
  if (isBandScaleConfig(axis)) {
157
157
  var _axis$categoryGapRati2;
158
158
  const categoryGapRatio = (_axis$categoryGapRati2 = axis.categoryGapRatio) != null ? _axis$categoryGapRati2 : DEFAULT_CATEGORY_GAP_RATIO;
159
- completedXAxis[axis.id] = _extends({
159
+ completedYAxis[axis.id] = _extends({
160
160
  categoryGapRatio,
161
161
  barGapRatio: 0
162
162
  }, axis, {
163
- scale: scaleBand(axis.data, range).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
163
+ scale: scaleBand(axis.data, [range[1], range[0]]).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
164
164
  ticksNumber: axis.data.length
165
165
  });
166
166
  }
167
167
  if (isPointScaleConfig(axis)) {
168
- completedXAxis[axis.id] = _extends({}, axis, {
169
- scale: scalePoint(axis.data, range),
168
+ completedYAxis[axis.id] = _extends({}, axis, {
169
+ scale: scalePoint(axis.data, [range[1], range[0]]),
170
170
  ticksNumber: axis.data.length
171
171
  });
172
172
  }
@@ -33,66 +33,49 @@ export const useAxisEvents = disableAxisListener => {
33
33
  if (element === null || disableAxisListener) {
34
34
  return () => {};
35
35
  }
36
- const getUpdateY = y => {
37
- if (usedYAxis === null) {
38
- return null;
39
- }
40
- const {
41
- scale: yScale,
42
- data: yAxisData
43
- } = yAxis[usedYAxis];
44
- if (!isBandScale(yScale)) {
45
- return {
46
- value: yScale.invert(y)
47
- };
48
- }
49
- const dataIndex = Math.floor((y - yScale.range()[0]) / yScale.step());
50
- if (dataIndex < 0 || dataIndex >= yAxisData.length) {
51
- return null;
52
- }
53
- return {
54
- index: dataIndex,
55
- value: yAxisData[dataIndex]
56
- };
57
- };
58
- const getUpdateX = x => {
36
+ const getUpdate = (axisConfig, mouseValue) => {
59
37
  if (usedXAxis === null) {
60
38
  return null;
61
39
  }
62
40
  const {
63
- scale: xScale,
64
- data: xAxisData
65
- } = xAxis[usedXAxis];
66
- if (!isBandScale(xScale)) {
67
- const value = xScale.invert(x);
68
- const closestIndex = xAxisData == null ? void 0 : xAxisData.findIndex((v, index) => {
41
+ scale,
42
+ data: axisData
43
+ } = axisConfig;
44
+ if (!isBandScale(scale)) {
45
+ const value = scale.invert(mouseValue);
46
+ if (axisData === undefined) {
47
+ return {
48
+ value
49
+ };
50
+ }
51
+ const closestIndex = axisData == null ? void 0 : axisData.findIndex((v, index) => {
69
52
  if (v > value) {
70
53
  // @ts-ignore
71
- if (index === 0 || Math.abs(value - v) <= Math.abs(value - xAxisData[index - 1])) {
54
+ if (index === 0 || Math.abs(value - v) <= Math.abs(value - axisData[index - 1])) {
72
55
  return true;
73
56
  }
74
57
  }
75
58
  if (v <= value) {
76
- if (index === xAxisData.length - 1 ||
59
+ if (index === axisData.length - 1 ||
77
60
  // @ts-ignore
78
- Math.abs(value - v) < Math.abs(value - xAxisData[index + 1])) {
61
+ Math.abs(value - v) < Math.abs(value - axisData[index + 1])) {
79
62
  return true;
80
63
  }
81
64
  }
82
65
  return false;
83
66
  });
84
67
  return {
85
- value: closestIndex !== undefined && closestIndex >= 0 ? xAxisData[closestIndex] : value,
68
+ value: closestIndex !== undefined && closestIndex >= 0 ? axisData[closestIndex] : value,
86
69
  index: closestIndex
87
70
  };
88
71
  }
89
- const dataIndex = xScale.bandwidth() === 0 ? Math.floor((x - xScale.range()[0] + xScale.step() / 2) / xScale.step()) : Math.floor((x - xScale.range()[0]) / xScale.step());
90
- if (dataIndex < 0 || dataIndex >= xAxisData.length) {
72
+ const dataIndex = scale.bandwidth() === 0 ? Math.floor((mouseValue - Math.min(...scale.range()) + scale.step() / 2) / scale.step()) : Math.floor((mouseValue - Math.min(...scale.range())) / scale.step());
73
+ if (dataIndex < 0 || dataIndex >= axisData.length) {
91
74
  return null;
92
75
  }
93
76
  return {
94
77
  index: dataIndex,
95
- value: xAxisData[dataIndex]
78
+ value: axisData[dataIndex]
96
79
  };
97
80
  };
98
81
  const handleMouseOut = () => {
@@ -130,8 +113,8 @@ export const useAxisEvents = disableAxisListener => {
130
113
  });
131
114
  return;
132
115
  }
133
- const newStateX = getUpdateX(svgPt.x);
134
- const newStateY = getUpdateY(svgPt.y);
116
+ const newStateX = getUpdate(xAxis[usedXAxis], svgPt.x);
117
+ const newStateY = getUpdate(yAxis[usedYAxis], svgPt.y);
135
118
  dispatch({
136
119
  type: 'updateAxis',
137
120
  data: {