velo-plot 1.11.1 → 1.12.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.
- package/README.md +21 -2
- package/dist/axisFormat-B7o_uIEA.js +127 -0
- package/dist/axisFormat-B7o_uIEA.js.map +1 -0
- package/dist/core/OverlayRenderer.d.ts +1 -2
- package/dist/core/OverlayRenderer.test.d.ts +1 -0
- package/dist/core/chart/ChartCore.d.ts +17 -1
- package/dist/core/chart/ChartRenderLoop.d.ts +4 -0
- package/dist/core/chart/ChartScaling.d.ts +11 -0
- package/dist/core/chart/ChartScaling.test.d.ts +1 -0
- package/dist/core/chart/NavigationUtils.d.ts +12 -0
- package/dist/core/chart/NavigationUtils.test.d.ts +1 -0
- package/dist/core/chart/types.d.ts +11 -1
- package/dist/core/format/axisFormat.d.ts +16 -0
- package/dist/core/format/axisFormat.test.d.ts +1 -0
- package/dist/core/indicator/buildIndicatorPane.d.ts +22 -0
- package/dist/core/indicator/buildIndicatorSeries.d.ts +14 -0
- package/dist/core/indicator/buildIndicatorSeries.test.d.ts +1 -0
- package/dist/core/indicator/index.d.ts +3 -0
- package/dist/core/indicator/types.d.ts +74 -0
- package/dist/core/series/SeriesBounds.d.ts +1 -1
- package/dist/core/series/SeriesBounds.test.d.ts +1 -0
- package/dist/core/stacked/createStackedChart.d.ts +3 -0
- package/dist/core/stacked/createStackedChart.test.d.ts +1 -0
- package/dist/core/stacked/index.d.ts +4 -0
- package/dist/core/stacked/paneAxis.d.ts +20 -0
- package/dist/core/stacked/paneAxis.test.d.ts +1 -0
- package/dist/core/stacked/paneResize.d.ts +32 -0
- package/dist/core/stacked/paneResize.test.d.ts +1 -0
- package/dist/core/stacked/types.d.ts +91 -0
- package/dist/core/sync/index.d.ts +25 -70
- package/dist/core/sync/index.test.d.ts +1 -0
- package/dist/{index-D8ifudJH.js → index-DjeWClO9.js} +601 -561
- package/dist/index-DjeWClO9.js.map +1 -0
- package/dist/{index.core-CYu3tydL.js → index.core-xiNcuFfJ.js} +1760 -1405
- package/dist/index.core-xiNcuFfJ.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/plugins/sync.js +169 -145
- package/dist/plugins/sync.js.map +1 -1
- package/dist/plugins/tools/tooltip/TooltipManager.d.ts +9 -1
- package/dist/plugins/tools/tooltip/format.d.ts +7 -0
- package/dist/plugins/tools/tooltip/format.test.d.ts +1 -0
- package/dist/plugins/tools/tooltip/types.d.ts +6 -8
- package/dist/plugins/tools.js +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/useStackedPlot.d.ts +17 -0
- package/dist/types.d.ts +21 -1
- package/dist/velo-plot.full.js +2906 -2399
- package/dist/velo-plot.full.js.map +1 -1
- package/dist/velo-plot.js +11 -11
- package/package.json +9 -2
- package/dist/EventEmitter-DAbs2K1C.js +0 -60
- package/dist/EventEmitter-DAbs2K1C.js.map +0 -1
- package/dist/index-D8ifudJH.js.map +0 -1
- package/dist/index.core-CYu3tydL.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var u = (
|
|
4
|
-
import { E as
|
|
5
|
-
class
|
|
1
|
+
var dt = Object.defineProperty;
|
|
2
|
+
var ct = (c, t, i) => t in c ? dt(c, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : c[t] = i;
|
|
3
|
+
var u = (c, t, i) => ct(c, typeof t != "symbol" ? t + "" : t, i);
|
|
4
|
+
import { f as O, a as N, E as ut } from "./axisFormat-B7o_uIEA.js";
|
|
5
|
+
class ft {
|
|
6
6
|
constructor(t, i) {
|
|
7
7
|
u(this, "ctx");
|
|
8
8
|
u(this, "options");
|
|
@@ -100,12 +100,12 @@ class lt {
|
|
|
100
100
|
*/
|
|
101
101
|
recalculate() {
|
|
102
102
|
if (!this.state.point1 || !this.state.point2) return;
|
|
103
|
-
const t = this.ctx.getSeries ? this.ctx.getSeries() : [], i = (
|
|
104
|
-
const
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
const l = this.ctx.getPlotArea(), h = this.ctx.getViewBounds(), a = this.ctx.getYBounds ? this.ctx.getYBounds(
|
|
108
|
-
return
|
|
103
|
+
const t = this.ctx.getSeries ? this.ctx.getSeries() : [], i = (s) => {
|
|
104
|
+
const o = t.find((l) => l.id === s.seriesId);
|
|
105
|
+
if (o && s.index < o.x.length) {
|
|
106
|
+
s.x = o.x[s.index], s.y = o.y[s.index], s.yAxisId = o.yAxisId;
|
|
107
|
+
const l = this.ctx.getPlotArea(), h = this.ctx.getViewBounds(), a = this.ctx.getYBounds ? this.ctx.getYBounds(o.yAxisId) : { yMin: h.yMin, yMax: h.yMax };
|
|
108
|
+
return s.pixelX = l.x + (s.x - h.xMin) / (h.xMax - h.xMin) * l.width, s.pixelY = l.y + (1 - (s.y - a.yMin) / (a.yMax - a.yMin)) * l.height, !0;
|
|
109
109
|
}
|
|
110
110
|
return !1;
|
|
111
111
|
}, e = i(this.state.point1), n = i(this.state.point2);
|
|
@@ -141,17 +141,17 @@ class lt {
|
|
|
141
141
|
}
|
|
142
142
|
handleMouseMove(t) {
|
|
143
143
|
if (!this.state.enabled) return;
|
|
144
|
-
const i = this.ctx.container.getBoundingClientRect(), e = this.ctx.getPlotArea(), n = this.ctx.getViewBounds(),
|
|
144
|
+
const i = this.ctx.container.getBoundingClientRect(), e = this.ctx.getPlotArea(), n = this.ctx.getViewBounds(), s = t.clientX - i.left, o = t.clientY - i.top;
|
|
145
145
|
if (this.isDraggingLabel) {
|
|
146
|
-
this.labelOffset.x +=
|
|
146
|
+
this.labelOffset.x += s - this.dragStart.x, this.labelOffset.y += o - this.dragStart.y, this.dragStart = { x: s, y: o }, this.renderOverlay();
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
if (this.labelBounds &&
|
|
149
|
+
if (this.labelBounds && s >= this.labelBounds.x && s <= this.labelBounds.x + this.labelBounds.width && o >= this.labelBounds.y && o <= this.labelBounds.y + this.labelBounds.height ? this.ctx.container.style.cursor = "move" : this.ctx.container.style.cursor = "crosshair", s < e.x || s > e.x + e.width || o < e.y || o > e.y + e.height) {
|
|
150
150
|
this.state.hoveredPoint = null, this.crosshairPosition = null, this.renderOverlay();
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
|
-
this.crosshairPosition = { x:
|
|
154
|
-
const l = this.findNearestPoint(
|
|
153
|
+
this.crosshairPosition = { x: s, y: o };
|
|
154
|
+
const l = this.findNearestPoint(s, o, e, n);
|
|
155
155
|
this.state.hoveredPoint = l, this.renderOverlay();
|
|
156
156
|
}
|
|
157
157
|
handleLabelMouseDown(t) {
|
|
@@ -166,10 +166,10 @@ class lt {
|
|
|
166
166
|
var h;
|
|
167
167
|
if (!this.state.enabled) return;
|
|
168
168
|
(h = this.ctx.animationEngine) != null && h.isAnimating() && await this.ctx.animationEngine.waitForIdle(), t.stopPropagation(), t.preventDefault();
|
|
169
|
-
const i = this.ctx.container.getBoundingClientRect(), e = this.ctx.getPlotArea(), n = this.ctx.getViewBounds(),
|
|
170
|
-
if (
|
|
169
|
+
const i = this.ctx.container.getBoundingClientRect(), e = this.ctx.getPlotArea(), n = this.ctx.getViewBounds(), s = t.clientX - i.left, o = t.clientY - i.top;
|
|
170
|
+
if (s < e.x || s > e.x + e.width || o < e.y || o > e.y + e.height)
|
|
171
171
|
return;
|
|
172
|
-
const l = this.findNearestPoint(
|
|
172
|
+
const l = this.findNearestPoint(s, o, e, n);
|
|
173
173
|
if (l) {
|
|
174
174
|
if (t.preventDefault(), t.stopPropagation(), this.state.selectionState === "idle" || this.state.selectionState === "complete")
|
|
175
175
|
this.state.point1 = l, this.state.point2 = null, this.state.selectionState = "waitingSecond", this.state.lastMeasurement = null;
|
|
@@ -186,29 +186,29 @@ class lt {
|
|
|
186
186
|
}
|
|
187
187
|
findNearestPoint(t, i, e, n) {
|
|
188
188
|
if (!this.ctx.getSeries) return null;
|
|
189
|
-
const
|
|
190
|
-
let
|
|
191
|
-
for (const h of
|
|
192
|
-
const a = h.x, r = h.y, d = Math.min(a.length, r.length),
|
|
193
|
-
for (let
|
|
194
|
-
const g = a[
|
|
189
|
+
const s = this.ctx.getSeries();
|
|
190
|
+
let o = null, l = this.options.snapRadius;
|
|
191
|
+
for (const h of s) {
|
|
192
|
+
const a = h.x, r = h.y, d = Math.min(a.length, r.length), f = this.ctx.getYBounds ? this.ctx.getYBounds(h.yAxisId) : { yMin: n.yMin, yMax: n.yMax };
|
|
193
|
+
for (let p = 0; p < d; p++) {
|
|
194
|
+
const g = a[p], y = r[p], b = e.x + (g - n.xMin) / (n.xMax - n.xMin) * e.width, x = e.y + (1 - (y - f.yMin) / (f.yMax - f.yMin)) * e.height;
|
|
195
195
|
if (b < e.x || b > e.x + e.width || x < e.y || x > e.y + e.height) continue;
|
|
196
196
|
const S = Math.sqrt((t - b) ** 2 + (i - x) ** 2);
|
|
197
|
-
S < l && (l = S,
|
|
197
|
+
S < l && (l = S, o = {
|
|
198
198
|
x: g,
|
|
199
199
|
y,
|
|
200
200
|
seriesId: h.id,
|
|
201
201
|
yAxisId: h.yAxisId,
|
|
202
|
-
index:
|
|
202
|
+
index: p,
|
|
203
203
|
pixelX: b,
|
|
204
204
|
pixelY: x
|
|
205
205
|
});
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
return
|
|
208
|
+
return o;
|
|
209
209
|
}
|
|
210
210
|
calculateMeasurement() {
|
|
211
|
-
const t = this.state.point1, i = this.state.point2, e = i.x - t.x, n = i.y - t.y,
|
|
211
|
+
const t = this.state.point1, i = this.state.point2, e = i.x - t.x, n = i.y - t.y, s = e !== 0 ? n / e : 1 / 0, o = Math.sqrt(e * e + n * n);
|
|
212
212
|
return {
|
|
213
213
|
x1: t.x,
|
|
214
214
|
y1: t.y,
|
|
@@ -216,8 +216,8 @@ class lt {
|
|
|
216
216
|
y2: i.y,
|
|
217
217
|
deltaX: e,
|
|
218
218
|
deltaY: n,
|
|
219
|
-
slope:
|
|
220
|
-
distance:
|
|
219
|
+
slope: s,
|
|
220
|
+
distance: o,
|
|
221
221
|
pixelX1: t.pixelX,
|
|
222
222
|
pixelY1: t.pixelY,
|
|
223
223
|
pixelX2: i.pixelX,
|
|
@@ -229,78 +229,78 @@ class lt {
|
|
|
229
229
|
this.resizeOverlay();
|
|
230
230
|
const t = this.ctx.container.getBoundingClientRect();
|
|
231
231
|
this.overlayCtx.clearRect(0, 0, t.width, t.height);
|
|
232
|
-
const i = this.options, e = this.overlayCtx, n = this.ctx.getPlotArea(),
|
|
232
|
+
const i = this.options, e = this.overlayCtx, n = this.ctx.getPlotArea(), s = this.ctx.getViewBounds();
|
|
233
233
|
if (this.state.point1) {
|
|
234
|
-
const
|
|
235
|
-
|
|
234
|
+
const o = this.state.point1, l = this.ctx.getYBounds ? this.ctx.getYBounds(o.yAxisId) : { yMin: s.yMin, yMax: s.yMax };
|
|
235
|
+
o.pixelX = n.x + (o.x - s.xMin) / (s.xMax - s.xMin) * n.width, o.pixelY = n.y + (1 - (o.y - l.yMin) / (l.yMax - l.yMin)) * n.height;
|
|
236
236
|
}
|
|
237
237
|
if (this.state.point2) {
|
|
238
|
-
const
|
|
239
|
-
|
|
238
|
+
const o = this.state.point2, l = this.ctx.getYBounds ? this.ctx.getYBounds(o.yAxisId) : { yMin: s.yMin, yMax: s.yMax };
|
|
239
|
+
o.pixelX = n.x + (o.x - s.xMin) / (s.xMax - s.xMin) * n.width, o.pixelY = n.y + (1 - (o.y - l.yMin) / (l.yMax - l.yMin)) * n.height;
|
|
240
240
|
}
|
|
241
241
|
if (this.crosshairPosition && this.state.selectionState !== "complete") {
|
|
242
|
-
const
|
|
243
|
-
e.save(), e.setLineDash([4, 4]), e.strokeStyle = "rgba(150, 150, 150, 0.7)", e.lineWidth = 1, e.beginPath(), e.moveTo(
|
|
242
|
+
const o = this.crosshairPosition.x, l = this.crosshairPosition.y;
|
|
243
|
+
e.save(), e.setLineDash([4, 4]), e.strokeStyle = "rgba(150, 150, 150, 0.7)", e.lineWidth = 1, e.beginPath(), e.moveTo(o, n.y), e.lineTo(o, n.y + n.height), e.stroke(), e.beginPath(), e.moveTo(n.x, l), e.lineTo(n.x + n.width, l), e.stroke(), e.restore();
|
|
244
244
|
}
|
|
245
245
|
if (this.state.hoveredPoint && this.state.selectionState !== "complete") {
|
|
246
|
-
const
|
|
247
|
-
e.beginPath(), e.arc(
|
|
246
|
+
const o = this.state.hoveredPoint;
|
|
247
|
+
e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize + 4, 0, Math.PI * 2), e.fillStyle = i.highlightColor + "30", e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize, 0, Math.PI * 2), e.strokeStyle = i.highlightColor, e.lineWidth = 2, e.stroke(), e.beginPath(), e.arc(o.pixelX, o.pixelY, 4, 0, Math.PI * 2), e.fillStyle = i.highlightColor, e.fill(), this.drawPointTooltip(e, o, "Hover");
|
|
248
248
|
}
|
|
249
249
|
if (this.state.point1) {
|
|
250
|
-
const
|
|
251
|
-
e.beginPath(), e.arc(
|
|
250
|
+
const o = this.state.point1;
|
|
251
|
+
e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize, 0, Math.PI * 2), e.fillStyle = i.lineColor, e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize - 3, 0, Math.PI * 2), e.fillStyle = "#ffffff", e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, 3, 0, Math.PI * 2), e.fillStyle = i.lineColor, e.fill(), this.drawPointLabel(e, o.pixelX, o.pixelY - i.highlightSize - 8, "P1", i.lineColor);
|
|
252
252
|
}
|
|
253
253
|
if (this.state.point2) {
|
|
254
|
-
const
|
|
255
|
-
e.beginPath(), e.arc(
|
|
254
|
+
const o = this.state.point2;
|
|
255
|
+
e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize, 0, Math.PI * 2), e.fillStyle = "#4ade80", e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize - 3, 0, Math.PI * 2), e.fillStyle = "#ffffff", e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, 3, 0, Math.PI * 2), e.fillStyle = "#4ade80", e.fill(), this.drawPointLabel(e, o.pixelX, o.pixelY - i.highlightSize - 8, "P2", "#4ade80");
|
|
256
256
|
}
|
|
257
257
|
if (this.state.point1 && this.state.point2) {
|
|
258
|
-
const
|
|
259
|
-
e.beginPath(), e.moveTo(
|
|
258
|
+
const o = this.state.point1, l = this.state.point2;
|
|
259
|
+
e.beginPath(), e.moveTo(o.pixelX, o.pixelY), e.lineTo(l.pixelX, l.pixelY), e.strokeStyle = i.lineColor, e.lineWidth = i.lineWidth, e.setLineDash([6, 4]), e.stroke(), e.setLineDash([]), e.beginPath(), e.moveTo(o.pixelX, o.pixelY), e.lineTo(l.pixelX, o.pixelY), e.lineTo(l.pixelX, l.pixelY), e.strokeStyle = "rgba(255, 107, 107, 0.4)", e.lineWidth = 1, e.setLineDash([3, 3]), e.stroke(), e.setLineDash([]), i.showLabels && this.state.lastMeasurement && this.drawMeasurementLabel(e, o, l, this.state.lastMeasurement);
|
|
260
260
|
}
|
|
261
261
|
this.drawStatusIndicator(e);
|
|
262
262
|
}
|
|
263
263
|
drawPointTooltip(t, i, e) {
|
|
264
|
-
const n = this.options,
|
|
264
|
+
const n = this.options, s = `${e}: (${this.formatValue(i.x)}, ${this.formatValue(i.y)})`;
|
|
265
265
|
t.font = `${n.labelFontSize}px system-ui, sans-serif`;
|
|
266
|
-
const
|
|
266
|
+
const o = t.measureText(s), l = 6, h = o.width + l * 2, a = n.labelFontSize + l * 2;
|
|
267
267
|
let r = i.pixelX + 15, d = i.pixelY - a / 2;
|
|
268
|
-
const
|
|
269
|
-
r + h >
|
|
268
|
+
const f = this.ctx.container.getBoundingClientRect();
|
|
269
|
+
r + h > f.width && (r = i.pixelX - h - 15), d < 0 && (d = 5), d + a > f.height && (d = f.height - a - 5), t.fillStyle = n.labelBackground, this.roundRect(t, r, d, h, a, 4), t.fill(), t.fillStyle = n.labelColor, t.textAlign = "left", t.textBaseline = "middle", t.fillText(s, r + l, d + a / 2);
|
|
270
270
|
}
|
|
271
|
-
drawPointLabel(t, i, e, n,
|
|
272
|
-
const
|
|
273
|
-
t.font = `bold ${
|
|
274
|
-
const l = t.measureText(n), h = 4, a = l.width + h * 2, r =
|
|
275
|
-
t.fillStyle =
|
|
271
|
+
drawPointLabel(t, i, e, n, s) {
|
|
272
|
+
const o = this.options;
|
|
273
|
+
t.font = `bold ${o.labelFontSize}px system-ui, sans-serif`, t.textAlign = "center", t.textBaseline = "bottom";
|
|
274
|
+
const l = t.measureText(n), h = 4, a = l.width + h * 2, r = o.labelFontSize + h;
|
|
275
|
+
t.fillStyle = s, this.roundRect(t, i - a / 2, e - r, a, r, 3), t.fill(), t.fillStyle = "#ffffff", t.fillText(n, i, e - 2);
|
|
276
276
|
}
|
|
277
277
|
drawMeasurementLabel(t, i, e, n) {
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
const a =
|
|
281
|
-
let
|
|
278
|
+
const s = this.options, o = (i.pixelX + e.pixelX) / 2, l = (i.pixelY + e.pixelY) / 2, h = [];
|
|
279
|
+
s.showDelta && (h.push(`ΔX: ${this.formatValue(n.deltaX)}`), h.push(`ΔY: ${this.formatValue(n.deltaY)}`)), s.showSlope && isFinite(n.slope) && h.push(`Slope: ${this.formatValue(n.slope)}`), s.showDistance && h.push(`Distance: ${this.formatValue(n.distance)}`);
|
|
280
|
+
const a = s.labelFontSize + 4, r = 10, d = 170, f = h.length * a + r * 2;
|
|
281
|
+
let p = o + this.labelOffset.x, g = l + this.labelOffset.y;
|
|
282
282
|
const y = this.ctx.container.getBoundingClientRect();
|
|
283
|
-
|
|
284
|
-
t.fillText(b,
|
|
283
|
+
p < 0 && (p = 0), p + d > y.width && (p = y.width - d), g < 0 && (g = 0), g + f > y.height && (g = y.height - f), this.labelBounds = { x: p, y: g, width: d, height: f }, t.fillStyle = s.labelBackground, t.strokeStyle = s.lineColor, t.lineWidth = 2, this.roundRect(t, p, g, d, f, 8), t.fill(), t.stroke(), t.fillStyle = s.labelColor, t.font = `${s.labelFontSize}px system-ui, sans-serif`, t.textAlign = "left", t.textBaseline = "top", h.forEach((b, x) => {
|
|
284
|
+
t.fillText(b, p + r, g + r + x * a);
|
|
285
285
|
});
|
|
286
286
|
}
|
|
287
287
|
drawStatusIndicator(t) {
|
|
288
288
|
const i = this.options, e = this.ctx.getPlotArea();
|
|
289
|
-
let n = "",
|
|
290
|
-
if (this.state.selectionState === "idle" ? (n = "📏 Click a point to start measuring",
|
|
289
|
+
let n = "", s = "#666";
|
|
290
|
+
if (this.state.selectionState === "idle" ? (n = "📏 Click a point to start measuring", s = i.highlightColor) : this.state.selectionState === "waitingSecond" ? (n = "📏 Click second point to complete", s = "#f59e0b") : this.state.selectionState === "complete" && (n = "📏 Measurement complete (ESC to clear)", s = "#4ade80"), !n) return;
|
|
291
291
|
t.font = "12px system-ui, sans-serif";
|
|
292
292
|
const h = t.measureText(n).width + 8 * 2, a = 24, r = e.x + 10, d = e.y + 10;
|
|
293
|
-
t.fillStyle = "rgba(0, 0, 0, 0.75)", this.roundRect(t, r, d, h, a, 4), t.fill(), t.beginPath(), t.arc(r + 16, d + a / 2, 4, 0, Math.PI * 2), t.fillStyle =
|
|
293
|
+
t.fillStyle = "rgba(0, 0, 0, 0.75)", this.roundRect(t, r, d, h, a, 4), t.fill(), t.beginPath(), t.arc(r + 16, d + a / 2, 4, 0, Math.PI * 2), t.fillStyle = s, t.fill(), t.fillStyle = "#fff", t.textAlign = "left", t.textBaseline = "middle", t.fillText(n, r + 26, d + a / 2);
|
|
294
294
|
}
|
|
295
|
-
roundRect(t, i, e, n,
|
|
296
|
-
t.beginPath(), t.moveTo(i +
|
|
295
|
+
roundRect(t, i, e, n, s, o) {
|
|
296
|
+
t.beginPath(), t.moveTo(i + o, e), t.lineTo(i + n - o, e), t.quadraticCurveTo(i + n, e, i + n, e + o), t.lineTo(i + n, e + s - o), t.quadraticCurveTo(i + n, e + s, i + n - o, e + s), t.lineTo(i + o, e + s), t.quadraticCurveTo(i, e + s, i, e + s - o), t.lineTo(i, e + o), t.quadraticCurveTo(i, e, i + o, e), t.closePath();
|
|
297
297
|
}
|
|
298
298
|
formatValue(t) {
|
|
299
299
|
const i = Math.abs(t);
|
|
300
300
|
return i === 0 ? "0" : i >= 1e6 || i < 1e-3 ? t.toExponential(this.options.precision - 1) : t.toPrecision(this.options.precision);
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
|
-
class
|
|
303
|
+
class pt {
|
|
304
304
|
constructor(t, i) {
|
|
305
305
|
u(this, "ctx");
|
|
306
306
|
u(this, "options");
|
|
@@ -398,12 +398,12 @@ class rt {
|
|
|
398
398
|
*/
|
|
399
399
|
recalculate() {
|
|
400
400
|
if (!this.state.point1 || !this.state.point2) return;
|
|
401
|
-
const t = this.ctx.getSeries ? this.ctx.getSeries() : [], i = (
|
|
402
|
-
const
|
|
403
|
-
if (
|
|
404
|
-
|
|
405
|
-
const l = this.ctx.getPlotArea(), h = this.ctx.getViewBounds(), a = this.ctx.getYBounds ? this.ctx.getYBounds(
|
|
406
|
-
return
|
|
401
|
+
const t = this.ctx.getSeries ? this.ctx.getSeries() : [], i = (s) => {
|
|
402
|
+
const o = t.find((l) => l.id === s.seriesId);
|
|
403
|
+
if (o && s.index < o.x.length) {
|
|
404
|
+
s.x = o.x[s.index], s.y = o.y[s.index], s.yAxisId = o.yAxisId;
|
|
405
|
+
const l = this.ctx.getPlotArea(), h = this.ctx.getViewBounds(), a = this.ctx.getYBounds ? this.ctx.getYBounds(o.yAxisId) : { yMin: h.yMin, yMax: h.yMax };
|
|
406
|
+
return s.pixelX = l.x + (s.x - h.xMin) / (h.xMax - h.xMin) * l.width, s.pixelY = l.y + (1 - (s.y - a.yMin) / (a.yMax - a.yMin)) * l.height, !0;
|
|
407
407
|
}
|
|
408
408
|
return !1;
|
|
409
409
|
}, e = i(this.state.point1), n = i(this.state.point2);
|
|
@@ -439,17 +439,17 @@ class rt {
|
|
|
439
439
|
}
|
|
440
440
|
handleMouseMove(t) {
|
|
441
441
|
if (!this.state.enabled) return;
|
|
442
|
-
const i = this.ctx.container.getBoundingClientRect(), e = this.ctx.getPlotArea(), n = this.ctx.getViewBounds(),
|
|
442
|
+
const i = this.ctx.container.getBoundingClientRect(), e = this.ctx.getPlotArea(), n = this.ctx.getViewBounds(), s = t.clientX - i.left, o = t.clientY - i.top;
|
|
443
443
|
if (this.isDraggingLabel) {
|
|
444
|
-
this.labelOffset.x +=
|
|
444
|
+
this.labelOffset.x += s - this.dragStart.x, this.labelOffset.y += o - this.dragStart.y, this.dragStart = { x: s, y: o }, this.renderOverlay();
|
|
445
445
|
return;
|
|
446
446
|
}
|
|
447
|
-
if (this.labelBounds &&
|
|
447
|
+
if (this.labelBounds && s >= this.labelBounds.x && s <= this.labelBounds.x + this.labelBounds.width && o >= this.labelBounds.y && o <= this.labelBounds.y + this.labelBounds.height ? this.ctx.container.style.cursor = "move" : this.ctx.container.style.cursor = "crosshair", s < e.x || s > e.x + e.width || o < e.y || o > e.y + e.height) {
|
|
448
448
|
this.state.hoveredPoint = null, this.crosshairPosition = null, this.renderOverlay();
|
|
449
449
|
return;
|
|
450
450
|
}
|
|
451
|
-
this.crosshairPosition = { x:
|
|
452
|
-
const l = this.state.selectionState === "waitingSecond" && this.state.point1 ? this.state.point1.seriesId : void 0, h = this.findNearestPoint(
|
|
451
|
+
this.crosshairPosition = { x: s, y: o };
|
|
452
|
+
const l = this.state.selectionState === "waitingSecond" && this.state.point1 ? this.state.point1.seriesId : void 0, h = this.findNearestPoint(s, o, e, n, l);
|
|
453
453
|
this.state.hoveredPoint = h, this.renderOverlay();
|
|
454
454
|
}
|
|
455
455
|
handleLabelMouseDown(t) {
|
|
@@ -464,10 +464,10 @@ class rt {
|
|
|
464
464
|
var a;
|
|
465
465
|
if (!this.state.enabled) return;
|
|
466
466
|
(a = this.ctx.animationEngine) != null && a.isAnimating() && await this.ctx.animationEngine.waitForIdle(), t.stopPropagation(), t.preventDefault();
|
|
467
|
-
const i = this.ctx.container.getBoundingClientRect(), e = this.ctx.getPlotArea(), n = this.ctx.getViewBounds(),
|
|
468
|
-
if (
|
|
467
|
+
const i = this.ctx.container.getBoundingClientRect(), e = this.ctx.getPlotArea(), n = this.ctx.getViewBounds(), s = t.clientX - i.left, o = t.clientY - i.top;
|
|
468
|
+
if (s < e.x || s > e.x + e.width || o < e.y || o > e.y + e.height)
|
|
469
469
|
return;
|
|
470
|
-
const l = this.state.selectionState === "waitingSecond" && this.state.point1 ? this.state.point1.seriesId : void 0, h = this.findNearestPoint(
|
|
470
|
+
const l = this.state.selectionState === "waitingSecond" && this.state.point1 ? this.state.point1.seriesId : void 0, h = this.findNearestPoint(s, o, e, n, l);
|
|
471
471
|
if (h) {
|
|
472
472
|
if (t.preventDefault(), t.stopPropagation(), this.state.selectionState === "idle" || this.state.selectionState === "complete")
|
|
473
473
|
this.state.point1 = h, this.state.point2 = null, this.state.selectionState = "waitingSecond", this.state.lastMeasurement = null;
|
|
@@ -484,18 +484,18 @@ class rt {
|
|
|
484
484
|
handleKeyDown(t) {
|
|
485
485
|
t.key === "Escape" && this.state.enabled && this.clear();
|
|
486
486
|
}
|
|
487
|
-
findNearestPoint(t, i, e, n,
|
|
487
|
+
findNearestPoint(t, i, e, n, s) {
|
|
488
488
|
if (!this.ctx.getSeries) return null;
|
|
489
|
-
const
|
|
489
|
+
const o = this.ctx.getSeries();
|
|
490
490
|
let l = null, h = this.options.snapRadius;
|
|
491
|
-
for (const a of
|
|
492
|
-
if (
|
|
493
|
-
const r = a.x, d = a.y,
|
|
494
|
-
for (let g = 0; g <
|
|
495
|
-
const y = r[g], b = d[g], x = e.x + (y - n.xMin) / (n.xMax - n.xMin) * e.width, S = e.y + (1 - (b -
|
|
491
|
+
for (const a of o) {
|
|
492
|
+
if (s && a.id !== s) continue;
|
|
493
|
+
const r = a.x, d = a.y, f = Math.min(r.length, d.length), p = this.ctx.getYBounds ? this.ctx.getYBounds(a.yAxisId) : { yMin: n.yMin, yMax: n.yMax };
|
|
494
|
+
for (let g = 0; g < f; g++) {
|
|
495
|
+
const y = r[g], b = d[g], x = e.x + (y - n.xMin) / (n.xMax - n.xMin) * e.width, S = e.y + (1 - (b - p.yMin) / (p.yMax - p.yMin)) * e.height;
|
|
496
496
|
if (x < e.x || x > e.x + e.width || S < e.y || S > e.y + e.height) continue;
|
|
497
|
-
const
|
|
498
|
-
|
|
497
|
+
const T = Math.sqrt((t - x) ** 2 + (i - S) ** 2);
|
|
498
|
+
T < h && (h = T, l = {
|
|
499
499
|
x: y,
|
|
500
500
|
y: b,
|
|
501
501
|
seriesId: a.id,
|
|
@@ -509,7 +509,7 @@ class rt {
|
|
|
509
509
|
return l;
|
|
510
510
|
}
|
|
511
511
|
calculateMeasurement() {
|
|
512
|
-
const t = this.state.point1, i = this.state.point2, n = (this.ctx.getSeries ? this.ctx.getSeries() : []).find((
|
|
512
|
+
const t = this.state.point1, i = this.state.point2, n = (this.ctx.getSeries ? this.ctx.getSeries() : []).find((m) => m.id === t.seriesId);
|
|
513
513
|
if (!n)
|
|
514
514
|
return {
|
|
515
515
|
x1: t.x,
|
|
@@ -528,37 +528,37 @@ class rt {
|
|
|
528
528
|
pixelX2: i.pixelX,
|
|
529
529
|
pixelY2: i.pixelY
|
|
530
530
|
};
|
|
531
|
-
const
|
|
532
|
-
for (let
|
|
533
|
-
r.push(
|
|
534
|
-
for (let
|
|
535
|
-
r.push(
|
|
536
|
-
const
|
|
537
|
-
let
|
|
538
|
-
for (let
|
|
539
|
-
|
|
540
|
-
const x = (
|
|
541
|
-
let
|
|
542
|
-
for (let
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
const
|
|
546
|
-
|
|
547
|
-
const
|
|
548
|
-
|
|
531
|
+
const s = n.x, o = n.y, l = Math.min(t.index, i.index), h = Math.max(t.index, i.index), a = this.options.baselineWindow, r = [], d = [];
|
|
532
|
+
for (let m = Math.max(0, l - Math.floor(a / 2)); m <= Math.min(s.length - 1, l + Math.floor(a / 2)); m++)
|
|
533
|
+
r.push(s[m]), d.push(o[m]);
|
|
534
|
+
for (let m = Math.max(0, h - Math.floor(a / 2)); m <= Math.min(s.length - 1, h + Math.floor(a / 2)); m++)
|
|
535
|
+
r.push(s[m]), d.push(o[m]);
|
|
536
|
+
const f = r.length;
|
|
537
|
+
let p = 0, g = 0, y = 0, b = 0;
|
|
538
|
+
for (let m = 0; m < f; m++)
|
|
539
|
+
p += r[m], g += d[m], y += r[m] * d[m], b += r[m] * r[m];
|
|
540
|
+
const x = (f * y - p * g) / (f * b - p * p), S = (g - x * p) / f;
|
|
541
|
+
let T = 0, v = 0, Y = -1 / 0, w = 0, C = 0;
|
|
542
|
+
for (let m = l; m < h; m++) {
|
|
543
|
+
const I = s[m], A = o[m], $ = s[m + 1], R = o[m + 1], D = $ - I, q = (A + R) / 2;
|
|
544
|
+
v += q * D;
|
|
545
|
+
const j = x * I + S, rt = x * $ + S, ht = (j + rt) / 2;
|
|
546
|
+
T += (q - ht) * D;
|
|
547
|
+
const J = A - j;
|
|
548
|
+
J > Y && (Y = J, w = I, C = A);
|
|
549
549
|
}
|
|
550
550
|
return {
|
|
551
551
|
x1: t.x,
|
|
552
552
|
y1: t.y,
|
|
553
553
|
x2: i.x,
|
|
554
554
|
y2: i.y,
|
|
555
|
-
area:
|
|
556
|
-
integral:
|
|
555
|
+
area: T,
|
|
556
|
+
integral: v,
|
|
557
557
|
baselineSlope: x,
|
|
558
558
|
baselineIntercept: S,
|
|
559
|
-
peakHeight:
|
|
560
|
-
peakX:
|
|
561
|
-
peakY:
|
|
559
|
+
peakHeight: Y,
|
|
560
|
+
peakX: w,
|
|
561
|
+
peakY: C,
|
|
562
562
|
pixelX1: t.pixelX,
|
|
563
563
|
pixelY1: t.pixelY,
|
|
564
564
|
pixelX2: i.pixelX,
|
|
@@ -570,89 +570,89 @@ class rt {
|
|
|
570
570
|
this.resizeOverlay();
|
|
571
571
|
const t = this.ctx.container.getBoundingClientRect();
|
|
572
572
|
this.overlayCtx.clearRect(0, 0, t.width, t.height);
|
|
573
|
-
const i = this.options, e = this.overlayCtx, n = this.ctx.getPlotArea(),
|
|
573
|
+
const i = this.options, e = this.overlayCtx, n = this.ctx.getPlotArea(), s = this.ctx.getViewBounds();
|
|
574
574
|
if (this.state.point1) {
|
|
575
|
-
const
|
|
576
|
-
|
|
575
|
+
const o = this.state.point1, l = this.ctx.getYBounds ? this.ctx.getYBounds(o.yAxisId) : { yMin: s.yMin, yMax: s.yMax };
|
|
576
|
+
o.pixelX = n.x + (o.x - s.xMin) / (s.xMax - s.xMin) * n.width, o.pixelY = n.y + (1 - (o.y - l.yMin) / (l.yMax - l.yMin)) * n.height;
|
|
577
577
|
}
|
|
578
578
|
if (this.state.point2) {
|
|
579
|
-
const
|
|
580
|
-
|
|
579
|
+
const o = this.state.point2, l = this.ctx.getYBounds ? this.ctx.getYBounds(o.yAxisId) : { yMin: s.yMin, yMax: s.yMax };
|
|
580
|
+
o.pixelX = n.x + (o.x - s.xMin) / (s.xMax - s.xMin) * n.width, o.pixelY = n.y + (1 - (o.y - l.yMin) / (l.yMax - l.yMin)) * n.height;
|
|
581
581
|
}
|
|
582
582
|
if (this.crosshairPosition && this.state.selectionState !== "complete") {
|
|
583
|
-
const
|
|
584
|
-
e.save(), e.setLineDash([4, 4]), e.strokeStyle = "rgba(150, 150, 150, 0.7)", e.lineWidth = 1, e.beginPath(), e.moveTo(
|
|
583
|
+
const o = this.crosshairPosition.x, l = this.crosshairPosition.y;
|
|
584
|
+
e.save(), e.setLineDash([4, 4]), e.strokeStyle = "rgba(150, 150, 150, 0.7)", e.lineWidth = 1, e.beginPath(), e.moveTo(o, n.y), e.lineTo(o, n.y + n.height), e.stroke(), e.beginPath(), e.moveTo(n.x, l), e.lineTo(n.x + n.width, l), e.stroke(), e.restore();
|
|
585
585
|
}
|
|
586
586
|
if (this.state.hoveredPoint && this.state.selectionState !== "complete") {
|
|
587
|
-
const
|
|
588
|
-
e.beginPath(), e.arc(
|
|
587
|
+
const o = this.state.hoveredPoint;
|
|
588
|
+
e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize + 4, 0, Math.PI * 2), e.fillStyle = i.highlightColor + "30", e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize, 0, Math.PI * 2), e.strokeStyle = i.highlightColor, e.lineWidth = 2, e.stroke(), e.beginPath(), e.arc(o.pixelX, o.pixelY, 4, 0, Math.PI * 2), e.fillStyle = i.highlightColor, e.fill(), this.drawPointTooltip(e, o, "Hover");
|
|
589
589
|
}
|
|
590
590
|
if (this.state.point1) {
|
|
591
|
-
const
|
|
592
|
-
e.beginPath(), e.arc(
|
|
591
|
+
const o = this.state.point1;
|
|
592
|
+
e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize, 0, Math.PI * 2), e.fillStyle = i.lineColor, e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize - 3, 0, Math.PI * 2), e.fillStyle = "#ffffff", e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, 3, 0, Math.PI * 2), e.fillStyle = i.lineColor, e.fill(), this.drawPointLabel(e, o.pixelX, o.pixelY - i.highlightSize - 8, "P1", i.lineColor);
|
|
593
593
|
}
|
|
594
594
|
if (this.state.point2) {
|
|
595
|
-
const
|
|
596
|
-
e.beginPath(), e.arc(
|
|
595
|
+
const o = this.state.point2;
|
|
596
|
+
e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize, 0, Math.PI * 2), e.fillStyle = "#4ade80", e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, i.highlightSize - 3, 0, Math.PI * 2), e.fillStyle = "#ffffff", e.fill(), e.beginPath(), e.arc(o.pixelX, o.pixelY, 3, 0, Math.PI * 2), e.fillStyle = "#4ade80", e.fill(), this.drawPointLabel(e, o.pixelX, o.pixelY - i.highlightSize - 8, "P2", "#4ade80");
|
|
597
597
|
}
|
|
598
598
|
if (this.state.point1 && this.state.point2 && this.state.lastMeasurement) {
|
|
599
|
-
const
|
|
600
|
-
if (
|
|
601
|
-
const S =
|
|
602
|
-
e.beginPath(), e.moveTo(
|
|
603
|
-
for (let
|
|
604
|
-
const
|
|
605
|
-
e.lineTo(
|
|
599
|
+
const o = this.state.point1, l = this.state.point2, h = this.state.lastMeasurement, a = this.ctx.getPlotArea(), r = this.ctx.getViewBounds(), f = (this.ctx.getSeries ? this.ctx.getSeries() : []).find((S) => S.id === o.seriesId);
|
|
600
|
+
if (f) {
|
|
601
|
+
const S = f.x, T = f.y, v = Math.min(o.index, l.index), Y = Math.max(o.index, l.index), w = this.ctx.getYBounds ? this.ctx.getYBounds(f.yAxisId) : { yMin: r.yMin, yMax: r.yMax };
|
|
602
|
+
e.beginPath(), e.moveTo(o.pixelX, o.pixelY);
|
|
603
|
+
for (let C = v; C <= Y; C++) {
|
|
604
|
+
const m = a.x + (S[C] - r.xMin) / (r.xMax - r.xMin) * a.width, I = a.y + (1 - (T[C] - w.yMin) / (w.yMax - w.yMin)) * a.height;
|
|
605
|
+
e.lineTo(m, I);
|
|
606
606
|
}
|
|
607
607
|
e.lineTo(l.pixelX, l.pixelY), e.closePath(), e.fillStyle = i.areaFill, e.fill();
|
|
608
608
|
}
|
|
609
|
-
e.beginPath(), e.moveTo(
|
|
610
|
-
const
|
|
611
|
-
e.beginPath(), e.moveTo(g, y), e.lineTo(g, x), e.strokeStyle = i.lineColor, e.setLineDash([2, 2]), e.stroke(), e.setLineDash([]), i.showLabels && this.drawMeasurementLabel(e,
|
|
609
|
+
e.beginPath(), e.moveTo(o.pixelX, o.pixelY), e.lineTo(l.pixelX, l.pixelY), e.strokeStyle = i.lineColor, e.lineWidth = 1, e.stroke();
|
|
610
|
+
const p = this.ctx.getYBounds ? this.ctx.getYBounds(o.yAxisId) : { yMin: r.yMin, yMax: r.yMax }, g = a.x + (h.peakX - r.xMin) / (r.xMax - r.xMin) * a.width, y = a.y + (1 - (h.peakY - p.yMin) / (p.yMax - p.yMin)) * a.height, b = h.baselineSlope * h.peakX + h.baselineIntercept, x = a.y + (1 - (b - p.yMin) / (p.yMax - p.yMin)) * a.height;
|
|
611
|
+
e.beginPath(), e.moveTo(g, y), e.lineTo(g, x), e.strokeStyle = i.lineColor, e.setLineDash([2, 2]), e.stroke(), e.setLineDash([]), i.showLabels && this.drawMeasurementLabel(e, o, l, h);
|
|
612
612
|
}
|
|
613
613
|
this.drawStatusIndicator(e);
|
|
614
614
|
}
|
|
615
615
|
drawPointTooltip(t, i, e) {
|
|
616
|
-
const n = this.options,
|
|
616
|
+
const n = this.options, s = `${e}: (${this.formatValue(i.x)}, ${this.formatValue(i.y)})`;
|
|
617
617
|
t.font = `${n.labelFontSize}px system-ui, sans-serif`;
|
|
618
|
-
const
|
|
618
|
+
const o = t.measureText(s), l = 6, h = o.width + l * 2, a = n.labelFontSize + l * 2;
|
|
619
619
|
let r = i.pixelX + 15, d = i.pixelY - a / 2;
|
|
620
|
-
const
|
|
621
|
-
r + h >
|
|
620
|
+
const f = this.ctx.container.getBoundingClientRect();
|
|
621
|
+
r + h > f.width && (r = i.pixelX - h - 15), d < 0 && (d = 5), d + a > f.height && (d = f.height - a - 5), t.fillStyle = n.labelBackground, this.roundRect(t, r, d, h, a, 4), t.fill(), t.fillStyle = n.labelColor, t.textAlign = "left", t.textBaseline = "middle", t.fillText(s, r + l, d + a / 2);
|
|
622
622
|
}
|
|
623
|
-
drawPointLabel(t, i, e, n,
|
|
624
|
-
const
|
|
625
|
-
t.font = `bold ${
|
|
626
|
-
const l = t.measureText(n), h = 4, a = l.width + h * 2, r =
|
|
627
|
-
t.fillStyle =
|
|
623
|
+
drawPointLabel(t, i, e, n, s) {
|
|
624
|
+
const o = this.options;
|
|
625
|
+
t.font = `bold ${o.labelFontSize}px system-ui, sans-serif`, t.textAlign = "center", t.textBaseline = "bottom";
|
|
626
|
+
const l = t.measureText(n), h = 4, a = l.width + h * 2, r = o.labelFontSize + h;
|
|
627
|
+
t.fillStyle = s, this.roundRect(t, i - a / 2, e - r, a, r, 3), t.fill(), t.fillStyle = "#ffffff", t.fillText(n, i, e - 2);
|
|
628
628
|
}
|
|
629
629
|
drawMeasurementLabel(t, i, e, n) {
|
|
630
|
-
const
|
|
631
|
-
|
|
632
|
-
const a =
|
|
633
|
-
let
|
|
630
|
+
const s = this.options, o = (i.pixelX + e.pixelX) / 2, l = (i.pixelY + e.pixelY) / 2, h = [];
|
|
631
|
+
s.showPeak && (h.push(`Peak Area: ${this.formatValue(n.area)}`), h.push(`Peak Height: ${this.formatValue(n.peakHeight)}`), h.push(`Integral: ${this.formatValue(n.integral)}`));
|
|
632
|
+
const a = s.labelFontSize + 4, r = 10, d = 170, f = h.length * a + r * 2;
|
|
633
|
+
let p = o + this.labelOffset.x, g = l + this.labelOffset.y;
|
|
634
634
|
const y = this.ctx.container.getBoundingClientRect();
|
|
635
|
-
|
|
636
|
-
t.fillText(b,
|
|
635
|
+
p < 0 && (p = 0), p + d > y.width && (p = y.width - d), g < 0 && (g = 0), g + f > y.height && (g = y.height - f), this.labelBounds = { x: p, y: g, width: d, height: f }, t.fillStyle = s.labelBackground, t.strokeStyle = s.lineColor, t.lineWidth = 2, this.roundRect(t, p, g, d, f, 8), t.fill(), t.stroke(), t.fillStyle = s.labelColor, t.font = `${s.labelFontSize}px system-ui, sans-serif`, t.textAlign = "left", t.textBaseline = "top", h.forEach((b, x) => {
|
|
636
|
+
t.fillText(b, p + r, g + r + x * a);
|
|
637
637
|
});
|
|
638
638
|
}
|
|
639
639
|
drawStatusIndicator(t) {
|
|
640
640
|
const i = this.options, e = this.ctx.getPlotArea();
|
|
641
|
-
let n = "",
|
|
642
|
-
if (this.state.selectionState === "idle" ? (n = "📏 Click a point to start measuring",
|
|
641
|
+
let n = "", s = "#666";
|
|
642
|
+
if (this.state.selectionState === "idle" ? (n = "📏 Click a point to start measuring", s = i.highlightColor) : this.state.selectionState === "waitingSecond" ? (n = "📏 Click second point to complete", s = "#f59e0b") : this.state.selectionState === "complete" && (n = "📏 Measurement complete (ESC to clear)", s = "#4ade80"), !n) return;
|
|
643
643
|
t.font = "12px system-ui, sans-serif";
|
|
644
644
|
const h = t.measureText(n).width + 8 * 2, a = 24, r = e.x + 10, d = e.y + 10;
|
|
645
|
-
t.fillStyle = "rgba(0, 0, 0, 0.75)", this.roundRect(t, r, d, h, a, 4), t.fill(), t.beginPath(), t.arc(r + 16, d + a / 2, 4, 0, Math.PI * 2), t.fillStyle =
|
|
645
|
+
t.fillStyle = "rgba(0, 0, 0, 0.75)", this.roundRect(t, r, d, h, a, 4), t.fill(), t.beginPath(), t.arc(r + 16, d + a / 2, 4, 0, Math.PI * 2), t.fillStyle = s, t.fill(), t.fillStyle = "#fff", t.textAlign = "left", t.textBaseline = "middle", t.fillText(n, r + 26, d + a / 2);
|
|
646
646
|
}
|
|
647
|
-
roundRect(t, i, e, n,
|
|
648
|
-
t.beginPath(), t.moveTo(i +
|
|
647
|
+
roundRect(t, i, e, n, s, o) {
|
|
648
|
+
t.beginPath(), t.moveTo(i + o, e), t.lineTo(i + n - o, e), t.quadraticCurveTo(i + n, e, i + n, e + o), t.lineTo(i + n, e + s - o), t.quadraticCurveTo(i + n, e + s, i + n - o, e + s), t.lineTo(i + o, e + s), t.quadraticCurveTo(i, e + s, i, e + s - o), t.lineTo(i, e + o), t.quadraticCurveTo(i, e, i + o, e), t.closePath();
|
|
649
649
|
}
|
|
650
650
|
formatValue(t) {
|
|
651
651
|
const i = Math.abs(t);
|
|
652
652
|
return i === 0 ? "0" : i >= 1e6 || i < 1e-3 ? t.toExponential(this.options.precision - 1) : t.toPrecision(this.options.precision);
|
|
653
653
|
}
|
|
654
654
|
}
|
|
655
|
-
const
|
|
655
|
+
const V = {
|
|
656
656
|
top: 10,
|
|
657
657
|
right: 12,
|
|
658
658
|
bottom: 10,
|
|
@@ -680,7 +680,7 @@ const W = {
|
|
|
680
680
|
contentFontSize: 11,
|
|
681
681
|
lineHeight: 1.4,
|
|
682
682
|
// Spacing
|
|
683
|
-
padding:
|
|
683
|
+
padding: V,
|
|
684
684
|
itemGap: 4,
|
|
685
685
|
headerGap: 8,
|
|
686
686
|
// Decorations
|
|
@@ -690,7 +690,7 @@ const W = {
|
|
|
690
690
|
separatorColor: "rgba(255, 255, 255, 0.1)",
|
|
691
691
|
showArrow: !0,
|
|
692
692
|
arrowSize: 6
|
|
693
|
-
},
|
|
693
|
+
}, et = {
|
|
694
694
|
// Container
|
|
695
695
|
backgroundColor: "rgba(255, 255, 255, 0.98)",
|
|
696
696
|
borderColor: "rgba(0, 0, 0, 0.12)",
|
|
@@ -712,7 +712,7 @@ const W = {
|
|
|
712
712
|
contentFontSize: 11,
|
|
713
713
|
lineHeight: 1.4,
|
|
714
714
|
// Spacing
|
|
715
|
-
padding:
|
|
715
|
+
padding: V,
|
|
716
716
|
itemGap: 4,
|
|
717
717
|
headerGap: 8,
|
|
718
718
|
// Decorations
|
|
@@ -722,7 +722,7 @@ const W = {
|
|
|
722
722
|
separatorColor: "rgba(0, 0, 0, 0.08)",
|
|
723
723
|
showArrow: !0,
|
|
724
724
|
arrowSize: 6
|
|
725
|
-
},
|
|
725
|
+
}, gt = {
|
|
726
726
|
// Container
|
|
727
727
|
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
|
728
728
|
backgroundGradient: "rgba(255, 255, 255, 0.04)",
|
|
@@ -755,7 +755,7 @@ const W = {
|
|
|
755
755
|
separatorColor: "rgba(255, 255, 255, 0.15)",
|
|
756
756
|
showArrow: !0,
|
|
757
757
|
arrowSize: 7
|
|
758
|
-
},
|
|
758
|
+
}, it = {
|
|
759
759
|
// Container
|
|
760
760
|
backgroundColor: "rgba(10, 15, 30, 0.95)",
|
|
761
761
|
backgroundGradient: "rgba(20, 25, 50, 0.90)",
|
|
@@ -778,7 +778,7 @@ const W = {
|
|
|
778
778
|
contentFontSize: 11,
|
|
779
779
|
lineHeight: 1.4,
|
|
780
780
|
// Spacing
|
|
781
|
-
padding:
|
|
781
|
+
padding: V,
|
|
782
782
|
itemGap: 4,
|
|
783
783
|
headerGap: 8,
|
|
784
784
|
// Decorations
|
|
@@ -788,7 +788,7 @@ const W = {
|
|
|
788
788
|
separatorColor: "rgba(100, 120, 255, 0.15)",
|
|
789
789
|
showArrow: !0,
|
|
790
790
|
arrowSize: 6
|
|
791
|
-
},
|
|
791
|
+
}, st = {
|
|
792
792
|
// Container
|
|
793
793
|
backgroundColor: "rgba(8, 20, 40, 0.96)",
|
|
794
794
|
backgroundGradient: "rgba(15, 35, 60, 0.92)",
|
|
@@ -821,7 +821,7 @@ const W = {
|
|
|
821
821
|
separatorColor: "rgba(30, 136, 229, 0.2)",
|
|
822
822
|
showArrow: !0,
|
|
823
823
|
arrowSize: 5
|
|
824
|
-
},
|
|
824
|
+
}, yt = {
|
|
825
825
|
// Container
|
|
826
826
|
backgroundColor: "rgba(0, 0, 0, 0.92)",
|
|
827
827
|
borderColor: "#00ffff",
|
|
@@ -853,7 +853,7 @@ const W = {
|
|
|
853
853
|
separatorColor: "rgba(0, 255, 255, 0.3)",
|
|
854
854
|
showArrow: !1,
|
|
855
855
|
arrowSize: 0
|
|
856
|
-
},
|
|
856
|
+
}, xt = {
|
|
857
857
|
// Container
|
|
858
858
|
backgroundColor: "rgba(30, 35, 45, 0.9)",
|
|
859
859
|
borderColor: "transparent",
|
|
@@ -885,21 +885,21 @@ const W = {
|
|
|
885
885
|
separatorColor: "transparent",
|
|
886
886
|
showArrow: !1,
|
|
887
887
|
arrowSize: 0
|
|
888
|
-
},
|
|
888
|
+
}, bt = {
|
|
889
889
|
dark: L,
|
|
890
|
-
light:
|
|
891
|
-
glass:
|
|
892
|
-
midnight:
|
|
893
|
-
electrochemistry:
|
|
894
|
-
neon:
|
|
895
|
-
minimal:
|
|
890
|
+
light: et,
|
|
891
|
+
glass: gt,
|
|
892
|
+
midnight: it,
|
|
893
|
+
electrochemistry: st,
|
|
894
|
+
neon: yt,
|
|
895
|
+
minimal: xt
|
|
896
896
|
};
|
|
897
|
-
function
|
|
898
|
-
const t =
|
|
899
|
-
return t || (console.warn(`[Tooltip] Unknown theme "${
|
|
897
|
+
function St(c) {
|
|
898
|
+
const t = bt[c];
|
|
899
|
+
return t || (console.warn(`[Tooltip] Unknown theme "${c}", using dark`), L);
|
|
900
900
|
}
|
|
901
|
-
function
|
|
902
|
-
const i = typeof
|
|
901
|
+
function mt(c, t) {
|
|
902
|
+
const i = typeof c == "string" ? St(c) : c;
|
|
903
903
|
return {
|
|
904
904
|
...i,
|
|
905
905
|
...t,
|
|
@@ -907,21 +907,21 @@ function pt(f, t) {
|
|
|
907
907
|
shadow: { ...i.shadow, ...t.shadow }
|
|
908
908
|
};
|
|
909
909
|
}
|
|
910
|
-
function
|
|
911
|
-
switch (
|
|
910
|
+
function B(c) {
|
|
911
|
+
switch (c.toLowerCase()) {
|
|
912
912
|
case "light":
|
|
913
|
-
return
|
|
913
|
+
return et;
|
|
914
914
|
case "midnight":
|
|
915
|
-
return
|
|
915
|
+
return it;
|
|
916
916
|
case "electrochemistry":
|
|
917
917
|
case "electrochem":
|
|
918
|
-
return
|
|
918
|
+
return st;
|
|
919
919
|
case "dark":
|
|
920
920
|
default:
|
|
921
921
|
return L;
|
|
922
922
|
}
|
|
923
923
|
}
|
|
924
|
-
const
|
|
924
|
+
const Tt = L, wt = {
|
|
925
925
|
offset: { x: 12, y: 12 },
|
|
926
926
|
preferredPosition: "auto",
|
|
927
927
|
constrainToPlotArea: !0,
|
|
@@ -930,13 +930,13 @@ const gt = L, yt = {
|
|
|
930
930
|
showArrow: !0,
|
|
931
931
|
arrowSize: 6
|
|
932
932
|
};
|
|
933
|
-
class
|
|
933
|
+
class Mt {
|
|
934
934
|
constructor(t = {}) {
|
|
935
935
|
u(this, "config");
|
|
936
936
|
u(this, "containerWidth", 0);
|
|
937
937
|
u(this, "containerHeight", 0);
|
|
938
938
|
u(this, "plotArea", null);
|
|
939
|
-
this.config = { ...
|
|
939
|
+
this.config = { ...wt, ...t };
|
|
940
940
|
}
|
|
941
941
|
/**
|
|
942
942
|
* Update container dimensions
|
|
@@ -965,14 +965,14 @@ class xt {
|
|
|
965
965
|
* @returns Calculated position with arrow configuration
|
|
966
966
|
*/
|
|
967
967
|
calculatePosition(t, i, e) {
|
|
968
|
-
const { offset: n, preferredPosition:
|
|
968
|
+
const { offset: n, preferredPosition: s, autoFlip: o, showArrow: l, arrowSize: h } = this.config, a = e.width + e.padding.left + e.padding.right, r = e.height + e.padding.top + e.padding.bottom;
|
|
969
969
|
let d = this.determinePosition(
|
|
970
970
|
t,
|
|
971
971
|
i,
|
|
972
972
|
a,
|
|
973
973
|
r,
|
|
974
|
-
|
|
975
|
-
), { x:
|
|
974
|
+
s
|
|
975
|
+
), { x: f, y: p, arrowPosition: g } = this.calculateCoordinates(
|
|
976
976
|
t,
|
|
977
977
|
i,
|
|
978
978
|
a,
|
|
@@ -981,8 +981,8 @@ class xt {
|
|
|
981
981
|
n,
|
|
982
982
|
l ? h : 0
|
|
983
983
|
), y = !1;
|
|
984
|
-
if (
|
|
985
|
-
const S = this.flipPosition(d),
|
|
984
|
+
if (o && !this.fitsInBounds(f, p, a, r)) {
|
|
985
|
+
const S = this.flipPosition(d), T = this.calculateCoordinates(
|
|
986
986
|
t,
|
|
987
987
|
i,
|
|
988
988
|
a,
|
|
@@ -991,9 +991,9 @@ class xt {
|
|
|
991
991
|
n,
|
|
992
992
|
l ? h : 0
|
|
993
993
|
);
|
|
994
|
-
this.fitsInBounds(
|
|
994
|
+
this.fitsInBounds(T.x, T.y, a, r) && (f = T.x, p = T.y, g = T.arrowPosition, y = !0);
|
|
995
995
|
}
|
|
996
|
-
const b = this.constrainToBounds(
|
|
996
|
+
const b = this.constrainToBounds(f, p, a, r);
|
|
997
997
|
let x = 0;
|
|
998
998
|
if (l) {
|
|
999
999
|
if (g === "top" || g === "bottom") {
|
|
@@ -1015,11 +1015,11 @@ class xt {
|
|
|
1015
1015
|
/**
|
|
1016
1016
|
* Determine best position based on available space
|
|
1017
1017
|
*/
|
|
1018
|
-
determinePosition(t, i, e, n,
|
|
1019
|
-
if (
|
|
1020
|
-
return
|
|
1021
|
-
const
|
|
1022
|
-
return d && l >= h ? "top" :
|
|
1018
|
+
determinePosition(t, i, e, n, s) {
|
|
1019
|
+
if (s !== "auto")
|
|
1020
|
+
return s;
|
|
1021
|
+
const o = this.getConstraintBounds(), l = i - o.top, h = o.bottom - i, a = t - o.left, r = o.right - t, d = l >= n + this.config.offset.y, f = h >= n + this.config.offset.y, p = r >= e + this.config.offset.x, g = a >= e + this.config.offset.x;
|
|
1022
|
+
return d && l >= h ? "top" : f ? "bottom" : p && r >= a ? "right" : g ? "left" : [
|
|
1023
1023
|
{ pos: "top", space: l },
|
|
1024
1024
|
{ pos: "bottom", space: h },
|
|
1025
1025
|
{ pos: "right", space: r },
|
|
@@ -1029,20 +1029,20 @@ class xt {
|
|
|
1029
1029
|
/**
|
|
1030
1030
|
* Calculate tooltip coordinates for a given position
|
|
1031
1031
|
*/
|
|
1032
|
-
calculateCoordinates(t, i, e, n,
|
|
1032
|
+
calculateCoordinates(t, i, e, n, s, o, l) {
|
|
1033
1033
|
let h, a, r;
|
|
1034
|
-
switch (
|
|
1034
|
+
switch (s) {
|
|
1035
1035
|
case "top":
|
|
1036
|
-
h = t - e / 2, a = i - n -
|
|
1036
|
+
h = t - e / 2, a = i - n - o.y - l, r = "bottom";
|
|
1037
1037
|
break;
|
|
1038
1038
|
case "bottom":
|
|
1039
|
-
h = t - e / 2, a = i +
|
|
1039
|
+
h = t - e / 2, a = i + o.y + l, r = "top";
|
|
1040
1040
|
break;
|
|
1041
1041
|
case "right":
|
|
1042
|
-
h = t +
|
|
1042
|
+
h = t + o.x + l, a = i - n / 2, r = "left";
|
|
1043
1043
|
break;
|
|
1044
1044
|
case "left":
|
|
1045
|
-
h = t - e -
|
|
1045
|
+
h = t - e - o.x - l, a = i - n / 2, r = "right";
|
|
1046
1046
|
break;
|
|
1047
1047
|
}
|
|
1048
1048
|
return { x: h, y: a, arrowPosition: r };
|
|
@@ -1066,16 +1066,16 @@ class xt {
|
|
|
1066
1066
|
* Check if tooltip fits within bounds
|
|
1067
1067
|
*/
|
|
1068
1068
|
fitsInBounds(t, i, e, n) {
|
|
1069
|
-
const
|
|
1070
|
-
return t >=
|
|
1069
|
+
const s = this.getConstraintBounds();
|
|
1070
|
+
return t >= s.left && i >= s.top && t + e <= s.right && i + n <= s.bottom;
|
|
1071
1071
|
}
|
|
1072
1072
|
/**
|
|
1073
1073
|
* Constrain position to stay within bounds
|
|
1074
1074
|
*/
|
|
1075
1075
|
constrainToBounds(t, i, e, n) {
|
|
1076
|
-
const
|
|
1076
|
+
const s = this.getConstraintBounds(), o = 4;
|
|
1077
1077
|
let l = t, h = i;
|
|
1078
|
-
return l <
|
|
1078
|
+
return l < s.left + o ? l = s.left + o : l + e > s.right - o && (l = s.right - e - o), h < s.top + o ? h = s.top + o : h + n > s.bottom - o && (h = s.bottom - n - o), { x: l, y: h };
|
|
1079
1079
|
}
|
|
1080
1080
|
/**
|
|
1081
1081
|
* Get the bounds to constrain tooltip within
|
|
@@ -1098,11 +1098,11 @@ class xt {
|
|
|
1098
1098
|
* Calculate position for crosshair tooltip (follows cursor vertically)
|
|
1099
1099
|
*/
|
|
1100
1100
|
calculateCrosshairPosition(t, i, e) {
|
|
1101
|
-
const { offset: n } = this.config,
|
|
1101
|
+
const { offset: n } = this.config, s = this.getConstraintBounds(), o = e.width + e.padding.left + e.padding.right, l = e.height + e.padding.top + e.padding.bottom;
|
|
1102
1102
|
let h = t + n.x, a = "left";
|
|
1103
|
-
h +
|
|
1103
|
+
h + o > s.right - 4 && (h = t - o - n.x, a = "right");
|
|
1104
1104
|
let r = i - l / 2;
|
|
1105
|
-
r = Math.max(
|
|
1105
|
+
r = Math.max(s.top + 4, Math.min(s.bottom - l - 4, r));
|
|
1106
1106
|
const d = i - r;
|
|
1107
1107
|
return {
|
|
1108
1108
|
x: h,
|
|
@@ -1113,7 +1113,7 @@ class xt {
|
|
|
1113
1113
|
};
|
|
1114
1114
|
}
|
|
1115
1115
|
}
|
|
1116
|
-
class
|
|
1116
|
+
class vt {
|
|
1117
1117
|
constructor(t, i) {
|
|
1118
1118
|
u(this, "ctx");
|
|
1119
1119
|
u(this, "theme");
|
|
@@ -1129,12 +1129,12 @@ class bt {
|
|
|
1129
1129
|
* Render a tooltip with the given template
|
|
1130
1130
|
*/
|
|
1131
1131
|
render(t, i, e) {
|
|
1132
|
-
const n = e.measure(this.ctx, t, this.theme),
|
|
1133
|
-
this.ctx.save(), this.drawBackground(i.x, i.y,
|
|
1132
|
+
const n = e.measure(this.ctx, t, this.theme), s = n.width + n.padding.left + n.padding.right, o = n.height + n.padding.top + n.padding.bottom;
|
|
1133
|
+
this.ctx.save(), this.drawBackground(i.x, i.y, s, o, i.arrowPosition || "none"), i.arrowPosition && i.arrowPosition !== "none" && this.drawArrow(
|
|
1134
1134
|
i.x,
|
|
1135
1135
|
i.y,
|
|
1136
|
-
o,
|
|
1137
1136
|
s,
|
|
1137
|
+
o,
|
|
1138
1138
|
i.arrowPosition,
|
|
1139
1139
|
i.arrowOffset || 0
|
|
1140
1140
|
), e.render(this.ctx, t, i, n, this.theme), this.ctx.restore();
|
|
@@ -1142,36 +1142,36 @@ class bt {
|
|
|
1142
1142
|
/**
|
|
1143
1143
|
* Draw tooltip background with all effects
|
|
1144
1144
|
*/
|
|
1145
|
-
drawBackground(t, i, e, n,
|
|
1146
|
-
const { ctx:
|
|
1147
|
-
if (
|
|
1148
|
-
const a =
|
|
1149
|
-
a.addColorStop(0, l.backgroundColor), a.addColorStop(1, l.backgroundGradient),
|
|
1145
|
+
drawBackground(t, i, e, n, s) {
|
|
1146
|
+
const { ctx: o, theme: l } = this, h = l.borderRadius;
|
|
1147
|
+
if (o.save(), l.shadow.blur > 0 && (o.shadowColor = l.shadow.color, o.shadowOffsetX = l.shadow.offsetX, o.shadowOffsetY = l.shadow.offsetY, o.shadowBlur = l.shadow.blur), o.beginPath(), this.roundRect(t, i, e, n, h), l.backgroundGradient) {
|
|
1148
|
+
const a = o.createLinearGradient(t, i, t, i + n);
|
|
1149
|
+
a.addColorStop(0, l.backgroundColor), a.addColorStop(1, l.backgroundGradient), o.fillStyle = a;
|
|
1150
1150
|
} else
|
|
1151
|
-
|
|
1152
|
-
|
|
1151
|
+
o.fillStyle = l.backgroundColor;
|
|
1152
|
+
o.fill(), o.shadowColor = "transparent", l.borderWidth > 0 && (o.strokeStyle = l.borderColor, o.lineWidth = l.borderWidth, o.stroke()), o.restore();
|
|
1153
1153
|
}
|
|
1154
1154
|
/**
|
|
1155
1155
|
* Draw arrow pointing to target
|
|
1156
1156
|
*/
|
|
1157
|
-
drawArrow(t, i, e, n,
|
|
1157
|
+
drawArrow(t, i, e, n, s, o) {
|
|
1158
1158
|
const { ctx: l, theme: h } = this, a = h.arrowSize;
|
|
1159
|
-
if (!(a <= 0 ||
|
|
1160
|
-
switch (l.save(), l.fillStyle = h.backgroundColor, l.strokeStyle = h.borderColor, l.lineWidth = h.borderWidth, l.beginPath(),
|
|
1159
|
+
if (!(a <= 0 || s === "none")) {
|
|
1160
|
+
switch (l.save(), l.fillStyle = h.backgroundColor, l.strokeStyle = h.borderColor, l.lineWidth = h.borderWidth, l.beginPath(), s) {
|
|
1161
1161
|
case "top":
|
|
1162
|
-
const r = t +
|
|
1162
|
+
const r = t + o;
|
|
1163
1163
|
l.moveTo(r - a, i), l.lineTo(r, i - a), l.lineTo(r + a, i);
|
|
1164
1164
|
break;
|
|
1165
1165
|
case "bottom":
|
|
1166
|
-
const d = t +
|
|
1167
|
-
l.moveTo(d - a,
|
|
1166
|
+
const d = t + o, f = i + n;
|
|
1167
|
+
l.moveTo(d - a, f), l.lineTo(d, f + a), l.lineTo(d + a, f);
|
|
1168
1168
|
break;
|
|
1169
1169
|
case "left":
|
|
1170
|
-
const
|
|
1171
|
-
l.moveTo(t,
|
|
1170
|
+
const p = i + o;
|
|
1171
|
+
l.moveTo(t, p - a), l.lineTo(t - a, p), l.lineTo(t, p + a);
|
|
1172
1172
|
break;
|
|
1173
1173
|
case "right":
|
|
1174
|
-
const g = t + e, y = i +
|
|
1174
|
+
const g = t + e, y = i + o;
|
|
1175
1175
|
l.moveTo(g, y - a), l.lineTo(g + a, y), l.lineTo(g, y + a);
|
|
1176
1176
|
break;
|
|
1177
1177
|
}
|
|
@@ -1181,57 +1181,57 @@ class bt {
|
|
|
1181
1181
|
/**
|
|
1182
1182
|
* Draw a rounded rectangle path
|
|
1183
1183
|
*/
|
|
1184
|
-
roundRect(t, i, e, n,
|
|
1185
|
-
const { ctx:
|
|
1186
|
-
|
|
1184
|
+
roundRect(t, i, e, n, s) {
|
|
1185
|
+
const { ctx: o } = this, l = Math.min(s, e / 2, n / 2);
|
|
1186
|
+
o.moveTo(t + l, i), o.lineTo(t + e - l, i), o.arcTo(t + e, i, t + e, i + l, l), o.lineTo(t + e, i + n - l), o.arcTo(t + e, i + n, t + e - l, i + n, l), o.lineTo(t + l, i + n), o.arcTo(t, i + n, t, i + n - l, l), o.lineTo(t, i + l), o.arcTo(t, i, t + l, i, l), o.closePath();
|
|
1187
1187
|
}
|
|
1188
1188
|
/**
|
|
1189
1189
|
* Draw a horizontal separator line
|
|
1190
1190
|
*/
|
|
1191
1191
|
drawSeparator(t, i, e) {
|
|
1192
|
-
const { ctx: n, theme:
|
|
1193
|
-
|
|
1192
|
+
const { ctx: n, theme: s } = this;
|
|
1193
|
+
s.showHeaderSeparator && (n.save(), n.strokeStyle = s.separatorColor, n.lineWidth = 1, n.beginPath(), n.moveTo(t, i), n.lineTo(t + e, i), n.stroke(), n.restore());
|
|
1194
1194
|
}
|
|
1195
1195
|
/**
|
|
1196
1196
|
* Draw a series color indicator (small circle or square)
|
|
1197
1197
|
*/
|
|
1198
1198
|
drawSeriesIndicator(t, i, e) {
|
|
1199
|
-
const { ctx: n, theme:
|
|
1200
|
-
if (!
|
|
1201
|
-
const l =
|
|
1199
|
+
const { ctx: n, theme: s } = this;
|
|
1200
|
+
if (!s.showSeriesIndicator) return;
|
|
1201
|
+
const l = s.seriesIndicatorSize / 2;
|
|
1202
1202
|
n.save(), n.fillStyle = e, n.beginPath(), n.arc(t + l, i, l, 0, Math.PI * 2), n.fill(), n.restore();
|
|
1203
1203
|
}
|
|
1204
1204
|
/**
|
|
1205
1205
|
* Measure text width
|
|
1206
1206
|
*/
|
|
1207
1207
|
measureText(t, i, e = 400) {
|
|
1208
|
-
const { ctx: n, theme:
|
|
1209
|
-
return n.font = `${e} ${i}px ${
|
|
1208
|
+
const { ctx: n, theme: s } = this;
|
|
1209
|
+
return n.font = `${e} ${i}px ${s.fontFamily}`, n.measureText(t).width;
|
|
1210
1210
|
}
|
|
1211
1211
|
/**
|
|
1212
1212
|
* Draw text with theme styling
|
|
1213
1213
|
*/
|
|
1214
1214
|
drawText(t, i, e, n = {}) {
|
|
1215
|
-
const { ctx:
|
|
1216
|
-
fontSize: l =
|
|
1215
|
+
const { ctx: s, theme: o } = this, {
|
|
1216
|
+
fontSize: l = o.contentFontSize,
|
|
1217
1217
|
fontWeight: h = 400,
|
|
1218
|
-
color: a =
|
|
1218
|
+
color: a = o.textColor,
|
|
1219
1219
|
align: r = "left",
|
|
1220
1220
|
baseline: d = "top"
|
|
1221
1221
|
} = n;
|
|
1222
|
-
|
|
1222
|
+
s.save(), s.font = `${h} ${l}px ${o.fontFamily}`, s.fillStyle = a, s.textAlign = r, s.textBaseline = d, s.fillText(t, i, e), s.restore();
|
|
1223
1223
|
}
|
|
1224
1224
|
/**
|
|
1225
1225
|
* Draw a label-value pair
|
|
1226
1226
|
*/
|
|
1227
|
-
drawLabelValue(t, i, e, n,
|
|
1228
|
-
const { theme:
|
|
1227
|
+
drawLabelValue(t, i, e, n, s) {
|
|
1228
|
+
const { theme: o } = this;
|
|
1229
1229
|
this.drawText(e, t, i, {
|
|
1230
|
-
color:
|
|
1231
|
-
fontSize:
|
|
1232
|
-
}), this.drawText(n, t +
|
|
1233
|
-
color:
|
|
1234
|
-
fontSize:
|
|
1230
|
+
color: o.textSecondaryColor,
|
|
1231
|
+
fontSize: o.contentFontSize
|
|
1232
|
+
}), this.drawText(n, t + s, i, {
|
|
1233
|
+
color: o.textColor,
|
|
1234
|
+
fontSize: o.contentFontSize,
|
|
1235
1235
|
align: "right"
|
|
1236
1236
|
});
|
|
1237
1237
|
}
|
|
@@ -1242,13 +1242,39 @@ class bt {
|
|
|
1242
1242
|
return this.theme;
|
|
1243
1243
|
}
|
|
1244
1244
|
}
|
|
1245
|
-
function
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
return
|
|
1245
|
+
function ot(c) {
|
|
1246
|
+
return c.axisFormat ? O(c.dataX, c.axisFormat) : W(c.dataX);
|
|
1247
|
+
}
|
|
1248
|
+
function nt(c) {
|
|
1249
|
+
return c.axisFormat ? N(c.dataY, c.axisFormat) : W(c.dataY);
|
|
1250
1250
|
}
|
|
1251
|
-
|
|
1251
|
+
function Ct(c) {
|
|
1252
|
+
return c.axisFormat ? O(c.dataX, c.axisFormat) : W(c.dataX);
|
|
1253
|
+
}
|
|
1254
|
+
function Pt(c, t) {
|
|
1255
|
+
return t.axisFormat ? N(c, t.axisFormat) : W(c);
|
|
1256
|
+
}
|
|
1257
|
+
function W(c) {
|
|
1258
|
+
if (c == null || isNaN(c)) return "N/A";
|
|
1259
|
+
const t = Math.abs(c);
|
|
1260
|
+
return t === 0 ? "0" : t < 1e-4 || t >= 1e4 ? c.toExponential(2) : t < 0.01 ? c.toPrecision(4) : t < 1 ? c.toFixed(4) : t < 100 ? c.toFixed(3) : c.toFixed(1);
|
|
1261
|
+
}
|
|
1262
|
+
function k(c, t) {
|
|
1263
|
+
const i = t === "x" ? c.dataX : c.dataY;
|
|
1264
|
+
if (c.axisFormat)
|
|
1265
|
+
return t === "x" ? O(i, c.axisFormat) : N(i, c.axisFormat);
|
|
1266
|
+
if (i == null || isNaN(i)) return "N/A";
|
|
1267
|
+
const e = Math.abs(i);
|
|
1268
|
+
return e === 0 ? "0" : e >= 1e9 ? (i / 1e9).toFixed(1) + "G" : e >= 1e6 ? (i / 1e6).toFixed(1) + "M" : e >= 1e3 ? (i / 1e3).toFixed(1) + "k" : e >= 1 ? i.toFixed(2) : e >= 1e-3 ? (i * 1e3).toFixed(1) + "m" : e >= 1e-6 ? (i * 1e6).toFixed(1) + "µ" : e >= 1e-9 ? (i * 1e9).toFixed(1) + "n" : i.toExponential(1);
|
|
1269
|
+
}
|
|
1270
|
+
function z(c, t, i) {
|
|
1271
|
+
if (t && i === "x") return ot(t);
|
|
1272
|
+
if (t && i === "y") return nt(t);
|
|
1273
|
+
if (c == null || isNaN(c)) return "N/A";
|
|
1274
|
+
const e = Math.abs(c);
|
|
1275
|
+
return e !== 0 && (e < 1e-4 || e >= 1e4) ? c.toExponential(2) : e < 0.01 ? c.toPrecision(4) : e < 1 ? c.toFixed(4) : e < 100 ? c.toFixed(3) : c.toFixed(1);
|
|
1276
|
+
}
|
|
1277
|
+
class Ft {
|
|
1252
1278
|
constructor() {
|
|
1253
1279
|
u(this, "id", "default");
|
|
1254
1280
|
u(this, "name", "Default Data Point");
|
|
@@ -1265,23 +1291,23 @@ class St {
|
|
|
1265
1291
|
if (n === this.cachedKey && this.cachedMeasurement)
|
|
1266
1292
|
return this.cachedMeasurement;
|
|
1267
1293
|
t.font = `${e.titleFontWeight} ${e.titleFontSize}px ${e.fontFamily}`;
|
|
1268
|
-
const
|
|
1294
|
+
const s = t.measureText(i.seriesName).width;
|
|
1269
1295
|
t.font = `400 ${e.contentFontSize}px ${e.fontFamily}`;
|
|
1270
|
-
const
|
|
1271
|
-
let a =
|
|
1296
|
+
const o = 35, l = t.measureText(z(i.dataX, i, "x")).width, h = t.measureText(z(i.dataY, i, "y")).width;
|
|
1297
|
+
let a = o + Math.max(l, h), r = e.contentFontSize * e.lineHeight * 2;
|
|
1272
1298
|
if (i.yError) {
|
|
1273
|
-
const g = `± ${
|
|
1299
|
+
const g = `± ${z(i.yError[0])} / ${z(i.yError[1])}`;
|
|
1274
1300
|
a = Math.max(a, t.measureText(g).width), r += e.contentFontSize * e.lineHeight;
|
|
1275
1301
|
}
|
|
1276
1302
|
if (i.cycle !== void 0) {
|
|
1277
1303
|
const g = `Cycle: ${i.cycle}`;
|
|
1278
1304
|
a = Math.max(a, t.measureText(g).width), r += e.contentFontSize * e.lineHeight;
|
|
1279
1305
|
}
|
|
1280
|
-
const d = e.showSeriesIndicator ? e.seriesIndicatorSize + 6 : 0,
|
|
1306
|
+
const d = e.showSeriesIndicator ? e.seriesIndicatorSize + 6 : 0, f = Math.max(s + d, a), p = e.titleFontSize * e.lineHeight + e.headerGap + r;
|
|
1281
1307
|
return this.cachedMeasurement = {
|
|
1282
|
-
width:
|
|
1308
|
+
width: f + 2,
|
|
1283
1309
|
// Tiny buffer
|
|
1284
|
-
height:
|
|
1310
|
+
height: p + 4,
|
|
1285
1311
|
padding: e.padding,
|
|
1286
1312
|
arrow: e.showArrow ? { width: e.arrowSize * 2, height: e.arrowSize } : void 0
|
|
1287
1313
|
}, this.cachedKey = n, this.cachedMeasurement;
|
|
@@ -1289,35 +1315,29 @@ class St {
|
|
|
1289
1315
|
/**
|
|
1290
1316
|
* Render the tooltip
|
|
1291
1317
|
*/
|
|
1292
|
-
render(t, i, e, n,
|
|
1293
|
-
const { x:
|
|
1294
|
-
let a =
|
|
1295
|
-
if (t.save(), t.textAlign = "left", t.textBaseline = "top",
|
|
1296
|
-
const
|
|
1297
|
-
t.save(), t.fillStyle = i.seriesColor, t.beginPath(), t.arc(a +
|
|
1318
|
+
render(t, i, e, n, s) {
|
|
1319
|
+
const { x: o, y: l } = e, { padding: h } = s;
|
|
1320
|
+
let a = o + h.left, r = l + h.top;
|
|
1321
|
+
if (t.save(), t.textAlign = "left", t.textBaseline = "top", s.showSeriesIndicator) {
|
|
1322
|
+
const f = r + s.titleFontSize / 2;
|
|
1323
|
+
t.save(), t.fillStyle = i.seriesColor, t.beginPath(), t.arc(a + s.seriesIndicatorSize / 2, f, s.seriesIndicatorSize / 2, 0, Math.PI * 2), t.fill(), t.restore(), a += s.seriesIndicatorSize + 6;
|
|
1298
1324
|
}
|
|
1299
|
-
if (t.font = `${
|
|
1300
|
-
const
|
|
1301
|
-
t.save(), t.strokeStyle =
|
|
1325
|
+
if (t.font = `${s.titleFontWeight} ${s.titleFontSize}px ${s.fontFamily}`, t.fillStyle = s.textColor, t.fillText(i.seriesName, a, r), r += s.titleFontSize * s.lineHeight + 2, s.showHeaderSeparator) {
|
|
1326
|
+
const f = n.width;
|
|
1327
|
+
t.save(), t.strokeStyle = s.separatorColor, t.lineWidth = 1, t.globalAlpha = 0.4, t.beginPath(), t.moveTo(o + h.left, r + s.headerGap / 2), t.lineTo(o + h.left + f, r + s.headerGap / 2), t.stroke(), t.restore();
|
|
1302
1328
|
}
|
|
1303
|
-
r +=
|
|
1329
|
+
r += s.headerGap + 2, a = o + h.left, t.font = `400 ${s.contentFontSize}px ${s.fontFamily}`, t.fillStyle = s.textSecondaryColor, t.fillText("X:", a, r), t.fillStyle = s.textColor;
|
|
1304
1330
|
const d = 35;
|
|
1305
|
-
if (t.fillText(
|
|
1306
|
-
t.fillStyle =
|
|
1307
|
-
const
|
|
1308
|
-
t.fillText(
|
|
1331
|
+
if (t.fillText(z(i.dataX, i, "x"), a + d, r), r += s.contentFontSize * s.lineHeight + 2, t.fillStyle = s.textSecondaryColor, t.fillText("Y:", a, r), t.fillStyle = s.textColor, t.fillText(z(i.dataY, i, "y"), a + d, r), r += s.contentFontSize * s.lineHeight + 2, i.yError) {
|
|
1332
|
+
t.fillStyle = s.textSecondaryColor;
|
|
1333
|
+
const f = `± ${z(i.yError[0])} / +${z(i.yError[1])}`;
|
|
1334
|
+
t.fillText(f, a, r), r += s.contentFontSize * s.lineHeight;
|
|
1309
1335
|
}
|
|
1310
|
-
i.cycle !== void 0 && (t.fillStyle =
|
|
1336
|
+
i.cycle !== void 0 && (t.fillStyle = s.textSecondaryColor, t.fillText("Cycle:", a, r), t.fillStyle = s.textColor, t.fillText(String(i.cycle), a + 45, r)), t.restore();
|
|
1311
1337
|
}
|
|
1312
1338
|
}
|
|
1313
|
-
const
|
|
1314
|
-
|
|
1315
|
-
if (f == null || isNaN(f))
|
|
1316
|
-
return "N/A";
|
|
1317
|
-
const t = Math.abs(f);
|
|
1318
|
-
return t === 0 ? "0" : t >= 1e9 ? (f / 1e9).toFixed(1) + "G" : t >= 1e6 ? (f / 1e6).toFixed(1) + "M" : t >= 1e3 ? (f / 1e3).toFixed(1) + "k" : t >= 1 ? f.toFixed(2) : t >= 1e-3 ? (f * 1e3).toFixed(1) + "m" : t >= 1e-6 ? (f * 1e6).toFixed(1) + "µ" : t >= 1e-9 ? (f * 1e9).toFixed(1) + "n" : f.toExponential(1);
|
|
1319
|
-
}
|
|
1320
|
-
class Tt {
|
|
1339
|
+
const H = new Ft();
|
|
1340
|
+
class It {
|
|
1321
1341
|
constructor() {
|
|
1322
1342
|
u(this, "id", "minimal");
|
|
1323
1343
|
u(this, "name", "Minimal");
|
|
@@ -1334,9 +1354,9 @@ class Tt {
|
|
|
1334
1354
|
if (n === this.cachedKey && this.cachedMeasurement)
|
|
1335
1355
|
return this.cachedMeasurement;
|
|
1336
1356
|
t.font = `${e.contentFontSize}px ${e.fontFamily}`;
|
|
1337
|
-
const
|
|
1357
|
+
const s = `${k(i, "x")} ▪ ${k(i, "y")}`, o = t.measureText(s).width;
|
|
1338
1358
|
return this.cachedMeasurement = {
|
|
1339
|
-
width:
|
|
1359
|
+
width: o,
|
|
1340
1360
|
height: e.contentFontSize * e.lineHeight,
|
|
1341
1361
|
padding: {
|
|
1342
1362
|
top: 6,
|
|
@@ -1349,16 +1369,16 @@ class Tt {
|
|
|
1349
1369
|
/**
|
|
1350
1370
|
* Render the tooltip
|
|
1351
1371
|
*/
|
|
1352
|
-
render(t, i, e, n,
|
|
1353
|
-
const { padding:
|
|
1354
|
-
t.save(), t.font = `${
|
|
1372
|
+
render(t, i, e, n, s) {
|
|
1373
|
+
const { padding: o } = n, l = e.x + o.left, h = e.y + o.top, a = k(i, "x"), r = k(i, "y");
|
|
1374
|
+
t.save(), t.font = `${s.contentFontSize}px ${s.fontFamily}`, t.textAlign = "left", t.textBaseline = "top", t.fillStyle = s.textSecondaryColor, t.fillText(a, l, h);
|
|
1355
1375
|
const d = t.measureText(a).width;
|
|
1356
1376
|
t.fillStyle = i.seriesColor, t.fillText(" ▪ ", l + d, h);
|
|
1357
|
-
const
|
|
1358
|
-
t.fillStyle =
|
|
1377
|
+
const f = t.measureText(" ▪ ").width;
|
|
1378
|
+
t.fillStyle = s.textColor, t.fillText(r, l + d + f, h), t.restore();
|
|
1359
1379
|
}
|
|
1360
1380
|
}
|
|
1361
|
-
const
|
|
1381
|
+
const at = new It(), F = {
|
|
1362
1382
|
INDICATOR_MARGIN: 8,
|
|
1363
1383
|
MIN_LABEL_WIDTH: 60,
|
|
1364
1384
|
LINE_SPACING: 2,
|
|
@@ -1366,13 +1386,7 @@ const tt = new Tt(), F = {
|
|
|
1366
1386
|
HEADER_SPACING: 2,
|
|
1367
1387
|
GAP_SPACING: 2
|
|
1368
1388
|
};
|
|
1369
|
-
|
|
1370
|
-
if (f == null || isNaN(f))
|
|
1371
|
-
return "N/A";
|
|
1372
|
-
const t = Math.abs(f);
|
|
1373
|
-
return t === 0 ? "0" : t < 1e-4 || t >= 1e4 ? f.toExponential(2) : t < 0.01 ? f.toPrecision(3) : t < 1 ? f.toFixed(4) : t < 100 ? f.toFixed(3) : f.toFixed(1);
|
|
1374
|
-
}
|
|
1375
|
-
class wt {
|
|
1389
|
+
class zt {
|
|
1376
1390
|
constructor() {
|
|
1377
1391
|
u(this, "id", "crosshair");
|
|
1378
1392
|
u(this, "name", "Multi-Series Crosshair");
|
|
@@ -1403,10 +1417,10 @@ class wt {
|
|
|
1403
1417
|
*/
|
|
1404
1418
|
formatData(t) {
|
|
1405
1419
|
return {
|
|
1406
|
-
header: `⌖ X = ${
|
|
1420
|
+
header: `⌖ X = ${Ct(t)}`,
|
|
1407
1421
|
series: t.interpolatedValues.map((i) => ({
|
|
1408
1422
|
name: i.seriesName,
|
|
1409
|
-
value:
|
|
1423
|
+
value: Pt(i.y, t),
|
|
1410
1424
|
color: i.seriesColor,
|
|
1411
1425
|
isInterpolated: i.isInterpolated
|
|
1412
1426
|
}))
|
|
@@ -1426,16 +1440,16 @@ class wt {
|
|
|
1426
1440
|
if (n === this.cachedKey && this.cachedMeasurement)
|
|
1427
1441
|
return this.cachedMeasurement;
|
|
1428
1442
|
this.formattedData = this.formatData(i), t.font = `${e.titleFontWeight} ${e.titleFontSize}px ${e.fontFamily}`;
|
|
1429
|
-
let
|
|
1443
|
+
let s = t.measureText(this.formattedData.header).width;
|
|
1430
1444
|
t.font = `400 ${e.contentFontSize}px ${e.fontFamily}`;
|
|
1431
|
-
const
|
|
1445
|
+
const o = e.showSeriesIndicator ? e.seriesIndicatorSize + F.INDICATOR_MARGIN : 0;
|
|
1432
1446
|
for (const r of this.formattedData.series) {
|
|
1433
|
-
const d = t.measureText(`${r.name}:`).width,
|
|
1434
|
-
|
|
1447
|
+
const d = t.measureText(`${r.name}:`).width, f = t.measureText(r.value).width, p = o + Math.max(d, F.MIN_LABEL_WIDTH) + f;
|
|
1448
|
+
s = Math.max(s, p);
|
|
1435
1449
|
}
|
|
1436
1450
|
const l = e.titleFontSize * e.lineHeight, a = this.formattedData.series.length * (e.contentFontSize * e.lineHeight + F.LINE_SPACING);
|
|
1437
1451
|
return this.cachedMeasurement = {
|
|
1438
|
-
width:
|
|
1452
|
+
width: s + F.SAFETY_BUFFER,
|
|
1439
1453
|
height: l + e.headerGap + a,
|
|
1440
1454
|
padding: e.padding
|
|
1441
1455
|
}, this.cachedKey = n, this.cachedMeasurement;
|
|
@@ -1443,34 +1457,34 @@ class wt {
|
|
|
1443
1457
|
/**
|
|
1444
1458
|
* Render the tooltip
|
|
1445
1459
|
*/
|
|
1446
|
-
render(t, i, e, n,
|
|
1460
|
+
render(t, i, e, n, s) {
|
|
1447
1461
|
if (!i.interpolatedValues || i.interpolatedValues.length === 0)
|
|
1448
1462
|
return;
|
|
1449
|
-
const
|
|
1463
|
+
const o = this.formattedData || this.formatData(i), { x: l, y: h } = e, { padding: a } = s;
|
|
1450
1464
|
let r = h + a.top;
|
|
1451
1465
|
const d = l + a.left;
|
|
1452
|
-
t.save(), t.textAlign = "left", t.textBaseline = "top", t.font = `${
|
|
1453
|
-
for (const
|
|
1454
|
-
let
|
|
1455
|
-
if (
|
|
1456
|
-
const b = r +
|
|
1457
|
-
t.save(), t.beginPath(), t.arc(
|
|
1466
|
+
t.save(), t.textAlign = "left", t.textBaseline = "top", t.font = `${s.titleFontWeight} ${s.titleFontSize}px ${s.fontFamily}`, t.fillStyle = s.textColor, t.fillText(o.header, d, r), r += s.titleFontSize * s.lineHeight + F.HEADER_SPACING, s.showHeaderSeparator && (t.strokeStyle = s.separatorColor, t.lineWidth = 1, t.globalAlpha = 0.4, t.beginPath(), t.moveTo(d, r + s.headerGap / 2), t.lineTo(d + n.width, r + s.headerGap / 2), t.stroke(), t.globalAlpha = 1), r += s.headerGap + F.GAP_SPACING, t.font = `400 ${s.contentFontSize}px ${s.fontFamily}`;
|
|
1467
|
+
for (const f of o.series) {
|
|
1468
|
+
let p = d;
|
|
1469
|
+
if (s.showSeriesIndicator && s.seriesIndicatorSize > 0) {
|
|
1470
|
+
const b = r + s.contentFontSize / 2, x = s.seriesIndicatorSize / 2;
|
|
1471
|
+
t.save(), t.beginPath(), t.arc(p + x, b, x, 0, Math.PI * 2), f.isInterpolated ? (t.strokeStyle = f.color, t.lineWidth = 1.5, t.stroke()) : (t.fillStyle = f.color, t.fill()), t.restore(), p += s.seriesIndicatorSize + F.INDICATOR_MARGIN;
|
|
1458
1472
|
}
|
|
1459
|
-
t.fillStyle =
|
|
1460
|
-
const g = t.measureText(`${
|
|
1461
|
-
t.fillStyle =
|
|
1473
|
+
t.fillStyle = s.textSecondaryColor, t.fillText(`${f.name}:`, p, r);
|
|
1474
|
+
const g = t.measureText(`${f.name}: `).width, y = Math.max(g, F.MIN_LABEL_WIDTH);
|
|
1475
|
+
t.fillStyle = s.textColor, t.fillText(f.value, p + y, r), r += s.contentFontSize * s.lineHeight + F.LINE_SPACING;
|
|
1462
1476
|
}
|
|
1463
1477
|
t.restore();
|
|
1464
1478
|
}
|
|
1465
1479
|
}
|
|
1466
|
-
const
|
|
1467
|
-
function P(
|
|
1468
|
-
if (
|
|
1480
|
+
const G = new zt();
|
|
1481
|
+
function P(c) {
|
|
1482
|
+
if (c == null || isNaN(c))
|
|
1469
1483
|
return "N/A";
|
|
1470
|
-
const t = Math.abs(
|
|
1471
|
-
return t === 0 ? "0" : t < 1e-4 || t >= 1e4 ?
|
|
1484
|
+
const t = Math.abs(c);
|
|
1485
|
+
return t === 0 ? "0" : t < 1e-4 || t >= 1e4 ? c.toExponential(3) : t < 0.01 ? c.toPrecision(4) : t < 1 ? c.toFixed(4) : t < 100 ? c.toFixed(3) : c.toFixed(2);
|
|
1472
1486
|
}
|
|
1473
|
-
class
|
|
1487
|
+
class Yt {
|
|
1474
1488
|
constructor() {
|
|
1475
1489
|
u(this, "id", "heatmap");
|
|
1476
1490
|
u(this, "name", "Heatmap Value");
|
|
@@ -1490,53 +1504,61 @@ class mt {
|
|
|
1490
1504
|
if (n === this.cachedKey && this.cachedMeasurement)
|
|
1491
1505
|
return this.cachedMeasurement;
|
|
1492
1506
|
t.font = `${e.titleFontWeight} ${e.titleFontSize}px ${e.fontFamily}`;
|
|
1493
|
-
const
|
|
1494
|
-
let
|
|
1507
|
+
const s = `Grid [${i.xIndex}, ${i.yIndex}]`;
|
|
1508
|
+
let o = t.measureText(s).width;
|
|
1495
1509
|
t.font = `400 ${e.contentFontSize}px ${e.fontFamily}`;
|
|
1496
1510
|
const l = `Value: ${P(i.zValue)}`, h = this.swatchSize + this.swatchGap + t.measureText(l).width;
|
|
1497
|
-
if (
|
|
1511
|
+
if (o = Math.max(o, h), i.colorScale) {
|
|
1498
1512
|
const y = `Min: ${P(i.colorScale.min)} Max: ${P(i.colorScale.max)}`;
|
|
1499
|
-
|
|
1513
|
+
o = Math.max(o, this.swatchSize + this.swatchGap + t.measureText(y).width);
|
|
1500
1514
|
}
|
|
1501
1515
|
const a = 25, r = a + t.measureText(P(i.dataX)).width, d = a + t.measureText(P(i.dataY)).width;
|
|
1502
|
-
|
|
1503
|
-
const
|
|
1516
|
+
o = Math.max(o, r, d);
|
|
1517
|
+
const f = e.titleFontSize * e.lineHeight, g = (i.colorScale ? 4 : 3) * e.contentFontSize * e.lineHeight;
|
|
1504
1518
|
return this.cachedMeasurement = {
|
|
1505
|
-
width:
|
|
1519
|
+
width: o + 4,
|
|
1506
1520
|
// Small buffer
|
|
1507
|
-
height:
|
|
1521
|
+
height: f + e.headerGap + g + e.itemGap,
|
|
1508
1522
|
padding: e.padding
|
|
1509
1523
|
}, this.cachedKey = n, this.cachedMeasurement;
|
|
1510
1524
|
}
|
|
1511
1525
|
/**
|
|
1512
1526
|
* Render the tooltip
|
|
1513
1527
|
*/
|
|
1514
|
-
render(t, i, e, n,
|
|
1515
|
-
const { x:
|
|
1528
|
+
render(t, i, e, n, s) {
|
|
1529
|
+
const { x: o, y: l } = e, { padding: h } = s;
|
|
1516
1530
|
let a = l + h.top;
|
|
1517
|
-
const r =
|
|
1518
|
-
t.save(), t.textAlign = "left", t.textBaseline = "top", t.font = `${
|
|
1531
|
+
const r = o + h.left;
|
|
1532
|
+
t.save(), t.textAlign = "left", t.textBaseline = "top", t.font = `${s.titleFontWeight} ${s.titleFontSize}px ${s.fontFamily}`, t.fillStyle = s.textColor;
|
|
1519
1533
|
const d = `Grid [${i.xIndex}, ${i.yIndex}]`;
|
|
1520
|
-
t.fillText(d, r, a), a +=
|
|
1521
|
-
const
|
|
1522
|
-
t.fillStyle = i.mappedColor ||
|
|
1523
|
-
const
|
|
1524
|
-
if (t.fillText(P(i.zValue), r + this.swatchSize + this.swatchGap +
|
|
1525
|
-
t.fillStyle =
|
|
1534
|
+
t.fillText(d, r, a), a += s.titleFontSize * s.lineHeight + 2, s.showHeaderSeparator && (t.strokeStyle = s.separatorColor, t.lineWidth = 1, t.globalAlpha = 0.4, t.beginPath(), t.moveTo(r, a + s.headerGap / 2), t.lineTo(r + n.width, a + s.headerGap / 2), t.stroke(), t.globalAlpha = 1), a += s.headerGap + 2, t.font = `400 ${s.contentFontSize}px ${s.fontFamily}`;
|
|
1535
|
+
const f = a + (s.contentFontSize * s.lineHeight - this.swatchSize) / 2;
|
|
1536
|
+
t.fillStyle = i.mappedColor || s.textColor, t.fillRect(r, f, this.swatchSize, this.swatchSize), t.strokeStyle = s.separatorColor, t.lineWidth = 1, t.strokeRect(r, f, this.swatchSize, this.swatchSize), t.fillStyle = s.textSecondaryColor, t.fillText("Value:", r + this.swatchSize + this.swatchGap, a), t.fillStyle = s.textColor;
|
|
1537
|
+
const p = t.measureText("Value: ").width;
|
|
1538
|
+
if (t.fillText(P(i.zValue), r + this.swatchSize + this.swatchGap + p, a), a += s.contentFontSize * s.lineHeight, i.colorScale) {
|
|
1539
|
+
t.fillStyle = s.textSecondaryColor, t.font = `400 ${s.contentFontSize - 1}px ${s.fontFamily}`;
|
|
1526
1540
|
const g = `Min: ${P(i.colorScale.min)} Max: ${P(i.colorScale.max)}`;
|
|
1527
|
-
t.fillText(g, r + this.swatchSize + this.swatchGap, a), a +=
|
|
1541
|
+
t.fillText(g, r + this.swatchSize + this.swatchGap, a), a += s.contentFontSize * s.lineHeight;
|
|
1528
1542
|
}
|
|
1529
|
-
a +=
|
|
1543
|
+
a += s.itemGap + 2, t.font = `400 ${s.contentFontSize}px ${s.fontFamily}`, t.fillStyle = s.textSecondaryColor, t.fillText("X:", r, a), t.fillStyle = s.textColor, t.fillText(P(i.dataX), r + 25, a), a += s.contentFontSize * s.lineHeight + 2, t.fillStyle = s.textSecondaryColor, t.fillText("Y:", r, a), t.fillStyle = s.textColor, t.fillText(P(i.dataY), r + 25, a), t.restore();
|
|
1530
1544
|
}
|
|
1531
1545
|
}
|
|
1532
|
-
const
|
|
1533
|
-
function
|
|
1534
|
-
|
|
1546
|
+
const _ = new Yt();
|
|
1547
|
+
function Q(c) {
|
|
1548
|
+
var t, i;
|
|
1549
|
+
return ((i = (t = c.axisFormat) == null ? void 0 : t.x) == null ? void 0 : i.type) === "time" ? ot(c) : E(c.dataX);
|
|
1550
|
+
}
|
|
1551
|
+
function Z(c) {
|
|
1552
|
+
var t, i;
|
|
1553
|
+
return ((i = (t = c.axisFormat) == null ? void 0 : t.y) == null ? void 0 : i.scientific) === !1 ? nt(c) : E(c.dataY);
|
|
1554
|
+
}
|
|
1555
|
+
function E(c, t = 3) {
|
|
1556
|
+
if (c == null || isNaN(c))
|
|
1535
1557
|
return "N/A";
|
|
1536
|
-
if (
|
|
1537
|
-
const i = Math.floor(Math.log10(Math.abs(
|
|
1558
|
+
if (c === 0) return "0";
|
|
1559
|
+
const i = Math.floor(Math.log10(Math.abs(c))), e = c / Math.pow(10, i);
|
|
1538
1560
|
if (Math.abs(i) <= 2)
|
|
1539
|
-
return
|
|
1561
|
+
return c.toPrecision(t);
|
|
1540
1562
|
const n = {
|
|
1541
1563
|
0: "⁰",
|
|
1542
1564
|
1: "¹",
|
|
@@ -1550,13 +1572,13 @@ function X(f, t = 3) {
|
|
|
1550
1572
|
9: "⁹",
|
|
1551
1573
|
"-": "⁻",
|
|
1552
1574
|
"+": "⁺"
|
|
1553
|
-
},
|
|
1554
|
-
let
|
|
1555
|
-
for (const l of
|
|
1556
|
-
|
|
1557
|
-
return `${e.toFixed(t - 1)} × 10${
|
|
1575
|
+
}, s = i.toString();
|
|
1576
|
+
let o = "";
|
|
1577
|
+
for (const l of s)
|
|
1578
|
+
o += n[l] || l;
|
|
1579
|
+
return `${e.toFixed(t - 1)} × 10${o}`;
|
|
1558
1580
|
}
|
|
1559
|
-
class
|
|
1581
|
+
class At {
|
|
1560
1582
|
constructor() {
|
|
1561
1583
|
u(this, "id", "scientific");
|
|
1562
1584
|
u(this, "name", "Scientific Notation");
|
|
@@ -1573,58 +1595,58 @@ class Mt {
|
|
|
1573
1595
|
if (n === this.cachedKey && this.cachedMeasurement)
|
|
1574
1596
|
return this.cachedMeasurement;
|
|
1575
1597
|
t.font = `${e.titleFontWeight} ${e.titleFontSize}px ${e.fontFamily}`;
|
|
1576
|
-
const
|
|
1598
|
+
const s = t.measureText(i.seriesName).width + (e.showSeriesIndicator ? e.seriesIndicatorSize + 8 : 0);
|
|
1577
1599
|
t.font = `400 ${e.contentFontSize}px ${e.fontFamily}`;
|
|
1578
|
-
const
|
|
1579
|
-
let h = Math.max(
|
|
1580
|
-
const a =
|
|
1581
|
-
let r =
|
|
1582
|
-
i.yError && (r += t.measureText(` ± ${
|
|
1600
|
+
const o = 28, l = Q(i);
|
|
1601
|
+
let h = Math.max(s, o + t.measureText(l).width);
|
|
1602
|
+
const a = Z(i);
|
|
1603
|
+
let r = o + t.measureText(a).width;
|
|
1604
|
+
i.yError && (r += t.measureText(` ± ${E(i.yError[0])}`).width), h = Math.max(h, r);
|
|
1583
1605
|
let d = `Index: ${i.dataIndex}`;
|
|
1584
1606
|
i.cycle !== void 0 && (d += ` │ Cycle: ${i.cycle}`), h = Math.max(h, t.measureText(d).width);
|
|
1585
|
-
let
|
|
1586
|
-
(i.cycle !== void 0 || i.yError) && (
|
|
1587
|
-
const
|
|
1607
|
+
let f = 3;
|
|
1608
|
+
(i.cycle !== void 0 || i.yError) && (f += 1);
|
|
1609
|
+
const p = e.titleFontSize * e.lineHeight + e.headerGap, g = (f - 1) * e.contentFontSize * e.lineHeight, y = i.cycle !== void 0 ? e.itemGap : 0;
|
|
1588
1610
|
return this.cachedMeasurement = {
|
|
1589
1611
|
width: h,
|
|
1590
|
-
height:
|
|
1612
|
+
height: p + g + y,
|
|
1591
1613
|
padding: e.padding
|
|
1592
1614
|
}, this.cachedKey = n, this.cachedMeasurement;
|
|
1593
1615
|
}
|
|
1594
1616
|
/**
|
|
1595
1617
|
* Render the tooltip
|
|
1596
1618
|
*/
|
|
1597
|
-
render(t, i, e, n,
|
|
1598
|
-
const { x:
|
|
1599
|
-
let a = l + h.top, r =
|
|
1600
|
-
if (t.save(), t.textAlign = "left", t.textBaseline = "top",
|
|
1601
|
-
const
|
|
1602
|
-
t.fillStyle = i.seriesColor, t.beginPath(), t.arc(r +
|
|
1619
|
+
render(t, i, e, n, s) {
|
|
1620
|
+
const { x: o, y: l } = e, { padding: h } = s;
|
|
1621
|
+
let a = l + h.top, r = o + h.left;
|
|
1622
|
+
if (t.save(), t.textAlign = "left", t.textBaseline = "top", s.showSeriesIndicator) {
|
|
1623
|
+
const p = a + s.titleFontSize / 2;
|
|
1624
|
+
t.fillStyle = i.seriesColor, t.beginPath(), t.arc(r + s.seriesIndicatorSize / 2, p, s.seriesIndicatorSize / 2, 0, Math.PI * 2), t.fill(), r += s.seriesIndicatorSize + 8;
|
|
1603
1625
|
}
|
|
1604
|
-
t.font = `${
|
|
1626
|
+
t.font = `${s.titleFontWeight} ${s.titleFontSize}px ${s.fontFamily}`, t.fillStyle = s.textColor, t.fillText(i.seriesName, r, a), a += s.titleFontSize * s.lineHeight + 2, r = o + h.left, s.showHeaderSeparator && (t.strokeStyle = s.separatorColor, t.lineWidth = 1, t.globalAlpha = 0.4, t.beginPath(), t.moveTo(r, a + s.headerGap / 2), t.lineTo(r + n.width, a + s.headerGap / 2), t.stroke(), t.globalAlpha = 1), a += s.headerGap + 2, t.font = `400 ${s.contentFontSize}px ${s.fontFamily}`;
|
|
1605
1627
|
const d = 28;
|
|
1606
|
-
t.fillStyle =
|
|
1607
|
-
let
|
|
1608
|
-
if (t.fillText(
|
|
1609
|
-
const
|
|
1610
|
-
t.fillStyle =
|
|
1628
|
+
t.fillStyle = s.textSecondaryColor, t.fillText("X:", r, a), t.fillStyle = s.textColor, t.fillText(Q(i), r + d, a), a += s.contentFontSize * s.lineHeight + 2, t.fillStyle = s.textSecondaryColor, t.fillText("Y:", r, a), t.fillStyle = s.textColor;
|
|
1629
|
+
let f = Z(i);
|
|
1630
|
+
if (t.fillText(f, r + d, a), i.yError) {
|
|
1631
|
+
const p = t.measureText(f).width;
|
|
1632
|
+
t.fillStyle = s.textSecondaryColor, t.fillText(` ± ${E(i.yError[0])}`, r + d + p, a);
|
|
1611
1633
|
}
|
|
1612
|
-
if (a +=
|
|
1613
|
-
a +=
|
|
1614
|
-
let
|
|
1615
|
-
i.cycle !== void 0 && (
|
|
1634
|
+
if (a += s.contentFontSize * s.lineHeight + 2, i.cycle !== void 0) {
|
|
1635
|
+
a += s.itemGap, t.strokeStyle = s.separatorColor, t.globalAlpha = 0.3, t.beginPath(), t.moveTo(r, a - s.itemGap / 2), t.lineTo(r + n.width, a - s.itemGap / 2), t.stroke(), t.globalAlpha = 1, t.fillStyle = s.textSecondaryColor, t.font = `400 ${s.contentFontSize - 1}px ${s.fontFamily}`;
|
|
1636
|
+
let p = `Index: ${i.dataIndex}`;
|
|
1637
|
+
i.cycle !== void 0 && (p += ` │ Cycle: ${i.cycle}`), t.fillText(p, r, a);
|
|
1616
1638
|
}
|
|
1617
1639
|
t.restore();
|
|
1618
1640
|
}
|
|
1619
1641
|
}
|
|
1620
|
-
const
|
|
1621
|
-
function
|
|
1622
|
-
if (
|
|
1642
|
+
const lt = new At();
|
|
1643
|
+
function X(c) {
|
|
1644
|
+
if (c == null || isNaN(c))
|
|
1623
1645
|
return "N/A";
|
|
1624
|
-
const t = Math.abs(
|
|
1625
|
-
return t === 0 ? "0" : t < 1e-4 || t >= 1e4 ?
|
|
1646
|
+
const t = Math.abs(c);
|
|
1647
|
+
return t === 0 ? "0" : t < 1e-4 || t >= 1e4 ? c.toExponential(2) : t < 1 ? c.toFixed(4) : c.toFixed(2);
|
|
1626
1648
|
}
|
|
1627
|
-
class
|
|
1649
|
+
class Xt {
|
|
1628
1650
|
constructor() {
|
|
1629
1651
|
u(this, "id", "annotation");
|
|
1630
1652
|
u(this, "name", "Annotation Info");
|
|
@@ -1641,22 +1663,22 @@ class Ct {
|
|
|
1641
1663
|
if (n === this.cachedKey && this.cachedMeasurement)
|
|
1642
1664
|
return this.cachedMeasurement;
|
|
1643
1665
|
t.font = `${e.titleFontWeight} ${e.titleFontSize}px ${e.fontFamily}`;
|
|
1644
|
-
const
|
|
1645
|
-
let
|
|
1666
|
+
const s = i.label || `Annotation: ${i.annotationType}`;
|
|
1667
|
+
let o = t.measureText(s).width;
|
|
1646
1668
|
t.font = `400 ${e.contentFontSize}px ${e.fontFamily}`;
|
|
1647
1669
|
let l = 0;
|
|
1648
1670
|
const h = 50;
|
|
1649
1671
|
if (i.value !== void 0) {
|
|
1650
|
-
const r =
|
|
1651
|
-
|
|
1672
|
+
const r = X(i.value);
|
|
1673
|
+
o = Math.max(o, h + t.measureText(r).width), l += e.contentFontSize * e.lineHeight;
|
|
1652
1674
|
}
|
|
1653
1675
|
if (i.valueX !== void 0 && i.valueY !== void 0) {
|
|
1654
|
-
const r =
|
|
1655
|
-
|
|
1676
|
+
const r = X(i.valueX), d = X(i.valueY);
|
|
1677
|
+
o = Math.max(o, h + t.measureText(r).width, h + t.measureText(d).width), l += e.contentFontSize * e.lineHeight * 2;
|
|
1656
1678
|
}
|
|
1657
1679
|
const a = e.titleFontSize * e.lineHeight + e.headerGap;
|
|
1658
1680
|
return this.cachedMeasurement = {
|
|
1659
|
-
width:
|
|
1681
|
+
width: o + 10,
|
|
1660
1682
|
height: a + l + 4,
|
|
1661
1683
|
padding: e.padding
|
|
1662
1684
|
}, this.cachedKey = n, this.cachedMeasurement;
|
|
@@ -1664,25 +1686,25 @@ class Ct {
|
|
|
1664
1686
|
/**
|
|
1665
1687
|
* Render the tooltip
|
|
1666
1688
|
*/
|
|
1667
|
-
render(t, i, e, n,
|
|
1668
|
-
const { x:
|
|
1689
|
+
render(t, i, e, n, s) {
|
|
1690
|
+
const { x: o, y: l } = e, { padding: h } = s;
|
|
1669
1691
|
let a = l + h.top;
|
|
1670
|
-
const r =
|
|
1671
|
-
t.save(), t.textAlign = "left", t.textBaseline = "top", t.font = `${
|
|
1692
|
+
const r = o + h.left;
|
|
1693
|
+
t.save(), t.textAlign = "left", t.textBaseline = "top", t.font = `${s.titleFontWeight} ${s.titleFontSize}px ${s.fontFamily}`, t.fillStyle = s.textColor;
|
|
1672
1694
|
const d = i.label || `${i.annotationType.toUpperCase()}`;
|
|
1673
|
-
t.fillText(d, r, a), a +=
|
|
1674
|
-
const
|
|
1675
|
-
i.value !== void 0 && (t.fillStyle =
|
|
1695
|
+
t.fillText(d, r, a), a += s.titleFontSize * s.lineHeight + 2, s.showHeaderSeparator && (t.strokeStyle = s.separatorColor, t.globalAlpha = 0.4, t.beginPath(), t.moveTo(r, a + s.headerGap / 2), t.lineTo(r + n.width, a + s.headerGap / 2), t.stroke(), t.globalAlpha = 1), a += s.headerGap + 2, t.font = `400 ${s.contentFontSize}px ${s.fontFamily}`;
|
|
1696
|
+
const f = 50;
|
|
1697
|
+
i.value !== void 0 && (t.fillStyle = s.textSecondaryColor, t.fillText("Value:", r, a), t.fillStyle = s.textColor, t.fillText(X(i.value), r + f, a), a += s.contentFontSize * s.lineHeight), i.valueX !== void 0 && i.valueY !== void 0 && (t.fillStyle = s.textSecondaryColor, t.fillText("X:", r, a), t.fillStyle = s.textColor, t.fillText(X(i.valueX), r + f, a), a += s.contentFontSize * s.lineHeight, t.fillStyle = s.textSecondaryColor, t.fillText("Y:", r, a), t.fillStyle = s.textColor, t.fillText(X(i.valueY), r + f, a)), t.restore();
|
|
1676
1698
|
}
|
|
1677
1699
|
}
|
|
1678
|
-
const
|
|
1679
|
-
function M(
|
|
1680
|
-
if (
|
|
1700
|
+
const K = new Xt();
|
|
1701
|
+
function M(c) {
|
|
1702
|
+
if (c == null || isNaN(c))
|
|
1681
1703
|
return "N/A";
|
|
1682
|
-
const t = Math.abs(
|
|
1683
|
-
return t === 0 ? "0" : t < 1e-4 || t >= 1e4 ?
|
|
1704
|
+
const t = Math.abs(c);
|
|
1705
|
+
return t === 0 ? "0" : t < 1e-4 || t >= 1e4 ? c.toExponential(3) : t < 1 ? c.toFixed(4) : c.toFixed(3);
|
|
1684
1706
|
}
|
|
1685
|
-
class
|
|
1707
|
+
class $t {
|
|
1686
1708
|
constructor() {
|
|
1687
1709
|
u(this, "id", "range");
|
|
1688
1710
|
u(this, "name", "Range Statistics");
|
|
@@ -1695,8 +1717,8 @@ class vt {
|
|
|
1695
1717
|
* Measure tooltip dimensions
|
|
1696
1718
|
*/
|
|
1697
1719
|
measure(t, i, e) {
|
|
1698
|
-
const n = i.statistics,
|
|
1699
|
-
if (
|
|
1720
|
+
const n = i.statistics, s = `${i.xMin}-${i.xMax}-${n.count}-${n.mean}-${e.fontFamily}`;
|
|
1721
|
+
if (s === this.cachedKey && this.cachedMeasurement)
|
|
1700
1722
|
return this.cachedMeasurement;
|
|
1701
1723
|
t.font = `${e.titleFontWeight} ${e.titleFontSize}px ${e.fontFamily}`;
|
|
1702
1724
|
let l = t.measureText("Range Statistics").width;
|
|
@@ -1715,51 +1737,51 @@ class vt {
|
|
|
1715
1737
|
width: Math.max(l, 140),
|
|
1716
1738
|
height: r + h + 10,
|
|
1717
1739
|
padding: e.padding
|
|
1718
|
-
}, this.cachedKey =
|
|
1740
|
+
}, this.cachedKey = s, this.cachedMeasurement;
|
|
1719
1741
|
}
|
|
1720
1742
|
/**
|
|
1721
1743
|
* Render the tooltip
|
|
1722
1744
|
*/
|
|
1723
|
-
render(t, i, e, n,
|
|
1724
|
-
const { x:
|
|
1745
|
+
render(t, i, e, n, s) {
|
|
1746
|
+
const { x: o, y: l } = e, { padding: h } = s, a = i.statistics;
|
|
1725
1747
|
let r = l + h.top;
|
|
1726
|
-
const d =
|
|
1727
|
-
t.save(), t.textAlign = "left", t.textBaseline = "top", t.font = `${
|
|
1728
|
-
const
|
|
1729
|
-
t.fillStyle =
|
|
1748
|
+
const d = o + h.left;
|
|
1749
|
+
t.save(), t.textAlign = "left", t.textBaseline = "top", t.font = `${s.titleFontWeight} ${s.titleFontSize}px ${s.fontFamily}`, t.fillStyle = s.textColor, t.fillText("Range Statistics", d, r), r += s.titleFontSize * s.lineHeight + 2, s.showHeaderSeparator && (t.strokeStyle = s.separatorColor, t.globalAlpha = 0.4, t.beginPath(), t.moveTo(d, r + s.headerGap / 2), t.lineTo(d + n.width, r + s.headerGap / 2), t.stroke(), t.globalAlpha = 1), r += s.headerGap + 2, t.font = `400 ${s.contentFontSize}px ${s.fontFamily}`;
|
|
1750
|
+
const f = 60, p = (g, y) => {
|
|
1751
|
+
t.fillStyle = s.textSecondaryColor, t.fillText(g, d, r), t.fillStyle = s.textColor, t.fillText(String(y), d + f, r), r += s.contentFontSize * s.lineHeight;
|
|
1730
1752
|
};
|
|
1731
|
-
|
|
1753
|
+
p("Points:", a.count), a.min !== void 0 && p("Min:", M(a.min)), a.max !== void 0 && p("Max:", M(a.max)), a.mean !== void 0 && p("Mean:", M(a.mean)), a.stdDev !== void 0 && p("StdDev:", M(a.stdDev)), a.area !== void 0 && p("Area:", M(a.area)), a.peakX !== void 0 && (r += 4, t.fillStyle = s.textSecondaryColor, t.font = `italic ${s.contentFontSize - 1}px ${s.fontFamily}`, t.fillText(`Peak: ${M(a.peakY ?? 0)} at X=${M(a.peakX)}`, d, r)), t.restore();
|
|
1732
1754
|
}
|
|
1733
1755
|
}
|
|
1734
|
-
const
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1756
|
+
const U = new $t(), Dt = [
|
|
1757
|
+
H,
|
|
1758
|
+
at,
|
|
1759
|
+
G,
|
|
1760
|
+
_,
|
|
1761
|
+
lt,
|
|
1762
|
+
K,
|
|
1763
|
+
U
|
|
1742
1764
|
];
|
|
1743
|
-
function
|
|
1744
|
-
return
|
|
1765
|
+
function Bt(c) {
|
|
1766
|
+
return Dt.find((t) => t.id === c);
|
|
1745
1767
|
}
|
|
1746
|
-
function
|
|
1747
|
-
switch (
|
|
1768
|
+
function tt(c) {
|
|
1769
|
+
switch (c) {
|
|
1748
1770
|
case "datapoint":
|
|
1749
|
-
return
|
|
1771
|
+
return H;
|
|
1750
1772
|
case "crosshair":
|
|
1751
|
-
return
|
|
1773
|
+
return G;
|
|
1752
1774
|
case "heatmap":
|
|
1753
|
-
return
|
|
1775
|
+
return _;
|
|
1754
1776
|
case "annotation":
|
|
1755
|
-
return
|
|
1777
|
+
return K;
|
|
1756
1778
|
case "range":
|
|
1757
|
-
return
|
|
1779
|
+
return U;
|
|
1758
1780
|
default:
|
|
1759
|
-
return
|
|
1781
|
+
return H;
|
|
1760
1782
|
}
|
|
1761
1783
|
}
|
|
1762
|
-
class
|
|
1784
|
+
class kt {
|
|
1763
1785
|
constructor(t) {
|
|
1764
1786
|
u(this, "ctx");
|
|
1765
1787
|
u(this, "getPlotArea");
|
|
@@ -1768,12 +1790,15 @@ class Ft {
|
|
|
1768
1790
|
u(this, "pixelToDataY");
|
|
1769
1791
|
u(this, "getXScale");
|
|
1770
1792
|
u(this, "getYScales");
|
|
1793
|
+
u(this, "getViewBounds");
|
|
1794
|
+
u(this, "getXAxisOptions");
|
|
1795
|
+
u(this, "getYAxisOptions");
|
|
1771
1796
|
u(this, "options");
|
|
1772
1797
|
u(this, "theme");
|
|
1773
1798
|
u(this, "positioner");
|
|
1774
1799
|
u(this, "renderer");
|
|
1775
1800
|
u(this, "templates", /* @__PURE__ */ new Map());
|
|
1776
|
-
u(this, "events", new
|
|
1801
|
+
u(this, "events", new ut());
|
|
1777
1802
|
u(this, "activeTooltips", /* @__PURE__ */ new Map());
|
|
1778
1803
|
u(this, "tooltipIdCounter", 0);
|
|
1779
1804
|
u(this, "showTimeoutId", null);
|
|
@@ -1792,7 +1817,7 @@ class Ft {
|
|
|
1792
1817
|
// Suspended state - used during drag operations to hide tooltip
|
|
1793
1818
|
u(this, "suspended", !1);
|
|
1794
1819
|
var i;
|
|
1795
|
-
this.ctx = t.overlayCtx, this.getPlotArea = t.getPlotArea, this.getSeries = t.getSeries, this.pixelToDataX = t.pixelToDataX, this.pixelToDataY = t.pixelToDataY, this.getXScale = t.getXScale, this.getYScales = t.getYScales, this.options = {
|
|
1820
|
+
this.ctx = t.overlayCtx, this.getPlotArea = t.getPlotArea, this.getSeries = t.getSeries, this.pixelToDataX = t.pixelToDataX, this.pixelToDataY = t.pixelToDataY, this.getXScale = t.getXScale, this.getYScales = t.getYScales, this.getViewBounds = t.getViewBounds, this.getXAxisOptions = t.getXAxisOptions, this.getYAxisOptions = t.getYAxisOptions, this.options = {
|
|
1796
1821
|
enabled: !0,
|
|
1797
1822
|
showDelay: 50,
|
|
1798
1823
|
hideDelay: 100,
|
|
@@ -1829,7 +1854,7 @@ class Ft {
|
|
|
1829
1854
|
constrainToPlotArea: !0,
|
|
1830
1855
|
constrainToContainer: !0,
|
|
1831
1856
|
autoFlip: !0
|
|
1832
|
-
}, this.theme = (i = t.options) != null && i.theme ? typeof t.options.theme == "string" ?
|
|
1857
|
+
}, this.theme = (i = t.options) != null && i.theme ? typeof t.options.theme == "string" ? B(t.options.theme) : mt(Tt, t.options.theme) : B(t.chartTheme.name), this.positioner = new Mt({
|
|
1833
1858
|
offset: this.options.offset,
|
|
1834
1859
|
preferredPosition: this.options.preferredPosition,
|
|
1835
1860
|
constrainToPlotArea: this.options.constrainToPlotArea,
|
|
@@ -1837,7 +1862,7 @@ class Ft {
|
|
|
1837
1862
|
autoFlip: this.options.autoFlip,
|
|
1838
1863
|
showArrow: this.theme.showArrow,
|
|
1839
1864
|
arrowSize: this.theme.arrowSize
|
|
1840
|
-
}), this.renderer = new
|
|
1865
|
+
}), this.renderer = new vt(this.ctx, this.theme), this.registerBuiltinTemplates(), t.options && this.configure(t.options);
|
|
1841
1866
|
}
|
|
1842
1867
|
/**
|
|
1843
1868
|
* Register built-in templates
|
|
@@ -1845,25 +1870,25 @@ class Ft {
|
|
|
1845
1870
|
registerBuiltinTemplates() {
|
|
1846
1871
|
this.templates.set(
|
|
1847
1872
|
"default",
|
|
1848
|
-
|
|
1873
|
+
H
|
|
1849
1874
|
), this.templates.set(
|
|
1850
1875
|
"minimal",
|
|
1851
|
-
|
|
1876
|
+
at
|
|
1852
1877
|
), this.templates.set(
|
|
1853
1878
|
"crosshair",
|
|
1854
|
-
|
|
1879
|
+
G
|
|
1855
1880
|
), this.templates.set(
|
|
1856
1881
|
"heatmap",
|
|
1857
|
-
|
|
1882
|
+
_
|
|
1858
1883
|
), this.templates.set(
|
|
1859
1884
|
"scientific",
|
|
1860
|
-
|
|
1885
|
+
lt
|
|
1861
1886
|
), this.templates.set(
|
|
1862
1887
|
"annotation",
|
|
1863
|
-
|
|
1888
|
+
K
|
|
1864
1889
|
), this.templates.set(
|
|
1865
1890
|
"range",
|
|
1866
|
-
|
|
1891
|
+
U
|
|
1867
1892
|
);
|
|
1868
1893
|
}
|
|
1869
1894
|
/**
|
|
@@ -1922,7 +1947,7 @@ class Ft {
|
|
|
1922
1947
|
* Set tooltip theme
|
|
1923
1948
|
*/
|
|
1924
1949
|
setTheme(t) {
|
|
1925
|
-
this.theme = typeof t == "string" ?
|
|
1950
|
+
this.theme = typeof t == "string" ? B(t) : t, this.renderer.setTheme(this.theme), this.positioner.configure({
|
|
1926
1951
|
showArrow: this.theme.showArrow,
|
|
1927
1952
|
arrowSize: this.theme.arrowSize
|
|
1928
1953
|
});
|
|
@@ -1931,7 +1956,7 @@ class Ft {
|
|
|
1931
1956
|
* Update theme based on chart theme
|
|
1932
1957
|
*/
|
|
1933
1958
|
updateChartTheme(t) {
|
|
1934
|
-
this.options.theme || (this.theme =
|
|
1959
|
+
this.options.theme || (this.theme = B(t.name), this.renderer.setTheme(this.theme));
|
|
1935
1960
|
}
|
|
1936
1961
|
/**
|
|
1937
1962
|
* Get current theme
|
|
@@ -1949,7 +1974,7 @@ class Ft {
|
|
|
1949
1974
|
* Get a template by ID
|
|
1950
1975
|
*/
|
|
1951
1976
|
getTemplate(t) {
|
|
1952
|
-
return this.templates.get(t) ||
|
|
1977
|
+
return this.templates.get(t) || Bt(t);
|
|
1953
1978
|
}
|
|
1954
1979
|
/**
|
|
1955
1980
|
* Handle cursor movement - main entry point for hover detection
|
|
@@ -1999,8 +2024,8 @@ class Ft {
|
|
|
1999
2024
|
* significantly closer to a new point.
|
|
2000
2025
|
*/
|
|
2001
2026
|
performTooltipUpdateWithHysteresis(t, i) {
|
|
2002
|
-
var
|
|
2003
|
-
if (!((
|
|
2027
|
+
var s;
|
|
2028
|
+
if (!((s = this.options.dataPoint) != null && s.enabled)) {
|
|
2004
2029
|
this.performFallbackTooltipUpdate(t, i);
|
|
2005
2030
|
return;
|
|
2006
2031
|
}
|
|
@@ -2010,7 +2035,7 @@ class Ft {
|
|
|
2010
2035
|
return;
|
|
2011
2036
|
}
|
|
2012
2037
|
if (this.cachedNearestResult && this.hoveredSeriesId !== null) {
|
|
2013
|
-
const
|
|
2038
|
+
const o = this.cachedNearestResult, l = o.pixelX - t, h = o.pixelY - i, a = l * l + h * h, r = n.pixelX - t, d = n.pixelY - i;
|
|
2014
2039
|
if ((r * r + d * d) * this.hysteresisRatio >= a) {
|
|
2015
2040
|
this.updateTooltipPosition(this.cachedNearestResult);
|
|
2016
2041
|
return;
|
|
@@ -2024,92 +2049,104 @@ class Ft {
|
|
|
2024
2049
|
performFallbackTooltipUpdate(t, i) {
|
|
2025
2050
|
var e, n;
|
|
2026
2051
|
if ((e = this.options.heatmap) != null && e.enabled) {
|
|
2027
|
-
const
|
|
2028
|
-
if (
|
|
2029
|
-
this.scheduleShow(
|
|
2052
|
+
const s = this.findHeatmapCell(t, i);
|
|
2053
|
+
if (s) {
|
|
2054
|
+
this.scheduleShow(s);
|
|
2030
2055
|
return;
|
|
2031
2056
|
}
|
|
2032
2057
|
}
|
|
2033
2058
|
if ((n = this.options.crosshair) != null && n.enabled) {
|
|
2034
|
-
const
|
|
2035
|
-
if (
|
|
2036
|
-
this.scheduleShow(
|
|
2059
|
+
const s = this.buildCrosshairTooltip(t, i);
|
|
2060
|
+
if (s) {
|
|
2061
|
+
this.scheduleShow(s);
|
|
2037
2062
|
return;
|
|
2038
2063
|
}
|
|
2039
2064
|
}
|
|
2040
2065
|
this.cachedNearestResult = null, this.scheduleHide();
|
|
2041
2066
|
}
|
|
2067
|
+
buildAxisFormat(t) {
|
|
2068
|
+
var o, l;
|
|
2069
|
+
const i = this.getViewBounds(), e = i.xMax - i.xMin, n = (o = this.getXAxisOptions) == null ? void 0 : o.call(this), s = (l = this.getYAxisOptions) == null ? void 0 : l.call(this, t);
|
|
2070
|
+
if (!(!n && !s && !Number.isFinite(e)))
|
|
2071
|
+
return {
|
|
2072
|
+
x: n,
|
|
2073
|
+
y: s,
|
|
2074
|
+
xSpan: Number.isFinite(e) ? e : void 0
|
|
2075
|
+
};
|
|
2076
|
+
}
|
|
2042
2077
|
/**
|
|
2043
2078
|
* Find data point by X coordinate only (O(log n) - fastest method)
|
|
2044
2079
|
* Best for very large datasets where precision is less important than speed
|
|
2045
2080
|
*/
|
|
2046
2081
|
findDataPointByXOnly(t) {
|
|
2047
|
-
var h, a;
|
|
2082
|
+
var h, a, r;
|
|
2048
2083
|
const i = this.getSeries().filter(
|
|
2049
|
-
(
|
|
2084
|
+
(d) => d.isVisible() && d.getType() !== "heatmap"
|
|
2050
2085
|
);
|
|
2051
2086
|
if (i.length === 0) return null;
|
|
2052
|
-
const e = this.getXScale(), n = this.getYScales(),
|
|
2053
|
-
let
|
|
2054
|
-
for (const
|
|
2055
|
-
const
|
|
2056
|
-
if (!
|
|
2057
|
-
const p = n.get(((h =
|
|
2087
|
+
const e = this.getXScale(), n = this.getYScales(), s = this.pixelToDataX(t);
|
|
2088
|
+
let o = null, l = 1 / 0;
|
|
2089
|
+
for (const d of i) {
|
|
2090
|
+
const f = d.getData();
|
|
2091
|
+
if (!f.x || f.x.length === 0) continue;
|
|
2092
|
+
const p = n.get(((h = d.getYAxisId) == null ? void 0 : h.call(d)) || "default") || n.values().next().value;
|
|
2058
2093
|
if (!p) continue;
|
|
2059
|
-
const
|
|
2060
|
-
if (
|
|
2061
|
-
l =
|
|
2062
|
-
const
|
|
2063
|
-
|
|
2094
|
+
const g = this.binarySearchClosest(f.x, s), y = Math.abs(f.x[g] - s);
|
|
2095
|
+
if (y < l) {
|
|
2096
|
+
l = y;
|
|
2097
|
+
const b = d.getStyle(), x = e.transform(f.x[g]), S = p.transform(f.y[g]);
|
|
2098
|
+
o = {
|
|
2064
2099
|
type: "datapoint",
|
|
2065
|
-
seriesId:
|
|
2066
|
-
seriesName:
|
|
2067
|
-
seriesColor:
|
|
2068
|
-
dataIndex:
|
|
2069
|
-
dataX:
|
|
2070
|
-
dataY:
|
|
2071
|
-
pixelX:
|
|
2072
|
-
pixelY:
|
|
2073
|
-
cycle: (a =
|
|
2100
|
+
seriesId: d.getId(),
|
|
2101
|
+
seriesName: d.getId(),
|
|
2102
|
+
seriesColor: b.color || "#ff0055",
|
|
2103
|
+
dataIndex: g,
|
|
2104
|
+
dataX: f.x[g],
|
|
2105
|
+
dataY: f.y[g],
|
|
2106
|
+
pixelX: x,
|
|
2107
|
+
pixelY: S,
|
|
2108
|
+
cycle: (a = d.getCycle) == null ? void 0 : a.call(d),
|
|
2109
|
+
axisFormat: this.buildAxisFormat((r = d.getYAxisId) == null ? void 0 : r.call(d))
|
|
2074
2110
|
};
|
|
2075
|
-
const
|
|
2076
|
-
|
|
2111
|
+
const T = d.getYError(g);
|
|
2112
|
+
T && (o.yError = T);
|
|
2077
2113
|
}
|
|
2078
2114
|
}
|
|
2079
|
-
return
|
|
2115
|
+
return o;
|
|
2080
2116
|
}
|
|
2081
2117
|
/**
|
|
2082
2118
|
* Optimized nearest data point finder
|
|
2083
2119
|
*/
|
|
2084
2120
|
findNearestDataPointOptimized(t, i) {
|
|
2085
|
-
var r, d, p;
|
|
2086
|
-
const e = this.getSeries().filter((
|
|
2121
|
+
var r, d, f, p;
|
|
2122
|
+
const e = this.getSeries().filter((g) => g.isVisible()), n = ((r = this.options.dataPoint) == null ? void 0 : r.hitRadius) ?? 20, s = this.getXScale(), o = this.getYScales();
|
|
2087
2123
|
let l = n * n, h = null;
|
|
2088
2124
|
const a = this.pixelToDataX(t);
|
|
2089
|
-
for (const
|
|
2090
|
-
if (
|
|
2091
|
-
const
|
|
2092
|
-
if (!
|
|
2093
|
-
const
|
|
2094
|
-
for (let
|
|
2095
|
-
const
|
|
2125
|
+
for (const g of e) {
|
|
2126
|
+
if (g.getType() === "heatmap") continue;
|
|
2127
|
+
const y = g.getData(), b = o.get(((d = g.getYAxisId) == null ? void 0 : d.call(g)) || "default") || o.values().next().value;
|
|
2128
|
+
if (!b || !y.x || y.x.length === 0) continue;
|
|
2129
|
+
const x = this.binarySearchClosest(y.x, a), S = y.x.length, T = S > 1e5 ? 2 : S > 1e4 ? 3 : 5, v = Math.max(0, x - T), Y = Math.min(S, x + T + 1);
|
|
2130
|
+
for (let w = v; w < Y; w++) {
|
|
2131
|
+
const C = s.transform(y.x[w]), m = b.transform(y.y[w]), I = C - t, A = m - i, $ = I * I + A * A;
|
|
2096
2132
|
if ($ < l) {
|
|
2097
2133
|
l = $;
|
|
2098
|
-
const
|
|
2134
|
+
const R = g.getStyle();
|
|
2099
2135
|
h = {
|
|
2100
2136
|
type: "datapoint",
|
|
2101
|
-
seriesId:
|
|
2102
|
-
seriesName:
|
|
2103
|
-
seriesColor:
|
|
2104
|
-
dataIndex:
|
|
2105
|
-
dataX:
|
|
2106
|
-
dataY:
|
|
2107
|
-
pixelX:
|
|
2108
|
-
pixelY:
|
|
2109
|
-
cycle: (
|
|
2137
|
+
seriesId: g.getId(),
|
|
2138
|
+
seriesName: g.getId(),
|
|
2139
|
+
seriesColor: R.color || "#ff0055",
|
|
2140
|
+
dataIndex: w,
|
|
2141
|
+
dataX: y.x[w],
|
|
2142
|
+
dataY: y.y[w],
|
|
2143
|
+
pixelX: C,
|
|
2144
|
+
pixelY: m,
|
|
2145
|
+
cycle: (f = g.getCycle) == null ? void 0 : f.call(g),
|
|
2146
|
+
axisFormat: this.buildAxisFormat((p = g.getYAxisId) == null ? void 0 : p.call(g))
|
|
2110
2147
|
};
|
|
2111
|
-
const
|
|
2112
|
-
|
|
2148
|
+
const D = g.getYError(w);
|
|
2149
|
+
D && (h.yError = D);
|
|
2113
2150
|
}
|
|
2114
2151
|
}
|
|
2115
2152
|
}
|
|
@@ -2124,25 +2161,25 @@ class Ft {
|
|
|
2124
2161
|
(r) => r.isVisible() && r.getType() === "heatmap"
|
|
2125
2162
|
);
|
|
2126
2163
|
if (e.length === 0) return null;
|
|
2127
|
-
const n = this.getXScale(),
|
|
2164
|
+
const n = this.getXScale(), s = this.getYScales(), o = this.pixelToDataX(t), l = this.pixelToDataY(i);
|
|
2128
2165
|
for (const r of e) {
|
|
2129
2166
|
const d = r.getHeatmapData();
|
|
2130
2167
|
if (!d || !d.xValues || !d.yValues || !d.zValues) continue;
|
|
2131
|
-
const
|
|
2168
|
+
const f = this.binarySearchClosest(d.xValues, o), p = this.binarySearchClosest(d.yValues, l), g = d.xValues[f], y = d.yValues[p], b = s.get(((h = r.getYAxisId) == null ? void 0 : h.call(r)) || "default") || s.values().next().value;
|
|
2132
2169
|
if (!b) continue;
|
|
2133
|
-
const x = n.transform(g), S = b.transform(y),
|
|
2170
|
+
const x = n.transform(g), S = b.transform(y), T = d.zValues[p * d.xValues.length + f], v = ((a = r.getHeatmapStyle) == null ? void 0 : a.call(r)) || {};
|
|
2134
2171
|
return {
|
|
2135
2172
|
type: "heatmap",
|
|
2136
2173
|
seriesId: r.getId(),
|
|
2137
2174
|
seriesName: r.getId(),
|
|
2138
|
-
xIndex:
|
|
2139
|
-
yIndex:
|
|
2175
|
+
xIndex: f,
|
|
2176
|
+
yIndex: p,
|
|
2140
2177
|
dataX: g,
|
|
2141
2178
|
dataY: y,
|
|
2142
|
-
zValue:
|
|
2179
|
+
zValue: T,
|
|
2143
2180
|
pixelX: x,
|
|
2144
2181
|
pixelY: S,
|
|
2145
|
-
colorScale:
|
|
2182
|
+
colorScale: v.colorScale
|
|
2146
2183
|
};
|
|
2147
2184
|
}
|
|
2148
2185
|
return null;
|
|
@@ -2153,8 +2190,8 @@ class Ft {
|
|
|
2153
2190
|
binarySearchClosest(t, i) {
|
|
2154
2191
|
let e = 0, n = t.length - 1;
|
|
2155
2192
|
for (; e < n; ) {
|
|
2156
|
-
const
|
|
2157
|
-
t[
|
|
2193
|
+
const s = Math.floor((e + n) / 2);
|
|
2194
|
+
t[s] < i ? e = s + 1 : n = s;
|
|
2158
2195
|
}
|
|
2159
2196
|
return e > 0 && Math.abs(t[e - 1] - i) < Math.abs(t[e] - i) ? e - 1 : e;
|
|
2160
2197
|
}
|
|
@@ -2167,35 +2204,36 @@ class Ft {
|
|
|
2167
2204
|
(a) => a.isVisible() && a.getType() !== "heatmap"
|
|
2168
2205
|
);
|
|
2169
2206
|
if (e.length === 0) return null;
|
|
2170
|
-
const n = this.pixelToDataX(t),
|
|
2207
|
+
const n = this.pixelToDataX(t), s = this.getYScales(), o = [];
|
|
2171
2208
|
for (const a of e) {
|
|
2172
2209
|
const r = a.getData();
|
|
2173
|
-
if (!r.x || r.x.length === 0 || !(
|
|
2174
|
-
const
|
|
2175
|
-
let
|
|
2176
|
-
if (
|
|
2177
|
-
|
|
2210
|
+
if (!r.x || r.x.length === 0 || !(s.get(((l = a.getYAxisId) == null ? void 0 : l.call(a)) || "default") || s.values().next().value)) continue;
|
|
2211
|
+
const f = this.binarySearchClosest(r.x, n);
|
|
2212
|
+
let p, g = !1;
|
|
2213
|
+
if (f === 0 || f >= r.x.length - 1 || r.x[f] === n)
|
|
2214
|
+
p = r.y[f];
|
|
2178
2215
|
else if ((h = this.options.crosshair) != null && h.interpolate) {
|
|
2179
|
-
const b = r.x[
|
|
2180
|
-
|
|
2216
|
+
const b = r.x[f - 1], x = r.x[f], S = r.y[f - 1], T = r.y[f], v = (n - b) / (x - b);
|
|
2217
|
+
p = S + v * (T - S), g = !0;
|
|
2181
2218
|
} else
|
|
2182
|
-
|
|
2219
|
+
p = r.y[f];
|
|
2183
2220
|
const y = a.getStyle();
|
|
2184
|
-
|
|
2221
|
+
o.push({
|
|
2185
2222
|
seriesId: a.getId(),
|
|
2186
2223
|
seriesName: a.getId(),
|
|
2187
2224
|
seriesColor: y.color || "#ff0055",
|
|
2188
2225
|
x: n,
|
|
2189
|
-
y:
|
|
2226
|
+
y: p,
|
|
2190
2227
|
isInterpolated: g
|
|
2191
2228
|
});
|
|
2192
2229
|
}
|
|
2193
|
-
return
|
|
2230
|
+
return o.length === 0 ? null : {
|
|
2194
2231
|
type: "crosshair",
|
|
2195
2232
|
cursorX: t,
|
|
2196
2233
|
cursorY: i,
|
|
2197
2234
|
dataX: n,
|
|
2198
|
-
interpolatedValues:
|
|
2235
|
+
interpolatedValues: o,
|
|
2236
|
+
axisFormat: this.buildAxisFormat()
|
|
2199
2237
|
};
|
|
2200
2238
|
}
|
|
2201
2239
|
/**
|
|
@@ -2234,10 +2272,10 @@ class Ft {
|
|
|
2234
2272
|
* Show a tooltip with the given data
|
|
2235
2273
|
*/
|
|
2236
2274
|
showTooltip(t) {
|
|
2237
|
-
const i = this.getTemplateIdForType(t.type), e = this.templates.get(i) ||
|
|
2275
|
+
const i = this.getTemplateIdForType(t.type), e = this.templates.get(i) || tt(t.type), n = t.pixelX ?? this.lastCursorX ?? 0, s = t.pixelY ?? this.lastCursorY ?? 0, o = e.measure(this.ctx, t, this.theme), l = this.positioner.calculatePosition(
|
|
2238
2276
|
n,
|
|
2239
|
-
|
|
2240
|
-
|
|
2277
|
+
s,
|
|
2278
|
+
o
|
|
2241
2279
|
), h = "main";
|
|
2242
2280
|
this.activeTooltips.set(h, {
|
|
2243
2281
|
id: h,
|
|
@@ -2252,15 +2290,15 @@ class Ft {
|
|
|
2252
2290
|
updateTooltipPosition(t) {
|
|
2253
2291
|
const i = this.activeTooltips.get("main");
|
|
2254
2292
|
if (!i) return;
|
|
2255
|
-
const e = t || i.data, n = e.pixelX ?? this.lastCursorX ?? 0,
|
|
2293
|
+
const e = t || i.data, n = e.pixelX ?? this.lastCursorX ?? 0, s = e.pixelY ?? this.lastCursorY ?? 0, o = i.template.measure(
|
|
2256
2294
|
this.ctx,
|
|
2257
2295
|
e,
|
|
2258
2296
|
this.theme
|
|
2259
2297
|
);
|
|
2260
2298
|
i.position = this.positioner.calculatePosition(
|
|
2261
2299
|
n,
|
|
2262
|
-
|
|
2263
|
-
|
|
2300
|
+
s,
|
|
2301
|
+
o
|
|
2264
2302
|
), i.data = e;
|
|
2265
2303
|
}
|
|
2266
2304
|
/**
|
|
@@ -2283,18 +2321,18 @@ class Ft {
|
|
|
2283
2321
|
* Show a tooltip programmatically
|
|
2284
2322
|
*/
|
|
2285
2323
|
show(t, i) {
|
|
2286
|
-
const e = `tooltip-${++this.tooltipIdCounter}`, n = (i == null ? void 0 : i.templateId) || this.getTemplateIdForType(t.type),
|
|
2287
|
-
let
|
|
2324
|
+
const e = `tooltip-${++this.tooltipIdCounter}`, n = (i == null ? void 0 : i.templateId) || this.getTemplateIdForType(t.type), s = this.templates.get(n) || tt(t.type);
|
|
2325
|
+
let o;
|
|
2288
2326
|
if (i != null && i.position) {
|
|
2289
|
-
const l =
|
|
2290
|
-
|
|
2327
|
+
const l = s.measure(this.ctx, t, this.theme);
|
|
2328
|
+
o = this.positioner.calculatePosition(
|
|
2291
2329
|
i.position.x,
|
|
2292
2330
|
i.position.y,
|
|
2293
2331
|
l
|
|
2294
2332
|
);
|
|
2295
2333
|
} else {
|
|
2296
|
-
const l = t.pixelX ?? 0, h = t.pixelY ?? 0, a =
|
|
2297
|
-
|
|
2334
|
+
const l = t.pixelX ?? 0, h = t.pixelY ?? 0, a = s.measure(this.ctx, t, this.theme);
|
|
2335
|
+
o = this.positioner.calculatePosition(
|
|
2298
2336
|
l,
|
|
2299
2337
|
h,
|
|
2300
2338
|
a
|
|
@@ -2303,8 +2341,8 @@ class Ft {
|
|
|
2303
2341
|
return this.activeTooltips.set(e, {
|
|
2304
2342
|
id: e,
|
|
2305
2343
|
data: t,
|
|
2306
|
-
position:
|
|
2307
|
-
template:
|
|
2344
|
+
position: o,
|
|
2345
|
+
template: s
|
|
2308
2346
|
}), i != null && i.duration && i.duration > 0 && setTimeout(() => this.hide(e), i.duration), e;
|
|
2309
2347
|
}
|
|
2310
2348
|
/**
|
|
@@ -2352,20 +2390,20 @@ class Ft {
|
|
|
2352
2390
|
this.clearShowTimeout(), this.clearHideTimeout(), this.activeTooltips.clear(), this.templates.clear(), this.events.clear();
|
|
2353
2391
|
}
|
|
2354
2392
|
}
|
|
2355
|
-
const
|
|
2393
|
+
const Ht = {
|
|
2356
2394
|
name: "velo-plot-tools",
|
|
2357
2395
|
version: "1.0.0",
|
|
2358
2396
|
description: "Advanced interaction and measurement tools for velo-plot",
|
|
2359
2397
|
provides: ["interaction"],
|
|
2360
2398
|
tags: ["delta-tool", "peak-tool", "tooltip"]
|
|
2361
2399
|
};
|
|
2362
|
-
function
|
|
2400
|
+
function Wt(c = {}) {
|
|
2363
2401
|
let t = null, i = null, e = null;
|
|
2364
2402
|
return {
|
|
2365
|
-
manifest:
|
|
2403
|
+
manifest: Ht,
|
|
2366
2404
|
onInit(n) {
|
|
2367
|
-
var
|
|
2368
|
-
const
|
|
2405
|
+
var o;
|
|
2406
|
+
const s = {
|
|
2369
2407
|
container: n.ui.container,
|
|
2370
2408
|
getPlotArea: () => n.render.plotArea,
|
|
2371
2409
|
getViewBounds: () => n.data.getViewBounds(),
|
|
@@ -2383,14 +2421,14 @@ function Xt(f = {}) {
|
|
|
2383
2421
|
}),
|
|
2384
2422
|
onMeasure: (l) => n.events.emit("measure", l)
|
|
2385
2423
|
};
|
|
2386
|
-
if ((
|
|
2424
|
+
if ((c.enableDeltaTool ?? !0) && (t = new ft(s)), (c.enablePeakTool ?? !0) && (i = new pt(s)), c.useEnhancedTooltips ?? !0) {
|
|
2387
2425
|
const l = n.chart;
|
|
2388
2426
|
n.log.debug("TooltipManager init - checking deps:", {
|
|
2389
2427
|
hasCtx2d: !!n.render.ctx2d,
|
|
2390
2428
|
hasXScale: !!l.xScale,
|
|
2391
2429
|
hasYScales: !!l.yScales,
|
|
2392
2430
|
seriesCount: n.data.getAllSeries().length
|
|
2393
|
-
}), n.render.ctx2d ? e = new
|
|
2431
|
+
}), n.render.ctx2d ? e = new kt({
|
|
2394
2432
|
overlayCtx: n.render.ctx2d,
|
|
2395
2433
|
chartTheme: n.ui.theme,
|
|
2396
2434
|
getPlotArea: () => n.render.plotArea,
|
|
@@ -2400,7 +2438,9 @@ function Xt(f = {}) {
|
|
|
2400
2438
|
getXScale: () => l.xScale,
|
|
2401
2439
|
getYScales: () => l.yScales,
|
|
2402
2440
|
getViewBounds: () => n.data.getViewBounds(),
|
|
2403
|
-
|
|
2441
|
+
getXAxisOptions: () => n.chart.getXAxis(),
|
|
2442
|
+
getYAxisOptions: (h) => n.chart.getYAxis(h || n.chart.getPrimaryYAxisId()),
|
|
2443
|
+
options: (o = l.initialOptions) == null ? void 0 : o.tooltip
|
|
2404
2444
|
}) : n.log.warn("TooltipManager: No 2D context available, tooltips disabled");
|
|
2405
2445
|
}
|
|
2406
2446
|
},
|
|
@@ -2421,11 +2461,11 @@ function Xt(f = {}) {
|
|
|
2421
2461
|
};
|
|
2422
2462
|
}
|
|
2423
2463
|
export {
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2464
|
+
ft as D,
|
|
2465
|
+
Wt as P,
|
|
2466
|
+
kt as T,
|
|
2467
|
+
bt as a,
|
|
2468
|
+
pt as b,
|
|
2469
|
+
B as g
|
|
2430
2470
|
};
|
|
2431
|
-
//# sourceMappingURL=index-
|
|
2471
|
+
//# sourceMappingURL=index-DjeWClO9.js.map
|