UNPKG

@mui/x-charts

Version:

The community edition of MUI X Charts components.

74 lines (72 loc) 2.5 kB
'use client'; import * as React from 'react'; import useEventCallback from '@mui/utils/useEventCallback'; import { useSvgRef } from "../../../../hooks/index.js"; import { useStore } from "../../../store/useStore.js"; import { useChartContext } from "../../../../context/ChartProvider/index.js"; import { getSVGPoint } from "../../../getSVGPoint.js"; /** * Hook to get pointer interaction props for chart items. */ export function useRegisterPointerInteractions(getItemAtPosition, onItemEnter, onItemLeave) { const { instance } = useChartContext(); const svgRef = useSvgRef(); const store = useStore(); const interactionActive = React.useRef(false); const lastItemRef = React.useRef(undefined); const onItemEnterRef = useEventCallback(() => onItemEnter?.()); const onItemLeaveRef = useEventCallback(() => onItemLeave?.()); React.useEffect(() => { const svg = svgRef.current; if (!svg) { return undefined; } function onPointerEnter() { interactionActive.current = true; } function reset() { const lastItem = lastItemRef.current; if (lastItem) { lastItemRef.current = undefined; instance.removeTooltipItem(lastItem); instance.clearHighlight(); onItemLeaveRef(); } } function onPointerLeave() { interactionActive.current = false; reset(); } const onPointerMove = function onPointerMove(event) { const svgPoint = getSVGPoint(svg, event); if (!instance.isPointInside(svgPoint.x, svgPoint.y)) { reset(); return; } const item = getItemAtPosition(store.state, svgPoint); if (item) { instance.setLastUpdateSource('pointer'); instance.setTooltipItem(item); instance.setHighlight(item); onItemEnterRef(); lastItemRef.current = item; } else { reset(); } }; svg.addEventListener('pointerleave', onPointerLeave); svg.addEventListener('pointermove', onPointerMove); svg.addEventListener('pointerenter', onPointerEnter); return () => { svg.removeEventListener('pointerenter', onPointerEnter); svg.removeEventListener('pointermove', onPointerMove); svg.removeEventListener('pointerleave', onPointerLeave); /* Clean up state if this item is unmounted while active. */ if (interactionActive.current) { onPointerLeave(); } }; }, [getItemAtPosition, instance, onItemEnterRef, onItemLeaveRef, store, svgRef]); }