UNPKG

@mui/x-charts

Version:

The community edition of MUI X Charts components.

216 lines (213 loc) 7.9 kB
"use strict"; 'use client'; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useChartClosestPoint = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect")); var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback")); var _getSVGPoint = require("../../../getSVGPoint"); var _useChartCartesianAxis = require("../useChartCartesianAxis"); var _useChartSeries = require("../../corePlugins/useChartSeries/useChartSeries.selectors"); var _findClosestPoints = require("./findClosestPoints"); const useChartClosestPoint = ({ svgRef, params, store, instance }) => { const { disableVoronoi, voronoiMaxRadius, onItemClick } = params; const { axis: xAxis, axisIds: xAxisIds } = store.use(_useChartCartesianAxis.selectorChartXAxis); const { axis: yAxis, axisIds: yAxisIds } = store.use(_useChartCartesianAxis.selectorChartYAxis); const zoomIsInteracting = store.use(_useChartCartesianAxis.selectorChartZoomIsInteracting); const { series, seriesOrder } = store.use(_useChartSeries.selectorChartSeriesProcessed)?.scatter ?? {}; const flatbushMap = store.use(zoomIsInteracting ? _useChartCartesianAxis.selectorChartSeriesEmptyFlatbushMap : _useChartCartesianAxis.selectorChartSeriesFlatbushMap); const defaultXAxisId = xAxisIds[0]; const defaultYAxisId = yAxisIds[0]; (0, _useEnhancedEffect.default)(() => { store.set('voronoi', { isVoronoiEnabled: !disableVoronoi }); }, [store, disableVoronoi]); React.useEffect(() => { if (svgRef.current === null || disableVoronoi) { return undefined; } const element = svgRef.current; function getClosestPoint(event) { // Get mouse coordinate in global SVG space const svgPoint = (0, _getSVGPoint.getSVGPoint)(element, event); if (!instance.isPointInside(svgPoint.x, svgPoint.y)) { return 'outside-chart'; } let closestPoint = undefined; for (const seriesId of seriesOrder ?? []) { const aSeries = (series ?? {})[seriesId]; const flatbush = flatbushMap.get(seriesId); if (!flatbush) { continue; } const xAxisId = aSeries.xAxisId ?? defaultXAxisId; const yAxisId = aSeries.yAxisId ?? defaultYAxisId; const xAxisZoom = (0, _useChartCartesianAxis.selectorChartAxisZoomData)(store.state, xAxisId); const yAxisZoom = (0, _useChartCartesianAxis.selectorChartAxisZoomData)(store.state, yAxisId); const maxRadius = voronoiMaxRadius === 'item' ? aSeries.markerSize : voronoiMaxRadius; const xZoomStart = (xAxisZoom?.start ?? 0) / 100; const xZoomEnd = (xAxisZoom?.end ?? 100) / 100; const yZoomStart = (yAxisZoom?.start ?? 0) / 100; const yZoomEnd = (yAxisZoom?.end ?? 100) / 100; const xScale = xAxis[xAxisId].scale; const yScale = yAxis[yAxisId].scale; const closestPointIndex = (0, _findClosestPoints.findClosestPoints)(flatbush, aSeries.data, xScale, yScale, xZoomStart, xZoomEnd, yZoomStart, yZoomEnd, svgPoint.x, svgPoint.y, maxRadius)[0]; if (closestPointIndex === undefined) { continue; } const point = aSeries.data[closestPointIndex]; const scaledX = xScale(point.x); const scaledY = yScale(point.y); const distSq = (scaledX - svgPoint.x) ** 2 + (scaledY - svgPoint.y) ** 2; if (closestPoint === undefined || distSq < closestPoint.distanceSq) { closestPoint = { dataIndex: closestPointIndex, seriesId, distanceSq: distSq }; } } if (closestPoint === undefined) { return 'no-point-found'; } return { seriesId: closestPoint.seriesId, dataIndex: closestPoint.dataIndex }; } // Clean the interaction when the mouse leaves the chart. const moveEndHandler = instance.addInteractionListener('moveEnd', event => { if (!event.detail.activeGestures.pan) { instance.cleanInteraction?.(); instance.clearHighlight?.(); instance.removeTooltipItem?.(); } }); const panEndHandler = instance.addInteractionListener('panEnd', event => { if (!event.detail.activeGestures.move) { instance.cleanInteraction?.(); instance.clearHighlight?.(); instance.removeTooltipItem?.(); } }); const pressEndHandler = instance.addInteractionListener('quickPressEnd', event => { if (!event.detail.activeGestures.move && !event.detail.activeGestures.pan) { instance.cleanInteraction?.(); instance.clearHighlight?.(); instance.removeTooltipItem?.(); } }); const gestureHandler = event => { const closestPoint = getClosestPoint(event.detail.srcEvent); if (closestPoint === 'outside-chart') { instance.cleanInteraction?.(); instance.clearHighlight?.(); instance.removeTooltipItem?.(); return; } if (closestPoint === 'outside-voronoi-max-radius' || closestPoint === 'no-point-found') { instance.removeTooltipItem?.(); instance.clearHighlight?.(); instance.removeTooltipItem?.(); return; } const { seriesId, dataIndex } = closestPoint; instance.setTooltipItem?.({ type: 'scatter', seriesId, dataIndex }); instance.setLastUpdateSource?.('pointer'); instance.setHighlight?.({ seriesId, dataIndex }); }; const tapHandler = instance.addInteractionListener('tap', event => { const closestPoint = getClosestPoint(event.detail.srcEvent); if (typeof closestPoint !== 'string' && onItemClick) { const { seriesId, dataIndex } = closestPoint; onItemClick(event.detail.srcEvent, { type: 'scatter', seriesId, dataIndex }); } }); const moveHandler = instance.addInteractionListener('move', gestureHandler); const panHandler = instance.addInteractionListener('pan', gestureHandler); const pressHandler = instance.addInteractionListener('quickPress', gestureHandler); return () => { tapHandler.cleanup(); moveHandler.cleanup(); moveEndHandler.cleanup(); panHandler.cleanup(); panEndHandler.cleanup(); pressHandler.cleanup(); pressEndHandler.cleanup(); }; }, [svgRef, yAxis, xAxis, voronoiMaxRadius, onItemClick, disableVoronoi, instance, seriesOrder, series, flatbushMap, defaultXAxisId, defaultYAxisId, store]); // Instance implementation const enableVoronoiCallback = (0, _useEventCallback.default)(() => { store.set('voronoi', { isVoronoiEnabled: true }); }); const disableVoronoiCallback = (0, _useEventCallback.default)(() => { store.set('voronoi', { isVoronoiEnabled: false }); }); return { instance: { enableVoronoi: enableVoronoiCallback, disableVoronoi: disableVoronoiCallback } }; }; exports.useChartClosestPoint = useChartClosestPoint; useChartClosestPoint.getDefaultizedParams = ({ params }) => (0, _extends2.default)({}, params, { disableVoronoi: params.disableVoronoi ?? !params.series.some(item => item.type === 'scatter') }); useChartClosestPoint.getInitialState = params => ({ voronoi: { isVoronoiEnabled: !params.disableVoronoi } }); useChartClosestPoint.params = { disableVoronoi: true, voronoiMaxRadius: true, onItemClick: true };