blazeplot 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +11 -2
  2. package/dist/Chart-BW9JaHs6.js +2903 -0
  3. package/dist/Chart-BW9JaHs6.js.map +1 -0
  4. package/dist/OverlayUtils-Cw1o8UH-.js +35 -0
  5. package/dist/OverlayUtils-Cw1o8UH-.js.map +1 -0
  6. package/dist/core/SeriesStore.d.ts +9 -0
  7. package/dist/core/SeriesStore.d.ts.map +1 -1
  8. package/dist/core/UniformRingBuffer.d.ts +67 -0
  9. package/dist/core/UniformRingBuffer.d.ts.map +1 -0
  10. package/dist/core/index.d.ts +3 -1
  11. package/dist/core/index.d.ts.map +1 -1
  12. package/dist/core/types.d.ts +13 -1
  13. package/dist/core/types.d.ts.map +1 -1
  14. package/dist/index.d.ts +5 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +153 -2185
  17. package/dist/index.js.map +1 -1
  18. package/dist/interaction/AxisController.d.ts +45 -3
  19. package/dist/interaction/AxisController.d.ts.map +1 -1
  20. package/dist/interaction/index.d.ts +1 -0
  21. package/dist/interaction/index.d.ts.map +1 -1
  22. package/dist/linked.d.ts +3 -0
  23. package/dist/linked.d.ts.map +1 -0
  24. package/dist/linked.js +64 -0
  25. package/dist/linked.js.map +1 -0
  26. package/dist/plugins/annotations.d.ts +3 -0
  27. package/dist/plugins/annotations.d.ts.map +1 -0
  28. package/dist/plugins/annotations.js +163 -0
  29. package/dist/plugins/annotations.js.map +1 -0
  30. package/dist/plugins/crosshair.d.ts +3 -0
  31. package/dist/plugins/crosshair.d.ts.map +1 -0
  32. package/dist/plugins/crosshair.js +192 -0
  33. package/dist/plugins/crosshair.js.map +1 -0
  34. package/dist/plugins/interactions.js +87 -65
  35. package/dist/plugins/interactions.js.map +1 -1
  36. package/dist/plugins/navigator.d.ts +3 -0
  37. package/dist/plugins/navigator.d.ts.map +1 -0
  38. package/dist/plugins/navigator.js +147 -0
  39. package/dist/plugins/navigator.js.map +1 -0
  40. package/dist/plugins/selection.d.ts +3 -0
  41. package/dist/plugins/selection.d.ts.map +1 -0
  42. package/dist/plugins/selection.js +144 -0
  43. package/dist/plugins/selection.js.map +1 -0
  44. package/dist/plugins/tooltip.js +29 -45
  45. package/dist/plugins/tooltip.js.map +1 -1
  46. package/dist/react.d.ts +14 -0
  47. package/dist/react.d.ts.map +1 -0
  48. package/dist/react.js +30 -0
  49. package/dist/react.js.map +1 -0
  50. package/dist/render/ReglBackend.d.ts +1 -0
  51. package/dist/render/ReglBackend.d.ts.map +1 -1
  52. package/dist/render/Renderer.d.ts +1 -0
  53. package/dist/render/Renderer.d.ts.map +1 -1
  54. package/dist/render/types.d.ts +1 -0
  55. package/dist/render/types.d.ts.map +1 -1
  56. package/dist/ui/Annotations.d.ts +94 -0
  57. package/dist/ui/Annotations.d.ts.map +1 -0
  58. package/dist/ui/Chart.d.ts +83 -1
  59. package/dist/ui/Chart.d.ts.map +1 -1
  60. package/dist/ui/ChartLayout.d.ts +10 -0
  61. package/dist/ui/ChartLayout.d.ts.map +1 -1
  62. package/dist/ui/Crosshair.d.ts +60 -0
  63. package/dist/ui/Crosshair.d.ts.map +1 -0
  64. package/dist/ui/Interactions.d.ts.map +1 -1
  65. package/dist/ui/LinkedCharts.d.ts +23 -0
  66. package/dist/ui/LinkedCharts.d.ts.map +1 -0
  67. package/dist/ui/Navigator.d.ts +32 -0
  68. package/dist/ui/Navigator.d.ts.map +1 -0
  69. package/dist/ui/OverlayUtils.d.ts +17 -0
  70. package/dist/ui/OverlayUtils.d.ts.map +1 -0
  71. package/dist/ui/Selection.d.ts +64 -0
  72. package/dist/ui/Selection.d.ts.map +1 -0
  73. package/dist/ui/Tooltip.d.ts.map +1 -1
  74. package/dist/ui/theme.d.ts +12 -0
  75. package/dist/ui/theme.d.ts.map +1 -1
  76. package/package.json +35 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crosshair.js","names":[],"sources":["../../src/ui/Crosshair.ts"],"sourcesContent":["import type { SeriesYAxis } from \"../core/types.js\";\nimport type { Chart, ChartPickItem, ChartPickMode, ChartPlugin } from \"./Chart.js\";\nimport { formatCompactNumber, placeAbsoluteWithinBox, renderPickItems, rgba } from \"./OverlayUtils.js\";\n\nexport type CrosshairAxis = \"x\" | \"y\" | \"xy\";\nexport type CrosshairSnapMode = \"none\" | \"nearest-x\" | \"nearest-point\";\nexport type CrosshairMode = \"crosshair\" | \"ruler\";\n\nexport interface CrosshairPosition {\n readonly dataX: number;\n readonly dataY: number;\n readonly plotX: number;\n readonly plotY: number;\n readonly items: readonly ChartPickItem[];\n}\n\nexport interface RulerMeasurement {\n readonly start: CrosshairPosition;\n readonly end: CrosshairPosition;\n readonly deltaX: number;\n readonly deltaY: number;\n readonly slope: number;\n readonly sampleCount: number;\n}\n\nexport type CrosshairEventType = \"move\" | \"measurestart\" | \"measurechange\" | \"measureend\";\n\nexport interface CrosshairPluginOptions {\n readonly mode?: CrosshairMode;\n readonly axis?: CrosshairAxis;\n readonly yAxis?: SeriesYAxis;\n readonly snap?: CrosshairSnapMode;\n readonly group?: string;\n readonly color?: string;\n readonly width?: number;\n readonly dash?: string;\n readonly label?: boolean;\n readonly labelBackground?: string;\n readonly labelColor?: string;\n readonly labelFont?: string;\n readonly zIndex?: number;\n readonly highlight?: boolean;\n readonly markerSize?: number;\n readonly markerStrokeColor?: string;\n readonly markerStrokeWidth?: number;\n readonly rulerModifier?: \"none\" | \"ctrl\" | \"shift\" | \"alt\" | \"meta\";\n readonly formatX?: (value: number) => string;\n readonly formatY?: (value: number) => string;\n readonly formatter?: (item: ChartPickItem, position: CrosshairPosition) => string;\n readonly render?: (position: CrosshairPosition, container: HTMLElement, chart: Chart) => void;\n readonly onMove?: (position: CrosshairPosition | null) => void;\n readonly onMeasureStart?: (position: CrosshairPosition) => void;\n readonly onMeasureChange?: (measurement: RulerMeasurement) => void;\n readonly onMeasureEnd?: (measurement: RulerMeasurement) => void;\n readonly onMeasure?: (measurement: RulerMeasurement) => void;\n}\n\ninterface Peer {\n showShared(dataX: number, source: Peer): void;\n hideShared(source: Peer): void;\n}\n\nconst groups = new Map<string, Set<Peer>>();\n\nexport interface CrosshairPlugin extends ChartPlugin {\n getPosition(): CrosshairPosition | null;\n getMeasurement(): RulerMeasurement | null;\n clearMeasurement(): void;\n subscribe(event: \"move\", callback: (position: CrosshairPosition | null) => void): () => void;\n subscribe(event: \"measurestart\", callback: (position: CrosshairPosition) => void): () => void;\n subscribe(event: \"measurechange\" | \"measureend\", callback: (measurement: RulerMeasurement) => void): () => void;\n}\n\nfunction countSamplesInRange(chart: Chart, xMin: number, xMax: number): number {\n const viewport = { xMin, xMax, yMin: -Infinity, yMax: Infinity };\n let total = 0;\n for (const state of chart.getSeriesState()) {\n if (!state.visible) continue;\n const range = state.series.visibleIndexRange(viewport);\n total += Math.max(0, range.end - range.start);\n }\n return total;\n}\n\nfunction hasModifier(event: PointerEvent, modifier: CrosshairPluginOptions[\"rulerModifier\"]): boolean {\n if (!modifier || modifier === \"none\") return true;\n if (modifier === \"ctrl\") return event.ctrlKey;\n if (modifier === \"shift\") return event.shiftKey;\n if (modifier === \"alt\") return event.altKey;\n return event.metaKey;\n}\n\nfunction positionFromPick(chart: Chart, clientX: number, clientY: number, mode: ChartPickMode): CrosshairPosition | null {\n const picked = chart.pick(clientX, clientY, { mode, group: \"none\" });\n const item = picked?.items[0];\n return item ? { dataX: item.x, dataY: item.y, plotX: item.plotX, plotY: item.plotY, items: [item] } : null;\n}\n\nfunction resolvePosition(chart: Chart, clientX: number, clientY: number, yAxis: SeriesYAxis, snap: CrosshairSnapMode): CrosshairPosition | null {\n const rect = chart.canvas.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) return null;\n\n const pickMode: ChartPickMode = snap === \"nearest-point\" ? \"nearest-point\" : \"nearest-x\";\n if (snap !== \"none\") {\n const picked = positionFromPick(chart, clientX, clientY, pickMode);\n if (picked) return picked;\n }\n\n const data = chart.clientToData(clientX, clientY, yAxis);\n if (!data) return null;\n const [plotX, plotY] = chart.dataToPlot(data[0], data[1], yAxis);\n return { dataX: data[0], dataY: data[1], plotX, plotY, items: [] };\n}\n\nfunction resolveSharedPosition(chart: Chart, dataX: number, yAxis: SeriesYAxis): CrosshairPosition | null {\n const rect = chart.canvas.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) return null;\n\n const viewport = chart.getViewport(yAxis);\n const dataY = viewport.yMin + (viewport.yMax - viewport.yMin) * 0.5;\n const [plotX, plotY] = chart.dataToPlot(dataX, dataY, yAxis);\n const picked = positionFromPick(chart, rect.left + plotX, rect.top + plotY, \"nearest-x\");\n if (picked) return picked;\n return { dataX, dataY, plotX, plotY, items: [] };\n}\n\nfunction renderDefaultLabel(\n position: CrosshairPosition,\n container: HTMLElement,\n formatX: (value: number) => string,\n formatY: (value: number) => string,\n formatter: CrosshairPluginOptions[\"formatter\"],\n): void {\n if (position.items.length === 0) {\n container.textContent = `x ${formatX(position.dataX)} y ${formatY(position.dataY)}`;\n return;\n }\n\n renderPickItems(\n container,\n position.items,\n position,\n formatter,\n (item) => `(${formatX(item.x)}, ${formatY(item.y)})`,\n );\n}\n\nexport function crosshairPlugin(options: CrosshairPluginOptions = {}): CrosshairPlugin {\n const axis = options.axis ?? \"xy\";\n const yAxis = options.yAxis ?? \"left\";\n const snap = options.snap ?? \"none\";\n const mode = options.mode ?? \"crosshair\";\n const rulerModifier = options.rulerModifier ?? \"none\";\n let chartRef: Chart | null = null;\n let root: HTMLDivElement | null = null;\n let vertical: HTMLDivElement | null = null;\n let horizontal: HTMLDivElement | null = null;\n let markerLayer: HTMLDivElement | null = null;\n let label: HTMLDivElement | null = null;\n let rulerSvg: SVGSVGElement | null = null;\n let rulerLine: SVGLineElement | null = null;\n let rulerStart: CrosshairPosition | null = null;\n\n const formatX = options.formatX ?? formatCompactNumber;\n const formatY = options.formatY ?? formatCompactNumber;\n let currentPosition: CrosshairPosition | null = null;\n let currentMeasurement: RulerMeasurement | null = null;\n const moveSubscribers = new Set<(position: CrosshairPosition | null) => void>();\n const measureStartSubscribers = new Set<(position: CrosshairPosition) => void>();\n const measureChangeSubscribers = new Set<(measurement: RulerMeasurement) => void>();\n const measureEndSubscribers = new Set<(measurement: RulerMeasurement) => void>();\n\n const setVisible = (visible: boolean): void => {\n if (root) root.style.display = visible ? \"block\" : \"none\";\n };\n\n const emitMove = (position: CrosshairPosition | null): void => {\n currentPosition = position;\n options.onMove?.(position);\n for (const callback of moveSubscribers) callback(position);\n };\n\n const emitMeasureStart = (position: CrosshairPosition): void => {\n options.onMeasureStart?.(position);\n for (const callback of measureStartSubscribers) callback(position);\n };\n\n const emitMeasureChange = (measurement: RulerMeasurement): void => {\n currentMeasurement = measurement;\n options.onMeasureChange?.(measurement);\n for (const callback of measureChangeSubscribers) callback(measurement);\n };\n\n const emitMeasureEnd = (measurement: RulerMeasurement): void => {\n currentMeasurement = measurement;\n options.onMeasureEnd?.(measurement);\n options.onMeasure?.(measurement);\n for (const callback of measureEndSubscribers) callback(measurement);\n };\n\n const placeLabel = (position: CrosshairPosition): void => {\n const chart = chartRef;\n if (!chart || !label) return;\n placeAbsoluteWithinBox(label, position.plotX, position.plotY, chart.canvas.clientWidth, chart.canvas.clientHeight, {\n offsetX: 12,\n offsetY: 12,\n });\n };\n\n const renderMarkers = (position: CrosshairPosition | null): void => {\n if (!markerLayer) return;\n markerLayer.replaceChildren();\n if (options.highlight === false || !position) return;\n\n const size = Math.max(2, options.markerSize ?? 10);\n const strokeWidth = Math.max(0, options.markerStrokeWidth ?? 2);\n for (const item of position.items) {\n const marker = document.createElement(\"div\");\n marker.style.position = \"absolute\";\n marker.style.left = `${item.plotX}px`;\n marker.style.top = `${item.plotY}px`;\n marker.style.width = `${size}px`;\n marker.style.height = `${size}px`;\n marker.style.border = `${strokeWidth}px solid ${options.markerStrokeColor ?? \"#f8fafc\"}`;\n marker.style.borderRadius = \"999px\";\n marker.style.background = rgba(item.series.style.color);\n marker.style.boxShadow = \"0 0 0 1px rgba(4, 8, 16, 0.85)\";\n marker.style.transform = \"translate(-50%, -50%)\";\n markerLayer.appendChild(marker);\n }\n };\n\n const renderPosition = (position: CrosshairPosition | null): void => {\n renderMarkers(position);\n if (!position || !root || !vertical || !horizontal || !label) {\n setVisible(false);\n return;\n }\n setVisible(true);\n vertical.style.display = axis === \"y\" ? \"none\" : \"block\";\n horizontal.style.display = axis === \"x\" ? \"none\" : \"block\";\n vertical.style.left = `${position.plotX}px`;\n horizontal.style.top = `${position.plotY}px`;\n if (options.label !== false) {\n label.style.display = \"block\";\n if (options.render) {\n options.render(position, label, chartRef!);\n } else {\n renderDefaultLabel(position, label, formatX, formatY, options.formatter);\n }\n placeLabel(position);\n } else {\n label.style.display = \"none\";\n }\n };\n\n const measurementFrom = (start: CrosshairPosition, end: CrosshairPosition, chart: Chart): RulerMeasurement => {\n const deltaX = end.dataX - start.dataX;\n const deltaY = end.dataY - start.dataY;\n return {\n start,\n end,\n deltaX,\n deltaY,\n slope: deltaX === 0 ? Infinity : deltaY / deltaX,\n sampleCount: countSamplesInRange(chart, Math.min(start.dataX, end.dataX), Math.max(start.dataX, end.dataX)),\n };\n };\n\n const renderRuler = (end: CrosshairPosition | null): void => {\n const chart = chartRef;\n if (!chart || !rulerSvg || !rulerLine || !rulerStart || !end) return;\n rulerSvg.style.display = \"block\";\n rulerLine.setAttribute(\"x1\", String(rulerStart.plotX));\n rulerLine.setAttribute(\"y1\", String(rulerStart.plotY));\n rulerLine.setAttribute(\"x2\", String(end.plotX));\n rulerLine.setAttribute(\"y2\", String(end.plotY));\n emitMeasureChange(measurementFrom(rulerStart, end, chart));\n };\n\n const emitShared = (position: CrosshairPosition): void => {\n if (!options.group || !peer) return;\n for (const target of groups.get(options.group) ?? []) {\n if (target !== peer) target.showShared(position.dataX, peer);\n }\n };\n\n const emitHideShared = (): void => {\n if (!options.group || !peer) return;\n for (const target of groups.get(options.group) ?? []) {\n if (target !== peer) target.hideShared(peer);\n }\n };\n\n const peer: Peer = {\n showShared(dataX: number, source: Peer): void {\n if (source === peer || !chartRef) return;\n const position = resolveSharedPosition(chartRef, dataX, yAxis);\n renderPosition(position);\n emitMove(position);\n },\n hideShared(source: Peer): void {\n if (source === peer) return;\n renderPosition(null);\n emitMove(null);\n },\n };\n\n return {\n install(chart: Chart) {\n chartRef = chart;\n const color = options.color ?? \"rgba(148, 163, 184, 0.55)\";\n const width = `${options.width ?? 1}px`;\n const dash = options.dash;\n\n root = document.createElement(\"div\");\n root.className = \"blazeplot-crosshair\";\n root.style.position = \"absolute\";\n root.style.inset = \"0\";\n root.style.display = \"none\";\n root.style.pointerEvents = \"none\";\n root.style.zIndex = String(options.zIndex ?? 10_000);\n\n vertical = document.createElement(\"div\");\n vertical.style.position = \"absolute\";\n vertical.style.top = \"0\";\n vertical.style.bottom = \"0\";\n vertical.style.zIndex = \"1\";\n vertical.style.borderLeft = `${width} solid ${color}`;\n if (dash) vertical.style.borderLeftStyle = \"dashed\";\n\n horizontal = document.createElement(\"div\");\n horizontal.style.position = \"absolute\";\n horizontal.style.left = \"0\";\n horizontal.style.right = \"0\";\n horizontal.style.zIndex = \"1\";\n horizontal.style.borderTop = `${width} solid ${color}`;\n if (dash) horizontal.style.borderTopStyle = \"dashed\";\n\n markerLayer = document.createElement(\"div\");\n markerLayer.className = \"blazeplot-crosshair-markers\";\n markerLayer.style.position = \"absolute\";\n markerLayer.style.inset = \"0\";\n markerLayer.style.zIndex = \"2\";\n markerLayer.style.pointerEvents = \"none\";\n\n label = document.createElement(\"div\");\n label.style.position = \"absolute\";\n label.style.zIndex = \"3\";\n label.style.padding = \"4px 6px\";\n label.style.borderRadius = \"3px\";\n label.style.background = options.labelBackground ?? chart.theme.tooltipBackgroundColor;\n label.style.color = options.labelColor ?? chart.theme.tooltipTextColor;\n label.style.font = options.labelFont ?? chart.theme.tooltipFont;\n label.style.whiteSpace = \"nowrap\";\n\n rulerSvg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n rulerSvg.style.position = \"absolute\";\n rulerSvg.style.inset = \"0\";\n rulerSvg.style.width = \"100%\";\n rulerSvg.style.height = \"100%\";\n rulerSvg.style.display = \"none\";\n rulerSvg.style.overflow = \"hidden\";\n rulerSvg.style.zIndex = \"1\";\n rulerLine = document.createElementNS(\"http://www.w3.org/2000/svg\", \"line\");\n rulerLine.setAttribute(\"stroke\", color);\n rulerLine.setAttribute(\"stroke-width\", String(options.width ?? 1));\n if (dash) rulerLine.setAttribute(\"stroke-dasharray\", dash);\n rulerSvg.appendChild(rulerLine);\n\n root.appendChild(vertical);\n root.appendChild(horizontal);\n root.appendChild(rulerSvg);\n root.appendChild(markerLayer);\n root.appendChild(label);\n chart.plotElement.appendChild(root);\n\n if (options.group) {\n const set = groups.get(options.group) ?? new Set<Peer>();\n set.add(peer);\n groups.set(options.group, set);\n }\n\n const onPointerMove = (event: PointerEvent): void => {\n const position = resolvePosition(chart, event.clientX, event.clientY, yAxis, snap);\n renderPosition(position);\n emitMove(position);\n if (position) emitShared(position);\n if (mode === \"ruler\") renderRuler(position);\n };\n\n const onPointerLeave = (): void => {\n if (!rulerStart) renderPosition(null);\n emitMove(null);\n emitHideShared();\n };\n\n const onPointerDown = (event: PointerEvent): void => {\n if (mode !== \"ruler\" || event.button !== 0 || !hasModifier(event, rulerModifier)) return;\n rulerStart = resolvePosition(chart, event.clientX, event.clientY, yAxis, snap);\n if (rulerStart) {\n emitMeasureStart(rulerStart);\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n\n const onPointerUp = (event: PointerEvent): void => {\n if (mode !== \"ruler\" || !rulerStart) return;\n event.stopImmediatePropagation();\n const end = resolvePosition(chart, event.clientX, event.clientY, yAxis, snap);\n if (!end) return;\n const measurement = measurementFrom(rulerStart, end, chart);\n emitMeasureEnd(measurement);\n rulerStart = null;\n };\n\n chart.canvas.addEventListener(\"pointermove\", onPointerMove);\n chart.canvas.addEventListener(\"pointerleave\", onPointerLeave);\n chart.canvas.addEventListener(\"pointerdown\", onPointerDown, { capture: true });\n chart.canvas.addEventListener(\"pointerup\", onPointerUp, { capture: true });\n\n return () => {\n chart.canvas.removeEventListener(\"pointermove\", onPointerMove);\n chart.canvas.removeEventListener(\"pointerleave\", onPointerLeave);\n chart.canvas.removeEventListener(\"pointerdown\", onPointerDown, { capture: true });\n chart.canvas.removeEventListener(\"pointerup\", onPointerUp, { capture: true });\n if (options.group) {\n const set = groups.get(options.group);\n set?.delete(peer);\n if (set?.size === 0) groups.delete(options.group);\n }\n root?.remove();\n root = null;\n vertical = null;\n horizontal = null;\n markerLayer = null;\n label = null;\n rulerSvg = null;\n rulerLine = null;\n rulerStart = null;\n chartRef = null;\n };\n },\n getPosition(): CrosshairPosition | null {\n return currentPosition;\n },\n getMeasurement(): RulerMeasurement | null {\n return currentMeasurement;\n },\n clearMeasurement(): void {\n currentMeasurement = null;\n rulerStart = null;\n if (rulerSvg) rulerSvg.style.display = \"none\";\n },\n subscribe(event: CrosshairEventType, callback: ((position: CrosshairPosition | null) => void) | ((position: CrosshairPosition) => void) | ((measurement: RulerMeasurement) => void)): () => void {\n if (event === \"move\") {\n const cb = callback as (position: CrosshairPosition | null) => void;\n moveSubscribers.add(cb);\n return () => moveSubscribers.delete(cb);\n }\n if (event === \"measurestart\") {\n const cb = callback as (position: CrosshairPosition) => void;\n measureStartSubscribers.add(cb);\n return () => measureStartSubscribers.delete(cb);\n }\n if (event === \"measurechange\") {\n const cb = callback as (measurement: RulerMeasurement) => void;\n measureChangeSubscribers.add(cb);\n return () => measureChangeSubscribers.delete(cb);\n }\n const cb = callback as (measurement: RulerMeasurement) => void;\n measureEndSubscribers.add(cb);\n return () => measureEndSubscribers.delete(cb);\n },\n };\n}\n"],"mappings":"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"}
@@ -33,38 +33,39 @@ function a(e, t, n, r) {
33
33
  }
34
34
  function o(o = {}) {
35
35
  return { install(s) {
36
- let c = o.minDragDistancePx ?? 6, l = s.canvas, u = s.xAxisElement, d = s.yAxisElement, f = document.createElement("div"), p = `blazeplot-axis-hover-${e++}`, m = document.createElement("style"), h = u.style.pointerEvents, g = d.style.pointerEvents, _ = u.style.cursor, v = d.style.cursor, y = u.style.filter, b = d.style.filter, x = null, S = null;
37
- f.className = "blazeplot-selection", f.style.position = "absolute", f.style.display = "none", f.style.pointerEvents = "none", f.style.zIndex = "24", f.style.border = `1px solid ${o.selectionStroke ?? "rgba(147, 197, 253, 0.95)"}`, f.style.background = o.selectionFill ?? "rgba(59, 130, 246, 0.18)", s.plotElement.appendChild(f), m.textContent = `.${p} > div { color: ${o.axisHoverColor ?? "#f8fafc"} !important; }`, o.axisInteractions !== !1 && o.axisHover !== !1 && s.rootElement.appendChild(m), o.axisInteractions !== !1 && (u.style.pointerEvents = "auto", d.style.pointerEvents = "auto", u.style.cursor = "ew-resize", d.style.cursor = "ns-resize");
38
- let C = () => {
39
- S ??= r(s.getViewport());
40
- }, w = (e, t) => {
41
- let r = n(e, t);
42
- return o.viewportPolicy?.beforePan?.(s.getCamera(), r) ?? r;
43
- }, T = (e) => o.viewportPolicy?.beforeZoom?.(s.getCamera(), e) ?? e, E = () => {
44
- f.style.display = "none";
45
- }, D = (e, t) => {
36
+ let c = o.minDragDistancePx ?? 6, l = s.canvas, u = s.xAxisElement, d = s.yAxisElement, f = s.y2AxisElement, p = document.createElement("div"), m = `blazeplot-axis-hover-${e++}`, h = document.createElement("style"), g = u.style.pointerEvents, _ = d.style.pointerEvents, v = f.style.pointerEvents, y = u.style.cursor, b = d.style.cursor, x = f.style.cursor, S = u.style.filter, C = d.style.filter, w = f.style.filter, T = null, E = null;
37
+ p.className = "blazeplot-selection", p.style.position = "absolute", p.style.display = "none", p.style.pointerEvents = "none", p.style.zIndex = "24", p.style.border = `1px solid ${o.selectionStroke ?? "rgba(147, 197, 253, 0.95)"}`, p.style.background = o.selectionFill ?? "rgba(59, 130, 246, 0.18)", s.plotElement.appendChild(p), h.textContent = `.${m} > div { color: ${o.axisHoverColor ?? "#f8fafc"} !important; }`, o.axisInteractions !== !1 && o.axisHover !== !1 && s.rootElement.appendChild(h), o.axisInteractions !== !1 && (u.style.pointerEvents = "auto", d.style.pointerEvents = "auto", f.style.pointerEvents = "auto", u.style.cursor = "ew-resize", d.style.cursor = "ns-resize", f.style.cursor = "ns-resize");
38
+ let D = () => {
39
+ E ??= r(s.getViewport());
40
+ }, O = (e, t, r = "left") => {
41
+ let i = n(e, t);
42
+ return o.viewportPolicy?.beforePan?.(s.getCamera(r), i) ?? i;
43
+ }, k = (e, t = "left") => o.viewportPolicy?.beforeZoom?.(s.getCamera(t), e) ?? e, A = () => {
44
+ p.style.display = "none";
45
+ }, j = (e, t) => {
46
46
  if (o.axisHover === !1) return;
47
47
  let n = t ? o.axisHoverFilter ?? "brightness(1.18)" : null;
48
- e.classList.toggle(p, t), e === u ? u.style.filter = n ?? y : e === d && (d.style.filter = n ?? b);
49
- }, O = () => D(u, !0), k = () => D(u, !1), A = () => D(d, !0), j = () => D(d, !1), M = (e) => {
50
- let n = l.getBoundingClientRect(), r = Math.max(0, Math.min(e.startX - n.left, n.width)), i = Math.max(0, Math.min(e.startY - n.top, n.height)), a = Math.max(0, Math.min(e.currentX - n.left, n.width)), s = Math.max(0, Math.min(e.currentY - n.top, n.height)), c = t(o.axis), u = c === "y" ? 0 : Math.min(r, a), d = c === "x" ? 0 : Math.min(i, s), p = c === "y" ? n.width : Math.abs(a - r), m = c === "x" ? n.height : Math.abs(s - i);
51
- f.style.left = `${u}px`, f.style.top = `${d}px`, f.style.width = `${p}px`, f.style.height = `${m}px`, f.style.display = "block";
52
- }, N = (e, t, n) => {
53
- C(), e.preventDefault(), n !== l && D(n, !0), n.setPointerCapture(e.pointerId), x = {
48
+ e.classList.toggle(m, t), e === u ? u.style.filter = n ?? S : e === d ? d.style.filter = n ?? C : e === f && (f.style.filter = n ?? w);
49
+ }, M = () => j(u, !0), N = () => j(u, !1), P = () => j(d, !0), F = () => j(d, !1), I = () => j(f, !0), L = () => j(f, !1), R = (e) => {
50
+ let n = l.getBoundingClientRect(), r = Math.max(0, Math.min(e.startX - n.left, n.width)), i = Math.max(0, Math.min(e.startY - n.top, n.height)), a = Math.max(0, Math.min(e.currentX - n.left, n.width)), s = Math.max(0, Math.min(e.currentY - n.top, n.height)), c = t(o.axis), u = c === "y" ? 0 : Math.min(r, a), d = c === "x" ? 0 : Math.min(i, s), f = c === "y" ? n.width : Math.abs(a - r), m = c === "x" ? n.height : Math.abs(s - i);
51
+ p.style.left = `${u}px`, p.style.top = `${d}px`, p.style.width = `${f}px`, p.style.height = `${m}px`, p.style.display = "block";
52
+ }, z = (e, t, n, r) => {
53
+ D(), e.preventDefault(), n !== l && j(n, !0), n.setPointerCapture(e.pointerId), T = {
54
54
  mode: "pan",
55
55
  pointerId: e.pointerId,
56
56
  axis: t,
57
57
  target: n,
58
+ yAxis: r,
58
59
  lastX: e.clientX,
59
60
  lastY: e.clientY
60
61
  };
61
- }, P = (e) => {
62
- if (!(x || e.button !== 0)) {
62
+ }, B = (e) => {
63
+ if (!(T || e.button !== 0)) {
63
64
  if (e.shiftKey && o.shiftDragPan !== !1) {
64
- N(e, t(o.axis), l);
65
+ z(e, t(o.axis), l);
65
66
  return;
66
67
  }
67
- o.boxZoom !== !1 && (C(), e.preventDefault(), l.setPointerCapture(e.pointerId), x = {
68
+ o.boxZoom !== !1 && (D(), e.preventDefault(), l.setPointerCapture(e.pointerId), T = {
68
69
  mode: "select",
69
70
  pointerId: e.pointerId,
70
71
  target: l,
@@ -72,71 +73,92 @@ function o(o = {}) {
72
73
  startY: e.clientY,
73
74
  currentX: e.clientX,
74
75
  currentY: e.clientY
75
- }, M(x));
76
+ }, R(T));
76
77
  }
77
- }, F = (e) => {
78
- x || e.button !== 0 || o.axisInteractions === !1 || N(e, "x", u);
79
- }, I = (e) => {
80
- x || e.button !== 0 || o.axisInteractions === !1 || N(e, "y", d);
81
- }, L = (e) => {
82
- if (!(!x || e.pointerId !== x.pointerId)) {
83
- if (e.preventDefault(), x.mode === "pan") {
84
- let t = l.getBoundingClientRect(), n = w({
85
- dx: t.width > 0 ? (x.lastX - e.clientX) / t.width : 0,
86
- dy: t.height > 0 ? (e.clientY - x.lastY) / t.height : 0
87
- }, x.axis);
88
- n && s.pan(n), x.lastX = e.clientX, x.lastY = e.clientY;
78
+ }, V = (e) => {
79
+ T || e.button !== 0 || o.axisInteractions === !1 || z(e, "x", u);
80
+ }, H = (e) => {
81
+ T || e.button !== 0 || o.axisInteractions === !1 || z(e, "y", d, "left");
82
+ }, U = (e) => {
83
+ T || e.button !== 0 || o.axisInteractions === !1 || z(e, "y", f, "right");
84
+ }, W = (e) => {
85
+ if (!(!T || e.pointerId !== T.pointerId)) {
86
+ if (e.preventDefault(), T.mode === "pan") {
87
+ let t = l.getBoundingClientRect(), n = O({
88
+ dx: t.width > 0 ? (T.lastX - e.clientX) / t.width : 0,
89
+ dy: t.height > 0 ? (e.clientY - T.lastY) / t.height : 0
90
+ }, T.axis, T.yAxis ?? "left");
91
+ if (n) if (T.yAxis && T.axis === "y") {
92
+ let e = s.getCamera(T.yAxis).clone();
93
+ e.pan({
94
+ dx: 0,
95
+ dy: n.dy
96
+ }), s.setYViewport(T.yAxis, {
97
+ yMin: e.yMin,
98
+ yMax: e.yMax
99
+ });
100
+ } else s.pan(n);
101
+ T.lastX = e.clientX, T.lastY = e.clientY;
89
102
  return;
90
103
  }
91
- x.currentX = e.clientX, x.currentY = e.clientY, M(x);
104
+ T.currentX = e.clientX, T.currentY = e.clientY, R(T);
92
105
  }
93
- }, R = (e) => {
94
- if (!x || e.pointerId !== x.pointerId) return;
106
+ }, G = (e) => {
107
+ if (!T || e.pointerId !== T.pointerId) return;
95
108
  e.preventDefault();
96
- let n = x;
97
- if (x = null, n.target.hasPointerCapture(e.pointerId) && n.target.releasePointerCapture(e.pointerId), E(), n.mode !== "select") return;
109
+ let n = T;
110
+ if (T = null, n.target.hasPointerCapture(e.pointerId) && n.target.releasePointerCapture(e.pointerId), A(), n.mode !== "select") return;
98
111
  let r = e.clientX - n.startX, u = e.clientY - n.startY;
99
112
  if (Math.hypot(r, u) < c) return;
100
113
  let d = s.getViewport(), f = l.getBoundingClientRect(), p = i(n.startX, n.startY, f, d), m = i(e.clientX, e.clientY, f, d);
101
114
  if (!p || !m) return;
102
115
  let h = a(d, p, m, t(o.axis));
103
116
  h.xMax > h.xMin && h.yMax > h.yMin && s.setViewport(h);
104
- }, z = (e) => {
105
- if (!x || e.pointerId !== x.pointerId) return;
106
- let t = x;
107
- x = null, t.target.hasPointerCapture(e.pointerId) && t.target.releasePointerCapture(e.pointerId), E();
108
- }, B = (e, t) => {
117
+ }, K = (e) => {
118
+ if (!T || e.pointerId !== T.pointerId) return;
119
+ let t = T;
120
+ T = null, t.target.hasPointerCapture(e.pointerId) && t.target.releasePointerCapture(e.pointerId), A();
121
+ }, q = (e, t, n) => {
109
122
  if (o.wheelZoom === !1) return;
110
- C(), e.preventDefault();
111
- let n = e.deltaY < 0 ? 1.1 : .9, r = l.getBoundingClientRect(), i = T({
112
- factor: n,
113
- cx: r.width > 0 ? (e.clientX - r.left) / r.width : .5,
114
- cy: r.height > 0 ? 1 - (e.clientY - r.top) / r.height : .5,
123
+ D(), e.preventDefault();
124
+ let r = e.deltaY < 0 ? 1.1 : .9, i = l.getBoundingClientRect(), a = k({
125
+ factor: r,
126
+ cx: i.width > 0 ? (e.clientX - i.left) / i.width : .5,
127
+ cy: i.height > 0 ? 1 - (e.clientY - i.top) / i.height : .5,
115
128
  axis: t
116
- });
117
- i && s.zoom(i);
118
- }, V = (e) => {
119
- B(e, t(o.axis));
120
- }, H = (e) => {
121
- o.axisInteractions !== !1 && B(e, "x");
122
- }, U = (e) => {
123
- o.axisInteractions !== !1 && B(e, "y");
124
- }, W = (e) => {
129
+ }, n ?? "left");
130
+ if (a) if (n && t === "y") {
131
+ let e = s.getCamera(n).clone();
132
+ e.zoom(a), s.setYViewport(n, {
133
+ yMin: e.yMin,
134
+ yMax: e.yMax
135
+ });
136
+ } else s.zoom(a);
137
+ }, J = (e) => {
138
+ q(e, t(o.axis));
139
+ }, Y = (e) => {
140
+ o.axisInteractions !== !1 && q(e, "x");
141
+ }, X = (e) => {
142
+ o.axisInteractions !== !1 && q(e, "y", "left");
143
+ }, Z = (e) => {
144
+ o.axisInteractions !== !1 && q(e, "y", "right");
145
+ }, Q = (e) => {
125
146
  if (o.doubleClickReset === !1) return;
126
147
  e.preventDefault();
127
- let t = S ?? r(s.getViewport());
148
+ let t = E ?? r(s.getViewport());
128
149
  s.setViewport(t);
129
- }, G = [
150
+ }, $ = [
130
151
  l,
131
152
  u,
132
- d
153
+ d,
154
+ f
133
155
  ];
134
- l.addEventListener("pointerdown", P), l.addEventListener("wheel", V, { passive: !1 }), l.addEventListener("dblclick", W), o.axisInteractions !== !1 && (u.addEventListener("pointerdown", F), d.addEventListener("pointerdown", I), u.addEventListener("pointerenter", O), u.addEventListener("pointerleave", k), d.addEventListener("pointerenter", A), d.addEventListener("pointerleave", j), u.addEventListener("wheel", H, { passive: !1 }), d.addEventListener("wheel", U, { passive: !1 }), u.addEventListener("dblclick", W), d.addEventListener("dblclick", W));
135
- for (let e of G) e.addEventListener("pointermove", L), e.addEventListener("pointerup", R), e.addEventListener("pointercancel", z);
156
+ l.addEventListener("pointerdown", B), l.addEventListener("wheel", J, { passive: !1 }), l.addEventListener("dblclick", Q), o.axisInteractions !== !1 && (u.addEventListener("pointerdown", V), d.addEventListener("pointerdown", H), f.addEventListener("pointerdown", U), u.addEventListener("pointerenter", M), u.addEventListener("pointerleave", N), d.addEventListener("pointerenter", P), d.addEventListener("pointerleave", F), f.addEventListener("pointerenter", I), f.addEventListener("pointerleave", L), u.addEventListener("wheel", Y, { passive: !1 }), d.addEventListener("wheel", X, { passive: !1 }), f.addEventListener("wheel", Z, { passive: !1 }), u.addEventListener("dblclick", Q), d.addEventListener("dblclick", Q), f.addEventListener("dblclick", Q));
157
+ for (let e of $) e.addEventListener("pointermove", W), e.addEventListener("pointerup", G), e.addEventListener("pointercancel", K);
136
158
  return () => {
137
- l.removeEventListener("pointerdown", P), l.removeEventListener("wheel", V), l.removeEventListener("dblclick", W), u.removeEventListener("pointerdown", F), d.removeEventListener("pointerdown", I), u.removeEventListener("pointerenter", O), u.removeEventListener("pointerleave", k), d.removeEventListener("pointerenter", A), d.removeEventListener("pointerleave", j), u.removeEventListener("wheel", H), d.removeEventListener("wheel", U), u.removeEventListener("dblclick", W), d.removeEventListener("dblclick", W);
138
- for (let e of G) e.removeEventListener("pointermove", L), e.removeEventListener("pointerup", R), e.removeEventListener("pointercancel", z);
139
- u.style.pointerEvents = h, d.style.pointerEvents = g, u.style.cursor = _, d.style.cursor = v, u.style.filter = y, d.style.filter = b, u.classList.remove(p), d.classList.remove(p), m.remove(), f.remove();
159
+ l.removeEventListener("pointerdown", B), l.removeEventListener("wheel", J), l.removeEventListener("dblclick", Q), u.removeEventListener("pointerdown", V), d.removeEventListener("pointerdown", H), f.removeEventListener("pointerdown", U), u.removeEventListener("pointerenter", M), u.removeEventListener("pointerleave", N), d.removeEventListener("pointerenter", P), d.removeEventListener("pointerleave", F), f.removeEventListener("pointerenter", I), f.removeEventListener("pointerleave", L), u.removeEventListener("wheel", Y), d.removeEventListener("wheel", X), f.removeEventListener("wheel", Z), u.removeEventListener("dblclick", Q), d.removeEventListener("dblclick", Q), f.removeEventListener("dblclick", Q);
160
+ for (let e of $) e.removeEventListener("pointermove", W), e.removeEventListener("pointerup", G), e.removeEventListener("pointercancel", K);
161
+ u.style.pointerEvents = g, d.style.pointerEvents = _, f.style.pointerEvents = v, u.style.cursor = y, d.style.cursor = b, f.style.cursor = x, u.style.filter = S, d.style.filter = C, f.style.filter = w, u.classList.remove(m), d.classList.remove(m), f.classList.remove(m), h.remove(), p.remove();
140
162
  };
141
163
  } };
142
164
  }
@@ -1 +1 @@
1
- {"version":3,"file":"interactions.js","names":[],"sources":["../../src/ui/Interactions.ts"],"sourcesContent":["import type { Viewport } from \"../core/types.js\";\nimport type { PanIntent, ViewportPolicy, ZoomAxis, ZoomIntent } from \"../interaction/types.js\";\nimport type { Chart, ChartPlugin } from \"./Chart.js\";\n\nexport type InteractionAxisOption = ZoomAxis | (() => ZoomAxis);\n\nexport interface InteractionsPluginOptions {\n readonly axis?: InteractionAxisOption;\n readonly viewportPolicy?: ViewportPolicy;\n readonly boxZoom?: boolean;\n readonly wheelZoom?: boolean;\n readonly axisInteractions?: boolean;\n readonly axisHover?: boolean;\n readonly axisHoverColor?: string;\n readonly axisHoverFilter?: string;\n readonly shiftDragPan?: boolean;\n readonly doubleClickReset?: boolean;\n readonly minDragDistancePx?: number;\n readonly selectionFill?: string;\n readonly selectionStroke?: string;\n}\n\nlet nextInteractionsPluginId = 1;\n\ntype InteractionTarget = HTMLCanvasElement | HTMLElement;\n\ntype DragState =\n | {\n readonly mode: \"pan\";\n readonly pointerId: number;\n readonly axis: ZoomAxis;\n readonly target: InteractionTarget;\n lastX: number;\n lastY: number;\n }\n | {\n readonly mode: \"select\";\n readonly pointerId: number;\n readonly target: HTMLCanvasElement;\n readonly startX: number;\n readonly startY: number;\n currentX: number;\n currentY: number;\n };\n\nfunction resolveAxis(axis: InteractionAxisOption | undefined): ZoomAxis {\n return typeof axis === \"function\" ? axis() : axis ?? \"xy\";\n}\n\nfunction constrainPan(intent: PanIntent, axis: ZoomAxis): PanIntent {\n return {\n dx: axis === \"y\" ? 0 : intent.dx,\n dy: axis === \"x\" ? 0 : intent.dy,\n };\n}\n\nfunction normalizeViewport(v: Viewport): Viewport {\n return { xMin: v.xMin, xMax: v.xMax, yMin: v.yMin, yMax: v.yMax };\n}\n\nfunction clientToDataClamped(\n clientX: number,\n clientY: number,\n rect: DOMRect,\n viewport: Viewport,\n): [number, number] | null {\n if (rect.width <= 0 || rect.height <= 0) return null;\n\n const plotX = Math.max(0, Math.min(clientX - rect.left, rect.width));\n const plotY = Math.max(0, Math.min(clientY - rect.top, rect.height));\n return [\n viewport.xMin + (plotX / rect.width) * (viewport.xMax - viewport.xMin),\n viewport.yMax - (plotY / rect.height) * (viewport.yMax - viewport.yMin),\n ];\n}\n\nfunction applySelectionAxis(\n current: Viewport,\n a: [number, number],\n b: [number, number],\n axis: ZoomAxis,\n): Viewport {\n const xMin = Math.min(a[0], b[0]);\n const xMax = Math.max(a[0], b[0]);\n const yMin = Math.min(a[1], b[1]);\n const yMax = Math.max(a[1], b[1]);\n\n return {\n xMin: axis === \"y\" ? current.xMin : xMin,\n xMax: axis === \"y\" ? current.xMax : xMax,\n yMin: axis === \"x\" ? current.yMin : yMin,\n yMax: axis === \"x\" ? current.yMax : yMax,\n };\n}\n\nexport function interactionsPlugin(options: InteractionsPluginOptions = {}): ChartPlugin {\n return {\n install(chart: Chart) {\n const minDragDistancePx = options.minDragDistancePx ?? 6;\n const canvas = chart.canvas;\n const xAxis = chart.xAxisElement;\n const yAxis = chart.yAxisElement;\n const selection = document.createElement(\"div\");\n const axisHoverClass = `blazeplot-axis-hover-${nextInteractionsPluginId++}`;\n const axisHoverStyle = document.createElement(\"style\");\n const originalXAxisPointerEvents = xAxis.style.pointerEvents;\n const originalYAxisPointerEvents = yAxis.style.pointerEvents;\n const originalXAxisCursor = xAxis.style.cursor;\n const originalYAxisCursor = yAxis.style.cursor;\n const originalXAxisFilter = xAxis.style.filter;\n const originalYAxisFilter = yAxis.style.filter;\n let drag: DragState | null = null;\n let resetViewport: Viewport | null = null;\n\n selection.className = \"blazeplot-selection\";\n selection.style.position = \"absolute\";\n selection.style.display = \"none\";\n selection.style.pointerEvents = \"none\";\n selection.style.zIndex = \"24\";\n selection.style.border = `1px solid ${options.selectionStroke ?? \"rgba(147, 197, 253, 0.95)\"}`;\n selection.style.background = options.selectionFill ?? \"rgba(59, 130, 246, 0.18)\";\n chart.plotElement.appendChild(selection);\n\n axisHoverStyle.textContent = `.${axisHoverClass} > div { color: ${options.axisHoverColor ?? \"#f8fafc\"} !important; }`;\n if (options.axisInteractions !== false && options.axisHover !== false) {\n chart.rootElement.appendChild(axisHoverStyle);\n }\n\n if (options.axisInteractions !== false) {\n xAxis.style.pointerEvents = \"auto\";\n yAxis.style.pointerEvents = \"auto\";\n xAxis.style.cursor = \"ew-resize\";\n yAxis.style.cursor = \"ns-resize\";\n }\n\n const captureResetViewport = (): void => {\n resetViewport ??= normalizeViewport(chart.getViewport());\n };\n\n const applyPanPolicy = (intent: PanIntent, panAxis: ZoomAxis): PanIntent | null => {\n const constrained = constrainPan(intent, panAxis);\n return options.viewportPolicy?.beforePan?.(chart.getCamera(), constrained) ?? constrained;\n };\n\n const applyZoomPolicy = (intent: ZoomIntent): ZoomIntent | null => {\n return options.viewportPolicy?.beforeZoom?.(chart.getCamera(), intent) ?? intent;\n };\n\n const hideSelection = (): void => {\n selection.style.display = \"none\";\n };\n\n const setAxisHovered = (target: HTMLElement, hovered: boolean): void => {\n if (options.axisHover === false) return;\n const filter = hovered ? options.axisHoverFilter ?? \"brightness(1.18)\" : null;\n target.classList.toggle(axisHoverClass, hovered);\n if (target === xAxis) {\n xAxis.style.filter = filter ?? originalXAxisFilter;\n } else if (target === yAxis) {\n yAxis.style.filter = filter ?? originalYAxisFilter;\n }\n };\n\n const onXAxisPointerEnter = (): void => setAxisHovered(xAxis, true);\n const onXAxisPointerLeave = (): void => setAxisHovered(xAxis, false);\n const onYAxisPointerEnter = (): void => setAxisHovered(yAxis, true);\n const onYAxisPointerLeave = (): void => setAxisHovered(yAxis, false);\n\n const updateSelection = (state: Extract<DragState, { mode: \"select\" }>): void => {\n const rect = canvas.getBoundingClientRect();\n const x0 = Math.max(0, Math.min(state.startX - rect.left, rect.width));\n const y0 = Math.max(0, Math.min(state.startY - rect.top, rect.height));\n const x1 = Math.max(0, Math.min(state.currentX - rect.left, rect.width));\n const y1 = Math.max(0, Math.min(state.currentY - rect.top, rect.height));\n const selectionAxis = resolveAxis(options.axis);\n const left = selectionAxis === \"y\" ? 0 : Math.min(x0, x1);\n const top = selectionAxis === \"x\" ? 0 : Math.min(y0, y1);\n const width = selectionAxis === \"y\" ? rect.width : Math.abs(x1 - x0);\n const height = selectionAxis === \"x\" ? rect.height : Math.abs(y1 - y0);\n\n selection.style.left = `${left}px`;\n selection.style.top = `${top}px`;\n selection.style.width = `${width}px`;\n selection.style.height = `${height}px`;\n selection.style.display = \"block\";\n };\n\n const beginPan = (event: PointerEvent, panAxis: ZoomAxis, target: InteractionTarget): void => {\n captureResetViewport();\n event.preventDefault();\n if (target !== canvas) setAxisHovered(target, true);\n target.setPointerCapture(event.pointerId);\n drag = {\n mode: \"pan\",\n pointerId: event.pointerId,\n axis: panAxis,\n target,\n lastX: event.clientX,\n lastY: event.clientY,\n };\n };\n\n const onCanvasPointerDown = (event: PointerEvent): void => {\n if (drag || event.button !== 0) return;\n\n if (event.shiftKey && options.shiftDragPan !== false) {\n beginPan(event, resolveAxis(options.axis), canvas);\n return;\n }\n\n if (options.boxZoom === false) return;\n captureResetViewport();\n event.preventDefault();\n canvas.setPointerCapture(event.pointerId);\n drag = {\n mode: \"select\",\n pointerId: event.pointerId,\n target: canvas,\n startX: event.clientX,\n startY: event.clientY,\n currentX: event.clientX,\n currentY: event.clientY,\n };\n updateSelection(drag);\n };\n\n const onXAxisPointerDown = (event: PointerEvent): void => {\n if (drag || event.button !== 0 || options.axisInteractions === false) return;\n beginPan(event, \"x\", xAxis);\n };\n\n const onYAxisPointerDown = (event: PointerEvent): void => {\n if (drag || event.button !== 0 || options.axisInteractions === false) return;\n beginPan(event, \"y\", yAxis);\n };\n\n const onPointerMove = (event: PointerEvent): void => {\n if (!drag || event.pointerId !== drag.pointerId) return;\n event.preventDefault();\n\n if (drag.mode === \"pan\") {\n const rect = canvas.getBoundingClientRect();\n const dx = rect.width > 0 ? (drag.lastX - event.clientX) / rect.width : 0;\n const dy = rect.height > 0 ? (event.clientY - drag.lastY) / rect.height : 0;\n const intent = applyPanPolicy({ dx, dy }, drag.axis);\n if (intent) chart.pan(intent);\n drag.lastX = event.clientX;\n drag.lastY = event.clientY;\n return;\n }\n\n drag.currentX = event.clientX;\n drag.currentY = event.clientY;\n updateSelection(drag);\n };\n\n const onPointerUp = (event: PointerEvent): void => {\n if (!drag || event.pointerId !== drag.pointerId) return;\n event.preventDefault();\n\n const completed = drag;\n drag = null;\n if (completed.target.hasPointerCapture(event.pointerId)) completed.target.releasePointerCapture(event.pointerId);\n hideSelection();\n\n if (completed.mode !== \"select\") return;\n\n const dx = event.clientX - completed.startX;\n const dy = event.clientY - completed.startY;\n if (Math.hypot(dx, dy) < minDragDistancePx) return;\n\n const current = chart.getViewport();\n const rect = canvas.getBoundingClientRect();\n const start = clientToDataClamped(completed.startX, completed.startY, rect, current);\n const end = clientToDataClamped(event.clientX, event.clientY, rect, current);\n if (!start || !end) return;\n\n const next = applySelectionAxis(current, start, end, resolveAxis(options.axis));\n if (next.xMax > next.xMin && next.yMax > next.yMin) chart.setViewport(next);\n };\n\n const onPointerCancel = (event: PointerEvent): void => {\n if (!drag || event.pointerId !== drag.pointerId) return;\n const completed = drag;\n drag = null;\n if (completed.target.hasPointerCapture(event.pointerId)) completed.target.releasePointerCapture(event.pointerId);\n hideSelection();\n };\n\n const wheelOnAxis = (event: WheelEvent, zoomAxis: ZoomAxis): void => {\n if (options.wheelZoom === false) return;\n captureResetViewport();\n event.preventDefault();\n const factor = event.deltaY < 0 ? 1.1 : 0.9;\n const rect = canvas.getBoundingClientRect();\n const cx = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0.5;\n const cy = rect.height > 0 ? 1 - (event.clientY - rect.top) / rect.height : 0.5;\n const intent = applyZoomPolicy({ factor, cx, cy, axis: zoomAxis });\n if (intent) chart.zoom(intent);\n };\n\n const onCanvasWheel = (event: WheelEvent): void => {\n wheelOnAxis(event, resolveAxis(options.axis));\n };\n\n const onXAxisWheel = (event: WheelEvent): void => {\n if (options.axisInteractions === false) return;\n wheelOnAxis(event, \"x\");\n };\n\n const onYAxisWheel = (event: WheelEvent): void => {\n if (options.axisInteractions === false) return;\n wheelOnAxis(event, \"y\");\n };\n\n const onDoubleClick = (event: MouseEvent): void => {\n if (options.doubleClickReset === false) return;\n event.preventDefault();\n const target = resetViewport ?? normalizeViewport(chart.getViewport());\n chart.setViewport(target);\n };\n\n const pointerTargets = [canvas, xAxis, yAxis];\n canvas.addEventListener(\"pointerdown\", onCanvasPointerDown);\n canvas.addEventListener(\"wheel\", onCanvasWheel, { passive: false });\n canvas.addEventListener(\"dblclick\", onDoubleClick);\n\n if (options.axisInteractions !== false) {\n xAxis.addEventListener(\"pointerdown\", onXAxisPointerDown);\n yAxis.addEventListener(\"pointerdown\", onYAxisPointerDown);\n xAxis.addEventListener(\"pointerenter\", onXAxisPointerEnter);\n xAxis.addEventListener(\"pointerleave\", onXAxisPointerLeave);\n yAxis.addEventListener(\"pointerenter\", onYAxisPointerEnter);\n yAxis.addEventListener(\"pointerleave\", onYAxisPointerLeave);\n xAxis.addEventListener(\"wheel\", onXAxisWheel, { passive: false });\n yAxis.addEventListener(\"wheel\", onYAxisWheel, { passive: false });\n xAxis.addEventListener(\"dblclick\", onDoubleClick);\n yAxis.addEventListener(\"dblclick\", onDoubleClick);\n }\n\n for (const target of pointerTargets) {\n target.addEventListener(\"pointermove\", onPointerMove);\n target.addEventListener(\"pointerup\", onPointerUp);\n target.addEventListener(\"pointercancel\", onPointerCancel);\n }\n\n return () => {\n canvas.removeEventListener(\"pointerdown\", onCanvasPointerDown);\n canvas.removeEventListener(\"wheel\", onCanvasWheel);\n canvas.removeEventListener(\"dblclick\", onDoubleClick);\n xAxis.removeEventListener(\"pointerdown\", onXAxisPointerDown);\n yAxis.removeEventListener(\"pointerdown\", onYAxisPointerDown);\n xAxis.removeEventListener(\"pointerenter\", onXAxisPointerEnter);\n xAxis.removeEventListener(\"pointerleave\", onXAxisPointerLeave);\n yAxis.removeEventListener(\"pointerenter\", onYAxisPointerEnter);\n yAxis.removeEventListener(\"pointerleave\", onYAxisPointerLeave);\n xAxis.removeEventListener(\"wheel\", onXAxisWheel);\n yAxis.removeEventListener(\"wheel\", onYAxisWheel);\n xAxis.removeEventListener(\"dblclick\", onDoubleClick);\n yAxis.removeEventListener(\"dblclick\", onDoubleClick);\n for (const target of pointerTargets) {\n target.removeEventListener(\"pointermove\", onPointerMove);\n target.removeEventListener(\"pointerup\", onPointerUp);\n target.removeEventListener(\"pointercancel\", onPointerCancel);\n }\n xAxis.style.pointerEvents = originalXAxisPointerEvents;\n yAxis.style.pointerEvents = originalYAxisPointerEvents;\n xAxis.style.cursor = originalXAxisCursor;\n yAxis.style.cursor = originalYAxisCursor;\n xAxis.style.filter = originalXAxisFilter;\n yAxis.style.filter = originalYAxisFilter;\n xAxis.classList.remove(axisHoverClass);\n yAxis.classList.remove(axisHoverClass);\n axisHoverStyle.remove();\n selection.remove();\n };\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"interactions.js","names":[],"sources":["../../src/ui/Interactions.ts"],"sourcesContent":["import type { SeriesYAxis, Viewport } from \"../core/types.js\";\nimport type { PanIntent, ViewportPolicy, ZoomAxis, ZoomIntent } from \"../interaction/types.js\";\nimport type { Chart, ChartPlugin } from \"./Chart.js\";\n\nexport type InteractionAxisOption = ZoomAxis | (() => ZoomAxis);\n\nexport interface InteractionsPluginOptions {\n readonly axis?: InteractionAxisOption;\n readonly viewportPolicy?: ViewportPolicy;\n readonly boxZoom?: boolean;\n readonly wheelZoom?: boolean;\n readonly axisInteractions?: boolean;\n readonly axisHover?: boolean;\n readonly axisHoverColor?: string;\n readonly axisHoverFilter?: string;\n readonly shiftDragPan?: boolean;\n readonly doubleClickReset?: boolean;\n readonly minDragDistancePx?: number;\n readonly selectionFill?: string;\n readonly selectionStroke?: string;\n}\n\nlet nextInteractionsPluginId = 1;\n\ntype InteractionTarget = HTMLCanvasElement | HTMLElement;\n\ntype DragState =\n | {\n readonly mode: \"pan\";\n readonly pointerId: number;\n readonly axis: ZoomAxis;\n readonly target: InteractionTarget;\n readonly yAxis?: SeriesYAxis;\n lastX: number;\n lastY: number;\n }\n | {\n readonly mode: \"select\";\n readonly pointerId: number;\n readonly target: HTMLCanvasElement;\n readonly startX: number;\n readonly startY: number;\n currentX: number;\n currentY: number;\n };\n\nfunction resolveAxis(axis: InteractionAxisOption | undefined): ZoomAxis {\n return typeof axis === \"function\" ? axis() : axis ?? \"xy\";\n}\n\nfunction constrainPan(intent: PanIntent, axis: ZoomAxis): PanIntent {\n return {\n dx: axis === \"y\" ? 0 : intent.dx,\n dy: axis === \"x\" ? 0 : intent.dy,\n };\n}\n\nfunction normalizeViewport(v: Viewport): Viewport {\n return { xMin: v.xMin, xMax: v.xMax, yMin: v.yMin, yMax: v.yMax };\n}\n\nfunction clientToDataClamped(\n clientX: number,\n clientY: number,\n rect: DOMRect,\n viewport: Viewport,\n): [number, number] | null {\n if (rect.width <= 0 || rect.height <= 0) return null;\n\n const plotX = Math.max(0, Math.min(clientX - rect.left, rect.width));\n const plotY = Math.max(0, Math.min(clientY - rect.top, rect.height));\n return [\n viewport.xMin + (plotX / rect.width) * (viewport.xMax - viewport.xMin),\n viewport.yMax - (plotY / rect.height) * (viewport.yMax - viewport.yMin),\n ];\n}\n\nfunction applySelectionAxis(\n current: Viewport,\n a: [number, number],\n b: [number, number],\n axis: ZoomAxis,\n): Viewport {\n const xMin = Math.min(a[0], b[0]);\n const xMax = Math.max(a[0], b[0]);\n const yMin = Math.min(a[1], b[1]);\n const yMax = Math.max(a[1], b[1]);\n\n return {\n xMin: axis === \"y\" ? current.xMin : xMin,\n xMax: axis === \"y\" ? current.xMax : xMax,\n yMin: axis === \"x\" ? current.yMin : yMin,\n yMax: axis === \"x\" ? current.yMax : yMax,\n };\n}\n\nexport function interactionsPlugin(options: InteractionsPluginOptions = {}): ChartPlugin {\n return {\n install(chart: Chart) {\n const minDragDistancePx = options.minDragDistancePx ?? 6;\n const canvas = chart.canvas;\n const xAxis = chart.xAxisElement;\n const yAxis = chart.yAxisElement;\n const y2Axis = chart.y2AxisElement;\n const selection = document.createElement(\"div\");\n const axisHoverClass = `blazeplot-axis-hover-${nextInteractionsPluginId++}`;\n const axisHoverStyle = document.createElement(\"style\");\n const originalXAxisPointerEvents = xAxis.style.pointerEvents;\n const originalYAxisPointerEvents = yAxis.style.pointerEvents;\n const originalY2AxisPointerEvents = y2Axis.style.pointerEvents;\n const originalXAxisCursor = xAxis.style.cursor;\n const originalYAxisCursor = yAxis.style.cursor;\n const originalY2AxisCursor = y2Axis.style.cursor;\n const originalXAxisFilter = xAxis.style.filter;\n const originalYAxisFilter = yAxis.style.filter;\n const originalY2AxisFilter = y2Axis.style.filter;\n let drag: DragState | null = null;\n let resetViewport: Viewport | null = null;\n\n selection.className = \"blazeplot-selection\";\n selection.style.position = \"absolute\";\n selection.style.display = \"none\";\n selection.style.pointerEvents = \"none\";\n selection.style.zIndex = \"24\";\n selection.style.border = `1px solid ${options.selectionStroke ?? \"rgba(147, 197, 253, 0.95)\"}`;\n selection.style.background = options.selectionFill ?? \"rgba(59, 130, 246, 0.18)\";\n chart.plotElement.appendChild(selection);\n\n axisHoverStyle.textContent = `.${axisHoverClass} > div { color: ${options.axisHoverColor ?? \"#f8fafc\"} !important; }`;\n if (options.axisInteractions !== false && options.axisHover !== false) {\n chart.rootElement.appendChild(axisHoverStyle);\n }\n\n if (options.axisInteractions !== false) {\n xAxis.style.pointerEvents = \"auto\";\n yAxis.style.pointerEvents = \"auto\";\n y2Axis.style.pointerEvents = \"auto\";\n xAxis.style.cursor = \"ew-resize\";\n yAxis.style.cursor = \"ns-resize\";\n y2Axis.style.cursor = \"ns-resize\";\n }\n\n const captureResetViewport = (): void => {\n resetViewport ??= normalizeViewport(chart.getViewport());\n };\n\n const applyPanPolicy = (intent: PanIntent, panAxis: ZoomAxis, targetYAxis: SeriesYAxis = \"left\"): PanIntent | null => {\n const constrained = constrainPan(intent, panAxis);\n return options.viewportPolicy?.beforePan?.(chart.getCamera(targetYAxis), constrained) ?? constrained;\n };\n\n const applyZoomPolicy = (intent: ZoomIntent, targetYAxis: SeriesYAxis = \"left\"): ZoomIntent | null => {\n return options.viewportPolicy?.beforeZoom?.(chart.getCamera(targetYAxis), intent) ?? intent;\n };\n\n const hideSelection = (): void => {\n selection.style.display = \"none\";\n };\n\n const setAxisHovered = (target: HTMLElement, hovered: boolean): void => {\n if (options.axisHover === false) return;\n const filter = hovered ? options.axisHoverFilter ?? \"brightness(1.18)\" : null;\n target.classList.toggle(axisHoverClass, hovered);\n if (target === xAxis) {\n xAxis.style.filter = filter ?? originalXAxisFilter;\n } else if (target === yAxis) {\n yAxis.style.filter = filter ?? originalYAxisFilter;\n } else if (target === y2Axis) {\n y2Axis.style.filter = filter ?? originalY2AxisFilter;\n }\n };\n\n const onXAxisPointerEnter = (): void => setAxisHovered(xAxis, true);\n const onXAxisPointerLeave = (): void => setAxisHovered(xAxis, false);\n const onYAxisPointerEnter = (): void => setAxisHovered(yAxis, true);\n const onYAxisPointerLeave = (): void => setAxisHovered(yAxis, false);\n const onY2AxisPointerEnter = (): void => setAxisHovered(y2Axis, true);\n const onY2AxisPointerLeave = (): void => setAxisHovered(y2Axis, false);\n\n const updateSelection = (state: Extract<DragState, { mode: \"select\" }>): void => {\n const rect = canvas.getBoundingClientRect();\n const x0 = Math.max(0, Math.min(state.startX - rect.left, rect.width));\n const y0 = Math.max(0, Math.min(state.startY - rect.top, rect.height));\n const x1 = Math.max(0, Math.min(state.currentX - rect.left, rect.width));\n const y1 = Math.max(0, Math.min(state.currentY - rect.top, rect.height));\n const selectionAxis = resolveAxis(options.axis);\n const left = selectionAxis === \"y\" ? 0 : Math.min(x0, x1);\n const top = selectionAxis === \"x\" ? 0 : Math.min(y0, y1);\n const width = selectionAxis === \"y\" ? rect.width : Math.abs(x1 - x0);\n const height = selectionAxis === \"x\" ? rect.height : Math.abs(y1 - y0);\n\n selection.style.left = `${left}px`;\n selection.style.top = `${top}px`;\n selection.style.width = `${width}px`;\n selection.style.height = `${height}px`;\n selection.style.display = \"block\";\n };\n\n const beginPan = (event: PointerEvent, panAxis: ZoomAxis, target: InteractionTarget, targetYAxis?: SeriesYAxis): void => {\n captureResetViewport();\n event.preventDefault();\n if (target !== canvas) setAxisHovered(target, true);\n target.setPointerCapture(event.pointerId);\n drag = {\n mode: \"pan\",\n pointerId: event.pointerId,\n axis: panAxis,\n target,\n yAxis: targetYAxis,\n lastX: event.clientX,\n lastY: event.clientY,\n };\n };\n\n const onCanvasPointerDown = (event: PointerEvent): void => {\n if (drag || event.button !== 0) return;\n\n if (event.shiftKey && options.shiftDragPan !== false) {\n beginPan(event, resolveAxis(options.axis), canvas);\n return;\n }\n\n if (options.boxZoom === false) return;\n captureResetViewport();\n event.preventDefault();\n canvas.setPointerCapture(event.pointerId);\n drag = {\n mode: \"select\",\n pointerId: event.pointerId,\n target: canvas,\n startX: event.clientX,\n startY: event.clientY,\n currentX: event.clientX,\n currentY: event.clientY,\n };\n updateSelection(drag);\n };\n\n const onXAxisPointerDown = (event: PointerEvent): void => {\n if (drag || event.button !== 0 || options.axisInteractions === false) return;\n beginPan(event, \"x\", xAxis);\n };\n\n const onYAxisPointerDown = (event: PointerEvent): void => {\n if (drag || event.button !== 0 || options.axisInteractions === false) return;\n beginPan(event, \"y\", yAxis, \"left\");\n };\n\n const onY2AxisPointerDown = (event: PointerEvent): void => {\n if (drag || event.button !== 0 || options.axisInteractions === false) return;\n beginPan(event, \"y\", y2Axis, \"right\");\n };\n\n const onPointerMove = (event: PointerEvent): void => {\n if (!drag || event.pointerId !== drag.pointerId) return;\n event.preventDefault();\n\n if (drag.mode === \"pan\") {\n const rect = canvas.getBoundingClientRect();\n const dx = rect.width > 0 ? (drag.lastX - event.clientX) / rect.width : 0;\n const dy = rect.height > 0 ? (event.clientY - drag.lastY) / rect.height : 0;\n const intent = applyPanPolicy({ dx, dy }, drag.axis, drag.yAxis ?? \"left\");\n if (intent) {\n if (drag.yAxis && drag.axis === \"y\") {\n const next = chart.getCamera(drag.yAxis).clone();\n next.pan({ dx: 0, dy: intent.dy });\n chart.setYViewport(drag.yAxis, { yMin: next.yMin, yMax: next.yMax });\n } else {\n chart.pan(intent);\n }\n }\n drag.lastX = event.clientX;\n drag.lastY = event.clientY;\n return;\n }\n\n drag.currentX = event.clientX;\n drag.currentY = event.clientY;\n updateSelection(drag);\n };\n\n const onPointerUp = (event: PointerEvent): void => {\n if (!drag || event.pointerId !== drag.pointerId) return;\n event.preventDefault();\n\n const completed = drag;\n drag = null;\n if (completed.target.hasPointerCapture(event.pointerId)) completed.target.releasePointerCapture(event.pointerId);\n hideSelection();\n\n if (completed.mode !== \"select\") return;\n\n const dx = event.clientX - completed.startX;\n const dy = event.clientY - completed.startY;\n if (Math.hypot(dx, dy) < minDragDistancePx) return;\n\n const current = chart.getViewport();\n const rect = canvas.getBoundingClientRect();\n const start = clientToDataClamped(completed.startX, completed.startY, rect, current);\n const end = clientToDataClamped(event.clientX, event.clientY, rect, current);\n if (!start || !end) return;\n\n const next = applySelectionAxis(current, start, end, resolveAxis(options.axis));\n if (next.xMax > next.xMin && next.yMax > next.yMin) chart.setViewport(next);\n };\n\n const onPointerCancel = (event: PointerEvent): void => {\n if (!drag || event.pointerId !== drag.pointerId) return;\n const completed = drag;\n drag = null;\n if (completed.target.hasPointerCapture(event.pointerId)) completed.target.releasePointerCapture(event.pointerId);\n hideSelection();\n };\n\n const wheelOnAxis = (event: WheelEvent, zoomAxis: ZoomAxis, targetYAxis?: SeriesYAxis): void => {\n if (options.wheelZoom === false) return;\n captureResetViewport();\n event.preventDefault();\n const factor = event.deltaY < 0 ? 1.1 : 0.9;\n const rect = canvas.getBoundingClientRect();\n const cx = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0.5;\n const cy = rect.height > 0 ? 1 - (event.clientY - rect.top) / rect.height : 0.5;\n const intent = applyZoomPolicy({ factor, cx, cy, axis: zoomAxis }, targetYAxis ?? \"left\");\n if (!intent) return;\n if (targetYAxis && zoomAxis === \"y\") {\n const next = chart.getCamera(targetYAxis).clone();\n next.zoom(intent);\n chart.setYViewport(targetYAxis, { yMin: next.yMin, yMax: next.yMax });\n } else {\n chart.zoom(intent);\n }\n };\n\n const onCanvasWheel = (event: WheelEvent): void => {\n wheelOnAxis(event, resolveAxis(options.axis));\n };\n\n const onXAxisWheel = (event: WheelEvent): void => {\n if (options.axisInteractions === false) return;\n wheelOnAxis(event, \"x\");\n };\n\n const onYAxisWheel = (event: WheelEvent): void => {\n if (options.axisInteractions === false) return;\n wheelOnAxis(event, \"y\", \"left\");\n };\n\n const onY2AxisWheel = (event: WheelEvent): void => {\n if (options.axisInteractions === false) return;\n wheelOnAxis(event, \"y\", \"right\");\n };\n\n const onDoubleClick = (event: MouseEvent): void => {\n if (options.doubleClickReset === false) return;\n event.preventDefault();\n const target = resetViewport ?? normalizeViewport(chart.getViewport());\n chart.setViewport(target);\n };\n\n const pointerTargets = [canvas, xAxis, yAxis, y2Axis];\n canvas.addEventListener(\"pointerdown\", onCanvasPointerDown);\n canvas.addEventListener(\"wheel\", onCanvasWheel, { passive: false });\n canvas.addEventListener(\"dblclick\", onDoubleClick);\n\n if (options.axisInteractions !== false) {\n xAxis.addEventListener(\"pointerdown\", onXAxisPointerDown);\n yAxis.addEventListener(\"pointerdown\", onYAxisPointerDown);\n y2Axis.addEventListener(\"pointerdown\", onY2AxisPointerDown);\n xAxis.addEventListener(\"pointerenter\", onXAxisPointerEnter);\n xAxis.addEventListener(\"pointerleave\", onXAxisPointerLeave);\n yAxis.addEventListener(\"pointerenter\", onYAxisPointerEnter);\n yAxis.addEventListener(\"pointerleave\", onYAxisPointerLeave);\n y2Axis.addEventListener(\"pointerenter\", onY2AxisPointerEnter);\n y2Axis.addEventListener(\"pointerleave\", onY2AxisPointerLeave);\n xAxis.addEventListener(\"wheel\", onXAxisWheel, { passive: false });\n yAxis.addEventListener(\"wheel\", onYAxisWheel, { passive: false });\n y2Axis.addEventListener(\"wheel\", onY2AxisWheel, { passive: false });\n xAxis.addEventListener(\"dblclick\", onDoubleClick);\n yAxis.addEventListener(\"dblclick\", onDoubleClick);\n y2Axis.addEventListener(\"dblclick\", onDoubleClick);\n }\n\n for (const target of pointerTargets) {\n target.addEventListener(\"pointermove\", onPointerMove);\n target.addEventListener(\"pointerup\", onPointerUp);\n target.addEventListener(\"pointercancel\", onPointerCancel);\n }\n\n return () => {\n canvas.removeEventListener(\"pointerdown\", onCanvasPointerDown);\n canvas.removeEventListener(\"wheel\", onCanvasWheel);\n canvas.removeEventListener(\"dblclick\", onDoubleClick);\n xAxis.removeEventListener(\"pointerdown\", onXAxisPointerDown);\n yAxis.removeEventListener(\"pointerdown\", onYAxisPointerDown);\n y2Axis.removeEventListener(\"pointerdown\", onY2AxisPointerDown);\n xAxis.removeEventListener(\"pointerenter\", onXAxisPointerEnter);\n xAxis.removeEventListener(\"pointerleave\", onXAxisPointerLeave);\n yAxis.removeEventListener(\"pointerenter\", onYAxisPointerEnter);\n yAxis.removeEventListener(\"pointerleave\", onYAxisPointerLeave);\n y2Axis.removeEventListener(\"pointerenter\", onY2AxisPointerEnter);\n y2Axis.removeEventListener(\"pointerleave\", onY2AxisPointerLeave);\n xAxis.removeEventListener(\"wheel\", onXAxisWheel);\n yAxis.removeEventListener(\"wheel\", onYAxisWheel);\n y2Axis.removeEventListener(\"wheel\", onY2AxisWheel);\n xAxis.removeEventListener(\"dblclick\", onDoubleClick);\n yAxis.removeEventListener(\"dblclick\", onDoubleClick);\n y2Axis.removeEventListener(\"dblclick\", onDoubleClick);\n for (const target of pointerTargets) {\n target.removeEventListener(\"pointermove\", onPointerMove);\n target.removeEventListener(\"pointerup\", onPointerUp);\n target.removeEventListener(\"pointercancel\", onPointerCancel);\n }\n xAxis.style.pointerEvents = originalXAxisPointerEvents;\n yAxis.style.pointerEvents = originalYAxisPointerEvents;\n y2Axis.style.pointerEvents = originalY2AxisPointerEvents;\n xAxis.style.cursor = originalXAxisCursor;\n yAxis.style.cursor = originalYAxisCursor;\n y2Axis.style.cursor = originalY2AxisCursor;\n xAxis.style.filter = originalXAxisFilter;\n yAxis.style.filter = originalYAxisFilter;\n y2Axis.style.filter = originalY2AxisFilter;\n xAxis.classList.remove(axisHoverClass);\n yAxis.classList.remove(axisHoverClass);\n y2Axis.classList.remove(axisHoverClass);\n axisHoverStyle.remove();\n selection.remove();\n };\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { navigatorPlugin } from '../ui/Navigator.js';
2
+ export type { NavigatorPlugin, NavigatorPluginOptions } from '../ui/Navigator.js';
3
+ //# sourceMappingURL=navigator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigator.d.ts","sourceRoot":"","sources":["../../src/plugins/navigator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,147 @@
1
+ //#region src/ui/Navigator.ts
2
+ var e = "http://www.w3.org/2000/svg";
3
+ function t(t) {
4
+ return document.createElementNS(e, t);
5
+ }
6
+ function n(e) {
7
+ return `rgba(${Math.round(e[0] * 255)}, ${Math.round(e[1] * 255)}, ${Math.round(e[2] * 255)}, ${e[3]})`;
8
+ }
9
+ function r(e, t) {
10
+ return t ? Array.isArray(t) ? [...t] : [t] : e.getSeriesState().filter((e) => e.visible).map((e) => e.series);
11
+ }
12
+ function i(e, t) {
13
+ let n = Infinity, r = -Infinity, i = Infinity, a = -Infinity;
14
+ for (let o of e) {
15
+ if (o.length <= 0) continue;
16
+ let e = o.sampleAt(0), s = o.sampleAt(o.length - 1);
17
+ if (!e || !s) continue;
18
+ n = Math.min(n, e.x, s.x), r = Math.max(r, e.x, s.x);
19
+ let c = Math.max(1, Math.ceil(o.length / t));
20
+ for (let e = 0; e < o.length; e += c) {
21
+ let t = o.sampleAt(e);
22
+ t && (i = Math.min(i, t.y), a = Math.max(a, t.y));
23
+ }
24
+ }
25
+ return !Number.isFinite(n) || !Number.isFinite(r) || r <= n || !Number.isFinite(i) || !Number.isFinite(a) ? null : (a <= i && (--i, a += 1), {
26
+ xMin: n,
27
+ xMax: r,
28
+ yMin: i,
29
+ yMax: a
30
+ });
31
+ }
32
+ function a(e, t, n, r, i) {
33
+ if (e.length <= 0 || n <= 0 || r <= 0) return "";
34
+ let a = Math.max(1, Math.ceil(e.length / i)), o = t.xMax - t.xMin, s = t.yMax - t.yMin, c = (n - 1) / o, l = (r - 1) / s, u = "", d = -1, f = (n) => {
35
+ if (n === d) return;
36
+ let i = e.sampleAt(n);
37
+ if (!i) return;
38
+ let a = (i.x - t.xMin) * c, o = r - 1 - (i.y - t.yMin) * l;
39
+ u += u ? ` L ${a.toFixed(2)} ${o.toFixed(2)}` : `M ${a.toFixed(2)} ${o.toFixed(2)}`, d = n;
40
+ };
41
+ f(0);
42
+ for (let t = a; t < e.length - 1; t += a) f(t);
43
+ return f(e.length - 1), u;
44
+ }
45
+ function o(e = {}) {
46
+ let o = Math.max(24, e.height ?? 56), s = Math.max(0, e.margin ?? 8), c = e.placement ?? "bottom", l = Math.max(16, e.maxSamplesPerSeries ?? 512), u = Math.max(4, e.handleWidth ?? 8), d = Math.max(u, e.handleHitWidth ?? 18), f = `navigator-${Math.random().toString(36).slice(2)}`, p = null, m = null, h = null, g = null, _ = null, v = null, y = null, b = null, x = [], S = null, C = null, w = !0, T = (e, t) => S ? (e - S.xMin) / (S.xMax - S.xMin) * t : 0, E = (e, t) => S ? S.xMin + e / t * (S.xMax - S.xMin) : 0, D = () => {
47
+ let t = p;
48
+ if (!t || !m) return;
49
+ let n = t.rootElement.getBoundingClientRect(), r = e.align === "chart" ? n : t.plotElement.getBoundingClientRect();
50
+ m.style.left = `${Math.max(0, r.left - n.left)}px`, m.style.width = `${Math.max(1, r.width)}px`;
51
+ }, O = () => {
52
+ let s = p;
53
+ if (!s || !m || !h || !g || !_ || !v || !y || !b) return;
54
+ D();
55
+ let c = r(s, e.series);
56
+ if (S = i(c, l), !S) {
57
+ m.style.display = "none";
58
+ return;
59
+ }
60
+ m.style.display = "block";
61
+ let f = Math.max(1, m.clientWidth);
62
+ for (h.setAttribute("viewBox", `0 0 ${f} ${o}`), h.setAttribute("preserveAspectRatio", "none"); x.length < c.length;) {
63
+ let e = t("path");
64
+ e.setAttribute("fill", "none"), e.setAttribute("vector-effect", "non-scaling-stroke"), h.insertBefore(e, g), x.push(e);
65
+ }
66
+ for (let t = 0; t < x.length; t++) {
67
+ let r = x[t], i = c[t];
68
+ if (!i) {
69
+ r.style.display = "none";
70
+ continue;
71
+ }
72
+ r.style.display = "block", r.setAttribute("d", a(i, S, f, o, l)), r.setAttribute("stroke", e.stroke ?? n(i.style.color)), r.setAttribute("stroke-width", String(e.strokeWidth ?? Math.max(1, i.style.lineWidth))), r.setAttribute("fill", e.fill ?? "none");
73
+ }
74
+ let C = s.getViewport();
75
+ if (e.followLive !== !1 && w && S.xMax > C.xMax) {
76
+ let e = C.xMax - C.xMin;
77
+ s.setViewport({
78
+ xMin: S.xMax - e,
79
+ xMax: S.xMax
80
+ });
81
+ }
82
+ let E = s.getViewport();
83
+ w = Math.abs(E.xMax - S.xMax) <= (S.xMax - S.xMin) * .005;
84
+ let O = T(E.xMin, f - 1), k = T(E.xMax, f - 1), A = Math.max(1, k - O);
85
+ g.setAttribute("x", String(O)), g.setAttribute("y", "0"), g.setAttribute("width", String(A)), g.setAttribute("height", String(o)), _.setAttribute("x", String(O - u * .5)), v.setAttribute("x", String(k - u * .5));
86
+ for (let e of [_, v]) e.setAttribute("y", "0"), e.setAttribute("width", String(u)), e.setAttribute("height", String(o));
87
+ y.setAttribute("x", String(O - d * .5)), b.setAttribute("x", String(k - d * .5));
88
+ for (let e of [y, b]) e.setAttribute("y", "0"), e.setAttribute("width", String(d)), e.setAttribute("height", String(o));
89
+ }, k = (t, n) => {
90
+ let r = p;
91
+ if (!r || !S) return;
92
+ let i = (S.xMax - S.xMin) / 1e4;
93
+ if (n - t < i) return;
94
+ let a = n - t;
95
+ t < S.xMin && (t = S.xMin, n = t + a), n > S.xMax && (n = S.xMax, t = n - a), r.setViewport({
96
+ xMin: t,
97
+ xMax: n
98
+ }), e.onRangeChange?.({
99
+ xMin: t,
100
+ xMax: n
101
+ }), O();
102
+ };
103
+ return {
104
+ install(r) {
105
+ p = r, m = document.createElement("div"), m.className = e.className ?? "blazeplot-navigator", m.style.position = "absolute", m.style.left = "0", m.style.width = "100%", m.style[c] = `${s}px`, m.style.height = `${o}px`, m.style.boxSizing = "border-box", m.style.border = "0", m.style.zIndex = String(e.zIndex ?? 30), m.style.touchAction = "none", e.reserveSpace !== !1 && r.setLayoutReservation(f, c === "top" ? { top: o + s * 2 } : { bottom: o + s * 2 }), h = t("svg"), h.style.width = "100%", h.style.height = "100%", h.style.display = "block", g = t("rect"), _ = t("rect"), v = t("rect"), y = t("rect"), b = t("rect");
106
+ for (let e of [_, v]) e.style.cursor = "ew-resize", e.style.pointerEvents = "none";
107
+ for (let e of [y, b]) e.setAttribute("fill", "transparent"), e.style.cursor = "ew-resize";
108
+ g.style.cursor = "grab", h.appendChild(g), h.appendChild(_), h.appendChild(v), h.appendChild(y), h.appendChild(b), m.appendChild(h), r.rootElement.appendChild(m);
109
+ let i = () => {
110
+ if (!m || !g || !_ || !v) return;
111
+ let t = e.windowStroke ?? r.theme.axisColor;
112
+ m.style.background = e.background ?? r.theme.legendBackgroundColor, m.style.outline = `1px solid ${e.borderColor ?? r.theme.legendBorderColor}`, g.setAttribute("fill", e.windowFill ?? n(r.theme.gridColor)), g.setAttribute("stroke", t), _.setAttribute("fill", t), v.setAttribute("fill", t);
113
+ }, a = () => O(), l = r.subscribe("render", a), u = r.subscribe("viewportchange", a), w = r.subscribe("themechange", () => {
114
+ i(), O();
115
+ });
116
+ i();
117
+ let D = (e) => {
118
+ if (!m || !S || e.button !== 0) return;
119
+ let t = m.getBoundingClientRect(), n = e.clientX - t.left, i = r.getViewport(), a = T(i.xMin, t.width), o = T(i.xMax, t.width), s = e.target, c = s === y || Math.abs(n - a) <= d * .5 ? "left" : s === b || Math.abs(n - o) <= d * .5 ? "right" : "pan";
120
+ C = {
121
+ mode: c,
122
+ startClientX: e.clientX,
123
+ startXMin: i.xMin,
124
+ startXMax: i.xMax
125
+ }, g && (g.style.cursor = c === "pan" ? "grabbing" : "ew-resize"), m.setPointerCapture(e.pointerId), e.preventDefault();
126
+ }, A = (e) => {
127
+ if (!C || !m || !S) return;
128
+ let t = m.getBoundingClientRect(), n = E(e.clientX - C.startClientX, t.width) - E(0, t.width);
129
+ C.mode === "left" ? k(C.startXMin + n, C.startXMax) : C.mode === "right" ? k(C.startXMin, C.startXMax + n) : k(C.startXMin + n, C.startXMax + n);
130
+ }, j = (e) => {
131
+ m?.hasPointerCapture(e.pointerId) && m.releasePointerCapture(e.pointerId), g && (g.style.cursor = "grab"), C = null;
132
+ }, M = () => {
133
+ S && k(S.xMin, S.xMax);
134
+ };
135
+ return m.addEventListener("pointerdown", D), m.addEventListener("pointermove", A), m.addEventListener("pointerup", j), m.addEventListener("pointercancel", j), m.addEventListener("dblclick", M), O(), () => {
136
+ l(), u(), w(), m?.removeEventListener("pointerdown", D), m?.removeEventListener("pointermove", A), m?.removeEventListener("pointerup", j), m?.removeEventListener("pointercancel", j), m?.removeEventListener("dblclick", M), e.reserveSpace !== !1 && r.setLayoutReservation(f, null), m?.remove(), m = null, h = null, g = null, _ = null, v = null, y = null, b = null, x = [], S = null, C = null, p = null;
137
+ };
138
+ },
139
+ refresh() {
140
+ O();
141
+ }
142
+ };
143
+ }
144
+ //#endregion
145
+ export { o as navigatorPlugin };
146
+
147
+ //# sourceMappingURL=navigator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigator.js","names":[],"sources":["../../src/ui/Navigator.ts"],"sourcesContent":["import type { SeriesStore } from \"../core/SeriesStore.js\";\nimport type { Chart, ChartPlugin } from \"./Chart.js\";\n\nexport interface NavigatorPluginOptions {\n readonly height?: number;\n readonly placement?: \"bottom\" | \"top\";\n readonly series?: SeriesStore | readonly SeriesStore[];\n readonly maxSamplesPerSeries?: number;\n readonly followLive?: boolean;\n readonly className?: string;\n readonly background?: string;\n readonly borderColor?: string;\n readonly stroke?: string;\n readonly strokeWidth?: number;\n readonly fill?: string;\n readonly windowFill?: string;\n readonly windowStroke?: string;\n readonly handleWidth?: number;\n readonly handleHitWidth?: number;\n readonly zIndex?: number;\n readonly reserveSpace?: boolean;\n readonly margin?: number;\n readonly align?: \"plot\" | \"chart\";\n readonly onRangeChange?: (range: { readonly xMin: number; readonly xMax: number }) => void;\n}\n\nexport interface NavigatorPlugin extends ChartPlugin {\n refresh(): void;\n}\n\ninterface Domain {\n readonly xMin: number;\n readonly xMax: number;\n readonly yMin: number;\n readonly yMax: number;\n}\n\ntype DragMode = \"pan\" | \"left\" | \"right\";\n\ninterface DragState {\n readonly mode: DragMode;\n readonly startClientX: number;\n readonly startXMin: number;\n readonly startXMax: number;\n}\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\nfunction svg<K extends keyof SVGElementTagNameMap>(tag: K): SVGElementTagNameMap[K] {\n return document.createElementNS(SVG_NS, tag);\n}\n\nfunction rgba(color: readonly [number, number, number, number]): string {\n return `rgba(${Math.round(color[0] * 255)}, ${Math.round(color[1] * 255)}, ${Math.round(color[2] * 255)}, ${color[3]})`;\n}\n\nfunction seriesList(chart: Chart, option: NavigatorPluginOptions[\"series\"]): SeriesStore[] {\n if (option) return Array.isArray(option) ? [...(option as readonly SeriesStore[])] : [option as SeriesStore];\n return chart.getSeriesState().filter((state) => state.visible).map((state) => state.series);\n}\n\nfunction computeDomain(series: readonly SeriesStore[], maxSamplesPerSeries: number): Domain | null {\n let xMin = Infinity;\n let xMax = -Infinity;\n let yMin = Infinity;\n let yMax = -Infinity;\n\n for (const s of series) {\n if (s.length <= 0) continue;\n const first = s.sampleAt(0);\n const last = s.sampleAt(s.length - 1);\n if (!first || !last) continue;\n xMin = Math.min(xMin, first.x, last.x);\n xMax = Math.max(xMax, first.x, last.x);\n const stride = Math.max(1, Math.ceil(s.length / maxSamplesPerSeries));\n for (let i = 0; i < s.length; i += stride) {\n const sample = s.sampleAt(i);\n if (!sample) continue;\n yMin = Math.min(yMin, sample.y);\n yMax = Math.max(yMax, sample.y);\n }\n }\n\n if (!Number.isFinite(xMin) || !Number.isFinite(xMax) || xMax <= xMin || !Number.isFinite(yMin) || !Number.isFinite(yMax)) return null;\n if (yMax <= yMin) {\n yMin -= 1;\n yMax += 1;\n }\n return { xMin, xMax, yMin, yMax };\n}\n\nfunction pathForSeries(series: SeriesStore, domain: Domain, width: number, height: number, maxSamples: number): string {\n if (series.length <= 0 || width <= 0 || height <= 0) return \"\";\n const stride = Math.max(1, Math.ceil(series.length / maxSamples));\n const xRange = domain.xMax - domain.xMin;\n const yRange = domain.yMax - domain.yMin;\n const xScale = (width - 1) / xRange;\n const yScale = (height - 1) / yRange;\n let path = \"\";\n let lastIndex = -1;\n const appendSample = (index: number): void => {\n if (index === lastIndex) return;\n const sample = series.sampleAt(index);\n if (!sample) return;\n const x = (sample.x - domain.xMin) * xScale;\n const y = (height - 1) - (sample.y - domain.yMin) * yScale;\n path += path ? ` L ${x.toFixed(2)} ${y.toFixed(2)}` : `M ${x.toFixed(2)} ${y.toFixed(2)}`;\n lastIndex = index;\n };\n\n appendSample(0);\n for (let i = stride; i < series.length - 1; i += stride) appendSample(i);\n appendSample(series.length - 1);\n return path;\n}\n\nexport function navigatorPlugin(options: NavigatorPluginOptions = {}): NavigatorPlugin {\n const height = Math.max(24, options.height ?? 56);\n const margin = Math.max(0, options.margin ?? 8);\n const placement = options.placement ?? \"bottom\";\n const maxSamplesPerSeries = Math.max(16, options.maxSamplesPerSeries ?? 512);\n const handleWidth = Math.max(4, options.handleWidth ?? 8);\n const handleHitWidth = Math.max(handleWidth, options.handleHitWidth ?? 18);\n const reservationId = `navigator-${Math.random().toString(36).slice(2)}`;\n let chartRef: Chart | null = null;\n let root: HTMLDivElement | null = null;\n let overlay: SVGSVGElement | null = null;\n let windowRect: SVGRectElement | null = null;\n let leftHandle: SVGRectElement | null = null;\n let rightHandle: SVGRectElement | null = null;\n let leftHandleHit: SVGRectElement | null = null;\n let rightHandleHit: SVGRectElement | null = null;\n let paths: SVGPathElement[] = [];\n let domain: Domain | null = null;\n let drag: DragState | null = null;\n let wasAtRightEdge = true;\n\n const dataToX = (x: number, width: number): number => domain ? ((x - domain.xMin) / (domain.xMax - domain.xMin)) * width : 0;\n const xToData = (x: number, width: number): number => domain ? domain.xMin + (x / width) * (domain.xMax - domain.xMin) : 0;\n\n const updateRootPosition = (): void => {\n const chart = chartRef;\n if (!chart || !root) return;\n const rootRect = chart.rootElement.getBoundingClientRect();\n const alignRect = options.align === \"chart\" ? rootRect : chart.plotElement.getBoundingClientRect();\n root.style.left = `${Math.max(0, alignRect.left - rootRect.left)}px`;\n root.style.width = `${Math.max(1, alignRect.width)}px`;\n };\n\n const render = (): void => {\n const chart = chartRef;\n if (!chart || !root || !overlay || !windowRect || !leftHandle || !rightHandle || !leftHandleHit || !rightHandleHit) return;\n updateRootPosition();\n const selectedSeries = seriesList(chart, options.series);\n domain = computeDomain(selectedSeries, maxSamplesPerSeries);\n if (!domain) {\n root.style.display = \"none\";\n return;\n }\n\n root.style.display = \"block\";\n const width = Math.max(1, root.clientWidth);\n overlay.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n overlay.setAttribute(\"preserveAspectRatio\", \"none\");\n\n while (paths.length < selectedSeries.length) {\n const path = svg(\"path\");\n path.setAttribute(\"fill\", \"none\");\n path.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n overlay.insertBefore(path, windowRect);\n paths.push(path);\n }\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i]!;\n const series = selectedSeries[i];\n if (!series) {\n path.style.display = \"none\";\n continue;\n }\n path.style.display = \"block\";\n path.setAttribute(\"d\", pathForSeries(series, domain, width, height, maxSamplesPerSeries));\n path.setAttribute(\"stroke\", options.stroke ?? rgba(series.style.color));\n path.setAttribute(\"stroke-width\", String(options.strokeWidth ?? Math.max(1, series.style.lineWidth)));\n path.setAttribute(\"fill\", options.fill ?? \"none\");\n }\n\n const viewport = chart.getViewport();\n if (options.followLive !== false && wasAtRightEdge && domain.xMax > viewport.xMax) {\n const span = viewport.xMax - viewport.xMin;\n chart.setViewport({ xMin: domain.xMax - span, xMax: domain.xMax });\n }\n\n const current = chart.getViewport();\n wasAtRightEdge = Math.abs(current.xMax - domain.xMax) <= (domain.xMax - domain.xMin) * 0.005;\n const left = dataToX(current.xMin, width - 1);\n const right = dataToX(current.xMax, width - 1);\n const winW = Math.max(1, right - left);\n windowRect.setAttribute(\"x\", String(left));\n windowRect.setAttribute(\"y\", \"0\");\n windowRect.setAttribute(\"width\", String(winW));\n windowRect.setAttribute(\"height\", String(height));\n leftHandle.setAttribute(\"x\", String(left - handleWidth * 0.5));\n rightHandle.setAttribute(\"x\", String(right - handleWidth * 0.5));\n for (const handle of [leftHandle, rightHandle]) {\n handle.setAttribute(\"y\", \"0\");\n handle.setAttribute(\"width\", String(handleWidth));\n handle.setAttribute(\"height\", String(height));\n }\n leftHandleHit.setAttribute(\"x\", String(left - handleHitWidth * 0.5));\n rightHandleHit.setAttribute(\"x\", String(right - handleHitWidth * 0.5));\n for (const handle of [leftHandleHit, rightHandleHit]) {\n handle.setAttribute(\"y\", \"0\");\n handle.setAttribute(\"width\", String(handleHitWidth));\n handle.setAttribute(\"height\", String(height));\n }\n };\n\n const applyRange = (xMin: number, xMax: number): void => {\n const chart = chartRef;\n if (!chart || !domain) return;\n const full = domain.xMax - domain.xMin;\n const minSpan = full / 10_000;\n if (xMax - xMin < minSpan) return;\n const span = xMax - xMin;\n if (xMin < domain.xMin) {\n xMin = domain.xMin;\n xMax = xMin + span;\n }\n if (xMax > domain.xMax) {\n xMax = domain.xMax;\n xMin = xMax - span;\n }\n chart.setViewport({ xMin, xMax });\n options.onRangeChange?.({ xMin, xMax });\n render();\n };\n\n return {\n install(chart: Chart) {\n chartRef = chart;\n root = document.createElement(\"div\");\n root.className = options.className ?? \"blazeplot-navigator\";\n root.style.position = \"absolute\";\n root.style.left = \"0\";\n root.style.width = \"100%\";\n root.style[placement] = `${margin}px`;\n root.style.height = `${height}px`;\n root.style.boxSizing = \"border-box\";\n root.style.border = \"0\";\n root.style.zIndex = String(options.zIndex ?? 30);\n root.style.touchAction = \"none\";\n\n if (options.reserveSpace !== false) {\n chart.setLayoutReservation(reservationId, placement === \"top\" ? { top: height + margin * 2 } : { bottom: height + margin * 2 });\n }\n\n overlay = svg(\"svg\");\n overlay.style.width = \"100%\";\n overlay.style.height = \"100%\";\n overlay.style.display = \"block\";\n windowRect = svg(\"rect\");\n leftHandle = svg(\"rect\");\n rightHandle = svg(\"rect\");\n leftHandleHit = svg(\"rect\");\n rightHandleHit = svg(\"rect\");\n for (const handle of [leftHandle, rightHandle]) {\n handle.style.cursor = \"ew-resize\";\n handle.style.pointerEvents = \"none\";\n }\n for (const handle of [leftHandleHit, rightHandleHit]) {\n handle.setAttribute(\"fill\", \"transparent\");\n handle.style.cursor = \"ew-resize\";\n }\n windowRect.style.cursor = \"grab\";\n overlay.appendChild(windowRect);\n overlay.appendChild(leftHandle);\n overlay.appendChild(rightHandle);\n overlay.appendChild(leftHandleHit);\n overlay.appendChild(rightHandleHit);\n root.appendChild(overlay);\n chart.rootElement.appendChild(root);\n\n const applyTheme = (): void => {\n if (!root || !windowRect || !leftHandle || !rightHandle) return;\n const windowStroke = options.windowStroke ?? chart.theme.axisColor;\n root.style.background = options.background ?? chart.theme.legendBackgroundColor;\n root.style.outline = `1px solid ${options.borderColor ?? chart.theme.legendBorderColor}`;\n windowRect.setAttribute(\"fill\", options.windowFill ?? rgba(chart.theme.gridColor));\n windowRect.setAttribute(\"stroke\", windowStroke);\n leftHandle.setAttribute(\"fill\", windowStroke);\n rightHandle.setAttribute(\"fill\", windowStroke);\n };\n\n const onRender = (): void => render();\n const unsubscribeRender = chart.subscribe(\"render\", onRender);\n const unsubscribeViewport = chart.subscribe(\"viewportchange\", onRender);\n const unsubscribeTheme = chart.subscribe(\"themechange\", () => {\n applyTheme();\n render();\n });\n applyTheme();\n\n const onPointerDown = (event: PointerEvent): void => {\n if (!root || !domain || event.button !== 0) return;\n const rect = root.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const viewport = chart.getViewport();\n const left = dataToX(viewport.xMin, rect.width);\n const right = dataToX(viewport.xMax, rect.width);\n const target = event.target;\n const mode: DragMode = target === leftHandleHit || Math.abs(x - left) <= handleHitWidth * 0.5\n ? \"left\"\n : target === rightHandleHit || Math.abs(x - right) <= handleHitWidth * 0.5\n ? \"right\"\n : \"pan\";\n drag = { mode, startClientX: event.clientX, startXMin: viewport.xMin, startXMax: viewport.xMax };\n if (windowRect) windowRect.style.cursor = mode === \"pan\" ? \"grabbing\" : \"ew-resize\";\n root.setPointerCapture(event.pointerId);\n event.preventDefault();\n };\n\n const onPointerMove = (event: PointerEvent): void => {\n if (!drag || !root || !domain) return;\n const rect = root.getBoundingClientRect();\n const dx = xToData(event.clientX - drag.startClientX, rect.width) - xToData(0, rect.width);\n if (drag.mode === \"left\") applyRange(drag.startXMin + dx, drag.startXMax);\n else if (drag.mode === \"right\") applyRange(drag.startXMin, drag.startXMax + dx);\n else applyRange(drag.startXMin + dx, drag.startXMax + dx);\n };\n\n const onPointerUp = (event: PointerEvent): void => {\n if (root?.hasPointerCapture(event.pointerId)) root.releasePointerCapture(event.pointerId);\n if (windowRect) windowRect.style.cursor = \"grab\";\n drag = null;\n };\n\n const onDoubleClick = (): void => {\n if (domain) applyRange(domain.xMin, domain.xMax);\n };\n\n root.addEventListener(\"pointerdown\", onPointerDown);\n root.addEventListener(\"pointermove\", onPointerMove);\n root.addEventListener(\"pointerup\", onPointerUp);\n root.addEventListener(\"pointercancel\", onPointerUp);\n root.addEventListener(\"dblclick\", onDoubleClick);\n render();\n\n return () => {\n unsubscribeRender();\n unsubscribeViewport();\n unsubscribeTheme();\n root?.removeEventListener(\"pointerdown\", onPointerDown);\n root?.removeEventListener(\"pointermove\", onPointerMove);\n root?.removeEventListener(\"pointerup\", onPointerUp);\n root?.removeEventListener(\"pointercancel\", onPointerUp);\n root?.removeEventListener(\"dblclick\", onDoubleClick);\n if (options.reserveSpace !== false) chart.setLayoutReservation(reservationId, null);\n root?.remove();\n root = null;\n overlay = null;\n windowRect = null;\n leftHandle = null;\n rightHandle = null;\n leftHandleHit = null;\n rightHandleHit = null;\n paths = [];\n domain = null;\n drag = null;\n chartRef = null;\n };\n },\n refresh(): void {\n render();\n },\n };\n}\n"],"mappings":"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"}