@mui/x-charts 7.0.0-alpha.3 → 7.0.0-alpha.4
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/CHANGELOG.md +123 -0
- package/ChartsVoronoiHandler/ChartsVoronoiHandler.d.ts +14 -0
- package/ChartsVoronoiHandler/ChartsVoronoiHandler.js +174 -0
- package/ChartsVoronoiHandler/index.d.ts +1 -0
- package/ChartsVoronoiHandler/index.js +16 -0
- package/ChartsVoronoiHandler/package.json +6 -0
- package/ScatterChart/Scatter.js +14 -5
- package/ScatterChart/ScatterChart.d.ts +7 -1
- package/ScatterChart/ScatterChart.js +18 -1
- package/SparkLineChart/SparkLineChart.js +1 -0
- package/context/InteractionProvider.d.ts +10 -0
- package/context/InteractionProvider.js +21 -1
- package/esm/ChartsVoronoiHandler/ChartsVoronoiHandler.js +168 -0
- package/esm/ChartsVoronoiHandler/index.js +1 -0
- package/esm/ScatterChart/Scatter.js +14 -5
- package/esm/ScatterChart/ScatterChart.js +18 -1
- package/esm/SparkLineChart/SparkLineChart.js +1 -0
- package/esm/context/InteractionProvider.js +21 -1
- package/esm/hooks/useAxisEvents.js +20 -27
- package/esm/hooks/useInteractionItemProps.js +4 -1
- package/esm/index.js +1 -0
- package/esm/internals/utils.js +11 -0
- package/hooks/useAxisEvents.js +20 -27
- package/hooks/useInteractionItemProps.d.ts +2 -2
- package/hooks/useInteractionItemProps.js +4 -1
- package/index.d.ts +1 -0
- package/index.js +12 -1
- package/internals/defaultizeColor.d.ts +1 -0
- package/internals/utils.d.ts +6 -0
- package/internals/utils.js +12 -0
- package/legacy/ChartsVoronoiHandler/ChartsVoronoiHandler.js +162 -0
- package/legacy/ChartsVoronoiHandler/index.js +1 -0
- package/legacy/ScatterChart/Scatter.js +17 -6
- package/legacy/ScatterChart/ScatterChart.js +18 -1
- package/legacy/SparkLineChart/SparkLineChart.js +1 -0
- package/legacy/context/InteractionProvider.js +21 -1
- package/legacy/hooks/useAxisEvents.js +20 -27
- package/legacy/hooks/useInteractionItemProps.js +6 -1
- package/legacy/index.js +2 -1
- package/legacy/internals/utils.js +11 -0
- package/models/seriesType/scatter.d.ts +5 -0
- package/modern/ChartsVoronoiHandler/ChartsVoronoiHandler.js +166 -0
- package/modern/ChartsVoronoiHandler/index.js +1 -0
- package/modern/ScatterChart/Scatter.js +14 -5
- package/modern/ScatterChart/ScatterChart.js +18 -1
- package/modern/SparkLineChart/SparkLineChart.js +1 -0
- package/modern/context/InteractionProvider.js +21 -1
- package/modern/hooks/useAxisEvents.js +20 -27
- package/modern/hooks/useInteractionItemProps.js +4 -1
- package/modern/index.js +2 -1
- package/modern/internals/utils.js +11 -0
- package/package.json +6 -4
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Delaunay } from 'd3-delaunay';
|
|
4
|
+
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
|
|
5
|
+
import { InteractionContext } from '../context/InteractionProvider';
|
|
6
|
+
import { CartesianContext } from '../context/CartesianContextProvider';
|
|
7
|
+
import { SVGContext, DrawingContext } from '../context/DrawingProvider';
|
|
8
|
+
import { SeriesContext } from '../context/SeriesContextProvider';
|
|
9
|
+
import { getValueToPositionMapper } from '../hooks/useScale';
|
|
10
|
+
import { getSVGPoint } from '../internals/utils';
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
function ChartsVoronoiHandler(props) {
|
|
13
|
+
var _React$useContext$sca;
|
|
14
|
+
const {
|
|
15
|
+
voronoiMaxRadius
|
|
16
|
+
} = props;
|
|
17
|
+
const svgRef = React.useContext(SVGContext);
|
|
18
|
+
const {
|
|
19
|
+
width,
|
|
20
|
+
height,
|
|
21
|
+
top,
|
|
22
|
+
left
|
|
23
|
+
} = React.useContext(DrawingContext);
|
|
24
|
+
const {
|
|
25
|
+
xAxis,
|
|
26
|
+
yAxis,
|
|
27
|
+
xAxisIds,
|
|
28
|
+
yAxisIds
|
|
29
|
+
} = React.useContext(CartesianContext);
|
|
30
|
+
const {
|
|
31
|
+
dispatch
|
|
32
|
+
} = React.useContext(InteractionContext);
|
|
33
|
+
const {
|
|
34
|
+
series,
|
|
35
|
+
seriesOrder
|
|
36
|
+
} = (_React$useContext$sca = React.useContext(SeriesContext).scatter) != null ? _React$useContext$sca : {};
|
|
37
|
+
const voronoiRef = React.useRef({});
|
|
38
|
+
const defaultXAxisId = xAxisIds[0];
|
|
39
|
+
const defaultYAxisId = yAxisIds[0];
|
|
40
|
+
useEnhancedEffect(() => {
|
|
41
|
+
dispatch({
|
|
42
|
+
type: 'updateVoronoiUsage',
|
|
43
|
+
useVoronoiInteraction: true
|
|
44
|
+
});
|
|
45
|
+
return () => {
|
|
46
|
+
dispatch({
|
|
47
|
+
type: 'updateVoronoiUsage',
|
|
48
|
+
useVoronoiInteraction: false
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
}, [dispatch]);
|
|
52
|
+
useEnhancedEffect(() => {
|
|
53
|
+
if (seriesOrder === undefined || series === undefined) {
|
|
54
|
+
// If there is no scatter chart series
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
voronoiRef.current = {};
|
|
58
|
+
let points = [];
|
|
59
|
+
seriesOrder.forEach(seriesId => {
|
|
60
|
+
const {
|
|
61
|
+
data,
|
|
62
|
+
xAxisKey,
|
|
63
|
+
yAxisKey
|
|
64
|
+
} = series[seriesId];
|
|
65
|
+
const xScale = xAxis[xAxisKey != null ? xAxisKey : defaultXAxisId].scale;
|
|
66
|
+
const yScale = yAxis[yAxisKey != null ? yAxisKey : defaultYAxisId].scale;
|
|
67
|
+
const getXPosition = getValueToPositionMapper(xScale);
|
|
68
|
+
const getYPosition = getValueToPositionMapper(yScale);
|
|
69
|
+
const seriesPoints = data.flatMap(({
|
|
70
|
+
x,
|
|
71
|
+
y
|
|
72
|
+
}) => [getXPosition(x), getYPosition(y)]);
|
|
73
|
+
voronoiRef.current[seriesId] = {
|
|
74
|
+
startIndex: points.length,
|
|
75
|
+
endIndex: points.length + seriesPoints.length
|
|
76
|
+
};
|
|
77
|
+
points = points.concat(seriesPoints);
|
|
78
|
+
});
|
|
79
|
+
voronoiRef.current.delauney = new Delaunay(points);
|
|
80
|
+
}, [defaultXAxisId, defaultYAxisId, series, seriesOrder, xAxis, yAxis]);
|
|
81
|
+
React.useEffect(() => {
|
|
82
|
+
const element = svgRef.current;
|
|
83
|
+
if (element === null) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
const handleMouseOut = () => {
|
|
87
|
+
dispatch({
|
|
88
|
+
type: 'exitChart'
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// TODO: A perf optimisation of voronoi could be to use the last point as the intial point for the next search.
|
|
93
|
+
const handleMouseMove = event => {
|
|
94
|
+
var _voronoiRef$current$d;
|
|
95
|
+
// Get mouse coordinate in global SVG space
|
|
96
|
+
const svgPoint = getSVGPoint(svgRef.current, event);
|
|
97
|
+
const outsideX = svgPoint.x < left || svgPoint.x > left + width;
|
|
98
|
+
const outsideY = svgPoint.y < top || svgPoint.y > top + height;
|
|
99
|
+
if (outsideX || outsideY) {
|
|
100
|
+
dispatch({
|
|
101
|
+
type: 'exitChart'
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (!voronoiRef.current.delauney) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const closestPointIndex = (_voronoiRef$current$d = voronoiRef.current.delauney) == null ? void 0 : _voronoiRef$current$d.find(svgPoint.x, svgPoint.y);
|
|
109
|
+
if (closestPointIndex !== undefined) {
|
|
110
|
+
const seriesId = Object.keys(voronoiRef.current).find(id => {
|
|
111
|
+
if (id === 'delauney') {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return 2 * closestPointIndex >= voronoiRef.current[id].startIndex && 2 * closestPointIndex < voronoiRef.current[id].endIndex;
|
|
115
|
+
});
|
|
116
|
+
if (seriesId === undefined) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const dataIndex = (2 * closestPointIndex - voronoiRef.current[seriesId].startIndex) / 2;
|
|
120
|
+
if (voronoiMaxRadius !== undefined) {
|
|
121
|
+
const pointX = voronoiRef.current.delauney.points[2 * closestPointIndex];
|
|
122
|
+
const pointY = voronoiRef.current.delauney.points[2 * closestPointIndex + 1];
|
|
123
|
+
const dist2 = (pointX - svgPoint.x) ** 2 + (pointY - svgPoint.y) ** 2;
|
|
124
|
+
if (dist2 > voronoiMaxRadius ** 2) {
|
|
125
|
+
// The closest point is too far to be considered.
|
|
126
|
+
dispatch({
|
|
127
|
+
type: 'leaveItem',
|
|
128
|
+
data: {
|
|
129
|
+
type: 'scatter',
|
|
130
|
+
seriesId,
|
|
131
|
+
dataIndex
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
dispatch({
|
|
138
|
+
type: 'enterItem',
|
|
139
|
+
data: {
|
|
140
|
+
type: 'scatter',
|
|
141
|
+
seriesId,
|
|
142
|
+
dataIndex
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
element.addEventListener('mouseout', handleMouseOut);
|
|
148
|
+
element.addEventListener('mousemove', handleMouseMove);
|
|
149
|
+
return () => {
|
|
150
|
+
element.removeEventListener('mouseout', handleMouseOut);
|
|
151
|
+
element.removeEventListener('mousemove', handleMouseMove);
|
|
152
|
+
};
|
|
153
|
+
}, [svgRef, dispatch, left, width, top, height, yAxis, xAxis, voronoiMaxRadius]);
|
|
154
|
+
return /*#__PURE__*/_jsx("g", {}); // Workaround to fix docs scripts
|
|
155
|
+
}
|
|
156
|
+
process.env.NODE_ENV !== "production" ? ChartsVoronoiHandler.propTypes = {
|
|
157
|
+
// ----------------------------- Warning --------------------------------
|
|
158
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
159
|
+
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
160
|
+
// ----------------------------------------------------------------------
|
|
161
|
+
/**
|
|
162
|
+
* Defines the maximal distance between a scatter point and the pointer that triggers the interaction.
|
|
163
|
+
* If `undefined`, the radius is assumed to be infinite.
|
|
164
|
+
* @default undefined
|
|
165
|
+
*/
|
|
166
|
+
voronoiMaxRadius: PropTypes.number
|
|
167
|
+
} : void 0;
|
|
168
|
+
export { ChartsVoronoiHandler };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ChartsVoronoiHandler';
|
|
@@ -23,10 +23,16 @@ function Scatter(props) {
|
|
|
23
23
|
color,
|
|
24
24
|
markerSize
|
|
25
25
|
} = props;
|
|
26
|
+
const highlightScope = React.useMemo(() => _extends({
|
|
27
|
+
highlighted: 'item',
|
|
28
|
+
faded: 'global'
|
|
29
|
+
}, series.highlightScope), [series.highlightScope]);
|
|
26
30
|
const {
|
|
27
|
-
item
|
|
31
|
+
item,
|
|
32
|
+
useVoronoiInteraction
|
|
28
33
|
} = React.useContext(InteractionContext);
|
|
29
|
-
const
|
|
34
|
+
const skipInteractionHandlers = useVoronoiInteraction || series.disableHover;
|
|
35
|
+
const getInteractionItemProps = useInteractionItemProps(highlightScope, skipInteractionHandlers);
|
|
30
36
|
const cleanData = React.useMemo(() => {
|
|
31
37
|
const getXPosition = getValueToPositionMapper(xScale);
|
|
32
38
|
const getYPosition = getValueToPositionMapper(yScale);
|
|
@@ -48,22 +54,24 @@ function Scatter(props) {
|
|
|
48
54
|
dataIndex: i
|
|
49
55
|
};
|
|
50
56
|
if (isInRange) {
|
|
57
|
+
const isHighlighted = getIsHighlighted(item, pointCtx, highlightScope);
|
|
51
58
|
temp.push({
|
|
52
59
|
x,
|
|
53
60
|
y,
|
|
54
|
-
|
|
61
|
+
isHighlighted,
|
|
62
|
+
isFaded: !isHighlighted && getIsFaded(item, pointCtx, highlightScope),
|
|
55
63
|
interactionProps: getInteractionItemProps(pointCtx),
|
|
56
64
|
id: scatterPoint.id
|
|
57
65
|
});
|
|
58
66
|
}
|
|
59
67
|
}
|
|
60
68
|
return temp;
|
|
61
|
-
}, [
|
|
69
|
+
}, [xScale, yScale, series.data, series.id, item, highlightScope, getInteractionItemProps]);
|
|
62
70
|
return /*#__PURE__*/_jsx("g", {
|
|
63
71
|
children: cleanData.map(dataPoint => /*#__PURE__*/_jsx("circle", _extends({
|
|
64
72
|
cx: 0,
|
|
65
73
|
cy: 0,
|
|
66
|
-
r: markerSize,
|
|
74
|
+
r: (dataPoint.isHighlighted ? 1.2 : 1) * markerSize,
|
|
67
75
|
transform: `translate(${dataPoint.x}, ${dataPoint.y})`,
|
|
68
76
|
fill: color,
|
|
69
77
|
opacity: dataPoint.isFaded && 0.3 || 1
|
|
@@ -84,6 +92,7 @@ process.env.NODE_ENV !== "production" ? Scatter.propTypes = {
|
|
|
84
92
|
x: PropTypes.number.isRequired,
|
|
85
93
|
y: PropTypes.number.isRequired
|
|
86
94
|
})).isRequired,
|
|
95
|
+
disableHover: PropTypes.bool,
|
|
87
96
|
highlightScope: PropTypes.shape({
|
|
88
97
|
faded: PropTypes.oneOf(['global', 'none', 'series']),
|
|
89
98
|
highlighted: PropTypes.oneOf(['item', 'none', 'series'])
|
|
@@ -7,6 +7,7 @@ import { ChartsAxis } from '../ChartsAxis';
|
|
|
7
7
|
import { ChartsTooltip } from '../ChartsTooltip';
|
|
8
8
|
import { ChartsLegend } from '../ChartsLegend';
|
|
9
9
|
import { ChartsAxisHighlight } from '../ChartsAxisHighlight';
|
|
10
|
+
import { ChartsVoronoiHandler } from '../ChartsVoronoiHandler/ChartsVoronoiHandler';
|
|
10
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
12
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
13
|
/**
|
|
@@ -26,6 +27,8 @@ const ScatterChart = /*#__PURE__*/React.forwardRef(function ScatterChart(props,
|
|
|
26
27
|
series,
|
|
27
28
|
tooltip,
|
|
28
29
|
axisHighlight,
|
|
30
|
+
voronoiMaxRadius,
|
|
31
|
+
disableVoronoi,
|
|
29
32
|
legend,
|
|
30
33
|
width,
|
|
31
34
|
height,
|
|
@@ -52,7 +55,9 @@ const ScatterChart = /*#__PURE__*/React.forwardRef(function ScatterChart(props,
|
|
|
52
55
|
xAxis: xAxis,
|
|
53
56
|
yAxis: yAxis,
|
|
54
57
|
sx: sx,
|
|
55
|
-
children: [/*#__PURE__*/_jsx(
|
|
58
|
+
children: [!disableVoronoi && /*#__PURE__*/_jsx(ChartsVoronoiHandler, {
|
|
59
|
+
voronoiMaxRadius: voronoiMaxRadius
|
|
60
|
+
}), /*#__PURE__*/_jsx(ChartsAxis, {
|
|
56
61
|
topAxis: topAxis,
|
|
57
62
|
leftAxis: leftAxis,
|
|
58
63
|
rightAxis: rightAxis,
|
|
@@ -126,6 +131,11 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
|
|
|
126
131
|
* @default false
|
|
127
132
|
*/
|
|
128
133
|
disableAxisListener: PropTypes.bool,
|
|
134
|
+
/**
|
|
135
|
+
* If true, the interaction will not use the Voronoi cell and fall back to hover events.
|
|
136
|
+
* @default false
|
|
137
|
+
*/
|
|
138
|
+
disableVoronoi: PropTypes.bool,
|
|
129
139
|
/**
|
|
130
140
|
* The height of the chart in px. If not defined, it takes the height of the parent element.
|
|
131
141
|
* @default undefined
|
|
@@ -218,6 +228,7 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
|
|
|
218
228
|
x: PropTypes.number.isRequired,
|
|
219
229
|
y: PropTypes.number.isRequired
|
|
220
230
|
})).isRequired,
|
|
231
|
+
disableHover: PropTypes.bool,
|
|
221
232
|
highlightScope: PropTypes.shape({
|
|
222
233
|
faded: PropTypes.oneOf(['global', 'none', 'series']),
|
|
223
234
|
highlighted: PropTypes.oneOf(['item', 'none', 'series'])
|
|
@@ -283,6 +294,12 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
|
|
|
283
294
|
x: PropTypes.number,
|
|
284
295
|
y: PropTypes.number
|
|
285
296
|
}),
|
|
297
|
+
/**
|
|
298
|
+
* Defines the maximal distance between a scatter point and the pointer that triggers the interaction.
|
|
299
|
+
* If `undefined`, the radius is assumed to be infinite.
|
|
300
|
+
* @default undefined
|
|
301
|
+
*/
|
|
302
|
+
voronoiMaxRadius: PropTypes.number,
|
|
286
303
|
/**
|
|
287
304
|
* The width of the chart in px. If not defined, it takes the width of the parent element.
|
|
288
305
|
* @default undefined
|
|
@@ -78,6 +78,7 @@ const SparkLineChart = /*#__PURE__*/React.forwardRef(function SparkLineChart(pro
|
|
|
78
78
|
sx: sx,
|
|
79
79
|
disableAxisListener: (!showTooltip || (tooltip == null ? void 0 : tooltip.trigger) !== 'axis') && (axisHighlight == null ? void 0 : axisHighlight.x) === 'none' && (axisHighlight == null ? void 0 : axisHighlight.y) === 'none',
|
|
80
80
|
children: [plotType === 'bar' && /*#__PURE__*/_jsx(BarPlot, {
|
|
81
|
+
skipAnimation: true,
|
|
81
82
|
slots: slots,
|
|
82
83
|
slotProps: slotProps,
|
|
83
84
|
sx: {
|
|
@@ -7,6 +7,7 @@ export const InteractionContext = /*#__PURE__*/React.createContext({
|
|
|
7
7
|
x: null,
|
|
8
8
|
y: null
|
|
9
9
|
},
|
|
10
|
+
useVoronoiInteraction: false,
|
|
10
11
|
dispatch: () => null
|
|
11
12
|
});
|
|
12
13
|
const dataReducer = (prevState, action) => {
|
|
@@ -15,6 +16,21 @@ const dataReducer = (prevState, action) => {
|
|
|
15
16
|
return _extends({}, prevState, {
|
|
16
17
|
item: action.data
|
|
17
18
|
});
|
|
19
|
+
case 'exitChart':
|
|
20
|
+
if (prevState.item === null && prevState.axis.x === null && prevState.axis.y === null) {
|
|
21
|
+
return prevState;
|
|
22
|
+
}
|
|
23
|
+
return _extends({}, prevState, {
|
|
24
|
+
axis: {
|
|
25
|
+
x: null,
|
|
26
|
+
y: null
|
|
27
|
+
},
|
|
28
|
+
item: null
|
|
29
|
+
});
|
|
30
|
+
case 'updateVoronoiUsage':
|
|
31
|
+
return _extends({}, prevState, {
|
|
32
|
+
useVoronoiInteraction: action.useVoronoiInteraction
|
|
33
|
+
});
|
|
18
34
|
case 'leaveItem':
|
|
19
35
|
if (prevState.item === null || Object.keys(action.data).some(key => action.data[key] !== prevState.item[key])) {
|
|
20
36
|
// The item is already something else
|
|
@@ -24,6 +40,9 @@ const dataReducer = (prevState, action) => {
|
|
|
24
40
|
item: null
|
|
25
41
|
});
|
|
26
42
|
case 'updateAxis':
|
|
43
|
+
if (action.data.x === prevState.axis.x && action.data.y === prevState.axis.y) {
|
|
44
|
+
return prevState;
|
|
45
|
+
}
|
|
27
46
|
return _extends({}, prevState, {
|
|
28
47
|
axis: action.data
|
|
29
48
|
});
|
|
@@ -39,7 +58,8 @@ export function InteractionProvider({
|
|
|
39
58
|
axis: {
|
|
40
59
|
x: null,
|
|
41
60
|
y: null
|
|
42
|
-
}
|
|
61
|
+
},
|
|
62
|
+
useVoronoiInteraction: false
|
|
43
63
|
});
|
|
44
64
|
const value = React.useMemo(() => _extends({}, data, {
|
|
45
65
|
dispatch
|
|
@@ -3,6 +3,10 @@ import { InteractionContext } from '../context/InteractionProvider';
|
|
|
3
3
|
import { CartesianContext } from '../context/CartesianContextProvider';
|
|
4
4
|
import { SVGContext, DrawingContext } from '../context/DrawingProvider';
|
|
5
5
|
import { isBandScale } from '../internals/isBandScale';
|
|
6
|
+
import { getSVGPoint } from '../internals/utils';
|
|
7
|
+
function getAsANumber(value) {
|
|
8
|
+
return value instanceof Date ? value.getTime() : value;
|
|
9
|
+
}
|
|
6
10
|
export const useAxisEvents = disableAxisListener => {
|
|
7
11
|
const svgRef = React.useContext(SVGContext);
|
|
8
12
|
const {
|
|
@@ -48,17 +52,18 @@ export const useAxisEvents = disableAxisListener => {
|
|
|
48
52
|
value
|
|
49
53
|
};
|
|
50
54
|
}
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
const valueAsNumber = getAsANumber(value);
|
|
56
|
+
const closestIndex = axisData == null ? void 0 : axisData.findIndex((pointValue, index) => {
|
|
57
|
+
const v = getAsANumber(pointValue);
|
|
58
|
+
if (v > valueAsNumber) {
|
|
59
|
+
if (index === 0 || Math.abs(valueAsNumber - v) <= Math.abs(valueAsNumber - getAsANumber(axisData[index - 1]))) {
|
|
55
60
|
return true;
|
|
56
61
|
}
|
|
57
62
|
}
|
|
58
|
-
if (v <=
|
|
63
|
+
if (v <= valueAsNumber) {
|
|
59
64
|
if (index === axisData.length - 1 ||
|
|
60
65
|
// @ts-ignore
|
|
61
|
-
Math.abs(value - v) < Math.abs(value - axisData[index + 1])) {
|
|
66
|
+
Math.abs(value - v) < Math.abs(value - getAsANumber(axisData[index + 1]))) {
|
|
62
67
|
return true;
|
|
63
68
|
}
|
|
64
69
|
}
|
|
@@ -84,37 +89,25 @@ export const useAxisEvents = disableAxisListener => {
|
|
|
84
89
|
y: -1
|
|
85
90
|
};
|
|
86
91
|
dispatch({
|
|
87
|
-
type: '
|
|
88
|
-
data: {
|
|
89
|
-
x: null,
|
|
90
|
-
y: null
|
|
91
|
-
}
|
|
92
|
+
type: 'exitChart'
|
|
92
93
|
});
|
|
93
94
|
};
|
|
94
95
|
const handleMouseMove = event => {
|
|
95
|
-
|
|
96
|
-
const pt = svgRef.current.createSVGPoint();
|
|
97
|
-
pt.x = event.clientX;
|
|
98
|
-
pt.y = event.clientY;
|
|
99
|
-
const svgPt = pt.matrixTransform(svgRef.current.getScreenCTM().inverse());
|
|
96
|
+
const svgPoint = getSVGPoint(svgRef.current, event);
|
|
100
97
|
mousePosition.current = {
|
|
101
|
-
x:
|
|
102
|
-
y:
|
|
98
|
+
x: svgPoint.x,
|
|
99
|
+
y: svgPoint.y
|
|
103
100
|
};
|
|
104
|
-
const outsideX =
|
|
105
|
-
const outsideY =
|
|
101
|
+
const outsideX = svgPoint.x < left || svgPoint.x > left + width;
|
|
102
|
+
const outsideY = svgPoint.y < top || svgPoint.y > top + height;
|
|
106
103
|
if (outsideX || outsideY) {
|
|
107
104
|
dispatch({
|
|
108
|
-
type: '
|
|
109
|
-
data: {
|
|
110
|
-
x: null,
|
|
111
|
-
y: null
|
|
112
|
-
}
|
|
105
|
+
type: 'exitChart'
|
|
113
106
|
});
|
|
114
107
|
return;
|
|
115
108
|
}
|
|
116
|
-
const newStateX = getUpdate(xAxis[usedXAxis],
|
|
117
|
-
const newStateY = getUpdate(yAxis[usedYAxis],
|
|
109
|
+
const newStateX = getUpdate(xAxis[usedXAxis], svgPoint.x);
|
|
110
|
+
const newStateY = getUpdate(yAxis[usedYAxis], svgPoint.y);
|
|
118
111
|
dispatch({
|
|
119
112
|
type: 'updateAxis',
|
|
120
113
|
data: {
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { InteractionContext } from '../context/InteractionProvider';
|
|
3
3
|
import { HighlighContext } from '../context/HighlightProvider';
|
|
4
|
-
export const useInteractionItemProps = scope => {
|
|
4
|
+
export const useInteractionItemProps = (scope, skip) => {
|
|
5
5
|
const {
|
|
6
6
|
dispatch: dispatchInteraction
|
|
7
7
|
} = React.useContext(InteractionContext);
|
|
8
8
|
const {
|
|
9
9
|
dispatch: dispatchHighlight
|
|
10
10
|
} = React.useContext(HighlighContext);
|
|
11
|
+
if (skip) {
|
|
12
|
+
return () => ({});
|
|
13
|
+
}
|
|
11
14
|
const getInteractionItemProps = data => {
|
|
12
15
|
const onMouseEnter = () => {
|
|
13
16
|
dispatchInteraction({
|
package/esm/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export * from './ChartsYAxis';
|
|
|
11
11
|
export * from './ChartsTooltip';
|
|
12
12
|
export * from './ChartsLegend';
|
|
13
13
|
export * from './ChartsAxisHighlight';
|
|
14
|
+
export * from './ChartsVoronoiHandler';
|
|
14
15
|
export * from './BarChart';
|
|
15
16
|
export * from './LineChart';
|
|
16
17
|
export * from './PieChart';
|
package/esm/internals/utils.js
CHANGED
|
@@ -2,4 +2,15 @@
|
|
|
2
2
|
export function getSymbol(shape) {
|
|
3
3
|
const symbolNames = 'circle cross diamond square star triangle wye'.split(/ /);
|
|
4
4
|
return symbolNames.indexOf(shape) || 0;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Transform mouse event position to corrdinates inside the SVG.
|
|
8
|
+
* @param svg The SVG element
|
|
9
|
+
* @param event The mouseEvent to transform
|
|
10
|
+
*/
|
|
11
|
+
export function getSVGPoint(svg, event) {
|
|
12
|
+
const pt = svg.createSVGPoint();
|
|
13
|
+
pt.x = event.clientX;
|
|
14
|
+
pt.y = event.clientY;
|
|
15
|
+
return pt.matrixTransform(svg.getScreenCTM().inverse());
|
|
5
16
|
}
|
package/hooks/useAxisEvents.js
CHANGED
|
@@ -9,8 +9,12 @@ var _InteractionProvider = require("../context/InteractionProvider");
|
|
|
9
9
|
var _CartesianContextProvider = require("../context/CartesianContextProvider");
|
|
10
10
|
var _DrawingProvider = require("../context/DrawingProvider");
|
|
11
11
|
var _isBandScale = require("../internals/isBandScale");
|
|
12
|
+
var _utils = require("../internals/utils");
|
|
12
13
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
13
14
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
15
|
+
function getAsANumber(value) {
|
|
16
|
+
return value instanceof Date ? value.getTime() : value;
|
|
17
|
+
}
|
|
14
18
|
const useAxisEvents = disableAxisListener => {
|
|
15
19
|
const svgRef = React.useContext(_DrawingProvider.SVGContext);
|
|
16
20
|
const {
|
|
@@ -56,17 +60,18 @@ const useAxisEvents = disableAxisListener => {
|
|
|
56
60
|
value
|
|
57
61
|
};
|
|
58
62
|
}
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
const valueAsNumber = getAsANumber(value);
|
|
64
|
+
const closestIndex = axisData?.findIndex((pointValue, index) => {
|
|
65
|
+
const v = getAsANumber(pointValue);
|
|
66
|
+
if (v > valueAsNumber) {
|
|
67
|
+
if (index === 0 || Math.abs(valueAsNumber - v) <= Math.abs(valueAsNumber - getAsANumber(axisData[index - 1]))) {
|
|
63
68
|
return true;
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
|
-
if (v <=
|
|
71
|
+
if (v <= valueAsNumber) {
|
|
67
72
|
if (index === axisData.length - 1 ||
|
|
68
73
|
// @ts-ignore
|
|
69
|
-
Math.abs(value - v) < Math.abs(value - axisData[index + 1])) {
|
|
74
|
+
Math.abs(value - v) < Math.abs(value - getAsANumber(axisData[index + 1]))) {
|
|
70
75
|
return true;
|
|
71
76
|
}
|
|
72
77
|
}
|
|
@@ -92,37 +97,25 @@ const useAxisEvents = disableAxisListener => {
|
|
|
92
97
|
y: -1
|
|
93
98
|
};
|
|
94
99
|
dispatch({
|
|
95
|
-
type: '
|
|
96
|
-
data: {
|
|
97
|
-
x: null,
|
|
98
|
-
y: null
|
|
99
|
-
}
|
|
100
|
+
type: 'exitChart'
|
|
100
101
|
});
|
|
101
102
|
};
|
|
102
103
|
const handleMouseMove = event => {
|
|
103
|
-
|
|
104
|
-
const pt = svgRef.current.createSVGPoint();
|
|
105
|
-
pt.x = event.clientX;
|
|
106
|
-
pt.y = event.clientY;
|
|
107
|
-
const svgPt = pt.matrixTransform(svgRef.current.getScreenCTM().inverse());
|
|
104
|
+
const svgPoint = (0, _utils.getSVGPoint)(svgRef.current, event);
|
|
108
105
|
mousePosition.current = {
|
|
109
|
-
x:
|
|
110
|
-
y:
|
|
106
|
+
x: svgPoint.x,
|
|
107
|
+
y: svgPoint.y
|
|
111
108
|
};
|
|
112
|
-
const outsideX =
|
|
113
|
-
const outsideY =
|
|
109
|
+
const outsideX = svgPoint.x < left || svgPoint.x > left + width;
|
|
110
|
+
const outsideY = svgPoint.y < top || svgPoint.y > top + height;
|
|
114
111
|
if (outsideX || outsideY) {
|
|
115
112
|
dispatch({
|
|
116
|
-
type: '
|
|
117
|
-
data: {
|
|
118
|
-
x: null,
|
|
119
|
-
y: null
|
|
120
|
-
}
|
|
113
|
+
type: 'exitChart'
|
|
121
114
|
});
|
|
122
115
|
return;
|
|
123
116
|
}
|
|
124
|
-
const newStateX = getUpdate(xAxis[usedXAxis],
|
|
125
|
-
const newStateY = getUpdate(yAxis[usedYAxis],
|
|
117
|
+
const newStateX = getUpdate(xAxis[usedXAxis], svgPoint.x);
|
|
118
|
+
const newStateY = getUpdate(yAxis[usedYAxis], svgPoint.y);
|
|
126
119
|
dispatch({
|
|
127
120
|
type: 'updateAxis',
|
|
128
121
|
data: {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { HighlightScope } from '../context/HighlightProvider';
|
|
2
2
|
import { SeriesItemIdentifier } from '../models';
|
|
3
|
-
export declare const useInteractionItemProps: (scope?: Partial<HighlightScope
|
|
3
|
+
export declare const useInteractionItemProps: (scope?: Partial<HighlightScope>, skip?: boolean) => (() => {}) | ((data: SeriesItemIdentifier) => {
|
|
4
4
|
onMouseEnter: () => void;
|
|
5
5
|
onMouseLeave: () => void;
|
|
6
|
-
};
|
|
6
|
+
});
|
|
7
7
|
export declare const getIsHighlighted: (selectedItem: SeriesItemIdentifier | null, currentItem: SeriesItemIdentifier, highlightScope?: Partial<HighlightScope>) => boolean;
|
|
8
8
|
export declare const getIsFaded: (selectedItem: SeriesItemIdentifier | null, currentItem: SeriesItemIdentifier, highlightScope?: Partial<HighlightScope>) => boolean;
|
|
@@ -9,13 +9,16 @@ var _InteractionProvider = require("../context/InteractionProvider");
|
|
|
9
9
|
var _HighlightProvider = require("../context/HighlightProvider");
|
|
10
10
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
11
11
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
12
|
-
const useInteractionItemProps = scope => {
|
|
12
|
+
const useInteractionItemProps = (scope, skip) => {
|
|
13
13
|
const {
|
|
14
14
|
dispatch: dispatchInteraction
|
|
15
15
|
} = React.useContext(_InteractionProvider.InteractionContext);
|
|
16
16
|
const {
|
|
17
17
|
dispatch: dispatchHighlight
|
|
18
18
|
} = React.useContext(_HighlightProvider.HighlighContext);
|
|
19
|
+
if (skip) {
|
|
20
|
+
return () => ({});
|
|
21
|
+
}
|
|
19
22
|
const getInteractionItemProps = data => {
|
|
20
23
|
const onMouseEnter = () => {
|
|
21
24
|
dispatchInteraction({
|
package/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from './ChartsYAxis';
|
|
|
11
11
|
export * from './ChartsTooltip';
|
|
12
12
|
export * from './ChartsLegend';
|
|
13
13
|
export * from './ChartsAxisHighlight';
|
|
14
|
+
export * from './ChartsVoronoiHandler';
|
|
14
15
|
export * from './BarChart';
|
|
15
16
|
export * from './LineChart';
|
|
16
17
|
export * from './PieChart';
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @mui/x-charts v7.0.0-alpha.
|
|
2
|
+
* @mui/x-charts v7.0.0-alpha.4
|
|
3
3
|
*
|
|
4
4
|
* @license MIT
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
@@ -153,6 +153,17 @@ Object.keys(_ChartsAxisHighlight).forEach(function (key) {
|
|
|
153
153
|
}
|
|
154
154
|
});
|
|
155
155
|
});
|
|
156
|
+
var _ChartsVoronoiHandler = require("./ChartsVoronoiHandler");
|
|
157
|
+
Object.keys(_ChartsVoronoiHandler).forEach(function (key) {
|
|
158
|
+
if (key === "default" || key === "__esModule") return;
|
|
159
|
+
if (key in exports && exports[key] === _ChartsVoronoiHandler[key]) return;
|
|
160
|
+
Object.defineProperty(exports, key, {
|
|
161
|
+
enumerable: true,
|
|
162
|
+
get: function () {
|
|
163
|
+
return _ChartsVoronoiHandler[key];
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
156
167
|
var _BarChart = require("./BarChart");
|
|
157
168
|
Object.keys(_BarChart).forEach(function (key) {
|
|
158
169
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -77,6 +77,7 @@ export declare function defaultizeColor(series: AllSeriesType, seriesIndex: numb
|
|
|
77
77
|
data: import("../models/seriesType").ScatterValueType[];
|
|
78
78
|
markerSize?: number | undefined;
|
|
79
79
|
label?: string | undefined;
|
|
80
|
+
disableHover?: boolean | undefined;
|
|
80
81
|
id?: string | undefined;
|
|
81
82
|
color: string;
|
|
82
83
|
valueFormatter?: ((value: import("../models/seriesType").ScatterValueType) => string) | undefined;
|
package/internals/utils.d.ts
CHANGED
|
@@ -4,4 +4,10 @@ type Without<T, U> = {
|
|
|
4
4
|
[P in Exclude<keyof T, keyof U>]?: never;
|
|
5
5
|
};
|
|
6
6
|
export type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
|
|
7
|
+
/**
|
|
8
|
+
* Transform mouse event position to corrdinates inside the SVG.
|
|
9
|
+
* @param svg The SVG element
|
|
10
|
+
* @param event The mouseEvent to transform
|
|
11
|
+
*/
|
|
12
|
+
export declare function getSVGPoint(svg: SVGSVGElement, event: MouseEvent): DOMPoint;
|
|
7
13
|
export {};
|
package/internals/utils.js
CHANGED
|
@@ -3,9 +3,21 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.getSVGPoint = getSVGPoint;
|
|
6
7
|
exports.getSymbol = getSymbol;
|
|
7
8
|
// Returns the index of a defined shape
|
|
8
9
|
function getSymbol(shape) {
|
|
9
10
|
const symbolNames = 'circle cross diamond square star triangle wye'.split(/ /);
|
|
10
11
|
return symbolNames.indexOf(shape) || 0;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Transform mouse event position to corrdinates inside the SVG.
|
|
15
|
+
* @param svg The SVG element
|
|
16
|
+
* @param event The mouseEvent to transform
|
|
17
|
+
*/
|
|
18
|
+
function getSVGPoint(svg, event) {
|
|
19
|
+
const pt = svg.createSVGPoint();
|
|
20
|
+
pt.x = event.clientX;
|
|
21
|
+
pt.y = event.clientY;
|
|
22
|
+
return pt.matrixTransform(svg.getScreenCTM().inverse());
|
|
11
23
|
}
|