@mui/x-charts 6.0.0-alpha.15 → 6.0.0-alpha.16
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 +13 -2
- package/BarChart/BarChart.js +45 -3
- package/BarChart/BarElement.d.ts +1318 -3
- package/BarChart/BarElement.js +10 -8
- package/BarChart/BarPlot.d.ts +17 -1
- package/BarChart/BarPlot.js +152 -66
- package/CHANGELOG.md +65 -0
- package/ChartContainer/index.js +5 -2
- package/ChartsAxis/ChartsAxis.js +18 -2
- package/ChartsAxis/axisClasses.d.ts +1 -1
- package/ChartsAxisHighlight/ChartsAxisHighlight.js +2 -2
- package/ChartsClipPath/ChartsClipPath.js +2 -2
- package/ChartsLegend/ChartsLegend.d.ts +2 -1
- package/ChartsLegend/ChartsLegend.js +12 -8
- package/ChartsSurface.js +2 -2
- package/ChartsTooltip/ChartsAxisTooltipContent.js +2 -2
- package/ChartsTooltip/ChartsItemTooltipContent.js +2 -2
- package/ChartsTooltip/ChartsTooltip.js +2 -2
- package/ChartsTooltip/utils.js +2 -2
- package/ChartsXAxis/ChartsXAxis.js +123 -35
- package/ChartsYAxis/ChartsYAxis.js +38 -16
- package/LineChart/AreaElement.d.ts +10 -0
- package/LineChart/AreaElement.js +12 -2
- package/LineChart/AreaPlot.d.ts +11 -0
- package/LineChart/AreaPlot.js +13 -2
- package/LineChart/LineChart.d.ts +10 -0
- package/LineChart/LineChart.js +36 -2
- package/LineChart/LineElement.d.ts +10 -0
- package/LineChart/LineElement.js +12 -2
- package/LineChart/LineHighlightElement.d.ts +10 -0
- package/LineChart/LineHighlightElement.js +12 -2
- package/LineChart/LineHighlightPlot.d.ts +10 -0
- package/LineChart/LineHighlightPlot.js +12 -2
- package/LineChart/LinePlot.d.ts +10 -0
- package/LineChart/LinePlot.js +12 -2
- package/LineChart/MarkElement.d.ts +10 -0
- package/LineChart/MarkElement.js +12 -2
- package/LineChart/MarkPlot.d.ts +10 -0
- package/LineChart/MarkPlot.js +12 -2
- package/PieChart/PieArc.js +2 -2
- package/PieChart/PieArcLabel.js +2 -2
- package/PieChart/PieChart.d.ts +10 -0
- package/PieChart/PieChart.js +37 -2
- package/PieChart/PiePlot.d.ts +10 -0
- package/PieChart/PiePlot.js +12 -2
- package/ResponsiveChartContainer/index.js +4 -4
- package/ScatterChart/Scatter.d.ts +10 -0
- package/ScatterChart/Scatter.js +12 -2
- package/ScatterChart/ScatterChart.d.ts +10 -0
- package/ScatterChart/ScatterChart.js +36 -2
- package/ScatterChart/ScatterPlot.d.ts +10 -0
- package/ScatterChart/ScatterPlot.js +12 -2
- package/SparkLineChart/SparkLineChart.d.ts +9 -0
- package/SparkLineChart/SparkLineChart.js +16 -2
- package/context/CartesianContextProvider.js +10 -2
- package/context/DrawingProvider.js +2 -2
- package/context/HighlightProvider.js +2 -2
- package/context/InteractionProvider.js +2 -2
- package/context/SeriesContextProvider.js +2 -2
- package/esm/BarChart/BarChart.js +43 -1
- package/esm/BarChart/BarElement.js +7 -4
- package/esm/BarChart/BarPlot.js +152 -67
- package/esm/ChartContainer/index.js +3 -0
- package/esm/ChartsAxis/ChartsAxis.js +16 -0
- package/esm/ChartsLegend/ChartsLegend.js +10 -6
- package/esm/ChartsXAxis/ChartsXAxis.js +122 -34
- package/esm/ChartsYAxis/ChartsYAxis.js +36 -14
- package/esm/LineChart/AreaElement.js +10 -0
- package/esm/LineChart/AreaPlot.js +11 -0
- package/esm/LineChart/LineChart.js +34 -0
- package/esm/LineChart/LineElement.js +10 -0
- package/esm/LineChart/LineHighlightElement.js +10 -0
- package/esm/LineChart/LineHighlightPlot.js +10 -0
- package/esm/LineChart/LinePlot.js +10 -0
- package/esm/LineChart/MarkElement.js +10 -0
- package/esm/LineChart/MarkPlot.js +10 -0
- package/esm/PieChart/PieChart.js +35 -0
- package/esm/PieChart/PiePlot.js +10 -0
- package/esm/ResponsiveChartContainer/index.js +2 -2
- package/esm/ScatterChart/Scatter.js +10 -0
- package/esm/ScatterChart/ScatterChart.js +34 -0
- package/esm/ScatterChart/ScatterPlot.js +10 -0
- package/esm/SparkLineChart/SparkLineChart.js +14 -0
- package/esm/context/CartesianContextProvider.js +8 -0
- package/esm/hooks/useMounted.js +16 -0
- package/esm/hooks/useReducedMotion.js +27 -0
- package/esm/hooks/useTicks.js +12 -6
- package/esm/internals/components/ChartsText.js +17 -13
- package/esm/internals/geometry.js +36 -0
- package/hooks/useAxisEvents.js +2 -2
- package/hooks/useChartDimensions.js +2 -2
- package/hooks/useDrawingArea.js +2 -2
- package/hooks/useInteractionItemProps.js +2 -2
- package/hooks/useMounted.d.ts +1 -0
- package/hooks/useMounted.js +25 -0
- package/hooks/useReducedMotion.d.ts +8 -0
- package/hooks/useReducedMotion.js +33 -0
- package/hooks/useScale.d.ts +2 -2
- package/hooks/useScale.js +2 -2
- package/hooks/useTicks.d.ts +18 -9
- package/hooks/useTicks.js +14 -8
- package/index.js +1 -1
- package/internals/components/ChartsText.d.ts +11 -8
- package/internals/components/ChartsText.js +19 -15
- package/internals/defaultizeColor.d.ts +1 -1
- package/internals/domUtils.d.ts +0 -1
- package/internals/geometry.d.ts +9 -0
- package/internals/geometry.js +42 -0
- package/legacy/BarChart/BarChart.js +43 -1
- package/legacy/BarChart/BarElement.js +6 -3
- package/legacy/BarChart/BarPlot.js +151 -63
- package/legacy/ChartContainer/index.js +3 -0
- package/legacy/ChartsAxis/ChartsAxis.js +16 -0
- package/legacy/ChartsLegend/ChartsLegend.js +14 -7
- package/legacy/ChartsXAxis/ChartsXAxis.js +126 -36
- package/legacy/ChartsYAxis/ChartsYAxis.js +36 -14
- package/legacy/LineChart/AreaElement.js +10 -0
- package/legacy/LineChart/AreaPlot.js +11 -0
- package/legacy/LineChart/LineChart.js +34 -0
- package/legacy/LineChart/LineElement.js +10 -0
- package/legacy/LineChart/LineHighlightElement.js +10 -0
- package/legacy/LineChart/LineHighlightPlot.js +10 -0
- package/legacy/LineChart/LinePlot.js +10 -0
- package/legacy/LineChart/MarkElement.js +10 -0
- package/legacy/LineChart/MarkPlot.js +10 -0
- package/legacy/PieChart/PieChart.js +35 -0
- package/legacy/PieChart/PiePlot.js +10 -0
- package/legacy/ResponsiveChartContainer/index.js +2 -2
- package/legacy/ScatterChart/Scatter.js +10 -0
- package/legacy/ScatterChart/ScatterChart.js +34 -0
- package/legacy/ScatterChart/ScatterPlot.js +10 -0
- package/legacy/SparkLineChart/SparkLineChart.js +14 -0
- package/legacy/context/CartesianContextProvider.js +8 -0
- package/legacy/hooks/useMounted.js +21 -0
- package/legacy/hooks/useReducedMotion.js +27 -0
- package/legacy/hooks/useTicks.js +13 -6
- package/legacy/index.js +1 -1
- package/legacy/internals/components/ChartsText.js +15 -15
- package/legacy/internals/geometry.js +37 -0
- package/models/axis.d.ts +19 -2
- package/models/seriesType/line.d.ts +2 -2
- package/modern/BarChart/BarChart.js +43 -1
- package/modern/BarChart/BarElement.js +7 -4
- package/modern/BarChart/BarPlot.js +149 -65
- package/modern/ChartContainer/index.js +3 -0
- package/modern/ChartsAxis/ChartsAxis.js +16 -0
- package/modern/ChartsLegend/ChartsLegend.js +10 -6
- package/modern/ChartsXAxis/ChartsXAxis.js +122 -34
- package/modern/ChartsYAxis/ChartsYAxis.js +36 -14
- package/modern/LineChart/AreaElement.js +10 -0
- package/modern/LineChart/AreaPlot.js +11 -0
- package/modern/LineChart/LineChart.js +34 -0
- package/modern/LineChart/LineElement.js +10 -0
- package/modern/LineChart/LineHighlightElement.js +10 -0
- package/modern/LineChart/LineHighlightPlot.js +10 -0
- package/modern/LineChart/LinePlot.js +10 -0
- package/modern/LineChart/MarkElement.js +10 -0
- package/modern/LineChart/MarkPlot.js +10 -0
- package/modern/PieChart/PieChart.js +35 -0
- package/modern/PieChart/PiePlot.js +10 -0
- package/modern/ResponsiveChartContainer/index.js +2 -2
- package/modern/ScatterChart/Scatter.js +10 -0
- package/modern/ScatterChart/ScatterChart.js +34 -0
- package/modern/ScatterChart/ScatterPlot.js +10 -0
- package/modern/SparkLineChart/SparkLineChart.js +14 -0
- package/modern/context/CartesianContextProvider.js +8 -0
- package/modern/hooks/useMounted.js +16 -0
- package/modern/hooks/useReducedMotion.js +27 -0
- package/modern/hooks/useTicks.js +12 -6
- package/modern/index.js +1 -1
- package/modern/internals/components/ChartsText.js +17 -13
- package/modern/internals/geometry.js +36 -0
- package/package.json +5 -3
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
1
2
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
3
|
+
const _excluded = ["skipAnimation"];
|
|
2
4
|
import * as React from 'react';
|
|
3
5
|
import PropTypes from 'prop-types';
|
|
6
|
+
import { useTransition } from '@react-spring/web';
|
|
4
7
|
import { SeriesContext } from '../context/SeriesContextProvider';
|
|
5
8
|
import { CartesianContext } from '../context/CartesianContextProvider';
|
|
6
9
|
import { BarElement } from './BarElement';
|
|
7
10
|
import { isBandScaleConfig } from '../models/axis';
|
|
8
|
-
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
12
|
/**
|
|
10
13
|
* Solution of the equations
|
|
11
14
|
* W = barWidth * N + offset * (N-1)
|
|
@@ -15,7 +18,6 @@ import { isBandScaleConfig } from '../models/axis';
|
|
|
15
18
|
* @param gapRatio The ratio of the gap between bars over the bar width.
|
|
16
19
|
* @returns The bar width and the offset between bars.
|
|
17
20
|
*/
|
|
18
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
19
21
|
function getBandSize({
|
|
20
22
|
bandWidth: W,
|
|
21
23
|
numberOfGroups: N,
|
|
@@ -34,12 +36,13 @@ function getBandSize({
|
|
|
34
36
|
offset
|
|
35
37
|
};
|
|
36
38
|
}
|
|
37
|
-
|
|
38
|
-
const seriesData = React.useContext(SeriesContext).bar
|
|
39
|
+
const useCompletedData = () => {
|
|
40
|
+
const seriesData = React.useContext(SeriesContext).bar ?? {
|
|
41
|
+
series: {},
|
|
42
|
+
stackingGroups: [],
|
|
43
|
+
seriesOrder: []
|
|
44
|
+
};
|
|
39
45
|
const axisData = React.useContext(CartesianContext);
|
|
40
|
-
if (seriesData === undefined) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
46
|
const {
|
|
44
47
|
series,
|
|
45
48
|
stackingGroups
|
|
@@ -52,66 +55,142 @@ function BarPlot(props) {
|
|
|
52
55
|
} = axisData;
|
|
53
56
|
const defaultXAxisId = xAxisIds[0];
|
|
54
57
|
const defaultYAxisId = yAxisIds[0];
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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;
|
|
58
|
+
const data = stackingGroups.flatMap(({
|
|
59
|
+
ids: groupIds
|
|
60
|
+
}, groupIndex) => {
|
|
61
|
+
return groupIds.flatMap(seriesId => {
|
|
62
|
+
const xAxisKey = series[seriesId].xAxisKey ?? defaultXAxisId;
|
|
63
|
+
const yAxisKey = series[seriesId].yAxisKey ?? defaultYAxisId;
|
|
64
|
+
const xAxisConfig = xAxis[xAxisKey];
|
|
65
|
+
const yAxisConfig = yAxis[yAxisKey];
|
|
66
|
+
const verticalLayout = series[seriesId].layout === 'vertical';
|
|
67
|
+
let baseScaleConfig;
|
|
68
|
+
if (verticalLayout) {
|
|
69
|
+
if (!isBandScaleConfig(xAxisConfig)) {
|
|
70
|
+
throw new Error(`Axis with id "${xAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
|
|
71
|
+
}
|
|
72
|
+
if (xAxis[xAxisKey].data === undefined) {
|
|
73
|
+
throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
|
|
74
|
+
}
|
|
75
|
+
baseScaleConfig = xAxisConfig;
|
|
76
|
+
} else {
|
|
77
|
+
if (!isBandScaleConfig(yAxisConfig)) {
|
|
78
|
+
throw new Error(`Axis with id "${yAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
|
|
82
79
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
80
|
+
if (yAxis[yAxisKey].data === undefined) {
|
|
81
|
+
throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
|
|
82
|
+
}
|
|
83
|
+
baseScaleConfig = yAxisConfig;
|
|
84
|
+
}
|
|
85
|
+
const xScale = xAxisConfig.scale;
|
|
86
|
+
const yScale = yAxisConfig.scale;
|
|
87
|
+
const bandWidth = baseScaleConfig.scale.bandwidth();
|
|
88
|
+
const {
|
|
89
|
+
barWidth,
|
|
90
|
+
offset
|
|
91
|
+
} = getBandSize({
|
|
92
|
+
bandWidth,
|
|
93
|
+
numberOfGroups: stackingGroups.length,
|
|
94
|
+
gapRatio: baseScaleConfig.barGapRatio
|
|
95
|
+
});
|
|
96
|
+
const barOffset = groupIndex * (barWidth + offset);
|
|
97
|
+
const {
|
|
98
|
+
stackedData,
|
|
99
|
+
color
|
|
100
|
+
} = series[seriesId];
|
|
101
|
+
return stackedData.map((values, dataIndex) => {
|
|
102
|
+
const bottom = Math.min(...values);
|
|
103
|
+
const top = Math.max(...values);
|
|
104
|
+
return {
|
|
105
|
+
bottom,
|
|
106
|
+
top,
|
|
107
|
+
seriesId,
|
|
108
|
+
dataIndex,
|
|
109
|
+
layout: series[seriesId].layout,
|
|
110
|
+
x: verticalLayout ? xScale(xAxis[xAxisKey].data?.[dataIndex]) + barOffset : xScale(bottom),
|
|
111
|
+
y: verticalLayout ? yScale(top) : yScale(yAxis[yAxisKey].data?.[dataIndex]) + barOffset,
|
|
112
|
+
xOrigin: xScale(0),
|
|
113
|
+
yOrigin: yScale(0),
|
|
114
|
+
height: verticalLayout ? Math.abs(yScale(bottom) - yScale(top)) : barWidth,
|
|
115
|
+
width: verticalLayout ? barWidth : Math.abs(xScale(bottom) - xScale(top)),
|
|
116
|
+
color,
|
|
117
|
+
highlightScope: series[seriesId].highlightScope
|
|
118
|
+
};
|
|
113
119
|
});
|
|
114
|
-
})
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
return data;
|
|
123
|
+
};
|
|
124
|
+
const getOutStyle = ({
|
|
125
|
+
layout,
|
|
126
|
+
yOrigin,
|
|
127
|
+
x,
|
|
128
|
+
width,
|
|
129
|
+
y,
|
|
130
|
+
xOrigin,
|
|
131
|
+
height
|
|
132
|
+
}) => _extends({}, layout === 'vertical' ? {
|
|
133
|
+
y: yOrigin,
|
|
134
|
+
x,
|
|
135
|
+
height: 0,
|
|
136
|
+
width
|
|
137
|
+
} : {
|
|
138
|
+
y,
|
|
139
|
+
x: xOrigin,
|
|
140
|
+
height,
|
|
141
|
+
width: 0
|
|
142
|
+
});
|
|
143
|
+
const getInStyle = ({
|
|
144
|
+
x,
|
|
145
|
+
width,
|
|
146
|
+
y,
|
|
147
|
+
height
|
|
148
|
+
}) => ({
|
|
149
|
+
y,
|
|
150
|
+
x,
|
|
151
|
+
height,
|
|
152
|
+
width
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Demos:
|
|
157
|
+
*
|
|
158
|
+
* - [Bars](https://mui.com/x/react-charts/bars/)
|
|
159
|
+
* - [Bar demonstration](https://mui.com/x/react-charts/bar-demo/)
|
|
160
|
+
* - [Stacking](https://mui.com/x/react-charts/stacking/)
|
|
161
|
+
*
|
|
162
|
+
* API:
|
|
163
|
+
*
|
|
164
|
+
* - [BarPlot API](https://mui.com/x/api/charts/bar-plot/)
|
|
165
|
+
*/
|
|
166
|
+
function BarPlot(props) {
|
|
167
|
+
const completedData = useCompletedData();
|
|
168
|
+
const {
|
|
169
|
+
skipAnimation
|
|
170
|
+
} = props,
|
|
171
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
172
|
+
const transition = useTransition(completedData, {
|
|
173
|
+
keys: bar => `${bar.seriesId}-${bar.dataIndex}`,
|
|
174
|
+
from: getOutStyle,
|
|
175
|
+
leave: getOutStyle,
|
|
176
|
+
enter: getInStyle,
|
|
177
|
+
update: getInStyle,
|
|
178
|
+
immediate: skipAnimation
|
|
179
|
+
});
|
|
180
|
+
return /*#__PURE__*/_jsx(React.Fragment, {
|
|
181
|
+
children: transition((style, {
|
|
182
|
+
seriesId,
|
|
183
|
+
dataIndex,
|
|
184
|
+
color,
|
|
185
|
+
highlightScope
|
|
186
|
+
}) => /*#__PURE__*/_jsx(BarElement, _extends({
|
|
187
|
+
id: seriesId,
|
|
188
|
+
dataIndex: dataIndex,
|
|
189
|
+
highlightScope: highlightScope,
|
|
190
|
+
color: color
|
|
191
|
+
}, other, {
|
|
192
|
+
style: style
|
|
193
|
+
})))
|
|
115
194
|
});
|
|
116
195
|
}
|
|
117
196
|
process.env.NODE_ENV !== "production" ? BarPlot.propTypes = {
|
|
@@ -119,6 +198,11 @@ process.env.NODE_ENV !== "production" ? BarPlot.propTypes = {
|
|
|
119
198
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
120
199
|
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
121
200
|
// ----------------------------------------------------------------------
|
|
201
|
+
/**
|
|
202
|
+
* If `true`, animations are skiped.
|
|
203
|
+
* @default false
|
|
204
|
+
*/
|
|
205
|
+
skipAnimation: PropTypes.bool,
|
|
122
206
|
/**
|
|
123
207
|
* The props used for each component slot.
|
|
124
208
|
* @default {}
|
|
@@ -3,6 +3,7 @@ import useForkRef from '@mui/utils/useForkRef';
|
|
|
3
3
|
import { DrawingProvider } from '../context/DrawingProvider';
|
|
4
4
|
import { SeriesContextProvider } from '../context/SeriesContextProvider';
|
|
5
5
|
import { InteractionProvider } from '../context/InteractionProvider';
|
|
6
|
+
import { useReducedMotion } from '../hooks/useReducedMotion';
|
|
6
7
|
import { ChartsSurface } from '../ChartsSurface';
|
|
7
8
|
import { CartesianContextProvider } from '../context/CartesianContextProvider';
|
|
8
9
|
import { HighlightProvider } from '../context/HighlightProvider';
|
|
@@ -25,6 +26,8 @@ export const ChartContainer = /*#__PURE__*/React.forwardRef(function ChartContai
|
|
|
25
26
|
} = props;
|
|
26
27
|
const svgRef = React.useRef(null);
|
|
27
28
|
const handleRef = useForkRef(ref, svgRef);
|
|
29
|
+
useReducedMotion(); // a11y reduce motion (see: https://react-spring.dev/docs/utilities/use-reduced-motion)
|
|
30
|
+
|
|
28
31
|
return /*#__PURE__*/_jsx(DrawingProvider, {
|
|
29
32
|
width: width,
|
|
30
33
|
height: height,
|
|
@@ -97,11 +97,15 @@ process.env.NODE_ENV !== "production" ? ChartsAxis.propTypes = {
|
|
|
97
97
|
fill: PropTypes.string,
|
|
98
98
|
label: PropTypes.string,
|
|
99
99
|
labelFontSize: PropTypes.number,
|
|
100
|
+
labelStyle: PropTypes.object,
|
|
100
101
|
position: PropTypes.oneOf(['bottom', 'top']),
|
|
101
102
|
slotProps: PropTypes.object,
|
|
102
103
|
slots: PropTypes.object,
|
|
103
104
|
stroke: PropTypes.string,
|
|
104
105
|
tickFontSize: PropTypes.number,
|
|
106
|
+
tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
|
|
107
|
+
tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
|
|
108
|
+
tickLabelStyle: PropTypes.object,
|
|
105
109
|
tickMaxStep: PropTypes.number,
|
|
106
110
|
tickMinStep: PropTypes.number,
|
|
107
111
|
tickNumber: PropTypes.number,
|
|
@@ -120,11 +124,15 @@ process.env.NODE_ENV !== "production" ? ChartsAxis.propTypes = {
|
|
|
120
124
|
fill: PropTypes.string,
|
|
121
125
|
label: PropTypes.string,
|
|
122
126
|
labelFontSize: PropTypes.number,
|
|
127
|
+
labelStyle: PropTypes.object,
|
|
123
128
|
position: PropTypes.oneOf(['left', 'right']),
|
|
124
129
|
slotProps: PropTypes.object,
|
|
125
130
|
slots: PropTypes.object,
|
|
126
131
|
stroke: PropTypes.string,
|
|
127
132
|
tickFontSize: PropTypes.number,
|
|
133
|
+
tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
|
|
134
|
+
tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
|
|
135
|
+
tickLabelStyle: PropTypes.object,
|
|
128
136
|
tickMaxStep: PropTypes.number,
|
|
129
137
|
tickMinStep: PropTypes.number,
|
|
130
138
|
tickNumber: PropTypes.number,
|
|
@@ -143,11 +151,15 @@ process.env.NODE_ENV !== "production" ? ChartsAxis.propTypes = {
|
|
|
143
151
|
fill: PropTypes.string,
|
|
144
152
|
label: PropTypes.string,
|
|
145
153
|
labelFontSize: PropTypes.number,
|
|
154
|
+
labelStyle: PropTypes.object,
|
|
146
155
|
position: PropTypes.oneOf(['left', 'right']),
|
|
147
156
|
slotProps: PropTypes.object,
|
|
148
157
|
slots: PropTypes.object,
|
|
149
158
|
stroke: PropTypes.string,
|
|
150
159
|
tickFontSize: PropTypes.number,
|
|
160
|
+
tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
|
|
161
|
+
tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
|
|
162
|
+
tickLabelStyle: PropTypes.object,
|
|
151
163
|
tickMaxStep: PropTypes.number,
|
|
152
164
|
tickMinStep: PropTypes.number,
|
|
153
165
|
tickNumber: PropTypes.number,
|
|
@@ -176,11 +188,15 @@ process.env.NODE_ENV !== "production" ? ChartsAxis.propTypes = {
|
|
|
176
188
|
fill: PropTypes.string,
|
|
177
189
|
label: PropTypes.string,
|
|
178
190
|
labelFontSize: PropTypes.number,
|
|
191
|
+
labelStyle: PropTypes.object,
|
|
179
192
|
position: PropTypes.oneOf(['bottom', 'top']),
|
|
180
193
|
slotProps: PropTypes.object,
|
|
181
194
|
slots: PropTypes.object,
|
|
182
195
|
stroke: PropTypes.string,
|
|
183
196
|
tickFontSize: PropTypes.number,
|
|
197
|
+
tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
|
|
198
|
+
tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
|
|
199
|
+
tickLabelStyle: PropTypes.object,
|
|
184
200
|
tickMaxStep: PropTypes.number,
|
|
185
201
|
tickMinStep: PropTypes.number,
|
|
186
202
|
tickNumber: PropTypes.number,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
2
2
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
3
|
-
const _excluded = ["
|
|
3
|
+
const _excluded = ["rotate", "dominantBaseline"],
|
|
4
|
+
_excluded2 = ["label"];
|
|
4
5
|
import * as React from 'react';
|
|
5
6
|
import { useSlotProps } from '@mui/base/utils';
|
|
6
7
|
import { NoSsr } from '@mui/base/NoSsr';
|
|
@@ -75,11 +76,16 @@ function DefaultChartsLegend(props) {
|
|
|
75
76
|
const theme = useTheme();
|
|
76
77
|
const labelStyle = React.useMemo(() => _extends({}, theme.typography.subtitle1, {
|
|
77
78
|
color: 'inherit',
|
|
79
|
+
dominantBaseline: 'central',
|
|
80
|
+
textAnchor: 'start',
|
|
78
81
|
fill: (theme.vars || theme).palette.text.primary,
|
|
79
82
|
lineHeight: 1
|
|
80
|
-
}, inLabelStyle),
|
|
83
|
+
}, inLabelStyle),
|
|
84
|
+
// To say to TS that the dominantBaseline and textAnchor are correct
|
|
85
|
+
[inLabelStyle, theme]);
|
|
81
86
|
const padding = React.useMemo(() => getStandardizedPadding(paddingProps), [paddingProps]);
|
|
82
|
-
const getItemSpace = React.useCallback((label,
|
|
87
|
+
const getItemSpace = React.useCallback((label, inStyle = {}) => {
|
|
88
|
+
const style = _objectWithoutPropertiesLoose(inStyle, _excluded);
|
|
83
89
|
const linesSize = getWordsByLines({
|
|
84
90
|
style,
|
|
85
91
|
needsComputation: true,
|
|
@@ -112,7 +118,7 @@ function DefaultChartsLegend(props) {
|
|
|
112
118
|
let {
|
|
113
119
|
label
|
|
114
120
|
} = _ref,
|
|
115
|
-
other = _objectWithoutPropertiesLoose(_ref,
|
|
121
|
+
other = _objectWithoutPropertiesLoose(_ref, _excluded2);
|
|
116
122
|
const itemSpace = getItemSpace(label, labelStyle);
|
|
117
123
|
const rep = _extends({}, other, {
|
|
118
124
|
label,
|
|
@@ -219,8 +225,6 @@ function DefaultChartsLegend(props) {
|
|
|
219
225
|
fill: color
|
|
220
226
|
}), /*#__PURE__*/_jsx(ChartsText, {
|
|
221
227
|
style: labelStyle,
|
|
222
|
-
dominantBaseline: "central",
|
|
223
|
-
textAnchor: "start",
|
|
224
228
|
text: label,
|
|
225
229
|
x: itemMarkWidth + markGap,
|
|
226
230
|
y: 0
|
|
@@ -11,7 +11,9 @@ import { DrawingContext } from '../context/DrawingProvider';
|
|
|
11
11
|
import useTicks from '../hooks/useTicks';
|
|
12
12
|
import { getAxisUtilityClass } from '../ChartsAxis/axisClasses';
|
|
13
13
|
import { AxisRoot } from '../internals/components/AxisSharedComponents';
|
|
14
|
-
import { ChartsText } from '../internals/components/ChartsText';
|
|
14
|
+
import { ChartsText, getWordsByLines } from '../internals/components/ChartsText';
|
|
15
|
+
import { getMinXTranslation } from '../internals/geometry';
|
|
16
|
+
import { useMounted } from '../hooks/useMounted';
|
|
15
17
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
18
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
19
|
const useUtilityClasses = ownerState => {
|
|
@@ -29,12 +31,64 @@ const useUtilityClasses = ownerState => {
|
|
|
29
31
|
};
|
|
30
32
|
return composeClasses(slots, getAxisUtilityClass, classes);
|
|
31
33
|
};
|
|
34
|
+
function addLabelDimension(xTicks, {
|
|
35
|
+
tickLabelStyle: style,
|
|
36
|
+
tickLabelInterval,
|
|
37
|
+
isMounted
|
|
38
|
+
}) {
|
|
39
|
+
const withDimension = xTicks.map(tick => {
|
|
40
|
+
if (!isMounted || tick.formattedValue === undefined) {
|
|
41
|
+
return _extends({}, tick, {
|
|
42
|
+
width: 0,
|
|
43
|
+
height: 0
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const tickSizes = getWordsByLines({
|
|
47
|
+
style,
|
|
48
|
+
needsComputation: true,
|
|
49
|
+
text: tick.formattedValue
|
|
50
|
+
});
|
|
51
|
+
return _extends({}, tick, {
|
|
52
|
+
width: Math.max(...tickSizes.map(size => size.width)),
|
|
53
|
+
height: Math.max(tickSizes.length * tickSizes[0].height)
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
if (typeof tickLabelInterval === 'function') {
|
|
57
|
+
return withDimension.map((item, index) => _extends({}, item, {
|
|
58
|
+
skipLabel: !tickLabelInterval(item.value, index)
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Filter label to avoid overlap
|
|
63
|
+
let textStart = 0;
|
|
64
|
+
let textEnd = 0;
|
|
65
|
+
return withDimension.map((item, labelIndex) => {
|
|
66
|
+
const {
|
|
67
|
+
width,
|
|
68
|
+
offset,
|
|
69
|
+
labelOffset,
|
|
70
|
+
height
|
|
71
|
+
} = item;
|
|
72
|
+
const distance = getMinXTranslation(width, height, style?.angle);
|
|
73
|
+
const textPosition = offset + labelOffset;
|
|
74
|
+
const gapRatio = 1.2; // Ratio applied to the minimal distance to add some margin.
|
|
75
|
+
|
|
76
|
+
textStart = textPosition - gapRatio * distance / 2;
|
|
77
|
+
if (labelIndex > 0 && textStart < textEnd) {
|
|
78
|
+
// Except for the first label, we skip all label that overlap with the last accepted.
|
|
79
|
+
// Notice that the early return prevents `textEnd` from being updated.
|
|
80
|
+
return _extends({}, item, {
|
|
81
|
+
skipLabel: true
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
textEnd = textPosition + gapRatio * distance / 2;
|
|
85
|
+
return item;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
32
88
|
const defaultProps = {
|
|
33
89
|
position: 'bottom',
|
|
34
90
|
disableLine: false,
|
|
35
91
|
disableTicks: false,
|
|
36
|
-
tickFontSize: 12,
|
|
37
|
-
labelFontSize: 14,
|
|
38
92
|
tickSize: 6
|
|
39
93
|
};
|
|
40
94
|
function ChartsXAxis(inProps) {
|
|
@@ -53,18 +107,23 @@ function ChartsXAxis(inProps) {
|
|
|
53
107
|
}
|
|
54
108
|
} = _React$useContext,
|
|
55
109
|
settings = _objectWithoutPropertiesLoose(_React$useContext.xAxis[_props$axisId], _excluded);
|
|
110
|
+
const isMounted = useMounted();
|
|
56
111
|
const defaultizedProps = _extends({}, defaultProps, settings, props);
|
|
57
112
|
const {
|
|
58
113
|
position,
|
|
59
114
|
disableLine,
|
|
60
115
|
disableTicks,
|
|
61
|
-
|
|
116
|
+
tickLabelStyle,
|
|
62
117
|
label,
|
|
118
|
+
labelStyle,
|
|
119
|
+
tickFontSize,
|
|
63
120
|
labelFontSize,
|
|
64
121
|
tickSize: tickSizeProp,
|
|
65
122
|
valueFormatter,
|
|
66
123
|
slots,
|
|
67
|
-
slotProps
|
|
124
|
+
slotProps,
|
|
125
|
+
tickInterval,
|
|
126
|
+
tickLabelInterval
|
|
68
127
|
} = defaultizedProps;
|
|
69
128
|
const theme = useTheme();
|
|
70
129
|
const classes = useUtilityClasses(_extends({}, defaultizedProps, {
|
|
@@ -77,16 +136,7 @@ function ChartsXAxis(inProps) {
|
|
|
77
136
|
height
|
|
78
137
|
} = React.useContext(DrawingContext);
|
|
79
138
|
const tickSize = disableTicks ? 4 : tickSizeProp;
|
|
80
|
-
const
|
|
81
|
-
scale: xScale,
|
|
82
|
-
tickNumber,
|
|
83
|
-
valueFormatter
|
|
84
|
-
});
|
|
85
|
-
const positionSigne = position === 'bottom' ? 1 : -1;
|
|
86
|
-
const labelRefPoint = {
|
|
87
|
-
x: left + width / 2,
|
|
88
|
-
y: positionSigne * (tickFontSize + tickSize + 10)
|
|
89
|
-
};
|
|
139
|
+
const positionSign = position === 'bottom' ? 1 : -1;
|
|
90
140
|
const Line = slots?.axisLine ?? 'line';
|
|
91
141
|
const Tick = slots?.axisTick ?? 'line';
|
|
92
142
|
const TickLabel = slots?.axisTickLabel ?? ChartsText;
|
|
@@ -95,27 +145,40 @@ function ChartsXAxis(inProps) {
|
|
|
95
145
|
elementType: TickLabel,
|
|
96
146
|
externalSlotProps: slotProps?.axisTickLabel,
|
|
97
147
|
additionalProps: {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
fontSize: tickFontSize
|
|
102
|
-
},
|
|
148
|
+
style: _extends({
|
|
149
|
+
textAnchor: 'middle',
|
|
150
|
+
dominantBaseline: position === 'bottom' ? 'hanging' : 'auto',
|
|
151
|
+
fontSize: tickFontSize ?? 12
|
|
152
|
+
}, tickLabelStyle),
|
|
103
153
|
className: classes.tickLabel
|
|
104
154
|
},
|
|
105
155
|
className: classes.tickLabel,
|
|
106
156
|
ownerState: {}
|
|
107
157
|
});
|
|
158
|
+
const xTicks = useTicks({
|
|
159
|
+
scale: xScale,
|
|
160
|
+
tickNumber,
|
|
161
|
+
valueFormatter,
|
|
162
|
+
tickInterval
|
|
163
|
+
});
|
|
164
|
+
const xTicksWithDimension = addLabelDimension(xTicks, {
|
|
165
|
+
tickLabelStyle: axisTickLabelProps.style,
|
|
166
|
+
tickLabelInterval,
|
|
167
|
+
isMounted
|
|
168
|
+
});
|
|
169
|
+
const labelRefPoint = {
|
|
170
|
+
x: left + width / 2,
|
|
171
|
+
y: positionSign * (tickSize + 22)
|
|
172
|
+
};
|
|
108
173
|
const axisLabelProps = useSlotProps({
|
|
109
174
|
elementType: Label,
|
|
110
175
|
externalSlotProps: slotProps?.axisLabel,
|
|
111
176
|
additionalProps: {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
},
|
|
118
|
-
className: classes.label
|
|
177
|
+
style: _extends({
|
|
178
|
+
fontSize: labelFontSize ?? 14,
|
|
179
|
+
textAnchor: 'middle',
|
|
180
|
+
dominantBaseline: position === 'bottom' ? 'hanging' : 'auto'
|
|
181
|
+
}, labelStyle)
|
|
119
182
|
},
|
|
120
183
|
ownerState: {}
|
|
121
184
|
});
|
|
@@ -126,23 +189,23 @@ function ChartsXAxis(inProps) {
|
|
|
126
189
|
x1: xScale.range()[0],
|
|
127
190
|
x2: xScale.range()[1],
|
|
128
191
|
className: classes.line
|
|
129
|
-
}, slotProps?.axisLine)),
|
|
192
|
+
}, slotProps?.axisLine)), xTicksWithDimension.map(({
|
|
130
193
|
formattedValue,
|
|
131
194
|
offset,
|
|
132
|
-
labelOffset
|
|
195
|
+
labelOffset,
|
|
196
|
+
skipLabel
|
|
133
197
|
}, index) => {
|
|
134
198
|
const xTickLabel = labelOffset ?? 0;
|
|
135
|
-
const yTickLabel =
|
|
199
|
+
const yTickLabel = positionSign * (tickSize + 3);
|
|
136
200
|
return /*#__PURE__*/_jsxs("g", {
|
|
137
201
|
transform: `translate(${offset}, 0)`,
|
|
138
202
|
className: classes.tickContainer,
|
|
139
203
|
children: [!disableTicks && /*#__PURE__*/_jsx(Tick, _extends({
|
|
140
|
-
y2:
|
|
204
|
+
y2: positionSign * tickSize,
|
|
141
205
|
className: classes.tick
|
|
142
|
-
}, slotProps?.axisTick)), formattedValue !== undefined && /*#__PURE__*/_jsx(TickLabel, _extends({
|
|
206
|
+
}, slotProps?.axisTick)), formattedValue !== undefined && !skipLabel && /*#__PURE__*/_jsx(TickLabel, _extends({
|
|
143
207
|
x: xTickLabel,
|
|
144
|
-
y: yTickLabel
|
|
145
|
-
"transform-origin": `${xTickLabel}px ${yTickLabel}px`
|
|
208
|
+
y: yTickLabel
|
|
146
209
|
}, axisTickLabelProps, {
|
|
147
210
|
text: formattedValue.toString()
|
|
148
211
|
}))]
|
|
@@ -190,8 +253,13 @@ process.env.NODE_ENV !== "production" ? ChartsXAxis.propTypes = {
|
|
|
190
253
|
/**
|
|
191
254
|
* The font size of the axis label.
|
|
192
255
|
* @default 14
|
|
256
|
+
* @deprecated Consider using `labelStyle.fontSize` instead.
|
|
193
257
|
*/
|
|
194
258
|
labelFontSize: PropTypes.number,
|
|
259
|
+
/**
|
|
260
|
+
* The style applied to the axis label.
|
|
261
|
+
*/
|
|
262
|
+
labelStyle: PropTypes.object,
|
|
195
263
|
/**
|
|
196
264
|
* Position of the axis.
|
|
197
265
|
*/
|
|
@@ -214,8 +282,28 @@ process.env.NODE_ENV !== "production" ? ChartsXAxis.propTypes = {
|
|
|
214
282
|
/**
|
|
215
283
|
* The font size of the axis ticks text.
|
|
216
284
|
* @default 12
|
|
285
|
+
* @deprecated Consider using `tickLabelStyle.fontSize` instead.
|
|
217
286
|
*/
|
|
218
287
|
tickFontSize: PropTypes.number,
|
|
288
|
+
/**
|
|
289
|
+
* Defines which ticks are displayed. Its value can be:
|
|
290
|
+
* - 'auto' In such case the ticks are computed based on axis scale and other parameters.
|
|
291
|
+
* - a filtering function of the form `(value, index) => boolean` which is available only if the axis has a data property.
|
|
292
|
+
* - an array containing the values where ticks should be displayed.
|
|
293
|
+
* @default 'auto'
|
|
294
|
+
*/
|
|
295
|
+
tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
|
|
296
|
+
/**
|
|
297
|
+
* Defines which ticks get its label displayed. Its value can be:
|
|
298
|
+
* - 'auto' In such case, labels are displayed if they do not overlap with the previous one.
|
|
299
|
+
* - a filtering function of the form (value, index) => boolean. Warning: the index is tick index, not data ones.
|
|
300
|
+
* @default 'auto'
|
|
301
|
+
*/
|
|
302
|
+
tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
|
|
303
|
+
/**
|
|
304
|
+
* The style applied to ticks text.
|
|
305
|
+
*/
|
|
306
|
+
tickLabelStyle: PropTypes.object,
|
|
219
307
|
/**
|
|
220
308
|
* Maximal step between two ticks.
|
|
221
309
|
* When using time data, the value is assumed to be in ms.
|