@grafana/ui
Version:
Grafana Components Library
118 lines (111 loc) • 3.86 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var uPlot = require('uplot');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
var uPlot__default = /*#__PURE__*/_interopDefaultCompat(uPlot);
;
const MIN_PAN_DIST = 5;
const calculatePanRange = (timeFrom, timeTo, dragPixels, plotWidth) => {
const unitsPerPx = (timeTo - timeFrom) / (plotWidth / uPlot__default.default.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 }) => {
React.useLayoutEffect(() => {
let cleanup;
config.addHook("init", (u) => {
if (queryZoom != null) {
cleanup = setupXAxisPan(u, config, queryZoom);
}
});
return () => {
if (cleanup) {
cleanup();
}
};
}, [config, queryZoom]);
return null;
};
exports.XAxisInteractionAreaPlugin = XAxisInteractionAreaPlugin;
exports.calculatePanRange = calculatePanRange;
exports.setupXAxisPan = setupXAxisPan;
//# sourceMappingURL=XAxisInteractionAreaPlugin.cjs.map