@trap_stevo/legendarybuilderproreact-ui
Version:
The legendary UI & utility API that makes your application a legendary application. ~ Created by Steven Compton
873 lines • 36.6 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import React, { useState, useEffect, useRef, useMemo, useCallback, useLayoutEffect } from "react";
import { createPortal } from "react-dom";
import { motion, AnimatePresence } from "framer-motion";
var minYRange = 1e-6;
function clampYRange(min, max, clamp) {
var ySource = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
if (clamp === true) {
return [Math.max(min, Math.min.apply(Math, _toConsumableArray(ySource))), Math.min(max, Math.max.apply(Math, _toConsumableArray(ySource)))];
}
if (Array.isArray(clamp) && clamp.length === 2) {
return [Math.max(min, clamp[0]), Math.min(max, clamp[1])];
}
return [min, max];
}
;
function HUDMultiLineChart(_ref) {
var _ref$toolTipContainer = _ref.toolTipContainerAnimationTransitionConfigurationSettings,
toolTipContainerAnimationTransitionConfigurationSettings = _ref$toolTipContainer === void 0 ? {} : _ref$toolTipContainer,
_ref$toolTipContainer2 = _ref.toolTipContainerInitialAnimationConfigurationSettings,
toolTipContainerInitialAnimationConfigurationSettings = _ref$toolTipContainer2 === void 0 ? {} : _ref$toolTipContainer2,
_ref$toolTipContainer3 = _ref.toolTipContainerExitAnimationConfigurationSettings,
toolTipContainerExitAnimationConfigurationSettings = _ref$toolTipContainer3 === void 0 ? {} : _ref$toolTipContainer3,
_ref$toolTipContainer4 = _ref.toolTipContainerAnimationConfigurationSettings,
toolTipContainerAnimationConfigurationSettings = _ref$toolTipContainer4 === void 0 ? {} : _ref$toolTipContainer4,
_ref$multiLineChartCo = _ref.multiLineChartContainerConfigurationSettings,
multiLineChartContainerConfigurationSettings = _ref$multiLineChartCo === void 0 ? {} : _ref$multiLineChartCo,
_ref$legendSeriesIndi = _ref.legendSeriesIndicatorConfigurationSettings,
legendSeriesIndicatorConfigurationSettings = _ref$legendSeriesIndi === void 0 ? {} : _ref$legendSeriesIndi,
_ref$toolTipContainer5 = _ref.toolTipContainerConfigurationSettings,
toolTipContainerConfigurationSettings = _ref$toolTipContainer5 === void 0 ? {} : _ref$toolTipContainer5,
_ref$multiLineChartCo2 = _ref.multiLineChartConfigurationSettings,
multiLineChartConfigurationSettings = _ref$multiLineChartCo2 === void 0 ? {} : _ref$multiLineChartCo2,
_ref$yAxisTickLabelCo = _ref.yAxisTickLabelConfigurationSettings,
yAxisTickLabelConfigurationSettings = _ref$yAxisTickLabelCo === void 0 ? {} : _ref$yAxisTickLabelCo,
_ref$xAxisTickLabelCo = _ref.xAxisTickLabelConfigurationSettings,
xAxisTickLabelConfigurationSettings = _ref$xAxisTickLabelCo === void 0 ? {} : _ref$xAxisTickLabelCo,
_ref$legendSeriesConf = _ref.legendSeriesConfigurationSettings,
legendSeriesConfigurationSettings = _ref$legendSeriesConf === void 0 ? {} : _ref$legendSeriesConf,
_ref$chartLegendConfi = _ref.chartLegendConfigurationSettings,
chartLegendConfigurationSettings = _ref$chartLegendConfi === void 0 ? {} : _ref$chartLegendConfi,
_ref$seriesLabelConfi = _ref.seriesLabelConfigurationSettings,
seriesLabelConfigurationSettings = _ref$seriesLabelConfi === void 0 ? {} : _ref$seriesLabelConfi,
_ref$yAxisTitleConfig = _ref.yAxisTitleConfigurationSettings,
yAxisTitleConfigurationSettings = _ref$yAxisTitleConfig === void 0 ? {} : _ref$yAxisTitleConfig,
_ref$xAxisTitleConfig = _ref.xAxisTitleConfigurationSettings,
xAxisTitleConfigurationSettings = _ref$xAxisTitleConfig === void 0 ? {} : _ref$xAxisTitleConfig,
_ref$multiLineChartCo3 = _ref.multiLineChartContainerConfigurations,
multiLineChartContainerConfigurations = _ref$multiLineChartCo3 === void 0 ? {} : _ref$multiLineChartCo3,
_ref$selectionIndicat = _ref.selectionIndicatorLineConfigurations,
selectionIndicatorLineConfigurations = _ref$selectionIndicat === void 0 ? {} : _ref$selectionIndicat,
_ref$legendSeriesIndi2 = _ref.legendSeriesIndicatorConfigurations,
legendSeriesIndicatorConfigurations = _ref$legendSeriesIndi2 === void 0 ? {} : _ref$legendSeriesIndi2,
_ref$legendSeriesLabe = _ref.legendSeriesLabelConfigurations,
legendSeriesLabelConfigurations = _ref$legendSeriesLabe === void 0 ? {} : _ref$legendSeriesLabe,
_ref$toolTipContainer6 = _ref.toolTipContainerConfigurations,
toolTipContainerConfigurations = _ref$toolTipContainer6 === void 0 ? {} : _ref$toolTipContainer6,
_ref$highlightedPoint = _ref.highlightedPointConfigurations,
highlightedPointConfigurations = _ref$highlightedPoint === void 0 ? {} : _ref$highlightedPoint,
_ref$seriesDataPointC = _ref.seriesDataPointConfigurations,
seriesDataPointConfigurations = _ref$seriesDataPointC === void 0 ? {} : _ref$seriesDataPointC,
_ref$multiLineChartCo4 = _ref.multiLineChartConfigurations,
multiLineChartConfigurations = _ref$multiLineChartCo4 === void 0 ? {} : _ref$multiLineChartCo4,
_ref$yAxisTickLabelCo2 = _ref.yAxisTickLabelConfigurations,
yAxisTickLabelConfigurations = _ref$yAxisTickLabelCo2 === void 0 ? {} : _ref$yAxisTickLabelCo2,
_ref$xAxisTickLabelCo2 = _ref.xAxisTickLabelConfigurations,
xAxisTickLabelConfigurations = _ref$xAxisTickLabelCo2 === void 0 ? {} : _ref$xAxisTickLabelCo2,
_ref$dragSelectionCon = _ref.dragSelectionConfigurations,
dragSelectionConfigurations = _ref$dragSelectionCon === void 0 ? {} : _ref$dragSelectionCon,
_ref$legendSeriesConf2 = _ref.legendSeriesConfigurations,
legendSeriesConfigurations = _ref$legendSeriesConf2 === void 0 ? {} : _ref$legendSeriesConf2,
_ref$chartLegendConfi2 = _ref.chartLegendConfigurations,
chartLegendConfigurations = _ref$chartLegendConfi2 === void 0 ? {} : _ref$chartLegendConfi2,
_ref$seriesLabelConfi2 = _ref.seriesLabelConfigurations,
seriesLabelConfigurations = _ref$seriesLabelConfi2 === void 0 ? {} : _ref$seriesLabelConfi2,
_ref$seriesLineConfig = _ref.seriesLineConfigurations,
seriesLineConfigurations = _ref$seriesLineConfig === void 0 ? {} : _ref$seriesLineConfig,
_ref$yAxisTitleConfig2 = _ref.yAxisTitleConfigurations,
yAxisTitleConfigurations = _ref$yAxisTitleConfig2 === void 0 ? {} : _ref$yAxisTitleConfig2,
_ref$xAxisTitleConfig2 = _ref.xAxisTitleConfigurations,
xAxisTitleConfigurations = _ref$xAxisTitleConfig2 === void 0 ? {} : _ref$xAxisTitleConfig2,
_ref$yAxisLineConfigu = _ref.yAxisLineConfigurations,
yAxisLineConfigurations = _ref$yAxisLineConfigu === void 0 ? {} : _ref$yAxisLineConfigu,
_ref$xAxisLineConfigu = _ref.xAxisLineConfigurations,
xAxisLineConfigurations = _ref$xAxisLineConfigu === void 0 ? {} : _ref$xAxisLineConfigu,
_ref$renderTooltip = _ref.renderTooltip,
renderTooltip = _ref$renderTooltip === void 0 ? function (_ref2) {
var _ref2$hoverPoints = _ref2.hoverPoints,
hoverPoints = _ref2$hoverPoints === void 0 ? [] : _ref2$hoverPoints,
hoverTime = _ref2.hoverTime,
clientX = _ref2.clientX,
clientY = _ref2.clientY,
getSeriesLabel = _ref2.getSeriesLabel,
getY = _ref2.getY;
if (!hoverPoints.length) return null;
return /*#__PURE__*/React.createElement("div", {
style: {
position: "relative",
color: "#fff",
borderRadius: 6,
fontFamily: "monospace",
fontSize: 12,
zIndex: 1000
}
}, hoverPoints.map(function (_ref3) {
var point = _ref3.point,
index = _ref3.index;
return /*#__PURE__*/React.createElement("div", {
key: index
}, /*#__PURE__*/React.createElement("strong", null, getSeriesLabel(point, index)), ": ", getY(point).toFixed(2));
}), /*#__PURE__*/React.createElement("div", {
style: {
color: "#aaa",
marginTop: 4
}
}, new Date(hoverTime).toLocaleTimeString()));
} : _ref$renderTooltip,
_ref$getSeriesLabel = _ref.getSeriesLabel,
getSeriesLabel = _ref$getSeriesLabel === void 0 ? function (series, i) {
return "Series ".concat(i + 1);
} : _ref$getSeriesLabel,
_ref$getY = _ref.getY,
getY = _ref$getY === void 0 ? function (d) {
return d.value;
} : _ref$getY,
_ref$getX = _ref.getX,
getX = _ref$getX === void 0 ? function (d) {
return d.time;
} : _ref$getX,
_ref$formatTickX = _ref.formatTickX,
formatTickX = _ref$formatTickX === void 0 ? function (t) {
return new Date(t).toLocaleTimeString();
} : _ref$formatTickX,
_ref$formatTickY = _ref.formatTickY,
formatTickY = _ref$formatTickY === void 0 ? function (v) {
return v.toFixed(2);
} : _ref$formatTickY,
_ref$onYValueWindowCh = _ref.onYValueWindowChange,
onYValueWindowChange = _ref$onYValueWindowCh === void 0 ? null : _ref$onYValueWindowCh,
_ref$onMaxZoomReached = _ref.onMaxZoomReached,
onMaxZoomReached = _ref$onMaxZoomReached === void 0 ? null : _ref$onMaxZoomReached,
onTimeWindowChange = _ref.onTimeWindowChange,
onHoverPointChange = _ref.onHoverPointChange,
_ref$yAxisTitle = _ref.yAxisTitle,
yAxisTitle = _ref$yAxisTitle === void 0 ? "Speed (MB/s)" : _ref$yAxisTitle,
_ref$xAxisTitle = _ref.xAxisTitle,
xAxisTitle = _ref$xAxisTitle === void 0 ? "Progress (%)" : _ref$xAxisTitle,
_ref$yValueWindow = _ref.yValueWindow,
yValueWindow = _ref$yValueWindow === void 0 ? null : _ref$yValueWindow,
timeWindow = _ref.timeWindow,
_ref$yAxisLabelCount = _ref.yAxisLabelCount,
yAxisLabelCount = _ref$yAxisLabelCount === void 0 ? 5 : _ref$yAxisLabelCount,
_ref$xAxisLabelCount = _ref.xAxisLabelCount,
xAxisLabelCount = _ref$xAxisLabelCount === void 0 ? 5 : _ref$xAxisLabelCount,
_ref$initialHeight = _ref.initialHeight,
initialHeight = _ref$initialHeight === void 0 ? 350 : _ref$initialHeight,
_ref$initialWidth = _ref.initialWidth,
initialWidth = _ref$initialWidth === void 0 ? 800 : _ref$initialWidth,
minZoomDelta = _ref.minZoomDelta,
_ref$clampYRangeToDat = _ref.clampYRangeToData,
clampYRangeToData = _ref$clampYRangeToDat === void 0 ? true : _ref$clampYRangeToDat,
_ref$enableDragToZoom = _ref.enableDragToZoom,
enableDragToZoom = _ref$enableDragToZoom === void 0 ? true : _ref$enableDragToZoom,
_ref$enableYZoom = _ref.enableYZoom,
enableYZoom = _ref$enableYZoom === void 0 ? true : _ref$enableYZoom,
_ref$enablePan = _ref.enablePan,
enablePan = _ref$enablePan === void 0 ? true : _ref$enablePan,
_ref$showGrid = _ref.showGrid,
showGrid = _ref$showGrid === void 0 ? true : _ref$showGrid,
_ref$snapToNearest = _ref.snapToNearest,
snapToNearest = _ref$snapToNearest === void 0 ? false : _ref$snapToNearest,
_ref$showEndLabels = _ref.showEndLabels,
showEndLabels = _ref$showEndLabels === void 0 ? true : _ref$showEndLabels,
_ref$showLineDots = _ref.showLineDots,
showLineDots = _ref$showLineDots === void 0 ? true : _ref$showLineDots,
_ref$highlightMode = _ref.highlightMode,
highlightMode = _ref$highlightMode === void 0 ? "nearest" : _ref$highlightMode,
_ref$legendPosition = _ref.legendPosition,
legendPosition = _ref$legendPosition === void 0 ? "left" : _ref$legendPosition,
_ref$margin = _ref.margin,
margin = _ref$margin === void 0 ? {
top: 20,
right: 70,
bottom: 60,
left: 80
} : _ref$margin,
_ref$lineColors = _ref.lineColors,
lineColors = _ref$lineColors === void 0 ? [] : _ref$lineColors,
_ref$data = _ref.data,
data = _ref$data === void 0 ? [] : _ref$data;
var _useState = useState({
height: initialHeight,
width: initialWidth
}),
_useState2 = _slicedToArray(_useState, 2),
containerSize = _useState2[0],
setContainerSize = _useState2[1];
var _useState3 = useState(new Set(data.map(function (_, i) {
return i;
}))),
_useState4 = _slicedToArray(_useState3, 2),
visibleSeries = _useState4[0],
setVisibleSeries = _useState4[1];
var _useState5 = useState({
x: 0,
y: 0
}),
_useState6 = _slicedToArray(_useState5, 2),
tooltipMousePos = _useState6[0],
setTooltipMousePos = _useState6[1];
var _useState7 = useState({
left: 0,
top: 0
}),
_useState8 = _slicedToArray(_useState7, 2),
tooltipStyle = _useState8[0],
setTooltipStyle = _useState8[1];
var _useState9 = useState([]),
_useState10 = _slicedToArray(_useState9, 2),
highlightedPoints = _useState10[0],
setHighlightedPoints = _useState10[1];
var _useState11 = useState(null),
_useState12 = _slicedToArray(_useState11, 2),
internalYWindow = _useState12[0],
setInternalYWindow = _useState12[1];
var _useState13 = useState(false),
_useState14 = _slicedToArray(_useState13, 2),
tooltipVisible = _useState14[0],
setTooltipVisible = _useState14[1];
var _useState15 = useState(null),
_useState16 = _slicedToArray(_useState15, 2),
hoveredPoint = _useState16[0],
setHoveredPoint = _useState16[1];
var _useState17 = useState(false),
_useState18 = _slicedToArray(_useState17, 2),
isYPanning = _useState18[0],
setIsYPanning = _useState18[1];
var _useState19 = useState(null),
_useState20 = _slicedToArray(_useState19, 2),
dragStartX = _useState20[0],
setDragStartX = _useState20[1];
var _useState21 = useState(null),
_useState22 = _slicedToArray(_useState21, 2),
panOriginY = _useState22[0],
setPanOriginY = _useState22[1];
var _useState23 = useState(false),
_useState24 = _slicedToArray(_useState23, 2),
isPanning = _useState24[0],
setIsPanning = _useState24[1];
var _useState25 = useState(null),
_useState26 = _slicedToArray(_useState25, 2),
panOrigin = _useState26[0],
setPanOrigin = _useState26[1];
var _useState27 = useState(null),
_useState28 = _slicedToArray(_useState27, 2),
hoverTime = _useState28[0],
setHoverTime = _useState28[1];
var _useState29 = useState(null),
_useState30 = _slicedToArray(_useState29, 2),
dragEndX = _useState30[0],
setDragEndX = _useState30[1];
var tooltipHovered = useRef(false);
var leaveTimeoutRef = useRef(null);
var containerRef = useRef(null);
var tooltipRef = useRef(null);
var svgRef = useRef(null);
var xMin = timeWindow[0];
var xMax = timeWindow[1];
var currentRange = xMax - xMin;
var filteredData = useMemo(function () {
return data.map(function (series, i) {
return visibleSeries.has(i) ? {
series: series,
i: i
} : null;
}).filter(Boolean);
}, [data, visibleSeries]);
var allXValues = useMemo(function () {
return filteredData.flatMap(function (_ref4) {
var series = _ref4.series;
return series.map(getX);
});
}, [filteredData, getX]);
var fullYValues = useMemo(function () {
return filteredData.flatMap(function (_ref5) {
var series = _ref5.series;
return series.map(getY);
});
}, [filteredData, getY]);
var yValues = useMemo(function () {
return filteredData.flatMap(function (_ref6) {
var series = _ref6.series;
return series.filter(function (p) {
return getX(p) >= xMin && getX(p) <= xMax;
}).map(getY);
});
}, [filteredData, getX, getY, xMin, xMax]);
var fullYMin = Math.min.apply(Math, _toConsumableArray(fullYValues));
var fullYMax = Math.max.apply(Math, _toConsumableArray(fullYValues));
var fullMinX = Math.min.apply(Math, _toConsumableArray(allXValues));
var fullMaxX = Math.max.apply(Math, _toConsumableArray(allXValues));
var yRangeToUse = yValueWindow !== null && yValueWindow !== void 0 ? yValueWindow : internalYWindow;
var yMin, yMax;
if (yRangeToUse) {
yMin = yRangeToUse[0];
yMax = yRangeToUse[1];
} else {
yMin = Math.min.apply(Math, _toConsumableArray(yValues));
yMax = Math.max.apply(Math, _toConsumableArray(yValues));
}
var yFullyZoomedOut = Math.abs(yMax - yMin) >= Math.abs(fullYMax - fullYMin) - 1e-6;
var width = containerSize.width,
height = containerSize.height;
var chartHeight = height - margin.top - margin.bottom;
var chartWidth = width - margin.left - margin.right;
var xScale = function xScale(x) {
return (x - xMin) / (xMax - xMin) * chartWidth;
};
var yScale = function yScale(y) {
var normalized = (y - yMin) / (yMax - yMin);
var clamped = Math.max(0, Math.min(1, normalized));
return chartHeight - clamped * chartHeight;
};
var getTimeFromMouseX = function getTimeFromMouseX(clientX) {
var rect = svgRef.current.getBoundingClientRect();
var x = clientX - rect.left - margin.left;
var actualChartWidth = rect.width - margin.left - margin.right;
var percent = x / actualChartWidth;
return xMin + percent * (xMax - xMin);
};
var handleWheelZoom = useCallback(function (e) {
var zoomFactor = Math.max(0.25, Math.min(0.5, 1 / (yMax - yMin)));
var rect = svgRef.current.getBoundingClientRect();
var mouseY = e.clientY - rect.top - margin.top;
if (mouseY < 0 || mouseY > chartHeight) {
return;
}
var yValueAtCursor = yMin + (1 - mouseY / chartHeight) * (yMax - yMin);
var currentRange = yMax - yMin;
var newRange = e.deltaY > 0 ? currentRange * (1 + zoomFactor) : currentRange * (1 - zoomFactor);
if (newRange < minYRange) {
onMaxZoomReached === null || onMaxZoomReached === void 0 || onMaxZoomReached();
return;
}
var newYMin = yValueAtCursor - (yValueAtCursor - yMin) / currentRange * newRange;
var newYMax = yValueAtCursor + (yMax - yValueAtCursor) / currentRange * newRange;
var _clampYRange = clampYRange(newYMin, newYMax, clampYRangeToData, yValues),
_clampYRange2 = _slicedToArray(_clampYRange, 2),
clampedMin = _clampYRange2[0],
clampedMax = _clampYRange2[1];
(onYValueWindowChange || setInternalYWindow)([clampedMin, clampedMax]);
}, [yMax, yMin, chartHeight, margin.top, onMaxZoomReached, clampYRangeToData, yValues, onYValueWindowChange]);
var handleWheel = useCallback(function (e) {
if (!enableYZoom || !e.ctrlKey) {
return;
}
e.preventDefault();
handleWheelZoom(e);
}, [enableYZoom, handleWheelZoom]);
var handleMouseLeave = function handleMouseLeave() {
leaveTimeoutRef.current = setTimeout(function () {
if (!tooltipHovered.current) {
setTooltipVisible(false);
setHoveredPoint(null);
setHighlightedPoints([]);
setHoverTime(null);
}
}, 150);
};
var handleMouseDown = function handleMouseDown(e) {
var time = getTimeFromMouseX(e.clientX);
if (enablePan && currentRange < fullMaxX - fullMinX) {
setIsPanning(true);
setPanOrigin(time);
}
if (enableYZoom) {
setIsYPanning(true);
setPanOriginY(e.clientY);
}
if (!isPanning && !isYPanning && enableDragToZoom) {
setDragStartX(time);
setDragEndX(null);
}
};
var handleMouseMove = function handleMouseMove(e) {
var time = getTimeFromMouseX(e.clientX);
if (snapToNearest) {
var findClosestXPoint = function findClosestXPoint(series, xVal) {
return series.reduce(function (closest, point) {
var dx = Math.abs(getX(point) - xVal);
return dx < Math.abs(getX(closest) - xVal) ? point : closest;
}, series[0]);
};
var snappedPoints = filteredData.map(function (_ref7) {
var series = _ref7.series;
return findClosestXPoint(series, time);
});
if (highlightMode === "nearest") {
var minDist = Infinity;
var nearest = null;
var nearestSeriesIndex = -1;
snappedPoints.forEach(function (point, j) {
var px = xScale(getX(point));
var py = yScale(getY(point));
var rect = svgRef.current.getBoundingClientRect();
var mouseX = e.clientX - rect.left - margin.left;
var mouseY = e.clientY - rect.top - margin.top;
var dist = Math.hypot(mouseX - px, mouseY - py);
if (!isNaN(dist) && dist < minDist) {
minDist = dist;
nearest = point;
nearestSeriesIndex = filteredData[j].i;
}
});
var result = nearest ? [{
point: nearest,
index: nearestSeriesIndex
}] : [];
setHighlightedPoints(result);
onHoverPointChange === null || onHoverPointChange === void 0 || onHoverPointChange(result);
} else {
var snappedHighlightedPoints = snappedPoints.map(function (point, j) {
return {
point: point,
index: filteredData[j].i
};
}).filter(function (_ref8) {
var point = _ref8.point;
return !isNaN(yScale(getY(point)));
});
setHighlightedPoints(snappedHighlightedPoints);
onHoverPointChange === null || onHoverPointChange === void 0 || onHoverPointChange(snappedHighlightedPoints);
}
setHoverTime(getX(snappedPoints[0]));
} else {
setHoverTime(time);
setHighlightedPoints([]);
}
if (isPanning && panOrigin !== null) {
var delta = panOrigin - time;
var newStart = xMin + delta;
var newEnd = xMax + delta;
if (newStart < fullMinX) {
newStart = fullMinX;
newEnd = newStart + currentRange;
}
if (newEnd > fullMaxX) {
newEnd = fullMaxX;
newStart = newEnd - currentRange;
}
onTimeWindowChange([newStart, newEnd]);
}
if (isYPanning && panOriginY !== null && !e.ctrlKey) {
var rect = svgRef.current.getBoundingClientRect();
var pixelDelta = e.clientY - panOriginY;
var valueDelta = pixelDelta / chartHeight * (yMax - yMin);
var newYMin = yMin + valueDelta;
var newYMax = yMax + valueDelta;
var _clampYRange3 = clampYRange(newYMin, newYMax, clampYRangeToData, yValues);
var _clampYRange4 = _slicedToArray(_clampYRange3, 2);
newYMin = _clampYRange4[0];
newYMax = _clampYRange4[1];
(onYValueWindowChange || setInternalYWindow)([newYMin, newYMax]);
setPanOriginY(e.clientY);
}
if (dragStartX !== null) {
setDragEndX(time);
}
setTooltipMousePos({
x: e.clientX,
y: e.clientY
});
setHoveredPoint({
hoverPoints: highlightedPoints,
nearestPoint: highlightedPoints[0],
hoverTime: hoverTime,
getSeriesLabel: getSeriesLabel,
getY: getY
});
setTooltipVisible(true);
};
var handleMouseUp = function handleMouseUp() {
setIsPanning(false);
setPanOrigin(null);
setIsYPanning(false);
setPanOriginY(null);
if (dragStartX !== null && dragEndX !== null) {
var delta = Math.abs(dragEndX - dragStartX);
var threshold = minZoomDelta || currentRange * 0.01;
if (delta > threshold) {
var newMin = Math.min(dragStartX, dragEndX);
var newMax = Math.max(dragStartX, dragEndX);
onTimeWindowChange([newMin, newMax]);
}
}
setDragStartX(null);
setDragEndX(null);
};
var handleDoubleClick = function handleDoubleClick() {
onTimeWindowChange([fullMinX, fullMaxX]);
if (!yValueWindow && enableYZoom) {
var fullY = fullYValues;
var _clampYRange5 = clampYRange(Math.min.apply(Math, _toConsumableArray(fullY)), Math.max.apply(Math, _toConsumableArray(fullY)), clampYRangeToData, fullY),
_clampYRange6 = _slicedToArray(_clampYRange5, 2),
newYMin = _clampYRange6[0],
newYMax = _clampYRange6[1];
setInternalYWindow([newYMin, newYMax]);
}
};
useLayoutEffect(function () {
if (!tooltipRef.current || !tooltipVisible || !svgRef.current) {
return;
}
var svgRect = svgRef.current.getBoundingClientRect();
var tooltipRect = tooltipRef.current.getBoundingClientRect();
var left = tooltipMousePos.x + 12;
var top = tooltipMousePos.y - tooltipRect.height - 12;
if (left + tooltipRect.width > svgRect.right) {
left = tooltipMousePos.x - tooltipRect.width - 12;
}
if (top < svgRect.top) {
top = tooltipMousePos.y + 12;
}
setTooltipStyle({
left: left,
top: top
});
}, [tooltipMousePos, tooltipVisible]);
useEffect(function () {
if (!yValueWindow && (!internalYWindow || !Array.isArray(internalYWindow))) {
var _clampYRange7 = clampYRange(fullYMin, fullYMax, clampYRangeToData, fullYValues),
_clampYRange8 = _slicedToArray(_clampYRange7, 2),
newYMin = _clampYRange8[0],
newYMax = _clampYRange8[1];
setInternalYWindow([newYMin, newYMax]);
}
}, [yValueWindow, internalYWindow, fullYMin, fullYMax, clampYRangeToData, fullYValues]);
useEffect(function () {
var svg = svgRef.current;
if (!svg) {
return;
}
var wheelHandler = function wheelHandler(e) {
handleWheel(e);
};
svg.addEventListener("wheel", wheelHandler, {
passive: false
});
return function () {
return svg.removeEventListener("wheel", wheelHandler);
};
}, [handleWheel]);
useEffect(function () {
function handleMouseMove(e) {
if (!tooltipRef.current) {
return;
}
var rect = tooltipRef.current.getBoundingClientRect();
var padding = 12;
var inside = e.clientX >= rect.left - padding && e.clientX <= rect.right + padding && e.clientY >= rect.top - padding && e.clientY <= rect.bottom + padding;
tooltipHovered.current = inside;
}
;
window.addEventListener("mousemove", handleMouseMove);
return function () {
return window.removeEventListener("mousemove", handleMouseMove);
};
}, []);
useEffect(function () {
setContainerSize({
height: initialHeight,
width: initialWidth
});
}, [initialHeight, initialWidth]);
useEffect(function () {
return function () {
if (leaveTimeoutRef.current) {
clearTimeout(leaveTimeoutRef.current);
}
};
}, []);
var dragX1 = xScale(dragStartX !== null && dragStartX !== void 0 ? dragStartX : 0);
var dragX2 = xScale(dragEndX !== null && dragEndX !== void 0 ? dragEndX : 0);
var dragging = dragStartX !== null && dragEndX !== null;
var legendStyle = useMemo(function () {
return {
display: "flex",
flexDirection: legendPosition === "left" ? "column" : "row",
userSelect: "none",
fontFamily: "monospace",
fontSize: 12,
background: "#101010",
gap: 8,
padding: "8px 12px"
};
}, [legendPosition]);
return /*#__PURE__*/React.createElement("div", _extends({
ref: containerRef,
style: _objectSpread({
display: "flex",
flexDirection: legendPosition === "left" ? "row" : "column",
overflow: "hidden",
borderRadius: 8,
background: "#0b0b0b",
height: 400,
width: "100%"
}, multiLineChartContainerConfigurationSettings)
}, multiLineChartContainerConfigurations), legendPosition === "left" && /*#__PURE__*/React.createElement("div", _extends({
style: _objectSpread(_objectSpread({}, legendStyle), chartLegendConfigurationSettings)
}, chartLegendConfigurations), data.map(function (series, i) {
var visible = visibleSeries.has(i);
return /*#__PURE__*/React.createElement("div", _extends({
key: i,
style: _objectSpread({
display: "flex",
alignItems: "center",
cursor: "pointer",
border: "1px solid ".concat(visible ? "#333" : "#222"),
borderRadius: 6,
background: visible ? "#222" : "transparent",
color: visible ? "#fff" : "#777",
gap: 6,
padding: "4px 8px"
}, legendSeriesConfigurationSettings),
onClick: function onClick() {
setVisibleSeries(function (prev) {
var next = new Set(prev);
next.has(i) ? next["delete"](i) : next.add(i);
return next;
});
}
}, legendSeriesConfigurations), /*#__PURE__*/React.createElement("div", _extends({
style: _objectSpread({
filter: visible ? "none" : "grayscale(1)",
borderRadius: 2,
background: lineColors[i] || "#1A73E8",
height: 10,
width: 10,
opacity: visible ? 1 : 0.5
}, legendSeriesIndicatorConfigurationSettings)
}, legendSeriesIndicatorConfigurations)), /*#__PURE__*/React.createElement("span", legendSeriesLabelConfigurations, getSeriesLabel(series, i)));
})), /*#__PURE__*/React.createElement("svg", _extends({
ref: svgRef,
style: _objectSpread({
cursor: isPanning ? "grabbing" : dragging ? "ew-resize" : "crosshair"
}, multiLineChartConfigurationSettings),
viewBox: "0 0 ".concat(width, " ").concat(height),
height: "100%",
width: "100%",
onMouseLeave: handleMouseLeave,
onMouseDown: handleMouseDown,
onMouseMove: handleMouseMove,
onMouseUp: handleMouseUp,
onDoubleClick: handleDoubleClick
}, multiLineChartConfigurations), /*#__PURE__*/React.createElement("g", {
transform: "translate(".concat(margin.left, ", ").concat(margin.top, ")")
}, /*#__PURE__*/React.createElement("text", {
x: -margin.left - 20,
y: chartHeight / 2,
transform: "rotate(-90, ".concat(-margin.left - 20, ", ").concat(chartHeight / 2, ")"),
textAnchor: "middle",
fill: "#888",
fontFamily: "monospace",
fontSize: 12,
style: _objectSpread({
userSelect: "none"
}, yAxisTitleConfigurationSettings)
}, yAxisTitle), showGrid && Array.from({
length: yAxisLabelCount
}).map(function (_, i) {
var yVal = yMin + i / (yAxisLabelCount - 1) * (yMax - yMin);
var y = yScale(yVal);
return /*#__PURE__*/React.createElement("g", {
key: "y-".concat(i)
}, /*#__PURE__*/React.createElement("line", _extends({
y2: y,
y1: y,
x2: chartWidth,
x1: 0,
strokeDasharray: "2 2",
stroke: "#333"
}, yAxisLineConfigurations)), /*#__PURE__*/React.createElement("text", _extends({
y: y,
x: -8,
alignmentBaseline: "middle",
textAnchor: "end",
fill: "#888",
fontFamily: "monospace",
fontSize: 10,
style: _objectSpread({
userSelect: "none"
}, yAxisTickLabelConfigurationSettings)
}, yAxisTickLabelConfigurations), formatTickY(yVal)));
}), showGrid && Array.from({
length: xAxisLabelCount
}).map(function (_, i) {
var xVal = xMin + i / (xAxisLabelCount - 1) * (xMax - xMin);
var x = xScale(xVal);
return /*#__PURE__*/React.createElement("g", {
key: "x-".concat(i)
}, /*#__PURE__*/React.createElement("line", _extends({
y2: chartHeight,
y1: 0,
x2: x,
x1: x,
strokeDasharray: "2 2",
stroke: "#333"
}, xAxisLineConfigurations)), /*#__PURE__*/React.createElement("text", _extends({
y: chartHeight + 14,
x: x,
textAnchor: "middle",
fill: "#888",
fontFamily: "monospace",
fontSize: 10,
style: _objectSpread({
userSelect: "none"
}, xAxisTickLabelConfigurationSettings)
}, xAxisTickLabelConfigurations), formatTickX(xVal)));
}), filteredData.map(function (_ref9) {
var series = _ref9.series,
i = _ref9.i;
var visiblePoints = series.filter(function (d) {
var x = getX(d),
y = getY(d);
return x >= xMin && x <= xMax && y >= yMin && y <= yMax;
});
if (visiblePoints.length === 0) {
return null;
}
var path = visiblePoints.map(function (d, j) {
return "".concat(j === 0 ? "M" : "L").concat(xScale(getX(d)), ",").concat(yScale(getY(d)));
}).join(" ");
return /*#__PURE__*/React.createElement("g", {
key: i
}, /*#__PURE__*/React.createElement(motion.path, _extends({
initial: {
pathLength: 0
},
animate: {
pathLength: 1
},
transition: {
duration: 0.3
},
stroke: lineColors[i] || "#1A73E8",
strokeWidth: 2,
fill: "none",
d: path
}, seriesLineConfigurations)), showLineDots && visiblePoints.map(function (pt, j) {
return /*#__PURE__*/React.createElement("circle", _extends({
key: j,
cy: yScale(getY(pt)),
cx: xScale(getX(pt)),
fill: lineColors[i] || "#1A73E8",
strokeWidth: 0.8,
stroke: "#000",
r: 2.5
}, seriesDataPointConfigurations));
}), showEndLabels && function () {
var last = visiblePoints[visiblePoints.length - 1];
var x = xScale(getX(last));
var y = yScale(getY(last));
return /*#__PURE__*/React.createElement("text", _extends({
x: x + 8,
y: y,
alignmentBaseline: "middle",
fontFamily: "monospace",
fontSize: 11,
fill: lineColors[i] || "#1A73E8",
style: _objectSpread({
userSelect: "none"
}, seriesLabelConfigurationSettings)
}, seriesLabelConfigurations), getSeriesLabel(series, i));
}());
}), hoverTime !== null && /*#__PURE__*/React.createElement("line", _extends({
x2: xScale(hoverTime),
x1: xScale(hoverTime),
y2: chartHeight,
y1: 0,
pointerEvents: "none",
strokeDasharray: "4 2",
strokeWidth: 1,
stroke: "#fff"
}, selectionIndicatorLineConfigurations)), snapToNearest && highlightedPoints.map(function (_ref10) {
var point = _ref10.point,
index = _ref10.index;
return /*#__PURE__*/React.createElement(motion.circle, _extends({
key: index,
initial: {
opacity: 0,
r: 0
},
animate: {
opacity: 1,
r: 5
},
transition: {
duration: 0.2
},
cx: xScale(getX(point)),
cy: yScale(getY(point)),
stroke: lineColors[index] || "#1A73E8",
strokeWidth: 2,
fill: "#fff",
r: 5
}, highlightedPointConfigurations));
}), dragging && /*#__PURE__*/React.createElement("rect", _extends({
x: Math.min(dragX1, dragX2),
y: 0,
height: chartHeight,
width: Math.abs(dragX2 - dragX1),
fill: "#1A73E8",
opacity: 0.2
}, dragSelectionConfigurations)), /*#__PURE__*/React.createElement("text", {
x: chartWidth / 2,
y: height - margin.bottom + 25,
textAnchor: "middle",
fill: "#888",
fontFamily: "monospace",
fontSize: 12,
style: _objectSpread({
userSelect: "none"
}, xAxisTitleConfigurationSettings)
}, xAxisTitle))), tooltipVisible && hoveredPoint && /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(AnimatePresence, null, /*#__PURE__*/React.createElement(motion.div, _extends({
ref: tooltipRef,
initial: _objectSpread({
opacity: 0,
scale: 0.95
}, toolTipContainerInitialAnimationConfigurationSettings),
animate: _objectSpread({
opacity: 1,
scale: 1
}, toolTipContainerAnimationConfigurationSettings),
exit: _objectSpread({
opacity: 0,
scale: 0.95
}, toolTipContainerExitAnimationConfigurationSettings),
transition: _objectSpread({
duration: 0.2
}, toolTipContainerAnimationTransitionConfigurationSettings),
style: _objectSpread({
position: "fixed",
pointerEvents: "auto",
WebkitBackdropFilter: "blur(10px)",
backdropFilter: "blur(10px)",
fontSize: 13,
border: "1px solid rgba(255,255,255,0.08)",
borderRadius: 12,
boxShadow: "0 8px 30px rgba(0, 0, 0, 0.3)",
background: "rgba(15, 20, 30, 0.9)",
color: "#fff",
maxWidth: 260,
zIndex: 9999,
padding: 12,
left: tooltipStyle.left,
top: tooltipStyle.top
}, toolTipContainerConfigurationSettings),
onMouseEnter: function onMouseEnter() {
return tooltipHovered.current = true;
},
onMouseLeave: function onMouseLeave() {
tooltipHovered.current = false;
handleMouseLeave();
}
}, toolTipContainerConfigurations), renderTooltip(hoveredPoint))), document.body));
}
;
export default HUDMultiLineChart;