UNPKG

@mui/x-charts

Version:

The community edition of the charts components (MUI X).

122 lines (121 loc) 4.5 kB
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import * as React from 'react'; import { InteractionContext } from '../context/InteractionProvider'; import { CartesianContext } from '../context/CartesianContextProvider'; import { SVGContext, DrawingContext } from '../context/DrawingProvider'; import { isBandScale } from '../internals/isBandScale'; import { getSVGPoint } from '../internals/utils'; function getAsANumber(value) { return value instanceof Date ? value.getTime() : value; } export var useAxisEvents = function useAxisEvents(disableAxisListener) { var svgRef = React.useContext(SVGContext); var _React$useContext = React.useContext(DrawingContext), width = _React$useContext.width, height = _React$useContext.height, top = _React$useContext.top, left = _React$useContext.left; var _React$useContext2 = React.useContext(CartesianContext), xAxis = _React$useContext2.xAxis, yAxis = _React$useContext2.yAxis, xAxisIds = _React$useContext2.xAxisIds, yAxisIds = _React$useContext2.yAxisIds; var _React$useContext3 = React.useContext(InteractionContext), dispatch = _React$useContext3.dispatch; var usedXAxis = xAxisIds[0]; var usedYAxis = yAxisIds[0]; // Use a ref to avoid rerendering on every mousemove event. var mousePosition = React.useRef({ x: -1, y: -1 }); React.useEffect(function () { var element = svgRef.current; if (element === null || disableAxisListener) { return function () {}; } var getUpdate = function getUpdate(axisConfig, mouseValue) { if (usedXAxis === null) { return null; } var scale = axisConfig.scale, axisData = axisConfig.data; if (!isBandScale(scale)) { var value = scale.invert(mouseValue); if (axisData === undefined) { return { value: value }; } var valueAsNumber = getAsANumber(value); var closestIndex = axisData == null ? void 0 : axisData.findIndex(function (pointValue, index) { var v = getAsANumber(pointValue); if (v > valueAsNumber) { if (index === 0 || Math.abs(valueAsNumber - v) <= Math.abs(valueAsNumber - getAsANumber(axisData[index - 1]))) { return true; } } if (v <= valueAsNumber) { if (index === axisData.length - 1 || // @ts-ignore Math.abs(value - v) < Math.abs(value - getAsANumber(axisData[index + 1]))) { return true; } } return false; }); return { value: closestIndex !== undefined && closestIndex >= 0 ? axisData[closestIndex] : value, index: closestIndex }; } var dataIndex = scale.bandwidth() === 0 ? Math.floor((mouseValue - Math.min.apply(Math, _toConsumableArray(scale.range())) + scale.step() / 2) / scale.step()) : Math.floor((mouseValue - Math.min.apply(Math, _toConsumableArray(scale.range()))) / scale.step()); if (dataIndex < 0 || dataIndex >= axisData.length) { return null; } return { index: dataIndex, value: axisData[dataIndex] }; }; var handleMouseOut = function handleMouseOut() { mousePosition.current = { x: -1, y: -1 }; dispatch({ type: 'exitChart' }); }; var handleMouseMove = function handleMouseMove(event) { var svgPoint = getSVGPoint(svgRef.current, event); mousePosition.current = { x: svgPoint.x, y: svgPoint.y }; var outsideX = svgPoint.x < left || svgPoint.x > left + width; var outsideY = svgPoint.y < top || svgPoint.y > top + height; if (outsideX || outsideY) { dispatch({ type: 'exitChart' }); return; } var newStateX = getUpdate(xAxis[usedXAxis], svgPoint.x); var newStateY = getUpdate(yAxis[usedYAxis], svgPoint.y); dispatch({ type: 'updateAxis', data: { x: newStateX, y: newStateY } }); }; element.addEventListener('mouseout', handleMouseOut); element.addEventListener('mousemove', handleMouseMove); return function () { element.removeEventListener('mouseout', handleMouseOut); element.removeEventListener('mousemove', handleMouseMove); }; }, [svgRef, dispatch, left, width, top, height, usedYAxis, yAxis, usedXAxis, xAxis, disableAxisListener]); };