UNPKG

@grafana/ui

Version:
108 lines (105 loc) 3.51 kB
import { useLayoutEffect } from 'react'; import uPlot from 'uplot'; "use strict"; const MIN_PAN_DIST = 5; const calculatePanRange = (timeFrom, timeTo, dragPixels, plotWidth) => { const unitsPerPx = (timeTo - timeFrom) / (plotWidth / uPlot.pxRatio); const timeShift = dragPixels * unitsPerPx; return { from: timeFrom - timeShift, to: timeTo - timeShift }; }; const setupXAxisPan = (u, config, queryZoom) => { let xAxes = u.root.querySelectorAll(".u-axis"); let xAxis = xAxes[0]; if (!xAxis || !(xAxis instanceof HTMLElement)) { return () => { }; } const xAxisEl = xAxis; let activeMoveListener = null; let activeUpListener = null; const handleMouseEnter = () => { xAxisEl.style.cursor = "grab"; }; const handleMouseLeave = () => { xAxisEl.style.cursor = ""; }; const handleMouseDown = (e) => { if (!(e instanceof MouseEvent)) { return; } e.preventDefault(); xAxisEl.style.cursor = "grabbing"; let xScale = u.scales.x; let rect = u.over.getBoundingClientRect(); let startX = e.clientX - rect.left; let startMin = xScale.min; let startMax = xScale.max; const onMove = (e2) => { e2.preventDefault(); let currentX = e2.clientX - rect.left; let dragPixels = currentX - startX; const { from, to } = calculatePanRange(startMin, startMax, dragPixels, u.bbox.width); config.setState({ isPanning: true, min: from, max: to }); u.setScale("x", { min: from, max: to }); }; const onUp = (e2) => { let endX = e2.clientX - rect.left; let dragPixels = endX - startX; xAxisEl.style.cursor = "grab"; const isSignificantDrag = Math.abs(dragPixels) >= MIN_PAN_DIST; if (isSignificantDrag) { const newRange = calculatePanRange(startMin, startMax, dragPixels, u.bbox.width); config.setState({ isPanning: true, min: newRange.from, max: newRange.to, isTimeRangePending: true }); queryZoom(newRange); } else { config.setState({ isPanning: false }); } document.removeEventListener("mousemove", onMove); document.removeEventListener("mouseup", onUp); activeMoveListener = null; activeUpListener = null; }; activeMoveListener = onMove; activeUpListener = onUp; document.addEventListener("mousemove", onMove); document.addEventListener("mouseup", onUp); }; xAxisEl.addEventListener("mouseenter", handleMouseEnter); xAxisEl.addEventListener("mouseleave", handleMouseLeave); xAxisEl.addEventListener("mousedown", handleMouseDown); return () => { xAxisEl.removeEventListener("mouseenter", handleMouseEnter); xAxisEl.removeEventListener("mouseleave", handleMouseLeave); xAxisEl.removeEventListener("mousedown", handleMouseDown); if (activeMoveListener) { document.removeEventListener("mousemove", activeMoveListener); } if (activeUpListener) { document.removeEventListener("mouseup", activeUpListener); } }; }; const XAxisInteractionAreaPlugin = ({ config, queryZoom }) => { useLayoutEffect(() => { let cleanup; config.addHook("init", (u) => { if (queryZoom != null) { cleanup = setupXAxisPan(u, config, queryZoom); } }); return () => { if (cleanup) { cleanup(); } }; }, [config, queryZoom]); return null; }; export { XAxisInteractionAreaPlugin, calculatePanRange, setupXAxisPan }; //# sourceMappingURL=XAxisInteractionAreaPlugin.mjs.map