@mui/x-charts 7.0.0-beta.0 → 7.0.0-beta.1
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 +2 -1
- package/BarChart/BarChart.js +23 -4
- package/BarChart/BarElement.d.ts +1 -1
- package/BarChart/BarElement.js +6 -3
- package/BarChart/BarPlot.d.ts +8 -1
- package/BarChart/BarPlot.js +19 -5
- package/BarChart/formatter.js +1 -1
- package/CHANGELOG.md +247 -0
- package/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.d.ts +20 -0
- package/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.js +83 -0
- package/ChartsOnAxisClickHandler/index.d.ts +1 -0
- package/ChartsOnAxisClickHandler/index.js +16 -0
- package/ChartsOnAxisClickHandler/package.json +6 -0
- package/ChartsReferenceLine/ChartsXReferenceLine.js +1 -1
- package/ChartsReferenceLine/ChartsYReferenceLine.js +1 -1
- package/ChartsTooltip/ChartsAxisTooltipContent.js +6 -5
- package/ChartsTooltip/DefaultChartsAxisTooltipContent.js +6 -4
- package/ChartsTooltip/utils.d.ts +3 -1
- package/ChartsTooltip/utils.js +8 -0
- package/ChartsVoronoiHandler/ChartsVoronoiHandler.d.ts +7 -0
- package/ChartsVoronoiHandler/ChartsVoronoiHandler.js +92 -44
- package/LineChart/AnimatedArea.d.ts +1361 -0
- package/LineChart/AnimatedArea.js +111 -0
- package/LineChart/AnimatedLine.d.ts +1361 -0
- package/LineChart/AnimatedLine.js +113 -0
- package/LineChart/AreaElement.d.ts +17 -17
- package/LineChart/AreaElement.js +17 -34
- package/LineChart/AreaPlot.d.ts +12 -7
- package/LineChart/AreaPlot.js +91 -58
- package/LineChart/LineChart.d.ts +13 -4
- package/LineChart/LineChart.js +35 -6
- package/LineChart/LineElement.d.ts +17 -17
- package/LineChart/LineElement.js +16 -36
- package/LineChart/LineHighlightElement.js +3 -2
- package/LineChart/LinePlot.d.ts +12 -7
- package/LineChart/LinePlot.js +89 -56
- package/LineChart/MarkElement.d.ts +5 -2
- package/LineChart/MarkElement.js +26 -13
- package/LineChart/MarkPlot.d.ts +8 -1
- package/LineChart/MarkPlot.js +80 -51
- package/LineChart/formatter.js +1 -1
- package/LineChart/index.d.ts +2 -0
- package/LineChart/index.js +22 -0
- package/PieChart/PieArcLabelPlot.d.ts +1 -1
- package/PieChart/PieArcLabelPlot.js +1 -1
- package/PieChart/PieArcPlot.d.ts +2 -2
- package/PieChart/PieArcPlot.js +6 -6
- package/PieChart/PieChart.d.ts +1 -1
- package/PieChart/PieChart.js +4 -4
- package/PieChart/PiePlot.d.ts +1 -1
- package/PieChart/PiePlot.js +4 -4
- package/ScatterChart/Scatter.d.ts +7 -1
- package/ScatterChart/Scatter.js +17 -3
- package/ScatterChart/ScatterChart.d.ts +8 -2
- package/ScatterChart/ScatterChart.js +11 -2
- package/ScatterChart/ScatterPlot.d.ts +1 -1
- package/ScatterChart/ScatterPlot.js +10 -2
- package/SparkLineChart/SparkLineChart.js +2 -0
- package/context/DrawingProvider.d.ts +6 -1
- package/context/DrawingProvider.js +9 -2
- package/context/InteractionProvider.d.ts +3 -3
- package/esm/BarChart/BarChart.js +23 -4
- package/esm/BarChart/BarElement.js +6 -3
- package/esm/BarChart/BarPlot.js +19 -5
- package/esm/BarChart/formatter.js +1 -1
- package/esm/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.js +77 -0
- package/esm/ChartsOnAxisClickHandler/index.js +1 -0
- package/esm/ChartsReferenceLine/ChartsXReferenceLine.js +1 -1
- package/esm/ChartsReferenceLine/ChartsYReferenceLine.js +1 -1
- package/esm/ChartsTooltip/ChartsAxisTooltipContent.js +6 -5
- package/esm/ChartsTooltip/DefaultChartsAxisTooltipContent.js +7 -4
- package/esm/ChartsTooltip/utils.js +6 -0
- package/esm/ChartsVoronoiHandler/ChartsVoronoiHandler.js +92 -44
- package/esm/LineChart/AnimatedArea.js +103 -0
- package/esm/LineChart/AnimatedLine.js +105 -0
- package/esm/LineChart/AreaElement.js +16 -33
- package/esm/LineChart/AreaPlot.js +92 -59
- package/esm/LineChart/LineChart.js +35 -6
- package/esm/LineChart/LineElement.js +16 -35
- package/esm/LineChart/LineHighlightElement.js +3 -2
- package/esm/LineChart/LinePlot.js +90 -57
- package/esm/LineChart/MarkElement.js +26 -13
- package/esm/LineChart/MarkPlot.js +80 -51
- package/esm/LineChart/formatter.js +1 -1
- package/esm/LineChart/index.js +2 -0
- package/esm/PieChart/PieArcLabelPlot.js +1 -1
- package/esm/PieChart/PieArcPlot.js +6 -6
- package/esm/PieChart/PieChart.js +4 -4
- package/esm/PieChart/PiePlot.js +4 -4
- package/esm/ScatterChart/Scatter.js +17 -3
- package/esm/ScatterChart/ScatterChart.js +11 -2
- package/esm/ScatterChart/ScatterPlot.js +10 -2
- package/esm/SparkLineChart/SparkLineChart.js +2 -0
- package/esm/context/DrawingProvider.js +9 -2
- package/esm/hooks/useDrawingArea.js +7 -3
- package/esm/index.js +1 -0
- package/esm/internals/geometry.js +1 -1
- package/esm/internals/useAnimatedPath.js +29 -0
- package/esm/internals/utils.js +7 -0
- package/hooks/useDrawingArea.d.ts +2 -0
- package/hooks/useDrawingArea.js +7 -3
- package/index.d.ts +1 -0
- package/index.js +12 -1
- package/internals/geometry.js +1 -1
- package/internals/useAnimatedPath.d.ts +1 -0
- package/internals/useAnimatedPath.js +38 -0
- package/internals/utils.d.ts +4 -0
- package/internals/utils.js +8 -0
- package/legacy/BarChart/BarChart.js +23 -4
- package/legacy/BarChart/BarElement.js +5 -2
- package/legacy/BarChart/BarPlot.js +18 -4
- package/legacy/BarChart/formatter.js +1 -1
- package/legacy/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.js +75 -0
- package/legacy/ChartsOnAxisClickHandler/index.js +1 -0
- package/legacy/ChartsReferenceLine/ChartsXReferenceLine.js +1 -1
- package/legacy/ChartsReferenceLine/ChartsYReferenceLine.js +1 -1
- package/legacy/ChartsTooltip/ChartsAxisTooltipContent.js +6 -7
- package/legacy/ChartsTooltip/DefaultChartsAxisTooltipContent.js +7 -4
- package/legacy/ChartsTooltip/utils.js +6 -0
- package/legacy/ChartsVoronoiHandler/ChartsVoronoiHandler.js +88 -44
- package/legacy/LineChart/AnimatedArea.js +102 -0
- package/legacy/LineChart/AnimatedLine.js +104 -0
- package/legacy/LineChart/AreaElement.js +15 -35
- package/legacy/LineChart/AreaPlot.js +102 -66
- package/legacy/LineChart/LineChart.js +35 -6
- package/legacy/LineChart/LineElement.js +15 -37
- package/legacy/LineChart/LineHighlightElement.js +3 -2
- package/legacy/LineChart/LinePlot.js +97 -63
- package/legacy/LineChart/MarkElement.js +29 -12
- package/legacy/LineChart/MarkPlot.js +83 -53
- package/legacy/LineChart/formatter.js +1 -1
- package/legacy/LineChart/index.js +2 -0
- package/legacy/PieChart/PieArcLabelPlot.js +1 -1
- package/legacy/PieChart/PieArcPlot.js +6 -6
- package/legacy/PieChart/PieChart.js +4 -4
- package/legacy/PieChart/PiePlot.js +4 -4
- package/legacy/ScatterChart/Scatter.js +19 -3
- package/legacy/ScatterChart/ScatterChart.js +11 -2
- package/legacy/ScatterChart/ScatterPlot.js +10 -2
- package/legacy/SparkLineChart/SparkLineChart.js +2 -0
- package/legacy/context/DrawingProvider.js +11 -2
- package/legacy/hooks/useDrawingArea.js +7 -3
- package/legacy/index.js +2 -1
- package/legacy/internals/geometry.js +1 -1
- package/legacy/internals/useAnimatedPath.js +32 -0
- package/legacy/internals/utils.js +7 -0
- package/modern/BarChart/BarChart.js +23 -4
- package/modern/BarChart/BarElement.js +6 -3
- package/modern/BarChart/BarPlot.js +19 -5
- package/modern/BarChart/formatter.js +1 -1
- package/modern/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.js +75 -0
- package/modern/ChartsOnAxisClickHandler/index.js +1 -0
- package/modern/ChartsReferenceLine/ChartsXReferenceLine.js +1 -1
- package/modern/ChartsReferenceLine/ChartsYReferenceLine.js +1 -1
- package/modern/ChartsTooltip/ChartsAxisTooltipContent.js +6 -5
- package/modern/ChartsTooltip/DefaultChartsAxisTooltipContent.js +6 -4
- package/modern/ChartsTooltip/utils.js +6 -0
- package/modern/ChartsVoronoiHandler/ChartsVoronoiHandler.js +92 -44
- package/modern/LineChart/AnimatedArea.js +103 -0
- package/modern/LineChart/AnimatedLine.js +105 -0
- package/modern/LineChart/AreaElement.js +16 -33
- package/modern/LineChart/AreaPlot.js +91 -58
- package/modern/LineChart/LineChart.js +35 -6
- package/modern/LineChart/LineElement.js +16 -35
- package/modern/LineChart/LineHighlightElement.js +3 -2
- package/modern/LineChart/LinePlot.js +89 -56
- package/modern/LineChart/MarkElement.js +26 -13
- package/modern/LineChart/MarkPlot.js +80 -51
- package/modern/LineChart/formatter.js +1 -1
- package/modern/LineChart/index.js +2 -0
- package/modern/PieChart/PieArcLabelPlot.js +1 -1
- package/modern/PieChart/PieArcPlot.js +6 -6
- package/modern/PieChart/PieChart.js +4 -4
- package/modern/PieChart/PiePlot.js +4 -4
- package/modern/ScatterChart/Scatter.js +17 -3
- package/modern/ScatterChart/ScatterChart.js +11 -2
- package/modern/ScatterChart/ScatterPlot.js +10 -2
- package/modern/SparkLineChart/SparkLineChart.js +2 -0
- package/modern/context/DrawingProvider.js +9 -2
- package/modern/hooks/useDrawingArea.js +7 -3
- package/modern/index.js +2 -1
- package/modern/internals/geometry.js +1 -1
- package/modern/internals/useAnimatedPath.js +29 -0
- package/modern/internals/utils.js +7 -0
- package/package.json +6 -5
|
@@ -11,7 +11,8 @@ import { getSVGPoint } from '../internals/utils';
|
|
|
11
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
12
|
function ChartsVoronoiHandler(props) {
|
|
13
13
|
const {
|
|
14
|
-
voronoiMaxRadius
|
|
14
|
+
voronoiMaxRadius,
|
|
15
|
+
onItemClick
|
|
15
16
|
} = props;
|
|
16
17
|
const svgRef = React.useContext(SVGContext);
|
|
17
18
|
const {
|
|
@@ -49,6 +50,8 @@ function ChartsVoronoiHandler(props) {
|
|
|
49
50
|
};
|
|
50
51
|
}, [dispatch]);
|
|
51
52
|
useEnhancedEffect(() => {
|
|
53
|
+
// This effect generate and store the Delaunay object that's used to map coordinate to closest point.
|
|
54
|
+
|
|
52
55
|
if (seriesOrder === undefined || series === undefined) {
|
|
53
56
|
// If there is no scatter chart series
|
|
54
57
|
return;
|
|
@@ -82,80 +85,125 @@ function ChartsVoronoiHandler(props) {
|
|
|
82
85
|
if (element === null) {
|
|
83
86
|
return undefined;
|
|
84
87
|
}
|
|
85
|
-
const handleMouseOut = () => {
|
|
86
|
-
dispatch({
|
|
87
|
-
type: 'exitChart'
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
88
|
|
|
91
89
|
// TODO: A perf optimisation of voronoi could be to use the last point as the intial point for the next search.
|
|
92
|
-
|
|
90
|
+
function getClosestPoint(event) {
|
|
93
91
|
// Get mouse coordinate in global SVG space
|
|
94
92
|
const svgPoint = getSVGPoint(svgRef.current, event);
|
|
95
93
|
const outsideX = svgPoint.x < left || svgPoint.x > left + width;
|
|
96
94
|
const outsideY = svgPoint.y < top || svgPoint.y > top + height;
|
|
97
95
|
if (outsideX || outsideY) {
|
|
98
|
-
|
|
99
|
-
type: 'exitChart'
|
|
100
|
-
});
|
|
101
|
-
return;
|
|
96
|
+
return 'outside-chart';
|
|
102
97
|
}
|
|
103
98
|
if (!voronoiRef.current.delauney) {
|
|
104
|
-
return;
|
|
99
|
+
return 'no-point-found';
|
|
105
100
|
}
|
|
106
101
|
const closestPointIndex = voronoiRef.current.delauney?.find(svgPoint.x, svgPoint.y);
|
|
107
|
-
if (closestPointIndex
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return
|
|
113
|
-
});
|
|
114
|
-
if (seriesId === undefined) {
|
|
115
|
-
return;
|
|
102
|
+
if (closestPointIndex === undefined) {
|
|
103
|
+
return 'no-point-found';
|
|
104
|
+
}
|
|
105
|
+
const seriesId = Object.keys(voronoiRef.current).find(id => {
|
|
106
|
+
if (id === 'delauney') {
|
|
107
|
+
return false;
|
|
116
108
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
109
|
+
return 2 * closestPointIndex >= voronoiRef.current[id].startIndex && 2 * closestPointIndex < voronoiRef.current[id].endIndex;
|
|
110
|
+
});
|
|
111
|
+
if (seriesId === undefined) {
|
|
112
|
+
return 'no-point-found';
|
|
113
|
+
}
|
|
114
|
+
const dataIndex = (2 * closestPointIndex - voronoiRef.current[seriesId].startIndex) / 2;
|
|
115
|
+
if (voronoiMaxRadius !== undefined) {
|
|
116
|
+
const pointX = voronoiRef.current.delauney.points[2 * closestPointIndex];
|
|
117
|
+
const pointY = voronoiRef.current.delauney.points[2 * closestPointIndex + 1];
|
|
118
|
+
const dist2 = (pointX - svgPoint.x) ** 2 + (pointY - svgPoint.y) ** 2;
|
|
119
|
+
if (dist2 > voronoiMaxRadius ** 2) {
|
|
120
|
+
// The closest point is too far to be considered.
|
|
121
|
+
return 'outside-voronoi-max-radius';
|
|
134
122
|
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
seriesId,
|
|
126
|
+
dataIndex
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const handleMouseOut = () => {
|
|
130
|
+
dispatch({
|
|
131
|
+
type: 'exitChart'
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
const handleMouseMove = event => {
|
|
135
|
+
const closestPoint = getClosestPoint(event);
|
|
136
|
+
if (closestPoint === 'outside-chart') {
|
|
137
|
+
dispatch({
|
|
138
|
+
type: 'exitChart'
|
|
139
|
+
});
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (closestPoint === 'outside-voronoi-max-radius' || closestPoint === 'no-point-found') {
|
|
135
143
|
dispatch({
|
|
136
|
-
type: '
|
|
144
|
+
type: 'leaveItem',
|
|
137
145
|
data: {
|
|
138
|
-
type: 'scatter'
|
|
139
|
-
seriesId,
|
|
140
|
-
dataIndex
|
|
146
|
+
type: 'scatter'
|
|
141
147
|
}
|
|
142
148
|
});
|
|
149
|
+
return;
|
|
143
150
|
}
|
|
151
|
+
const {
|
|
152
|
+
seriesId,
|
|
153
|
+
dataIndex
|
|
154
|
+
} = closestPoint;
|
|
155
|
+
dispatch({
|
|
156
|
+
type: 'enterItem',
|
|
157
|
+
data: {
|
|
158
|
+
type: 'scatter',
|
|
159
|
+
seriesId,
|
|
160
|
+
dataIndex
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
const handleMouseClick = event => {
|
|
165
|
+
if (!onItemClick) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const closestPoint = getClosestPoint(event);
|
|
169
|
+
if (typeof closestPoint === 'string') {
|
|
170
|
+
// No point fond for any reason
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const {
|
|
174
|
+
seriesId,
|
|
175
|
+
dataIndex
|
|
176
|
+
} = closestPoint;
|
|
177
|
+
onItemClick(event, {
|
|
178
|
+
type: 'scatter',
|
|
179
|
+
seriesId,
|
|
180
|
+
dataIndex
|
|
181
|
+
});
|
|
144
182
|
};
|
|
145
183
|
element.addEventListener('mouseout', handleMouseOut);
|
|
146
184
|
element.addEventListener('mousemove', handleMouseMove);
|
|
185
|
+
element.addEventListener('click', handleMouseClick);
|
|
147
186
|
return () => {
|
|
148
187
|
element.removeEventListener('mouseout', handleMouseOut);
|
|
149
188
|
element.removeEventListener('mousemove', handleMouseMove);
|
|
189
|
+
element.removeEventListener('click', handleMouseClick);
|
|
150
190
|
};
|
|
151
|
-
}, [svgRef, dispatch, left, width, top, height, yAxis, xAxis, voronoiMaxRadius]);
|
|
152
|
-
|
|
191
|
+
}, [svgRef, dispatch, left, width, top, height, yAxis, xAxis, voronoiMaxRadius, onItemClick]);
|
|
192
|
+
|
|
193
|
+
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
194
|
+
return /*#__PURE__*/_jsx(React.Fragment, {});
|
|
153
195
|
}
|
|
154
196
|
process.env.NODE_ENV !== "production" ? ChartsVoronoiHandler.propTypes = {
|
|
155
197
|
// ----------------------------- Warning --------------------------------
|
|
156
198
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
157
199
|
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
158
200
|
// ----------------------------------------------------------------------
|
|
201
|
+
/**
|
|
202
|
+
* Callback fired when clicking on a scatter item.
|
|
203
|
+
* @param {MouseEvent} event Mouse event catched at the svg level
|
|
204
|
+
* @param {ScatterItemIdentifier} scatterItemIdentifier Identify whihc item got clicked
|
|
205
|
+
*/
|
|
206
|
+
onItemClick: PropTypes.func,
|
|
159
207
|
/**
|
|
160
208
|
* Defines the maximal distance between a scatter point and the pointer that triggers the interaction.
|
|
161
209
|
* If `undefined`, the radius is assumed to be infinite.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
+
const _excluded = ["d", "skipAnimation", "ownerState"];
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import PropTypes from 'prop-types';
|
|
6
|
+
import { styled } from '@mui/material/styles';
|
|
7
|
+
import { color as d3Color } from 'd3-color';
|
|
8
|
+
import { animated, useSpring } from '@react-spring/web';
|
|
9
|
+
import { useAnimatedPath } from '../internals/useAnimatedPath';
|
|
10
|
+
import { DrawingContext } from '../context/DrawingProvider';
|
|
11
|
+
import { cleanId } from '../internals/utils';
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
export const AreaElementPath = styled(animated.path, {
|
|
15
|
+
name: 'MuiAreaElement',
|
|
16
|
+
slot: 'Root',
|
|
17
|
+
overridesResolver: (_, styles) => styles.root
|
|
18
|
+
})(({
|
|
19
|
+
ownerState
|
|
20
|
+
}) => ({
|
|
21
|
+
stroke: 'none',
|
|
22
|
+
fill: ownerState.isHighlighted ? d3Color(ownerState.color).brighter(1).formatHex() : d3Color(ownerState.color).brighter(0.5).formatHex(),
|
|
23
|
+
transition: 'opacity 0.2s ease-in, fill 0.2s ease-in',
|
|
24
|
+
opacity: ownerState.isFaded ? 0.3 : 1
|
|
25
|
+
}));
|
|
26
|
+
/**
|
|
27
|
+
* Demos:
|
|
28
|
+
*
|
|
29
|
+
* - [Lines](https://mui.com/x/react-charts/lines/)
|
|
30
|
+
* - [Areas demonstration](https://mui.com/x/react-charts/areas-demo/)
|
|
31
|
+
*
|
|
32
|
+
* API:
|
|
33
|
+
*
|
|
34
|
+
* - [AreaElement API](https://mui.com/x/api/charts/animated-area/)
|
|
35
|
+
*/
|
|
36
|
+
function AnimatedArea(props) {
|
|
37
|
+
const {
|
|
38
|
+
d,
|
|
39
|
+
skipAnimation,
|
|
40
|
+
ownerState
|
|
41
|
+
} = props,
|
|
42
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
43
|
+
const {
|
|
44
|
+
left,
|
|
45
|
+
top,
|
|
46
|
+
right,
|
|
47
|
+
bottom,
|
|
48
|
+
width,
|
|
49
|
+
height,
|
|
50
|
+
chartId
|
|
51
|
+
} = React.useContext(DrawingContext);
|
|
52
|
+
const path = useAnimatedPath(d, skipAnimation);
|
|
53
|
+
const {
|
|
54
|
+
animatedWidth
|
|
55
|
+
} = useSpring({
|
|
56
|
+
from: {
|
|
57
|
+
animatedWidth: left
|
|
58
|
+
},
|
|
59
|
+
to: {
|
|
60
|
+
animatedWidth: width + left + right
|
|
61
|
+
},
|
|
62
|
+
reset: false,
|
|
63
|
+
immediate: skipAnimation
|
|
64
|
+
});
|
|
65
|
+
const clipId = cleanId(`${chartId}-${ownerState.id}-area-clip`);
|
|
66
|
+
return /*#__PURE__*/_jsxs(React.Fragment, {
|
|
67
|
+
children: [/*#__PURE__*/_jsx("clipPath", {
|
|
68
|
+
id: clipId,
|
|
69
|
+
children: /*#__PURE__*/_jsx(animated.rect, {
|
|
70
|
+
x: 0,
|
|
71
|
+
y: 0,
|
|
72
|
+
width: animatedWidth,
|
|
73
|
+
height: top + height + bottom
|
|
74
|
+
})
|
|
75
|
+
}), /*#__PURE__*/_jsx("g", {
|
|
76
|
+
clipPath: `url(#${clipId})`,
|
|
77
|
+
children: /*#__PURE__*/_jsx(AreaElementPath, _extends({}, other, {
|
|
78
|
+
ownerState: ownerState,
|
|
79
|
+
d: path
|
|
80
|
+
}))
|
|
81
|
+
})]
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
process.env.NODE_ENV !== "production" ? AnimatedArea.propTypes = {
|
|
85
|
+
// ----------------------------- Warning --------------------------------
|
|
86
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
87
|
+
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
88
|
+
// ----------------------------------------------------------------------
|
|
89
|
+
d: PropTypes.string.isRequired,
|
|
90
|
+
ownerState: PropTypes.shape({
|
|
91
|
+
classes: PropTypes.object,
|
|
92
|
+
color: PropTypes.string.isRequired,
|
|
93
|
+
id: PropTypes.string.isRequired,
|
|
94
|
+
isFaded: PropTypes.bool.isRequired,
|
|
95
|
+
isHighlighted: PropTypes.bool.isRequired
|
|
96
|
+
}).isRequired,
|
|
97
|
+
/**
|
|
98
|
+
* If `true`, animations are skipped.
|
|
99
|
+
* @default false
|
|
100
|
+
*/
|
|
101
|
+
skipAnimation: PropTypes.bool
|
|
102
|
+
} : void 0;
|
|
103
|
+
export { AnimatedArea };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
+
const _excluded = ["d", "skipAnimation", "ownerState"];
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import PropTypes from 'prop-types';
|
|
6
|
+
import { animated, useSpring } from '@react-spring/web';
|
|
7
|
+
import { color as d3Color } from 'd3-color';
|
|
8
|
+
import { styled } from '@mui/material/styles';
|
|
9
|
+
import { useAnimatedPath } from '../internals/useAnimatedPath';
|
|
10
|
+
import { DrawingContext } from '../context/DrawingProvider';
|
|
11
|
+
import { cleanId } from '../internals/utils';
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
export const LineElementPath = styled(animated.path, {
|
|
15
|
+
name: 'MuiLineElement',
|
|
16
|
+
slot: 'Root',
|
|
17
|
+
overridesResolver: (_, styles) => styles.root
|
|
18
|
+
})(({
|
|
19
|
+
ownerState
|
|
20
|
+
}) => ({
|
|
21
|
+
strokeWidth: 2,
|
|
22
|
+
strokeLinejoin: 'round',
|
|
23
|
+
fill: 'none',
|
|
24
|
+
stroke: ownerState.isHighlighted ? d3Color(ownerState.color).brighter(0.5).formatHex() : ownerState.color,
|
|
25
|
+
transition: 'opacity 0.2s ease-in, stroke 0.2s ease-in',
|
|
26
|
+
opacity: ownerState.isFaded ? 0.3 : 1
|
|
27
|
+
}));
|
|
28
|
+
/**
|
|
29
|
+
* Demos:
|
|
30
|
+
*
|
|
31
|
+
* - [Lines](https://mui.com/x/react-charts/lines/)
|
|
32
|
+
* - [Line demonstration](https://mui.com/x/react-charts/line-demo/)
|
|
33
|
+
*
|
|
34
|
+
* API:
|
|
35
|
+
*
|
|
36
|
+
* - [AnimatedLine API](https://mui.com/x/api/charts/animated-line/)
|
|
37
|
+
*/
|
|
38
|
+
function AnimatedLine(props) {
|
|
39
|
+
const {
|
|
40
|
+
d,
|
|
41
|
+
skipAnimation,
|
|
42
|
+
ownerState
|
|
43
|
+
} = props,
|
|
44
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
45
|
+
const {
|
|
46
|
+
left,
|
|
47
|
+
top,
|
|
48
|
+
bottom,
|
|
49
|
+
width,
|
|
50
|
+
height,
|
|
51
|
+
right,
|
|
52
|
+
chartId
|
|
53
|
+
} = React.useContext(DrawingContext);
|
|
54
|
+
const path = useAnimatedPath(d, skipAnimation);
|
|
55
|
+
const {
|
|
56
|
+
animatedWidth
|
|
57
|
+
} = useSpring({
|
|
58
|
+
from: {
|
|
59
|
+
animatedWidth: left
|
|
60
|
+
},
|
|
61
|
+
to: {
|
|
62
|
+
animatedWidth: width + left + right
|
|
63
|
+
},
|
|
64
|
+
reset: false,
|
|
65
|
+
immediate: skipAnimation
|
|
66
|
+
});
|
|
67
|
+
const clipId = cleanId(`${chartId}-${ownerState.id}-line-clip`);
|
|
68
|
+
return /*#__PURE__*/_jsxs(React.Fragment, {
|
|
69
|
+
children: [/*#__PURE__*/_jsx("clipPath", {
|
|
70
|
+
id: clipId,
|
|
71
|
+
children: /*#__PURE__*/_jsx(animated.rect, {
|
|
72
|
+
x: 0,
|
|
73
|
+
y: 0,
|
|
74
|
+
width: animatedWidth,
|
|
75
|
+
height: top + height + bottom
|
|
76
|
+
})
|
|
77
|
+
}), /*#__PURE__*/_jsx("g", {
|
|
78
|
+
clipPath: `url(#${clipId})`,
|
|
79
|
+
children: /*#__PURE__*/_jsx(LineElementPath, _extends({}, other, {
|
|
80
|
+
ownerState: ownerState,
|
|
81
|
+
d: path
|
|
82
|
+
}))
|
|
83
|
+
})]
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
process.env.NODE_ENV !== "production" ? AnimatedLine.propTypes = {
|
|
87
|
+
// ----------------------------- Warning --------------------------------
|
|
88
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
89
|
+
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
90
|
+
// ----------------------------------------------------------------------
|
|
91
|
+
d: PropTypes.string.isRequired,
|
|
92
|
+
ownerState: PropTypes.shape({
|
|
93
|
+
classes: PropTypes.object,
|
|
94
|
+
color: PropTypes.string.isRequired,
|
|
95
|
+
id: PropTypes.string.isRequired,
|
|
96
|
+
isFaded: PropTypes.bool.isRequired,
|
|
97
|
+
isHighlighted: PropTypes.bool.isRequired
|
|
98
|
+
}).isRequired,
|
|
99
|
+
/**
|
|
100
|
+
* If `true`, animations are skipped.
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
skipAnimation: PropTypes.bool
|
|
104
|
+
} : void 0;
|
|
105
|
+
export { AnimatedLine };
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
-
const _excluded = ["id", "classes", "color", "highlightScope", "slots", "slotProps"];
|
|
3
|
+
const _excluded = ["id", "classes", "color", "highlightScope", "slots", "slotProps", "onClick"];
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import composeClasses from '@mui/utils/composeClasses';
|
|
7
7
|
import { useSlotProps } from '@mui/base/utils';
|
|
8
8
|
import generateUtilityClass from '@mui/utils/generateUtilityClass';
|
|
9
|
-
import { styled } from '@mui/material/styles';
|
|
10
9
|
import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
|
|
11
|
-
import { color as d3Color } from 'd3-color';
|
|
12
10
|
import { getIsFaded, getIsHighlighted, useInteractionItemProps } from '../hooks/useInteractionItemProps';
|
|
13
11
|
import { InteractionContext } from '../context/InteractionProvider';
|
|
12
|
+
import { AnimatedArea } from './AnimatedArea';
|
|
14
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
14
|
export function getAreaElementUtilityClass(slot) {
|
|
16
15
|
return generateUtilityClass('MuiAreaElement', slot);
|
|
@@ -28,33 +27,6 @@ const useUtilityClasses = ownerState => {
|
|
|
28
27
|
};
|
|
29
28
|
return composeClasses(slots, getAreaElementUtilityClass, classes);
|
|
30
29
|
};
|
|
31
|
-
export const AreaElementPath = styled('path', {
|
|
32
|
-
name: 'MuiAreaElement',
|
|
33
|
-
slot: 'Root',
|
|
34
|
-
overridesResolver: (_, styles) => styles.root
|
|
35
|
-
})(({
|
|
36
|
-
ownerState
|
|
37
|
-
}) => ({
|
|
38
|
-
stroke: 'none',
|
|
39
|
-
fill: ownerState.isHighlighted ? d3Color(ownerState.color).brighter(1).formatHex() : d3Color(ownerState.color).brighter(0.5).formatHex(),
|
|
40
|
-
transition: 'opacity 0.2s ease-in, fill 0.2s ease-in',
|
|
41
|
-
opacity: ownerState.isFaded ? 0.3 : 1
|
|
42
|
-
}));
|
|
43
|
-
AreaElementPath.propTypes = {
|
|
44
|
-
// ----------------------------- Warning --------------------------------
|
|
45
|
-
// | These PropTypes are generated from the TypeScript type definitions |
|
|
46
|
-
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
47
|
-
// ----------------------------------------------------------------------
|
|
48
|
-
as: PropTypes.elementType,
|
|
49
|
-
ownerState: PropTypes.shape({
|
|
50
|
-
classes: PropTypes.object,
|
|
51
|
-
color: PropTypes.string.isRequired,
|
|
52
|
-
id: PropTypes.string.isRequired,
|
|
53
|
-
isFaded: PropTypes.bool.isRequired,
|
|
54
|
-
isHighlighted: PropTypes.bool.isRequired
|
|
55
|
-
}).isRequired,
|
|
56
|
-
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
|
|
57
|
-
};
|
|
58
30
|
/**
|
|
59
31
|
* Demos:
|
|
60
32
|
*
|
|
@@ -72,7 +44,8 @@ function AreaElement(props) {
|
|
|
72
44
|
color,
|
|
73
45
|
highlightScope,
|
|
74
46
|
slots,
|
|
75
|
-
slotProps
|
|
47
|
+
slotProps,
|
|
48
|
+
onClick
|
|
76
49
|
} = props,
|
|
77
50
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
78
51
|
const getInteractionItemProps = useInteractionItemProps(highlightScope);
|
|
@@ -95,7 +68,7 @@ function AreaElement(props) {
|
|
|
95
68
|
isHighlighted
|
|
96
69
|
};
|
|
97
70
|
const classes = useUtilityClasses(ownerState);
|
|
98
|
-
const Area = slots?.area ??
|
|
71
|
+
const Area = slots?.area ?? AnimatedArea;
|
|
99
72
|
const areaProps = useSlotProps({
|
|
100
73
|
elementType: Area,
|
|
101
74
|
externalSlotProps: slotProps?.area,
|
|
@@ -103,7 +76,9 @@ function AreaElement(props) {
|
|
|
103
76
|
type: 'line',
|
|
104
77
|
seriesId: id
|
|
105
78
|
}), {
|
|
106
|
-
className: classes.root
|
|
79
|
+
className: classes.root,
|
|
80
|
+
onClick,
|
|
81
|
+
cursor: onClick ? 'pointer' : 'unset'
|
|
107
82
|
}),
|
|
108
83
|
ownerState
|
|
109
84
|
});
|
|
@@ -115,10 +90,18 @@ process.env.NODE_ENV !== "production" ? AreaElement.propTypes = {
|
|
|
115
90
|
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
116
91
|
// ----------------------------------------------------------------------
|
|
117
92
|
classes: PropTypes.object,
|
|
93
|
+
color: PropTypes.string.isRequired,
|
|
94
|
+
d: PropTypes.string.isRequired,
|
|
118
95
|
highlightScope: PropTypes.shape({
|
|
119
96
|
faded: PropTypes.oneOf(['global', 'none', 'series']),
|
|
120
97
|
highlighted: PropTypes.oneOf(['item', 'none', 'series'])
|
|
121
98
|
}),
|
|
99
|
+
id: PropTypes.string.isRequired,
|
|
100
|
+
/**
|
|
101
|
+
* If `true`, animations are skipped.
|
|
102
|
+
* @default false
|
|
103
|
+
*/
|
|
104
|
+
skipAnimation: PropTypes.bool,
|
|
122
105
|
/**
|
|
123
106
|
* The props used for each component slot.
|
|
124
107
|
* @default {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
1
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
-
|
|
2
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
3
|
+
const _excluded = ["slots", "slotProps", "onItemClick", "skipAnimation"];
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import { area as d3Area } from 'd3-shape';
|
|
@@ -11,27 +11,11 @@ import { getValueToPositionMapper } from '../hooks/useScale';
|
|
|
11
11
|
import getCurveFactory from '../internals/getCurve';
|
|
12
12
|
import { DEFAULT_X_AXIS_KEY } from '../constants';
|
|
13
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
-
|
|
15
|
-
* Demos:
|
|
16
|
-
*
|
|
17
|
-
* - [Lines](https://mui.com/x/react-charts/lines/)
|
|
18
|
-
* - [Areas demonstration](https://mui.com/x/react-charts/areas-demo/)
|
|
19
|
-
* - [Stacking](https://mui.com/x/react-charts/stacking/)
|
|
20
|
-
*
|
|
21
|
-
* API:
|
|
22
|
-
*
|
|
23
|
-
* - [AreaPlot API](https://mui.com/x/api/charts/area-plot/)
|
|
24
|
-
*/
|
|
25
|
-
function AreaPlot(props) {
|
|
26
|
-
const {
|
|
27
|
-
slots,
|
|
28
|
-
slotProps
|
|
29
|
-
} = props,
|
|
30
|
-
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
14
|
+
const useAggregatedData = () => {
|
|
31
15
|
const seriesData = React.useContext(SeriesContext).line;
|
|
32
16
|
const axisData = React.useContext(CartesianContext);
|
|
33
17
|
if (seriesData === undefined) {
|
|
34
|
-
return
|
|
18
|
+
return [];
|
|
35
19
|
}
|
|
36
20
|
const {
|
|
37
21
|
series,
|
|
@@ -45,46 +29,84 @@ function AreaPlot(props) {
|
|
|
45
29
|
} = axisData;
|
|
46
30
|
const defaultXAxisId = xAxisIds[0];
|
|
47
31
|
const defaultYAxisId = yAxisIds[0];
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
throw new Error(`MUI X Charts: ${xAxisKey === DEFAULT_X_AXIS_KEY ? 'The first `xAxis`' : `The x-axis with id "${xAxisKey}"`} should have data property to be able to display a line plot.`);
|
|
66
|
-
}
|
|
67
|
-
if (xData.length < stackedData.length) {
|
|
68
|
-
throw new Error(`MUI X Charts: The data length of the x axis (${xData.length} items) is lower than the length of series (${stackedData.length} items).`);
|
|
69
|
-
}
|
|
32
|
+
return stackingGroups.flatMap(({
|
|
33
|
+
ids: groupIds
|
|
34
|
+
}) => {
|
|
35
|
+
return groupIds.flatMap(seriesId => {
|
|
36
|
+
const {
|
|
37
|
+
xAxisKey = defaultXAxisId,
|
|
38
|
+
yAxisKey = defaultYAxisId,
|
|
39
|
+
stackedData,
|
|
40
|
+
data,
|
|
41
|
+
connectNulls
|
|
42
|
+
} = series[seriesId];
|
|
43
|
+
const xScale = getValueToPositionMapper(xAxis[xAxisKey].scale);
|
|
44
|
+
const yScale = yAxis[yAxisKey].scale;
|
|
45
|
+
const xData = xAxis[xAxisKey].data;
|
|
46
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
47
|
+
if (xData === undefined) {
|
|
48
|
+
throw new Error(`MUI X Charts: ${xAxisKey === DEFAULT_X_AXIS_KEY ? 'The first `xAxis`' : `The x-axis with id "${xAxisKey}"`} should have data property to be able to display a line plot.`);
|
|
70
49
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
50
|
+
if (xData.length < stackedData.length) {
|
|
51
|
+
throw new Error(`MUI X Charts: The data length of the x axis (${xData.length} items) is lower than the length of series (${stackedData.length} items).`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const areaPath = d3Area().x(d => xScale(d.x)).defined((_, i) => connectNulls || data[i] != null).y0(d => d.y && yScale(d.y[0])).y1(d => d.y && yScale(d.y[1]));
|
|
55
|
+
const curve = getCurveFactory(series[seriesId].curve);
|
|
56
|
+
const formattedData = xData?.map((x, index) => ({
|
|
57
|
+
x,
|
|
58
|
+
y: stackedData[index]
|
|
59
|
+
})) ?? [];
|
|
60
|
+
const d3Data = connectNulls ? formattedData.filter((_, i) => data[i] != null) : formattedData;
|
|
61
|
+
const d = areaPath.curve(curve)(d3Data) || '';
|
|
62
|
+
return _extends({}, series[seriesId], {
|
|
63
|
+
d,
|
|
64
|
+
seriesId
|
|
86
65
|
});
|
|
87
|
-
})
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Demos:
|
|
72
|
+
*
|
|
73
|
+
* - [Lines](https://mui.com/x/react-charts/lines/)
|
|
74
|
+
* - [Areas demonstration](https://mui.com/x/react-charts/areas-demo/)
|
|
75
|
+
* - [Stacking](https://mui.com/x/react-charts/stacking/)
|
|
76
|
+
*
|
|
77
|
+
* API:
|
|
78
|
+
*
|
|
79
|
+
* - [AreaPlot API](https://mui.com/x/api/charts/area-plot/)
|
|
80
|
+
*/
|
|
81
|
+
function AreaPlot(props) {
|
|
82
|
+
const {
|
|
83
|
+
slots,
|
|
84
|
+
slotProps,
|
|
85
|
+
onItemClick,
|
|
86
|
+
skipAnimation
|
|
87
|
+
} = props,
|
|
88
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
89
|
+
const completedData = useAggregatedData();
|
|
90
|
+
return /*#__PURE__*/_jsx("g", _extends({}, other, {
|
|
91
|
+
children: completedData.reverse().map(({
|
|
92
|
+
d,
|
|
93
|
+
seriesId,
|
|
94
|
+
color,
|
|
95
|
+
highlightScope,
|
|
96
|
+
area
|
|
97
|
+
}) => !!area && /*#__PURE__*/_jsx(AreaElement, {
|
|
98
|
+
id: seriesId,
|
|
99
|
+
d: d,
|
|
100
|
+
color: color,
|
|
101
|
+
highlightScope: highlightScope,
|
|
102
|
+
slots: slots,
|
|
103
|
+
slotProps: slotProps,
|
|
104
|
+
onClick: onItemClick && (event => onItemClick(event, {
|
|
105
|
+
type: 'line',
|
|
106
|
+
seriesId
|
|
107
|
+
})),
|
|
108
|
+
skipAnimation: skipAnimation
|
|
109
|
+
}, seriesId))
|
|
88
110
|
}));
|
|
89
111
|
}
|
|
90
112
|
process.env.NODE_ENV !== "production" ? AreaPlot.propTypes = {
|
|
@@ -92,6 +114,17 @@ process.env.NODE_ENV !== "production" ? AreaPlot.propTypes = {
|
|
|
92
114
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
93
115
|
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
94
116
|
// ----------------------------------------------------------------------
|
|
117
|
+
/**
|
|
118
|
+
* Callback fired when a line area item is clicked.
|
|
119
|
+
* @param {React.MouseEvent<SVGPathElement, MouseEvent>} event The event source of the callback.
|
|
120
|
+
* @param {LineItemIdentifier} lineItemIdentifier The line item identifier.
|
|
121
|
+
*/
|
|
122
|
+
onItemClick: PropTypes.func,
|
|
123
|
+
/**
|
|
124
|
+
* If `true`, animations are skipped.
|
|
125
|
+
* @default false
|
|
126
|
+
*/
|
|
127
|
+
skipAnimation: PropTypes.bool,
|
|
95
128
|
/**
|
|
96
129
|
* The props used for each component slot.
|
|
97
130
|
* @default {}
|