@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.
- package/BarChart/BarChart.d.ts +1 -0
- package/BarChart/BarChart.js +26 -13
- package/BarChart/BarPlot.js +25 -15
- package/BarChart/extremums.js +19 -3
- package/BarChart/formatter.js +3 -1
- package/CHANGELOG.md +154 -31
- package/ChartsAxisHighlight/ChartsAxisHighlight.d.ts +3 -2
- package/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
- package/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
- package/LineChart/LineChart.js +1 -1
- package/LineChart/MarkPlot.js +7 -4
- package/PieChart/PieChart.js +1 -1
- package/ScatterChart/ScatterChart.js +1 -1
- package/SparkLineChart/SparkLineChart.js +1 -1
- package/context/CartesianContextProvider.js +4 -4
- package/esm/BarChart/BarChart.js +30 -17
- package/esm/BarChart/BarPlot.js +26 -16
- package/esm/BarChart/extremums.js +18 -2
- package/esm/BarChart/formatter.js +3 -1
- package/esm/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
- package/esm/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
- package/esm/LineChart/LineChart.js +1 -1
- package/esm/LineChart/MarkPlot.js +7 -4
- package/esm/PieChart/PieChart.js +1 -1
- package/esm/ScatterChart/ScatterChart.js +1 -1
- package/esm/SparkLineChart/SparkLineChart.js +1 -1
- package/esm/context/CartesianContextProvider.js +4 -4
- package/esm/hooks/useAxisEvents.js +21 -38
- package/esm/hooks/useTicks.js +2 -2
- package/hooks/useAxisEvents.js +21 -38
- package/hooks/useTicks.js +2 -2
- package/index.js +1 -1
- package/internals/defaultizeColor.d.ts +1 -0
- package/legacy/BarChart/BarChart.js +35 -20
- package/legacy/BarChart/BarPlot.js +26 -16
- package/legacy/BarChart/extremums.js +22 -2
- package/legacy/BarChart/formatter.js +3 -1
- package/legacy/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
- package/legacy/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
- package/legacy/LineChart/LineChart.js +1 -1
- package/legacy/LineChart/MarkPlot.js +5 -2
- package/legacy/PieChart/PieChart.js +1 -1
- package/legacy/ScatterChart/ScatterChart.js +1 -1
- package/legacy/SparkLineChart/SparkLineChart.js +1 -1
- package/legacy/context/CartesianContextProvider.js +4 -4
- package/legacy/hooks/useAxisEvents.js +21 -37
- package/legacy/hooks/useTicks.js +2 -2
- package/legacy/index.js +1 -1
- package/models/seriesType/bar.d.ts +6 -1
- package/modern/BarChart/BarChart.js +27 -14
- package/modern/BarChart/BarPlot.js +25 -15
- package/modern/BarChart/extremums.js +18 -2
- package/modern/BarChart/formatter.js +3 -1
- package/modern/ChartsAxisHighlight/ChartsAxisHighlight.js +11 -3
- package/modern/ChartsTooltip/ChartsAxisTooltipContent.js +13 -9
- package/modern/LineChart/LineChart.js +1 -1
- package/modern/LineChart/MarkPlot.js +7 -4
- package/modern/PieChart/PieChart.js +1 -1
- package/modern/ScatterChart/ScatterChart.js +1 -1
- package/modern/SparkLineChart/SparkLineChart.js +1 -1
- package/modern/context/CartesianContextProvider.js +4 -4
- package/modern/hooks/useAxisEvents.js +21 -38
- package/modern/hooks/useTicks.js +2 -2
- package/modern/index.js +1 -1
- 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
|
|
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
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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 -
|
|
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 ===
|
|
55
|
+
if (index === axisData.length - 1 ||
|
|
72
56
|
// @ts-ignore
|
|
73
|
-
Math.abs(value - v) < Math.abs(value -
|
|
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 ?
|
|
64
|
+
value: closestIndex !== undefined && closestIndex >= 0 ? axisData[closestIndex] : value,
|
|
81
65
|
index: closestIndex
|
|
82
66
|
};
|
|
83
67
|
}
|
|
84
|
-
var dataIndex =
|
|
85
|
-
if (dataIndex < 0 || dataIndex >=
|
|
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:
|
|
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 =
|
|
129
|
-
var newStateY =
|
|
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: {
|
package/legacy/hooks/useTicks.js
CHANGED
|
@@ -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
|
|
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:
|
|
29
|
+
offset: scale(value) - (scale.step() - scale.bandwidth()) / 2,
|
|
30
30
|
labelOffset: scale.step() / 2
|
|
31
31
|
};
|
|
32
32
|
})), [{
|
package/legacy/index.js
CHANGED
|
@@ -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
|
}
|
|
@@ -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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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:
|
|
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]) +
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
|
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]} ${
|
|
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
|
|
75
|
-
const
|
|
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
|
|
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
|
|
87
|
-
|
|
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
|
-
}, [
|
|
97
|
+
}, [USED_AXIS_ID, isXaxis, series]);
|
|
94
98
|
const relevantAxis = React.useMemo(() => {
|
|
95
|
-
return xAxis[
|
|
96
|
-
}, [
|
|
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,
|
|
@@ -94,7 +94,7 @@ process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
|
|
|
94
94
|
// ----------------------------------------------------------------------
|
|
95
95
|
axisHighlight: PropTypes.shape({
|
|
96
96
|
x: PropTypes.oneOf(['band', 'line', 'none']),
|
|
97
|
-
y: PropTypes.oneOf(['line', 'none'])
|
|
97
|
+
y: PropTypes.oneOf(['band', 'line', 'none'])
|
|
98
98
|
}),
|
|
99
99
|
/**
|
|
100
100
|
* 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';
|
|
@@ -8,9 +10,10 @@ import { getValueToPositionMapper } from '../hooks/useScale';
|
|
|
8
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
11
|
function MarkPlot(props) {
|
|
10
12
|
const {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
slots,
|
|
14
|
+
slotProps
|
|
15
|
+
} = props,
|
|
16
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
14
17
|
const seriesData = React.useContext(SeriesContext).line;
|
|
15
18
|
const axisData = React.useContext(CartesianContext);
|
|
16
19
|
const Mark = slots?.mark ?? MarkElement;
|
|
@@ -29,7 +32,7 @@ function MarkPlot(props) {
|
|
|
29
32
|
} = axisData;
|
|
30
33
|
const defaultXAxisId = xAxisIds[0];
|
|
31
34
|
const defaultYAxisId = yAxisIds[0];
|
|
32
|
-
return /*#__PURE__*/_jsx("g", _extends({},
|
|
35
|
+
return /*#__PURE__*/_jsx("g", _extends({}, other, {
|
|
33
36
|
children: stackingGroups.flatMap(({
|
|
34
37
|
ids: groupIds
|
|
35
38
|
}) => {
|
|
@@ -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,
|
|
@@ -150,17 +150,17 @@ function CartesianContextProvider({
|
|
|
150
150
|
const range = [drawingArea.top + drawingArea.height, drawingArea.top];
|
|
151
151
|
if (isBandScaleConfig(axis)) {
|
|
152
152
|
const categoryGapRatio = axis.categoryGapRatio ?? DEFAULT_CATEGORY_GAP_RATIO;
|
|
153
|
-
|
|
153
|
+
completedYAxis[axis.id] = _extends({
|
|
154
154
|
categoryGapRatio,
|
|
155
155
|
barGapRatio: 0
|
|
156
156
|
}, axis, {
|
|
157
|
-
scale: scaleBand(axis.data, range).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
|
|
157
|
+
scale: scaleBand(axis.data, [range[1], range[0]]).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
|
|
158
158
|
ticksNumber: axis.data.length
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
if (isPointScaleConfig(axis)) {
|
|
162
|
-
|
|
163
|
-
scale: scalePoint(axis.data, range),
|
|
162
|
+
completedYAxis[axis.id] = _extends({}, axis, {
|
|
163
|
+
scale: scalePoint(axis.data, [range[1], range[0]]),
|
|
164
164
|
ticksNumber: axis.data.length
|
|
165
165
|
});
|
|
166
166
|
}
|
|
@@ -33,66 +33,49 @@ export const useAxisEvents = disableAxisListener => {
|
|
|
33
33
|
if (element === null || disableAxisListener) {
|
|
34
34
|
return () => {};
|
|
35
35
|
}
|
|
36
|
-
const
|
|
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
|
|
64
|
-
data:
|
|
65
|
-
} =
|
|
66
|
-
if (!isBandScale(
|
|
67
|
-
const value =
|
|
68
|
-
|
|
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?.findIndex((v, index) => {
|
|
69
52
|
if (v > value) {
|
|
70
53
|
// @ts-ignore
|
|
71
|
-
if (index === 0 || Math.abs(value - v) <= Math.abs(value -
|
|
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 ===
|
|
59
|
+
if (index === axisData.length - 1 ||
|
|
77
60
|
// @ts-ignore
|
|
78
|
-
Math.abs(value - v) < Math.abs(value -
|
|
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 ?
|
|
68
|
+
value: closestIndex !== undefined && closestIndex >= 0 ? axisData[closestIndex] : value,
|
|
86
69
|
index: closestIndex
|
|
87
70
|
};
|
|
88
71
|
}
|
|
89
|
-
const dataIndex =
|
|
90
|
-
if (dataIndex < 0 || dataIndex >=
|
|
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:
|
|
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 =
|
|
134
|
-
const newStateY =
|
|
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: {
|
package/modern/hooks/useTicks.js
CHANGED
|
@@ -25,9 +25,9 @@ function useTicks(options) {
|
|
|
25
25
|
const domain = scale.domain();
|
|
26
26
|
if (scale.bandwidth() > 0) {
|
|
27
27
|
// scale type = 'band'
|
|
28
|
-
return [...domain.map(
|
|
28
|
+
return [...domain.map(value => ({
|
|
29
29
|
formattedValue: valueFormatter?.(value) ?? value,
|
|
30
|
-
offset:
|
|
30
|
+
offset: scale(value) - (scale.step() - scale.bandwidth()) / 2,
|
|
31
31
|
labelOffset: scale.step() / 2
|
|
32
32
|
})), {
|
|
33
33
|
formattedValue: undefined,
|
package/modern/index.js
CHANGED