@wick-charts/vue 0.6.2 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +2 -2
  2. package/dist/BandSeries.vue.js +50 -0
  3. package/dist/BandSeries.vue2.js +4 -0
  4. package/dist/ChartContainer.vue.js +45 -39
  5. package/dist/composables.js +39 -26
  6. package/dist/core/dist/animation/config.js +92 -75
  7. package/dist/core/dist/axis/dom-labels.js +56 -43
  8. package/dist/core/dist/chart/badge-animator.js +30 -22
  9. package/dist/core/dist/chart/edge-indicators.js +22 -21
  10. package/dist/core/dist/chart/last-value.js +33 -26
  11. package/dist/core/dist/chart/options.js +5 -5
  12. package/dist/core/dist/chart/scale-guards.js +26 -0
  13. package/dist/core/dist/chart/y-target.js +46 -19
  14. package/dist/core/dist/chart.js +670 -518
  15. package/dist/core/dist/components/crosshair.js +8 -8
  16. package/dist/core/dist/components/grid.js +26 -17
  17. package/dist/core/dist/components/marker.js +28 -28
  18. package/dist/core/dist/components/reference-line.js +16 -16
  19. package/dist/core/dist/data/decimation.js +58 -39
  20. package/dist/core/dist/interactions/handler.js +3 -2
  21. package/dist/core/dist/interactions/zoom.js +6 -5
  22. package/dist/core/dist/navigator/controller.js +47 -44
  23. package/dist/core/dist/perf/perf-hud.js +3 -3
  24. package/dist/core/dist/scales/log-scale.js +76 -0
  25. package/dist/core/dist/scales/y-scale.js +134 -35
  26. package/dist/core/dist/series/band.js +670 -0
  27. package/dist/core/dist/series/bar-intro.js +11 -11
  28. package/dist/core/dist/series/bar.js +301 -251
  29. package/dist/core/dist/series/base-multi-layer.js +100 -76
  30. package/dist/core/dist/series/candlestick.js +238 -235
  31. package/dist/core/dist/series/heatmap.js +5 -5
  32. package/dist/core/dist/series/line-intro.js +50 -40
  33. package/dist/core/dist/series/line.js +561 -483
  34. package/dist/core/dist/series/painters/builtins.js +4 -4
  35. package/dist/core/dist/series/painters/canvas-path.js +64 -52
  36. package/dist/core/dist/series/register-builtins.js +9 -8
  37. package/dist/core/dist/series/scale-stack.js +25 -0
  38. package/dist/core/dist/snapshots.js +36 -35
  39. package/dist/core/dist/tooltip-position.js +5 -5
  40. package/dist/core/dist/utils/point.js +10 -0
  41. package/dist/index.d.ts +501 -128
  42. package/dist/index.js +195 -189
  43. package/dist/ui/Crosshair.vue.js +14 -14
  44. package/dist/ui/HeatmapTooltip.vue.js +6 -6
  45. package/dist/ui/InfoBar.vue.js +100 -81
  46. package/dist/ui/PieTooltip.vue.js +4 -4
  47. package/dist/ui/TimeAxis.vue.js +23 -22
  48. package/dist/ui/Tooltip.vue.js +140 -111
  49. package/dist/ui/YAxis.vue.js +25 -24
  50. package/dist/ui/YLabel.vue.js +63 -70
  51. package/package.json +2 -2
  52. package/src/BandSeries.vue +87 -0
  53. package/src/ChartContainer.vue +20 -8
  54. package/src/composables.ts +35 -1
  55. package/src/index.ts +13 -0
  56. package/src/ui/Crosshair.vue +2 -2
  57. package/src/ui/InfoBar.vue +20 -1
  58. package/src/ui/TimeAxis.vue +7 -4
  59. package/src/ui/Tooltip.vue +40 -3
  60. package/src/ui/YAxis.vue +5 -3
  61. package/src/ui/YLabel.vue +5 -16
@@ -1,90 +1,82 @@
1
- import { DEFAULT_HISTORY_REVEAL as et, DEFAULT_LINE_INTRO as it, DEFAULT_LINE_PULSE as ot, DEFAULT_LINE_SMOOTH as st, DEFAULT_LINE_ENTRY as nt } from "../animation/config.js";
1
+ import { DEFAULT_HISTORY_REVEAL as nt, DEFAULT_LINE_INTRO as lt, DEFAULT_LINE_PULSE as at, DEFAULT_LINE_SMOOTH as rt, DEFAULT_LINE_ENTRY as ht } from "../animation/config.js";
2
2
  import { easeOutCubic as U } from "../animation/easing.js";
3
- import { decimateLineData as K } from "../data/decimation.js";
4
- import { hexToRgba as W } from "../utils/color.js";
5
- import { lerp as Y } from "../utils/math.js";
6
- import { BaseMultiLayerSeries as at } from "./base-multi-layer.js";
7
- import { unfoldIntro as lt, backfillSweepIntro as ht } from "./line-intro.js";
8
- import { buildCurveSegments as Q } from "./painters/canvas-path.js";
9
- import { resolveLinePainter as ct } from "./painters/resolve.js";
10
- const ut = {
3
+ import { decimateLineData as q } from "../data/decimation.js";
4
+ import { hexToRgba as X } from "../utils/color.js";
5
+ import { lerp as N } from "../utils/math.js";
6
+ import { BaseMultiLayerSeries as ut } from "./base-multi-layer.js";
7
+ import { unfoldIntro as ft, scaleMean as mt, backfillSweepIntro as pt } from "./line-intro.js";
8
+ import { buildCurveSegments as tt, replaySegmentsForward as et, replaySegmentsReversed as gt } from "./painters/canvas-path.js";
9
+ import { resolveLinePainter as dt } from "./painters/resolve.js";
10
+ import { ScaleStack as it } from "./scale-stack.js";
11
+ const vt = {
11
12
  colors: ["#2962FF"],
12
13
  strokeWidth: 1,
13
14
  area: { visible: !0 },
14
15
  pulse: !0,
15
16
  stacking: "off",
16
17
  curve: "straight",
17
- entryMs: nt,
18
- smoothMs: st,
19
- pulseMs: ot,
20
- introMs: it,
21
- historyRevealMs: et
18
+ entryMs: ht,
19
+ smoothMs: rt,
20
+ pulseMs: at,
21
+ introMs: lt,
22
+ historyRevealMs: nt
22
23
  };
23
- function Z(g) {
24
- const t = g.areaFill, e = t !== void 0 && g.area === void 0 ? { visible: !!t } : g.area;
24
+ function ot(y) {
25
+ const t = y.areaFill, i = t !== void 0 && y.area === void 0 ? { visible: !!t } : y.area;
25
26
  return {
26
- ...g,
27
- area: e,
28
- entryMs: g.entryMs === !1 ? 0 : g.entryMs ?? nt,
29
- smoothMs: g.smoothMs === !1 ? 0 : g.smoothMs ?? st,
30
- pulseMs: g.pulseMs === !1 ? 0 : g.pulseMs ?? ot,
31
- introMs: g.introMs === !1 ? 0 : g.introMs ?? it,
32
- historyRevealMs: g.historyRevealMs === !1 ? 0 : g.historyRevealMs ?? et
27
+ ...y,
28
+ area: i,
29
+ entryMs: y.entryMs === !1 ? 0 : y.entryMs ?? ht,
30
+ smoothMs: y.smoothMs === !1 ? 0 : y.smoothMs ?? rt,
31
+ pulseMs: y.pulseMs === !1 ? 0 : y.pulseMs ?? at,
32
+ introMs: y.introMs === !1 ? 0 : y.introMs ?? lt,
33
+ historyRevealMs: y.historyRevealMs === !1 ? 0 : y.historyRevealMs ?? nt
33
34
  };
34
35
  }
35
- function $(g) {
36
- return g.map(([t, e]) => ({ x: t, y: e }));
36
+ function st(y) {
37
+ return y.map(([t, i]) => ({ x: t, y: i }));
37
38
  }
38
- const J = 0.15, mt = ht();
39
- function j(g, t, e) {
40
- if (g.length === 0) return null;
41
- if (t <= g[0].time) return Number.isFinite(g[0].value) ? e(g[0]) : null;
42
- const i = g[g.length - 1];
43
- if (t >= i.time) return Number.isFinite(i.value) ? e(i) : null;
44
- let o = 0, s = g.length - 1;
45
- for (; s - o > 1; ) {
46
- const l = o + s >> 1;
47
- g[l].time <= t ? o = l : s = l;
48
- }
49
- const n = g[o], a = g[s];
50
- if (!Number.isFinite(n.value) || !Number.isFinite(a.value)) return null;
51
- const u = a.time - n.time;
52
- return u <= 0 ? e(n) : Y(e(n), e(a), (t - n.time) / u);
39
+ const J = 0.15, xt = pt();
40
+ function j(y, t, i) {
41
+ const { resolve: e, lerp: o = N } = i;
42
+ if (y.length === 0) return null;
43
+ if (t <= y[0].time) return Number.isFinite(y[0].value) ? e(y[0]) : null;
44
+ const s = y[y.length - 1];
45
+ if (t >= s.time) return Number.isFinite(s.value) ? e(s) : null;
46
+ let l = 0, r = y.length - 1;
47
+ for (; r - l > 1; ) {
48
+ const c = l + r >> 1;
49
+ y[c].time <= t ? l = c : r = c;
50
+ }
51
+ const f = y[l], h = y[r];
52
+ if (!Number.isFinite(f.value) || !Number.isFinite(h.value)) return null;
53
+ const m = h.time - f.time;
54
+ return m <= 0 ? e(f) : o(e(f), e(h), (t - f.time) / m);
53
55
  }
54
- function pt(g, t) {
55
- let e = 0, i = g.length - 1;
56
- for (; e <= i; ) {
57
- const o = e + i >> 1;
58
- if (g[o] === t) return o;
59
- g[o] < t ? e = o + 1 : i = o - 1;
56
+ function yt(y, t) {
57
+ let i = 0, e = y.length - 1;
58
+ for (; i <= e; ) {
59
+ const o = i + e >> 1;
60
+ if (y[o] === t) return o;
61
+ y[o] < t ? i = o + 1 : e = o - 1;
60
62
  }
61
63
  return -1;
62
64
  }
63
- function tt(g, t) {
64
- for (const e of t)
65
- e.kind === "line" ? g.lineTo(e.x, e.y) : g.bezierCurveTo(e.cp1x, e.cp1y, e.cp2x, e.cp2y, e.x, e.y);
66
- }
67
- function ft(g, t, e) {
68
- for (let i = e.length - 1; i >= 0; i--) {
69
- const o = e[i], s = i > 0 ? e[i - 1] : t[0];
70
- o.kind === "line" ? g.lineTo(s.x, s.y) : g.bezierCurveTo(o.cp2x, o.cp2y, o.cp1x, o.cp1y, s.x, s.y);
71
- }
72
- }
73
- class dt extends at {
65
+ class Pt extends ut {
74
66
  kind = "line";
75
67
  areaGradientCache = /* @__PURE__ */ new Map();
76
- constructor(t, e) {
77
- super(t), this.options = Z({ ...ut, ...e });
68
+ constructor(t, i) {
69
+ super(t), this.options = ot({ ...vt, ...i });
78
70
  }
79
71
  updateOptions(t) {
80
- this.options = Z({ ...this.options, ...t });
72
+ this.options = ot({ ...this.options, ...t });
81
73
  }
82
74
  getStacking() {
83
75
  return this.options.stacking;
84
76
  }
85
- applyTheme(t, e) {
86
- const i = this.stores.length === 1 ? [t.line.color] : t.seriesColors.slice(0, this.stores.length);
87
- this.updateOptions({ colors: i }), this.options.strokeWidth === e.line.width && this.updateOptions({ strokeWidth: t.line.width });
77
+ applyTheme(t, i) {
78
+ const e = this.stores.length === 1 ? [t.line.color] : t.seriesColors.slice(0, this.stores.length);
79
+ this.updateOptions({ colors: e }), this.options.strokeWidth === i.line.width && this.updateOptions({ strokeWidth: t.line.width });
88
80
  }
89
81
  isEntryEnabled() {
90
82
  return (this.options.entryAnimation ?? "grow") !== "none";
@@ -95,27 +87,27 @@ class dt extends at {
95
87
  get overlayNeedsAnimation() {
96
88
  return this.hasPulse;
97
89
  }
98
- hasOverlayContentInRange(t, e) {
99
- for (let i = 0; i < this.stores.length; i++) {
100
- if (this.getLayerAlpha(i) <= 0) continue;
101
- const o = this.stores[i].last();
90
+ hasOverlayContentInRange(t, i) {
91
+ for (let e = 0; e < this.stores.length; e++) {
92
+ if (this.getLayerAlpha(e) <= 0) continue;
93
+ const o = this.stores[e].last();
102
94
  if (o && o.time >= t) return !0;
103
95
  }
104
96
  return !1;
105
97
  }
106
98
  render(t) {
107
- this.tickAnimations(performance.now());
108
- const { context: e } = t.scope;
99
+ this.tickAnimations(performance.now()), this.lastYScale = t.yScale;
100
+ const { context: i } = t.scope;
109
101
  this.historyDirectives = null;
110
- const i = this.historyRange;
111
- if (this.historyWave.active && i !== null) {
112
- const a = this.options.historyReveal ?? mt;
113
- a !== "none" && (this.historyDirectives = a(this.buildHistoryFrame(t, i)));
102
+ const e = this.historyRange;
103
+ if (this.historyWave.active && e !== null) {
104
+ const r = this.options.historyReveal ?? xt;
105
+ r !== "none" && (this.historyDirectives = r(this.buildHistoryFrame(t, e)));
114
106
  }
115
107
  const o = this.historyDirectives, s = o?.ghostAlpha ?? 0;
116
- s > 0 && (e.save(), e.globalAlpha *= s, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, e.restore());
117
- const n = this.applyHistoryClip(t, o, i);
118
- this.introWave.active ? this.renderWithIntro(t) : (this.introDirectives = null, this.renderBody(t)), n && e.restore(), o?.heads !== void 0 && o.heads.length > 0 && this.drawIntroHeads(t, o.heads, this.historyWave.linear());
108
+ s > 0 && (i.save(), i.globalAlpha *= s, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, i.restore());
109
+ const l = this.applyHistoryClip(t, o, e);
110
+ this.introWave.active ? this.renderWithIntro(t) : (this.introDirectives = null, this.renderBody(t)), l && i.restore(), o?.heads !== void 0 && o.heads.length > 0 && this.drawIntroHeads(t, o.heads, this.historyWave.linear());
119
111
  }
120
112
  /**
121
113
  * Initial-load intro pass: the resolved LineIntroFn describes this frame
@@ -123,16 +115,16 @@ class dt extends at {
123
115
  * renderer executes the directives around the untouched body pass.
124
116
  */
125
117
  renderWithIntro(t) {
126
- const e = this.resolveIntro()(this.buildIntroFrame(t));
127
- this.introDirectives = e;
128
- const { context: i } = t.scope, { width: o, height: s } = t.scope.bitmapSize, n = e.ghostAlpha ?? 0;
129
- n > 0 && (i.save(), i.globalAlpha *= n, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, i.restore());
130
- const a = e.clip, u = a !== void 0 && (a.fromX !== void 0 || a.toX !== void 0);
131
- if (u) {
132
- const l = a.fromX ?? 0, p = a.toX ?? o;
133
- i.save(), i.beginPath(), i.rect(l, 0, Math.max(0, p - l), s), i.clip();
118
+ const i = this.resolveIntro()(this.buildIntroFrame(t));
119
+ this.introDirectives = i;
120
+ const { context: e } = t.scope, { width: o, height: s } = t.scope.bitmapSize, l = i.ghostAlpha ?? 0;
121
+ l > 0 && (e.save(), e.globalAlpha *= l, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, e.restore());
122
+ const r = i.clip, f = r !== void 0 && (r.fromX !== void 0 || r.toX !== void 0);
123
+ if (f) {
124
+ const h = r.fromX ?? 0, m = r.toX ?? o;
125
+ e.save(), e.beginPath(), e.rect(h, 0, Math.max(0, m - h), s), e.clip();
134
126
  }
135
- this.renderBody(t), u && i.restore(), e.heads !== void 0 && e.heads.length > 0 && this.drawIntroHeads(t, e.heads, this.introWave.linear());
127
+ this.renderBody(t), f && e.restore(), i.heads !== void 0 && i.heads.length > 0 && this.drawIntroHeads(t, i.heads, this.introWave.linear());
136
128
  }
137
129
  /**
138
130
  * Apply the history reveal's clip directive, mapped from reveal space
@@ -140,11 +132,11 @@ class dt extends at {
140
132
  * to bitmap space. Everything at or after the boundary always draws; a
141
133
  * small pad keeps the stroke cap at the reveal front from being shaved.
142
134
  */
143
- applyHistoryClip(t, e, i) {
144
- const o = e?.clip;
145
- if (o === void 0 || i === null || o.fromX === void 0 && o.toX === void 0) return !1;
146
- const { context: s } = t.scope, { width: n, height: a } = t.scope.bitmapSize, u = t.timeScale.timeToBitmapXExact(i.to), l = Math.abs(u - t.timeScale.timeToBitmapXExact(i.from)), p = Math.max(2, (this.options.strokeWidth ?? 1) * t.scope.horizontalPixelRatio), h = o.fromX ?? 0, d = o.toX ?? l;
147
- return s.save(), s.beginPath(), s.rect(u - d - p, 0, Math.max(0, d - h + p), a), s.rect(u, 0, Math.max(0, n - u), a), s.clip(), !0;
135
+ applyHistoryClip(t, i, e) {
136
+ const o = i?.clip;
137
+ if (o === void 0 || e === null || o.fromX === void 0 && o.toX === void 0) return !1;
138
+ const { context: s } = t.scope, { width: l, height: r } = t.scope.bitmapSize, f = t.timeScale.timeToBitmapXExact(e.to), h = Math.abs(f - t.timeScale.timeToBitmapXExact(e.from)), m = Math.max(2, (this.options.strokeWidth ?? 1) * t.scope.horizontalPixelRatio), c = o.fromX ?? 0, x = o.toX ?? h;
139
+ return s.save(), s.beginPath(), s.rect(f - x - m, 0, Math.max(0, x - c + m), r), s.rect(f, 0, Math.max(0, l - f), r), s.clip(), !0;
148
140
  }
149
141
  renderBody(t) {
150
142
  this.options.stacking === "off" ? (this.stackedEdges = null, this.renderOff(t)) : this.renderStacked(t, this.options.stacking === "percent");
@@ -168,11 +160,13 @@ class dt extends at {
168
160
  introDirectives = null;
169
161
  /** Per-frame history-reveal directives; `null` when no reveal is in flight. */
170
162
  historyDirectives = null;
163
+ /** Y scale of the last render — value queries run without a render context. */
164
+ lastYScale = null;
171
165
  /** Default intro, built lazily — one instance per renderer. */
172
166
  defaultIntro = null;
173
167
  resolveIntro() {
174
168
  const t = this.options.introAnimation;
175
- return t !== void 0 ? t : (this.defaultIntro === null && (this.defaultIntro = lt()), this.defaultIntro);
169
+ return t !== void 0 ? t : (this.defaultIntro === null && (this.defaultIntro = ft()), this.defaultIntro);
176
170
  }
177
171
  /**
178
172
  * Frame context handed to the intro fn — progress plus memoized data
@@ -194,60 +188,55 @@ class dt extends at {
194
188
  * accessors are scoped to that span — `layerMean` anchors an unfold to
195
189
  * the new history, not the whole window.
196
190
  */
197
- buildHistoryFrame(t, e) {
191
+ buildHistoryFrame(t, i) {
198
192
  return this.buildFrame(t, {
199
193
  progress: this.historyWave.linear(),
200
- range: e,
194
+ range: i,
201
195
  width: Math.abs(
202
- t.timeScale.timeToBitmapXExact(e.to) - t.timeScale.timeToBitmapXExact(e.from)
196
+ t.timeScale.timeToBitmapXExact(i.to) - t.timeScale.timeToBitmapXExact(i.from)
203
197
  )
204
198
  });
205
199
  }
206
- buildFrame(t, e) {
207
- const { timeScale: i, yScale: o, scope: s } = t, { progress: n, range: a, width: u } = e, l = new Array(this.stores.length), p = new Array(this.stores.length);
208
- let h;
209
- const d = (r) => {
210
- let f = l[r];
211
- return f === void 0 && (f = this.stores[r]?.getVisibleData(a.from, a.to) ?? [], l[r] = f), f;
200
+ buildFrame(t, i) {
201
+ const { timeScale: e, yScale: o, scope: s } = t, { progress: l, range: r, width: f } = i, h = this.options.stacking === "percent", m = new Array(this.stores.length), c = new Array(this.stores.length);
202
+ let x, n;
203
+ const p = (a) => {
204
+ let g = m[a];
205
+ return g === void 0 && (g = this.stores[a]?.getVisibleData(r.from, r.to) ?? [], m[a] = g), g;
212
206
  };
213
207
  return {
214
- progress: n,
215
- range: a,
216
- width: u,
208
+ progress: l,
209
+ range: r,
210
+ width: f,
217
211
  height: o.getMediaHeight() * s.verticalPixelRatio,
218
212
  stacking: this.options.stacking,
219
- timeToX: (r) => i.timeToBitmapXExact(r),
220
- xToTime: (r) => i.xToTime(r / s.horizontalPixelRatio),
221
- valueToY: (r) => o.valueToBitmapYExact(r),
213
+ timeToX: (a) => e.timeToBitmapXExact(a),
214
+ xToTime: (a) => e.xToTime(a / s.horizontalPixelRatio),
215
+ valueToY: (a) => o.valueToBitmapYExact(a),
216
+ lerpValue: (a, g, A) => o.lerpValue(a, g, A),
222
217
  layerCount: this.stores.length,
223
- layerData: d,
224
- layerMean: (r) => {
225
- let f = p[r];
226
- if (f === void 0) {
227
- let c = 0, y = 0;
228
- for (const R of d(r))
229
- Number.isFinite(R.value) && (c += R.value, y++);
230
- f = y > 0 ? c / y : null, p[r] = f;
231
- }
232
- return f;
218
+ layerData: p,
219
+ layerMean: (a) => {
220
+ let g = c[a];
221
+ return g === void 0 && (h ? (x ??= this.meanShares(p, o), g = x[a]) : g = mt(p(a), o), c[a] = g), g;
233
222
  },
234
223
  primaryPath: () => {
235
- if (h === void 0) {
236
- h = null;
237
- for (let r = 0; r < this.stores.length; r++) {
238
- if (this.getLayerAlpha(r) <= 0 || !this.stores[r].isVisible()) continue;
239
- const f = d(r).filter((c) => Number.isFinite(c.value));
240
- if (!(f.length < 2)) {
241
- h = f.map((c) => ({
242
- x: i.timeToBitmapXExact(c.time),
243
- y: o.valueToBitmapYExact(c.value),
244
- time: c.time
224
+ if (n === void 0) {
225
+ n = null;
226
+ for (let a = 0; a < this.stores.length; a++) {
227
+ if (this.getLayerAlpha(a) <= 0 || !this.stores[a].isVisible()) continue;
228
+ const g = p(a).filter((A) => o.isPlottable(A.value));
229
+ if (!(g.length < 2)) {
230
+ n = g.map((A) => ({
231
+ x: e.timeToBitmapXExact(A.time),
232
+ y: o.valueToBitmapYExact(A.value),
233
+ time: A.time
245
234
  }));
246
235
  break;
247
236
  }
248
237
  }
249
238
  }
250
- return h;
239
+ return n;
251
240
  }
252
241
  };
253
242
  }
@@ -257,51 +246,98 @@ class dt extends at {
257
246
  * overlay pulse) already flows through `effectiveValue`, so one override
258
247
  * animates the whole geometry.
259
248
  */
260
- effectiveValue(t, e, i, o) {
261
- const s = super.effectiveValue(t, e, i, o), n = this.historyWave.active ? this.historyDirectives?.value : void 0, a = this.historyRange;
262
- if (n !== void 0 && a !== null && i < a.to) {
263
- const d = a.to - a.from, r = d > 0 ? Math.min(1, Math.max(0, (a.to - i) / d)) : 0;
264
- return n({ layerIndex: e, time: i, value: s, position: r });
249
+ effectiveValue(t, i, e, o) {
250
+ const s = super.effectiveValue(t, i, e, o);
251
+ return this.options.stacking === "percent" ? s : this.introValue(t, { layerIndex: i, time: e, value: s });
252
+ }
253
+ /** Layer's share of its column in percent, passed through the intro value transform. */
254
+ introShare(t, i) {
255
+ const { layerIndex: e, time: o, value: s, total: l } = i;
256
+ if (l <= 0) return s;
257
+ const r = s / l * 100;
258
+ return Math.max(0, this.introValue(t, { layerIndex: e, time: o, value: r }));
259
+ }
260
+ /**
261
+ * What `layerMean` reports on a percent stack: each layer's mean share over
262
+ * the shared columns, alpha-weighted like the stacked pass, or `null` when it has none.
263
+ * A layer counts 0 where it has no sample yet, so the means sum to 100.
264
+ */
265
+ meanShares(t, i) {
266
+ const e = this.stores.length, o = /* @__PURE__ */ new Set();
267
+ for (let h = 0; h < e; h++)
268
+ for (const m of t(h))
269
+ o.add(m.time);
270
+ const s = new Array(e).fill(0), l = new Array(e).fill(!1), r = new Array(e);
271
+ let f = 0;
272
+ for (const h of o) {
273
+ let m = 0;
274
+ for (let c = 0; c < e; c++) {
275
+ r[c] = null;
276
+ const x = this.getLayerAlpha(c), n = t(c);
277
+ if (x <= 0 || n.length === 0 || h < n[0].time) continue;
278
+ const p = j(n, h, { resolve: (a) => a.value });
279
+ p === null || !i.isPlottable(p) || (r[c] = p * x, m += p * x);
280
+ }
281
+ if (!(m <= 0)) {
282
+ f++;
283
+ for (let c = 0; c < e; c++) {
284
+ const x = r[c];
285
+ x !== null && (s[c] += x / m * 100, l[c] = !0);
286
+ }
287
+ }
288
+ }
289
+ return s.map((h, m) => l[m] ? h / f : null);
290
+ }
291
+ /** The active history-reveal or intro value transform applied to one value. */
292
+ introValue(t, i) {
293
+ const { layerIndex: e, time: o, value: s } = i, l = this.historyWave.active ? this.historyDirectives?.value : void 0, r = this.historyRange;
294
+ if (l !== void 0 && r !== null && o < r.to) {
295
+ const x = r.to - r.from, n = x > 0 ? Math.min(1, Math.max(0, (r.to - o) / x)) : 0;
296
+ return l({ layerIndex: e, time: o, value: s, position: n });
265
297
  }
266
- const u = this.introWave.active ? this.introDirectives?.value : void 0;
267
- if (u === void 0) return s;
268
- const l = t.timeScale.getRange(), p = l.to - l.from, h = p > 0 ? Math.min(1, Math.max(0, (i - l.from) / p)) : 0;
269
- return u({ layerIndex: e, time: i, value: s, position: h });
298
+ const f = this.introWave.active ? this.introDirectives?.value : void 0;
299
+ if (f === void 0) return s;
300
+ const h = t.timeScale.getRange(), m = h.to - h.from, c = m > 0 ? Math.min(1, Math.max(0, (o - h.from) / m)) : 0;
301
+ return f({ layerIndex: e, time: o, value: s, position: c });
270
302
  }
271
303
  /**
272
304
  * Extends the base last-value query with the 'grow' entrance's value-space
273
- * equivalent of {@link chainedTailPositions}'s eased position lerp — the Y
274
- * scale is affine, so lerping the *value* by the same eased progress and
275
- * mapping it through `yScale` afterward lands on the identical pixel the
276
- * renderer paints. Without this, a tooltip/YLabel query would report a
277
- * freshly-appended point's raw value the instant it lands, `entryMs`
278
- * before the marker visually arrives there.
305
+ * equivalent of {@link chainedTailPositions}'s eased position lerp — the
306
+ * value lerps along the Y axis by the same eased progress, so mapping it
307
+ * through `yScale` lands on the identical pixel the renderer paints. Without
308
+ * this, a tooltip/YLabel query would report a freshly-appended point's raw
309
+ * value the instant it lands, `entryMs` before the marker visually arrives there.
279
310
  */
280
- snapshotValue(t, e, i) {
281
- const o = super.snapshotValue(t, e, i);
282
- return (this.options.entryAnimation ?? "grow") !== "grow" ? o : this.chainedTailValues(t)?.get(e) ?? o;
311
+ snapshotValue(t, i, e) {
312
+ const o = super.snapshotValue(t, i, e);
313
+ return (this.options.entryAnimation ?? "grow") !== "grow" ? o : this.chainedTailValues(t)?.get(i) ?? o;
283
314
  }
284
315
  /**
285
316
  * Value-space counterpart of {@link chainedTailPositions} — see {@link snapshotValue}.
286
317
  * `resolve` lets the stacked renderer feed its ctx-aware `effectiveValue`
287
318
  * in; query paths, which have no render context, keep the `liveValue` default.
288
319
  */
289
- chainedTailValues(t, e = (i, o) => this.liveValue(t, i, o)) {
290
- const i = this.unsettledTail(t);
291
- if (i.length === 0) return null;
292
- const o = this.stores[t].getAll(), s = o.length - 1 - i.length;
320
+ chainedTailValues(t, i = (e, o) => this.liveValue(t, e, o)) {
321
+ const e = this.unsettledTail(t);
322
+ if (e.length === 0) return null;
323
+ const o = this.stores[t].getAll(), s = o.length - 1 - e.length;
293
324
  if (s < 0) return null;
294
- const n = o[s];
295
- if (!Number.isFinite(n.value)) return null;
296
- let a = e(n.time, n.value);
297
- const u = /* @__PURE__ */ new Map();
298
- for (let l = 0; l < i.length; l++) {
299
- const p = o[s + 1 + l];
300
- if (!Number.isFinite(p.value)) return null;
301
- const h = U(i[l].progress), d = e(p.time, p.value), r = Y(a, d, h);
302
- u.set(p.time, r), a = r;
325
+ const l = o[s];
326
+ if (!Number.isFinite(l.value)) return null;
327
+ let r = i(l.time, l.value);
328
+ const f = /* @__PURE__ */ new Map();
329
+ for (let h = 0; h < e.length; h++) {
330
+ const m = o[s + 1 + h];
331
+ if (!Number.isFinite(m.value)) return null;
332
+ const c = U(e[h].progress), x = i(m.time, m.value), n = this.axisLerp(r, x, c);
333
+ f.set(m.time, n), r = n;
303
334
  }
304
- return u;
335
+ return f;
336
+ }
337
+ /** `lerp` along the last rendered Y axis — plain before the first render. */
338
+ axisLerp(t, i, e) {
339
+ const o = this.lastYScale;
340
+ return o === null ? N(t, i, e) : o.lerpValue(t, i, e);
305
341
  }
306
342
  /**
307
343
  * Glowing pulse dots riding the intro's head anchors — the line reads as
@@ -309,24 +345,24 @@ class dt extends at {
309
345
  * the reveal lands. Off-mode only: recomputing the stacked cumulative at
310
346
  * an arbitrary head time isn't worth it for a one-second decoration.
311
347
  */
312
- drawIntroHeads(t, e, i) {
348
+ drawIntroHeads(t, i, e) {
313
349
  if (this.options.stacking !== "off") return;
314
- const o = Math.min(1, i / J), s = Math.min(1, (1 - i) / J), n = Math.max(0, Math.min(o, s));
315
- if (n <= 0) return;
316
- const { scope: a } = t;
317
- for (const u of e)
318
- for (let l = 0; l < this.stores.length; l++) {
319
- const p = this.getLayerAlpha(l);
320
- if (p <= 0 || !this.stores[l].isVisible()) continue;
321
- const h = this.introHeadAnchor(t, l, u);
322
- h !== null && this.drawPulse({
323
- ctx: a.context,
324
- x: h.x,
325
- y: h.y,
326
- color: this.resolveLayerColor(l, h.value),
327
- pixelRatio: a.horizontalPixelRatio,
328
- phase: i * 2,
329
- alpha: n * p
350
+ const o = Math.min(1, e / J), s = Math.min(1, (1 - e) / J), l = Math.max(0, Math.min(o, s));
351
+ if (l <= 0) return;
352
+ const { scope: r } = t;
353
+ for (const f of i)
354
+ for (let h = 0; h < this.stores.length; h++) {
355
+ const m = this.getLayerAlpha(h);
356
+ if (m <= 0 || !this.stores[h].isVisible()) continue;
357
+ const c = this.introHeadAnchor(t, h, f);
358
+ c !== null && this.drawPulse({
359
+ ctx: r.context,
360
+ x: c.x,
361
+ y: c.y,
362
+ color: this.resolveLayerColor(h, c.value),
363
+ pixelRatio: r.horizontalPixelRatio,
364
+ phase: e * 2,
365
+ alpha: l * m
330
366
  });
331
367
  }
332
368
  }
@@ -341,27 +377,31 @@ class dt extends at {
341
377
  * right-padding region beyond the line's end (the sweep front travels the
342
378
  * visible range, not the data span) and jumps back on settle.
343
379
  */
344
- introHeadAnchor(t, e, i) {
345
- const { timeScale: o, yScale: s } = t, n = o.getRange(), a = this.stores[e].getVisibleData(n.from, n.to);
346
- if (a.length === 0) return null;
347
- const u = this.stores[e].last();
348
- if (u !== void 0 && i.time >= u.time) {
349
- if (!Number.isFinite(u.value)) return null;
350
- const h = this.trailingEndpoint(t, e);
351
- return h === null ? null : { x: h.x, y: h.y, value: u.value };
380
+ introHeadAnchor(t, i, e) {
381
+ const { timeScale: o, yScale: s } = t, l = o.getRange(), r = this.stores[i].getVisibleData(l.from, l.to);
382
+ if (r.length === 0) return null;
383
+ const f = this.stores[i].last();
384
+ if (f !== void 0 && e.time >= f.time) {
385
+ if (!s.isPlottable(f.value)) return null;
386
+ const c = this.trailingEndpoint(t, i);
387
+ return c === null ? null : { x: c.x, y: c.y, value: f.value };
352
388
  }
353
- const l = a[0];
354
- if (i.time <= l.time) {
355
- if (!Number.isFinite(l.value)) return null;
356
- const h = this.effectiveValue(t, e, l.time, l.value);
389
+ const h = r[0];
390
+ if (e.time <= h.time) {
391
+ if (!s.isPlottable(h.value)) return null;
392
+ const c = this.effectiveValue(t, i, h.time, h.value);
357
393
  return {
358
- x: o.timeToBitmapXExact(l.time),
359
- y: s.valueToBitmapYExact(h),
360
- value: l.value
394
+ x: o.timeToBitmapXExact(h.time),
395
+ y: s.valueToBitmapYExact(c),
396
+ value: h.value
361
397
  };
362
398
  }
363
- const p = j(a, i.time, (h) => this.effectiveValue(t, e, h.time, h.value));
364
- return p === null ? null : { x: i.x, y: s.valueToBitmapYExact(p), value: p };
399
+ const m = j(r, e.time, {
400
+ resolve: (c) => this.effectiveValue(t, i, c.time, c.value),
401
+ // Along the axis, so the dot stays on the straight segment the stroke draws.
402
+ lerp: (c, x, n) => !s.isPlottable(c) || !s.isPlottable(x) ? Number.NaN : s.lerpValue(c, x, n)
403
+ });
404
+ return m === null || !s.isPlottable(m) ? null : { x: e.x, y: s.valueToBitmapYExact(m), value: m };
365
405
  }
366
406
  /**
367
407
  * Rendered positions of the layer's still-unsettled trailing points, keyed
@@ -385,34 +425,52 @@ class dt extends at {
385
425
  * lagging sibling shouldn't zero out the moment another layer ticks past
386
426
  * it (see `renderStacked`'s `valueMaps` comment for the full rationale).
387
427
  */
388
- stackedValueAt(t, e, i) {
389
- const o = this.options.stacking === "percent", s = (this.options.entryAnimation ?? "grow") === "grow", n = new Array(this.stores.length), a = (h) => {
428
+ stackedValueAt(t, i, e) {
429
+ const o = this.options.stacking === "percent", s = (this.options.entryAnimation ?? "grow") === "grow", l = new Array(this.stores.length), r = (n) => {
390
430
  if (!s) return null;
391
- const d = n[h];
392
- if (d !== void 0) return d;
393
- const r = this.chainedTailValues(h, (f, c) => this.effectiveValue(t, h, f, c));
394
- return n[h] = r, r;
395
- }, u = (h) => {
396
- const d = this.getLayerAlpha(h);
397
- if (d <= 0) return 0;
398
- const r = this.stores[h].getAll();
399
- if (r.length === 0 || i < r[0].time) return 0;
400
- const f = a(h), c = j(
401
- r,
402
- i,
403
- (y) => f?.get(y.time) ?? this.effectiveValue(t, h, y.time, y.value)
404
- );
405
- return c === null ? 0 : c * d;
431
+ const p = l[n];
432
+ if (p !== void 0) return p;
433
+ const a = this.chainedTailValues(n, (g, A) => this.effectiveValue(t, n, g, A));
434
+ return l[n] = a, a;
435
+ }, f = (n) => {
436
+ const p = this.stores[n].getAll();
437
+ if (p.length === 0 || e < p[0].time) return null;
438
+ const a = r(n);
439
+ return j(p, e, {
440
+ resolve: (g) => a?.get(g.time) ?? this.effectiveValue(t, n, g.time, g.value)
441
+ });
442
+ }, { yScale: h } = t;
443
+ if (h.getTransform() !== null && !o) {
444
+ const n = new it(h);
445
+ for (let p = 0; p <= i; p++) {
446
+ const a = this.getLayerAlpha(p), g = a > 0 ? f(p) : null;
447
+ g !== null && h.isPlottable(g) && n.push(g, a);
448
+ }
449
+ return n.edge;
450
+ }
451
+ const m = (n) => {
452
+ const p = this.getLayerAlpha(n);
453
+ if (p <= 0) return null;
454
+ const a = this.stores[n].getAll();
455
+ if (o && a.length > 0 && e < a[0].time) return 0;
456
+ const g = f(n);
457
+ return g === null ? null : g * p;
406
458
  };
407
- let l = 0;
459
+ let c = 0;
408
460
  if (o)
409
- for (let h = 0; h < this.stores.length; h++) l += u(h);
410
- let p = 0;
411
- for (let h = 0; h <= e; h++) {
412
- const d = u(h);
413
- p += o && l > 0 ? d / l * 100 : d;
461
+ for (let n = 0; n < this.stores.length; n++)
462
+ c += m(n) ?? 0;
463
+ let x = 0;
464
+ for (let n = 0; n <= i; n++) {
465
+ const p = m(n);
466
+ if (p !== null)
467
+ if (o) {
468
+ const a = this.introShare(t, { layerIndex: n, time: e, value: p, total: c });
469
+ x = Math.min(100, x + a);
470
+ } else
471
+ x += p;
414
472
  }
415
- return p;
473
+ return x;
416
474
  }
417
475
  /**
418
476
  * Bitmap position for layer `li`'s stacked boundary at time `t`.
@@ -425,46 +483,46 @@ class dt extends at {
425
483
  * feed. Falls back to the raw settled position off-column (decimated
426
484
  * history, or before the first stacked frame).
427
485
  */
428
- stackedPositionAt(t, e, i) {
429
- const o = this.paintedStackVertex(t, e, i);
486
+ stackedPositionAt(t, i, e) {
487
+ const o = this.paintedStackVertex(t, i, e);
430
488
  if (o !== null) return o;
431
- const { timeScale: s, yScale: n } = t, a = n.valueToBitmapYExact(this.stackedValueAt(t, e, i)), u = s.timeToBitmapXExact(i), l = this.unsettledTail(e), p = this.stores[e].getAll(), h = p.length - 1 - l.length;
432
- if ((this.options.entryAnimation ?? "grow") !== "grow" || i !== p[p.length - 1]?.time || l.length === 0 || h < 0) return { x: u, y: a };
433
- let d = s.timeToBitmapXExact(p[h].time);
434
- for (let r = 0; r < l.length; r++)
435
- d = Y(d, s.timeToBitmapXExact(p[h + 1 + r].time), U(l[r].progress));
436
- return { x: d, y: a };
489
+ const { timeScale: s, yScale: l } = t, r = l.valueToBitmapYExact(this.stackedValueAt(t, i, e)), f = s.timeToBitmapXExact(e), h = this.unsettledTail(i), m = this.stores[i].getAll(), c = m.length - 1 - h.length;
490
+ if ((this.options.entryAnimation ?? "grow") !== "grow" || e !== m[m.length - 1]?.time || h.length === 0 || c < 0) return { x: f, y: r };
491
+ let x = s.timeToBitmapXExact(m[c].time);
492
+ for (let n = 0; n < h.length; n++)
493
+ x = N(x, s.timeToBitmapXExact(m[c + 1 + n].time), U(h[n].progress));
494
+ return { x, y: r };
437
495
  }
438
496
  /** Upper-edge vertex of layer `li` at column `t`, replayed from the last
439
497
  * stacked frame's data-space record against `ctx`'s scales. */
440
- paintedStackVertex(t, e, i) {
441
- const o = this.stackedEdges, s = o?.cumulative[e];
498
+ paintedStackVertex(t, i, e) {
499
+ const o = this.stackedEdges, s = o?.cumulative[i];
442
500
  if (o === null || s === void 0) return null;
443
- const { times: n, growChain: a, collapse: u } = o, l = pt(n, i);
444
- if (l < 0) return null;
445
- const { timeScale: p, yScale: h } = t, d = t.scope.bitmapSize.height, r = u[e] ?? 1, f = h.valueToBitmapYExact(s[l]), c = r >= 1 ? f : d + (f - d) * r, y = n.length - a.length;
446
- if (l < y) return { x: p.timeToBitmapXExact(i), y: c };
447
- let R = p.timeToBitmapXExact(n[y - 1]);
448
- for (let M = 0; M <= l - y; M++)
449
- R = Y(R, p.timeToBitmapXExact(n[y + M]), a[M]);
450
- return { x: R, y: c };
451
- }
452
- chainedTailPositions(t, e) {
453
- const i = this.unsettledTail(e);
454
- if (i.length === 0) return null;
455
- const o = this.stores[e].getAll(), s = o.length - 1 - i.length;
501
+ const { times: l, growChain: r, collapse: f } = o, h = yt(l, e);
502
+ if (h < 0) return null;
503
+ const { timeScale: m, yScale: c } = t, x = t.scope.bitmapSize.height, n = f[i] ?? 1, p = c.valueToBitmapYExact(s[h]), a = n >= 1 ? p : x + (p - x) * n, g = l.length - r.length;
504
+ if (h < g) return { x: m.timeToBitmapXExact(e), y: a };
505
+ let A = m.timeToBitmapXExact(l[g - 1]);
506
+ for (let E = 0; E <= h - g; E++)
507
+ A = N(A, m.timeToBitmapXExact(l[g + E]), r[E]);
508
+ return { x: A, y: a };
509
+ }
510
+ chainedTailPositions(t, i) {
511
+ const e = this.unsettledTail(i);
512
+ if (e.length === 0) return null;
513
+ const o = this.stores[i].getAll(), s = o.length - 1 - e.length;
456
514
  if (s < 0) return null;
457
- const { timeScale: n, yScale: a } = t, u = o[s];
458
- if (!Number.isFinite(u.value)) return null;
459
- let l = n.timeToBitmapXExact(u.time), p = a.valueToBitmapYExact(this.effectiveValue(t, e, u.time, u.value));
460
- const h = /* @__PURE__ */ new Map();
461
- for (let d = 0; d < i.length; d++) {
462
- const r = o[s + 1 + d];
463
- if (!Number.isFinite(r.value)) return null;
464
- const f = U(i[d].progress), c = n.timeToBitmapXExact(r.time), y = a.valueToBitmapYExact(this.effectiveValue(t, e, r.time, r.value)), R = Y(l, c, f), M = Y(p, y, f);
465
- h.set(r.time, { x: R, y: M }), l = R, p = M;
515
+ const { timeScale: l, yScale: r } = t, f = o[s];
516
+ if (!r.isPlottable(f.value)) return null;
517
+ let h = l.timeToBitmapXExact(f.time), m = r.valueToBitmapYExact(this.effectiveValue(t, i, f.time, f.value));
518
+ const c = /* @__PURE__ */ new Map();
519
+ for (let x = 0; x < e.length; x++) {
520
+ const n = o[s + 1 + x];
521
+ if (!r.isPlottable(n.value)) return null;
522
+ const p = U(e[x].progress), a = l.timeToBitmapXExact(n.time), g = r.valueToBitmapYExact(this.effectiveValue(t, i, n.time, n.value)), A = N(h, a, p), E = N(m, g, p);
523
+ c.set(n.time, { x: A, y: E }), h = A, m = E;
466
524
  }
467
- return h;
525
+ return c;
468
526
  }
469
527
  /**
470
528
  * Bitmap coordinates for the trailing endpoint of a layer — i.e. where the
@@ -476,11 +534,11 @@ class dt extends at {
476
534
  * (pulse dot) so the pulse glides in sync with the trailing segment instead
477
535
  * of teleporting to the raw last.time while the line still unfurls.
478
536
  */
479
- trailingEndpoint(t, e) {
480
- const i = this.stores[e].last();
481
- if (!i) return null;
482
- const { timeScale: o, yScale: s } = t, n = o.timeToBitmapXExact(i.time), a = s.valueToBitmapYExact(this.effectiveValue(t, e, i.time, i.value));
483
- return (this.options.entryAnimation ?? "grow") !== "grow" ? { x: n, y: a } : this.chainedTailPositions(t, e)?.get(i.time) ?? { x: n, y: a };
537
+ trailingEndpoint(t, i) {
538
+ const e = this.stores[i].last();
539
+ if (!e) return null;
540
+ const { timeScale: o, yScale: s } = t, l = o.timeToBitmapXExact(e.time), r = s.valueToBitmapYExact(this.effectiveValue(t, i, e.time, e.value));
541
+ return (this.options.entryAnimation ?? "grow") !== "grow" ? { x: l, y: r } : this.chainedTailPositions(t, i)?.get(e.time) ?? { x: l, y: r };
484
542
  }
485
543
  /**
486
544
  * Vertical stroke + area gradients for `options.threshold`, pinned to the
@@ -491,13 +549,13 @@ class dt extends at {
491
549
  * the Y-axis autoscales (and during the spike's entrance), so a cache keyed on
492
550
  * the row would miss almost every frame anyway.
493
551
  */
494
- buildThresholdPaint(t, e) {
495
- const i = this.options.threshold;
496
- if (!i) return null;
497
- const { scope: o, yScale: s } = t, { context: n } = o, a = o.bitmapSize.height, u = i.above, l = i.below ?? e, p = Math.min(1, Math.max(0, s.valueToBitmapYExact(i.value) / a)), h = Math.min(6 * o.verticalPixelRatio, a * 0.02) / a, d = Math.max(0, p - h), r = Math.min(1, p + h), f = n.createLinearGradient(0, 0, 0, a);
498
- f.addColorStop(0, u), f.addColorStop(d, u), f.addColorStop(r, l), f.addColorStop(1, l);
499
- const c = n.createLinearGradient(0, 0, 0, a);
500
- return c.addColorStop(0, W(u, 0.26)), c.addColorStop(d, W(u, 0.14)), c.addColorStop(r, W(l, 0.1)), c.addColorStop(1, W(l, 0.01)), { stroke: f, area: c };
552
+ buildThresholdPaint(t, i) {
553
+ const e = this.options.threshold;
554
+ if (!e) return null;
555
+ const { scope: o, yScale: s } = t, { context: l } = o, r = o.bitmapSize.height, f = e.above, h = e.below ?? i, m = Math.min(1, Math.max(0, s.valueToBitmapYExact(e.value) / r)), c = Math.min(6 * o.verticalPixelRatio, r * 0.02) / r, x = Math.max(0, m - c), n = Math.min(1, m + c), p = l.createLinearGradient(0, 0, 0, r);
556
+ p.addColorStop(0, f), p.addColorStop(x, f), p.addColorStop(n, h), p.addColorStop(1, h);
557
+ const a = l.createLinearGradient(0, 0, 0, r);
558
+ return a.addColorStop(0, X(f, 0.26)), a.addColorStop(x, X(f, 0.14)), a.addColorStop(n, X(h, 0.1)), a.addColorStop(1, X(h, 0.01)), { stroke: p, area: a };
501
559
  }
502
560
  /**
503
561
  * Dot markers at each data point (`options.points`). Callers pass the same
@@ -508,226 +566,245 @@ class dt extends at {
508
566
  * the stroke.
509
567
  */
510
568
  drawPointMarkers(t) {
511
- const e = this.options.points;
512
- if (!e?.visible) return;
513
- const { context: i, points: o, pixelRatio: s, color: n } = t;
569
+ const i = this.options.points;
570
+ if (!i?.visible) return;
571
+ const { context: e, points: o, pixelRatio: s, color: l } = t;
514
572
  if (o.length === 0) return;
515
- const a = Math.max(1, (e.radius ?? 3) * s);
516
- if (!(o.length > 1 && (o[o.length - 1].x - o[0].x) / (o.length - 1) < a * 3)) {
517
- i.beginPath();
518
- for (const u of o)
519
- i.moveTo(u.x + a, u.y), i.arc(u.x, u.y, a, 0, Math.PI * 2);
520
- i.fillStyle = e.color ?? n, i.fill();
573
+ const r = Math.max(1, (i.radius ?? 3) * s);
574
+ if (!(o.length > 1 && (o[o.length - 1].x - o[0].x) / (o.length - 1) < r * 3)) {
575
+ e.beginPath();
576
+ for (const f of o)
577
+ e.moveTo(f.x + r, f.y), e.arc(f.x, f.y, r, 0, Math.PI * 2);
578
+ e.fillStyle = i.color ?? l, e.fill();
521
579
  }
522
580
  }
523
581
  /** Each layer drawn independently */
524
582
  renderOff(t) {
525
- const { scope: e, timeScale: i, yScale: o } = t, { context: s } = e, n = i.getRange(), { verticalPixelRatio: a } = e, u = this.options.strokeWidth > 0, l = Math.max(1, Math.round(this.options.strokeWidth * a)), p = this.options.entryAnimation ?? "grow", h = ct(this.options.linePainter ?? this.options.curve ?? "straight"), d = {
583
+ const { scope: i, timeScale: e, yScale: o } = t, { context: s } = i, l = e.getRange(), { verticalPixelRatio: r } = i, f = this.options.strokeWidth > 0, h = Math.max(1, Math.round(this.options.strokeWidth * r)), m = this.options.entryAnimation ?? "grow", c = dt(this.options.linePainter ?? this.options.curve ?? "straight"), x = {
526
584
  ctx: s,
527
585
  theme: t.theme,
528
- horizontalPixelRatio: e.horizontalPixelRatio,
529
- verticalPixelRatio: a
586
+ horizontalPixelRatio: i.horizontalPixelRatio,
587
+ verticalPixelRatio: r
530
588
  };
531
- for (let r = 0; r < this.stores.length; r++) {
532
- const f = this.getLayerAlpha(r);
533
- if (f <= 0) continue;
534
- let c = this.stores[r].getVisibleData(n.from, n.to);
535
- const y = e.mediaSize.width;
536
- if (c.length > y * 2 && (c = K(c, Math.round(y * 1.5))), c.length < 2) continue;
537
- const R = this.stores[r].last()?.value ?? c[c.length - 1].value, M = this.resolveLayerColor(r, R), V = this.buildThresholdPaint(t, M), C = c[c.length - 1], N = this.stores[r].last(), D = N !== void 0 && C.time === N.time, z = D ? this.entranceProgress(r, C.time) : 1, I = D && p === "fade" && z < 1, G = (D ? this.trailingEndpoint(t, r) : null) ?? {
538
- x: i.timeToBitmapXExact(C.time),
539
- y: o.valueToBitmapYExact(this.effectiveValue(t, r, C.time, C.value))
540
- }, H = G.x, _ = G.y, m = D && p === "grow" ? this.chainedTailPositions(t, r) : null, v = f < 1;
541
- (v || I) && (s.save(), v && (s.globalAlpha *= f), I && (s.globalAlpha *= z));
542
- const b = c.length - 1, T = [];
543
- let x = null;
544
- for (let S = 0; S < b; S++) {
545
- const B = c[S].value;
546
- if (!Number.isFinite(B)) {
547
- x = null;
589
+ for (let n = 0; n < this.stores.length; n++) {
590
+ const p = this.getLayerAlpha(n);
591
+ if (p <= 0) continue;
592
+ let a = this.stores[n].getVisibleData(l.from, l.to);
593
+ const g = i.mediaSize.width;
594
+ if (a.length > g * 2 && (a = q(a, Math.round(g * 1.5))), a.length < 2) continue;
595
+ const A = this.stores[n].last()?.value ?? a[a.length - 1].value, E = this.resolveLayerColor(n, A), B = this.buildThresholdPaint(t, E), L = a[a.length - 1], D = this.stores[n].last(), Y = D !== void 0 && L.time === D.time, z = Y ? this.entranceProgress(n, L.time) : 1, I = Y && m === "fade" && z < 1, O = (Y ? this.trailingEndpoint(t, n) : null) ?? {
596
+ x: e.timeToBitmapXExact(L.time),
597
+ y: o.valueToBitmapYExact(this.effectiveValue(t, n, L.time, L.value))
598
+ }, W = O.x, C = O.y, _ = Y && m === "grow" ? this.chainedTailPositions(t, n) : null, G = p < 1;
599
+ (G || I) && (s.save(), G && (s.globalAlpha *= p), I && (s.globalAlpha *= z));
600
+ const $ = a.length - 1, u = [];
601
+ let v = null;
602
+ for (let d = 0; d < $; d++) {
603
+ const S = a[d].value;
604
+ if (!o.isPlottable(S)) {
605
+ v = null;
548
606
  continue;
549
607
  }
550
- x || (x = [], T.push(x));
551
- const P = m?.get(c[S].time);
552
- if (P)
553
- x.push({ x: P.x, y: P.y });
608
+ v || (v = [], u.push(v));
609
+ const w = _?.get(a[d].time);
610
+ if (w)
611
+ v.push({ x: w.x, y: w.y });
554
612
  else {
555
- const w = o.valueToBitmapYExact(this.effectiveValue(t, r, c[S].time, B));
556
- x.push({ x: i.timeToBitmapXExact(c[S].time), y: w });
613
+ const F = o.valueToBitmapYExact(this.effectiveValue(t, n, a[d].time, S));
614
+ v.push({ x: e.timeToBitmapXExact(a[d].time), y: F });
557
615
  }
558
616
  }
559
- const k = c[b]?.value, L = Number.isFinite(H) && Number.isFinite(_) && Number.isFinite(k), A = p === "grow" && z < 1;
560
- let F = null;
561
- if (L && (x ? (x.push({ x: H, y: _ }), F = x) : T.push([{ x: H, y: _ }])), u && T.some((S) => S.length >= 2)) {
617
+ const M = a[$]?.value, b = Number.isFinite(W) && Number.isFinite(C) && o.isPlottable(M), P = m === "grow" && z < 1;
618
+ let T = null;
619
+ if (b && (v ? (v.push({ x: W, y: C }), T = v) : u.push([{ x: W, y: C }])), f && u.some((d) => d.length >= 2)) {
562
620
  s.beginPath();
563
- for (const S of T)
564
- S.length < 2 || h(d, { points: S, color: M, lineWidth: l, closing: !1, grew: A && S === F });
565
- s.strokeStyle = V ? V.stroke : M, s.lineWidth = l, s.lineJoin = "round", s.lineCap = "round", s.stroke();
621
+ for (const d of u)
622
+ d.length < 2 || c(x, { points: d, color: E, lineWidth: h, closing: !1, grew: P && d === T });
623
+ s.strokeStyle = B ? B.stroke : E, s.lineWidth = h, s.lineJoin = "round", s.lineCap = "round", s.stroke();
566
624
  }
567
- if (u) {
568
- const S = Math.max(1, l / 2);
569
- let B = !1;
570
- for (const P of T)
571
- P.length === 1 && (B || (s.beginPath(), B = !0), s.moveTo(P[0].x + S, P[0].y), s.arc(P[0].x, P[0].y, S, 0, Math.PI * 2));
572
- B && (s.fillStyle = M, s.fill());
625
+ if (f) {
626
+ const d = Math.max(1, h / 2);
627
+ let S = !1;
628
+ for (const w of u)
629
+ w.length === 1 && (S || (s.beginPath(), S = !0), s.moveTo(w[0].x + d, w[0].y), s.arc(w[0].x, w[0].y, d, 0, Math.PI * 2));
630
+ S && (s.fillStyle = E, s.fill());
573
631
  }
574
632
  if (this.options.area.visible && !this.introGhostPass) {
575
- const S = e.bitmapSize.height;
576
- let B;
577
- if (V)
578
- B = V.area;
633
+ const d = i.bitmapSize.height;
634
+ let S;
635
+ if (B)
636
+ S = B.area;
579
637
  else {
580
- const P = String(r), w = this.areaGradientCache.get(P);
581
- w && w.bottomY === S && w.color === M ? B = w.gradient : (B = s.createLinearGradient(0, 0, 0, S), B.addColorStop(0, W(M, 0.12)), B.addColorStop(1, W(M, 0.01)), this.areaGradientCache.set(P, { gradient: B, bottomY: S, color: M }));
638
+ const w = String(n), F = this.areaGradientCache.get(w);
639
+ F && F.bottomY === d && F.color === E ? S = F.gradient : (S = s.createLinearGradient(0, 0, 0, d), S.addColorStop(0, X(E, 0.12)), S.addColorStop(1, X(E, 0.01)), this.areaGradientCache.set(w, { gradient: S, bottomY: d, color: E }));
582
640
  }
583
- s.fillStyle = B;
584
- for (const P of T)
585
- P.length < 2 || (s.beginPath(), h(d, { points: P, color: M, lineWidth: l, closing: !0, grew: A && P === F }), s.lineTo(P[P.length - 1].x, S), s.lineTo(P[0].x, S), s.closePath(), s.fill());
641
+ s.fillStyle = S;
642
+ for (const w of u)
643
+ w.length < 2 || (s.beginPath(), c(x, { points: w, color: E, lineWidth: h, closing: !0, grew: P && w === T }), s.lineTo(w[w.length - 1].x, d), s.lineTo(w[0].x, d), s.closePath(), s.fill());
586
644
  }
587
645
  if (this.options.points?.visible) {
588
- const S = [];
589
- for (const B of T)
590
- for (const P of B) S.push(P);
591
- this.drawPointMarkers({ context: s, points: S, pixelRatio: e.horizontalPixelRatio, color: M });
646
+ const d = [];
647
+ for (const S of u)
648
+ for (const w of S) d.push(w);
649
+ this.drawPointMarkers({ context: s, points: d, pixelRatio: i.horizontalPixelRatio, color: E });
592
650
  }
593
- (I || v) && s.restore();
651
+ (I || G) && s.restore();
594
652
  }
595
653
  }
596
654
  /** Stacked area rendering */
597
- renderStacked(t, e) {
598
- const { scope: i, timeScale: o, yScale: s } = t, { context: n } = i, a = o.getRange(), { verticalPixelRatio: u } = i, l = this.options.strokeWidth > 0, p = Math.max(1, Math.round(this.options.strokeWidth * u)), h = this.options.curve ?? "straight", d = i.mediaSize.width, r = this.stores.map((m, v) => {
655
+ renderStacked(t, i) {
656
+ const { scope: e, timeScale: o, yScale: s } = t, { context: l } = e, r = o.getRange(), { verticalPixelRatio: f } = e, h = this.options.strokeWidth > 0, m = Math.max(1, Math.round(this.options.strokeWidth * f)), c = this.options.curve ?? "straight", x = e.mediaSize.width, n = this.stores.map((u, v) => {
599
657
  if (this.getLayerAlpha(v) <= 0) return [];
600
- let b = m.getVisibleData(a.from, a.to);
601
- return b.length > d * 2 && (b = K(b, Math.round(d * 1.5))), b;
602
- }), f = /* @__PURE__ */ new Set();
603
- for (const m of r)
604
- for (const v of m) f.add(v.time);
605
- const c = Array.from(f).sort((m, v) => m - v);
606
- if (c.length < 2) {
658
+ let M = u.getVisibleData(r.from, r.to);
659
+ return M.length > x * 2 && (M = q(M, Math.round(x * 1.5))), M;
660
+ }), p = /* @__PURE__ */ new Set();
661
+ for (const u of n)
662
+ for (const v of u) p.add(v.time);
663
+ const a = Array.from(p).sort((u, v) => u - v);
664
+ if (a.length < 2) {
607
665
  this.stackedEdges = null;
608
666
  return;
609
667
  }
610
- const y = this.options.entryAnimation ?? "grow", R = r.map((m, v) => {
611
- const b = /* @__PURE__ */ new Map();
612
- if (m.length === 0) return b;
613
- const T = this.getLayerAlpha(v), x = m[0].time, k = y === "grow" ? this.chainedTailValues(v, (A, F) => this.effectiveValue(t, v, A, F)) : null, L = (A) => k?.get(A.time) ?? this.effectiveValue(t, v, A.time, A.value);
614
- for (const A of c) {
615
- if (A < x) continue;
616
- const F = j(m, A, L);
617
- F !== null && b.set(A, F * T);
668
+ const g = this.options.entryAnimation ?? "grow", A = n.map((u, v) => {
669
+ const M = /* @__PURE__ */ new Map();
670
+ if (u.length === 0) return M;
671
+ const b = u[0].time, P = g === "grow" ? this.chainedTailValues(v, (d, S) => this.effectiveValue(t, v, d, S)) : null, T = (d) => P?.get(d.time) ?? this.effectiveValue(t, v, d.time, d.value);
672
+ for (const d of a) {
673
+ if (d < b) continue;
674
+ const S = j(u, d, { resolve: T });
675
+ S !== null && M.set(d, S);
618
676
  }
619
- return b;
620
- }), M = Array.from({ length: this.stores.length }, () => new Array(c.length).fill(0));
621
- for (let m = 0; m < c.length; m++) {
622
- const v = c[m];
623
- let b = 0;
624
- if (e)
625
- for (let x = 0; x < this.stores.length; x++) {
626
- const k = R[x].get(v);
627
- Number.isFinite(k) && (b += k);
677
+ return M;
678
+ }), E = this.stores.map((u, v) => this.getLayerAlpha(v)), B = (u, v) => {
679
+ const M = A[u].get(v);
680
+ return M === void 0 ? void 0 : M * E[u];
681
+ }, L = s.getTransform() !== null && !i, D = Array.from({ length: this.stores.length }, () => new Array(a.length).fill(0));
682
+ for (let u = 0; u < a.length; u++) {
683
+ const v = a[u];
684
+ if (L) {
685
+ const P = new it(s);
686
+ for (let T = 0; T < this.stores.length; T++) {
687
+ const d = A[T].get(v);
688
+ d !== void 0 && s.isPlottable(d) && P.push(d, E[T]), D[T][u] = P.edge;
628
689
  }
629
- let T = 0;
630
- for (let x = 0; x < this.stores.length; x++) {
631
- const k = R[x].get(v), L = Number.isFinite(k) ? k : 0;
632
- T += e && b > 0 ? L / b * 100 : L, M[x][m] = T;
690
+ continue;
691
+ }
692
+ let M = 0;
693
+ if (i)
694
+ for (let P = 0; P < this.stores.length; P++) {
695
+ const T = B(P, v);
696
+ T !== void 0 && s.isPlottable(T) && (M += T);
697
+ }
698
+ let b = 0;
699
+ for (let P = 0; P < this.stores.length; P++) {
700
+ const T = B(P, v);
701
+ let d = T !== void 0 && s.isPlottable(T) ? T : null;
702
+ const S = n[P];
703
+ if (i && S.length > 0 && v < S[0].time && (d = 0), d !== null)
704
+ if (i) {
705
+ const w = this.introShare(t, { layerIndex: P, time: v, value: d, total: M });
706
+ b = Math.min(100, b + w);
707
+ } else
708
+ b += d;
709
+ D[P][u] = b;
633
710
  }
634
711
  }
635
- const V = /* @__PURE__ */ new Map();
636
- for (let m = 0; m < c.length; m++) V.set(c[m], m);
637
- const C = new Array(this.stores.length).fill(1);
638
- for (let m = 0; m < this.stores.length; m++) {
639
- if (this.getLayerAlpha(m) <= 0) continue;
640
- const v = this.unsettledTail(m), b = v.length;
641
- if (b === 0) continue;
642
- let T = !0;
643
- for (let x = 0; x < b; x++)
644
- if (V.get(v[x].time) !== c.length - b + x) {
645
- T = !1;
712
+ const Y = /* @__PURE__ */ new Map();
713
+ for (let u = 0; u < a.length; u++) Y.set(a[u], u);
714
+ const z = new Array(this.stores.length).fill(1);
715
+ for (let u = 0; u < this.stores.length; u++) {
716
+ if (this.getLayerAlpha(u) <= 0) continue;
717
+ const v = this.unsettledTail(u), M = v.length;
718
+ if (M === 0) continue;
719
+ let b = !0;
720
+ for (let P = 0; P < M; P++)
721
+ if (Y.get(v[P].time) !== a.length - M + P) {
722
+ b = !1;
646
723
  break;
647
724
  }
648
- T && (C[m] = v[b - 1].progress);
725
+ b && (z[u] = v[M - 1].progress);
649
726
  }
650
- const N = [];
651
- if (y === "grow") {
652
- const m = r.map((v) => v.length - 1);
653
- for (let v = c.length - 1; v >= 1; v--) {
654
- const b = c[v];
655
- let T = 1, x = !1;
656
- for (let k = 0; k < r.length; k++) {
657
- if (this.getLayerAlpha(k) <= 0) continue;
658
- const L = r[k];
659
- for (; m[k] >= 0 && L[m[k]].time > b; ) m[k]--;
660
- if (m[k] < 0 || L[m[k]].time !== b) continue;
661
- const A = this.entranceProgress(k, b);
662
- (!x || A > T) && (T = A), x = !0;
727
+ const I = [];
728
+ if (g === "grow") {
729
+ const u = n.map((v) => v.length - 1);
730
+ for (let v = a.length - 1; v >= 1; v--) {
731
+ const M = a[v];
732
+ let b = 1, P = !1;
733
+ for (let T = 0; T < n.length; T++) {
734
+ if (this.getLayerAlpha(T) <= 0) continue;
735
+ const d = n[T];
736
+ for (; u[T] >= 0 && d[u[T]].time > M; ) u[T]--;
737
+ if (u[T] < 0 || d[u[T]].time !== M) continue;
738
+ const S = this.entranceProgress(T, M);
739
+ (!P || S > b) && (b = S), P = !0;
663
740
  }
664
- if (!x || T >= 1) break;
665
- N.unshift(U(T));
741
+ if (!P || b >= 1) break;
742
+ I.unshift(U(b));
666
743
  }
667
744
  }
668
- const D = (m, v) => {
669
- const b = v.length;
670
- if (!(b === 0 || m.length < b + 1))
671
- for (let T = 0; T < b; T++) {
672
- const x = m.length - b + T;
673
- m[x][0] = Y(m[x - 1][0], m[x][0], v[T]);
745
+ const O = (u, v) => {
746
+ const M = v.length;
747
+ if (!(M === 0 || u.length < M + 1))
748
+ for (let b = 0; b < M; b++) {
749
+ const P = u.length - M + b;
750
+ u[P][0] = N(u[P - 1][0], u[P][0], v[b]);
674
751
  }
675
- }, z = i.bitmapSize.height;
676
- let I = -1, G = -1;
677
- for (let m = 0; m < this.stores.length; m++)
678
- if (!(this.getLayerAlpha(m) <= 0))
679
- if (I < 0)
680
- I = m;
752
+ }, W = e.bitmapSize.height;
753
+ let C = -1, _ = -1;
754
+ for (let u = 0; u < this.stores.length; u++)
755
+ if (!(this.getLayerAlpha(u) <= 0))
756
+ if (C < 0)
757
+ C = u;
681
758
  else {
682
- G = m;
759
+ _ = u;
683
760
  break;
684
761
  }
685
- const H = I >= 0 ? this.getLayerAlpha(I) : 1, _ = r.map((m, v) => v === I ? Math.min(1, this.getLayerAlpha(v)) : 1);
686
- for (let m = this.stores.length - 1; m >= 0; m--) {
687
- const v = this.getLayerAlpha(m);
762
+ const G = C >= 0 ? this.getLayerAlpha(C) : 1, $ = n.map((u, v) => v === C ? Math.min(1, this.getLayerAlpha(v)) : 1);
763
+ for (let u = this.stores.length - 1; u >= 0; u--) {
764
+ const v = this.getLayerAlpha(u);
688
765
  if (v <= 0) continue;
689
- const b = this.stores[m].last()?.value ?? 0, T = this.resolveLayerColor(m, b), x = m === I, k = G >= 0 && m === G && H < 1, L = [];
690
- for (let w = 0; w < c.length; w++) {
691
- const X = m > 0 ? s.valueToBitmapYExact(M[m - 1][w]) : z;
692
- let O = X;
693
- x ? O = z : k && (O = X + (z - X) * (1 - H)), L.push([o.timeToBitmapXExact(c[w]), O]);
766
+ const M = this.stores[u].last()?.value ?? 0, b = this.resolveLayerColor(u, M), P = u === C, T = _ >= 0 && u === _ && G < 1, d = [];
767
+ for (let R = 0; R < a.length; R++) {
768
+ const V = u > 0 ? s.valueToBitmapYExact(D[u - 1][R]) : W;
769
+ let H = V;
770
+ P ? H = W : T && (H = V + (W - V) * (1 - G)), d.push([o.timeToBitmapXExact(a[R]), H]);
694
771
  }
695
- y === "grow" && D(L, N);
696
- const A = [];
697
- for (let w = 0; w < c.length; w++) {
698
- let X = s.valueToBitmapYExact(M[m][w]);
699
- x && v < 1 && (X = z + (X - z) * v), A.push([o.timeToBitmapXExact(c[w]), X]);
772
+ g === "grow" && O(d, I);
773
+ const S = [];
774
+ for (let R = 0; R < a.length; R++) {
775
+ let V = s.valueToBitmapYExact(D[u][R]);
776
+ P && v < 1 && (V = W + (V - W) * v), S.push([o.timeToBitmapXExact(a[R]), V]);
700
777
  }
701
- y === "grow" && D(A, N);
702
- const F = $(A), S = Q(F, h, y === "grow" && N.length > 0), B = y === "fade" && C[m] < 1;
703
- if (B && (n.save(), n.globalAlpha *= C[m]), this.options.area.visible && !this.introGhostPass) {
704
- let w = A[0][1], X = L[0][1];
705
- for (let E = 1; E < A.length; E++)
706
- A[E][1] < w && (w = A[E][1]);
707
- for (let E = 1; E < L.length; E++)
708
- L[E][1] > X && (X = L[E][1]);
709
- let O = W(T, 0.25);
710
- if (X > w + 0.5) {
711
- const E = n.createLinearGradient(0, w, 0, X);
712
- E.addColorStop(0, W(T, 0.25)), E.addColorStop(1, W(T, 0.05)), O = E;
778
+ g === "grow" && O(S, I);
779
+ const w = st(S), F = tt(w, c, g === "grow" && I.length > 0), K = g === "fade" && z[u] < 1;
780
+ if (K && (l.save(), l.globalAlpha *= z[u]), this.options.area.visible && !this.introGhostPass) {
781
+ let R = S[0][1], V = d[0][1];
782
+ for (let k = 1; k < S.length; k++)
783
+ S[k][1] < R && (R = S[k][1]);
784
+ for (let k = 1; k < d.length; k++)
785
+ d[k][1] > V && (V = d[k][1]);
786
+ let H = X(b, 0.25);
787
+ if (V > R + 0.5) {
788
+ const k = l.createLinearGradient(0, R, 0, V);
789
+ k.addColorStop(0, X(b, 0.25)), k.addColorStop(1, X(b, 0.05)), H = k;
713
790
  }
714
- if (n.beginPath(), n.moveTo(F[0].x, F[0].y), tt(n, S), x)
715
- for (let E = L.length - 1; E >= 0; E--)
716
- n.lineTo(L[E][0], L[E][1]);
791
+ if (l.beginPath(), l.moveTo(w[0].x, w[0].y), et(l, F), P)
792
+ for (let k = d.length - 1; k >= 0; k--)
793
+ l.lineTo(d[k][0], d[k][1]);
717
794
  else {
718
- const E = $(L), rt = Q(E, h, y === "grow" && N.length > 0), q = E[E.length - 1];
719
- n.lineTo(q.x, q.y), ft(n, E, rt);
795
+ const k = st(d), ct = tt(k, c, g === "grow" && I.length > 0), Z = k[k.length - 1];
796
+ l.lineTo(Z.x, Z.y), gt(l, k, ct);
720
797
  }
721
- n.closePath(), n.fillStyle = O, n.fill();
798
+ l.closePath(), l.fillStyle = H, l.fill();
722
799
  }
723
- const P = l && v < 1;
724
- if (P && (n.save(), n.globalAlpha *= v), l && (n.beginPath(), n.moveTo(F[0].x, F[0].y), tt(n, S), n.strokeStyle = T, n.lineWidth = p, n.lineJoin = "round", n.lineCap = "round", n.stroke()), P && n.restore(), this.options.points?.visible) {
725
- const w = v < 1;
726
- w && (n.save(), n.globalAlpha *= v), this.drawPointMarkers({ context: n, points: F, pixelRatio: i.horizontalPixelRatio, color: T }), w && n.restore();
800
+ const Q = h && v < 1;
801
+ if (Q && (l.save(), l.globalAlpha *= v), h && (l.beginPath(), l.moveTo(w[0].x, w[0].y), et(l, F), l.strokeStyle = b, l.lineWidth = m, l.lineJoin = "round", l.lineCap = "round", l.stroke()), Q && l.restore(), this.options.points?.visible) {
802
+ const R = v < 1;
803
+ R && (l.save(), l.globalAlpha *= v), this.drawPointMarkers({ context: l, points: w, pixelRatio: e.horizontalPixelRatio, color: b }), R && l.restore();
727
804
  }
728
- B && n.restore();
805
+ K && l.restore();
729
806
  }
730
- this.stackedEdges = { times: c, cumulative: M, growChain: N, collapse: _ };
807
+ this.stackedEdges = { times: a, cumulative: D, growChain: I, collapse: $ };
731
808
  }
732
809
  /**
733
810
  * Overlay hook: draws crosshair nearest-point dots and last-point pulse dots.
@@ -735,80 +812,81 @@ class dt extends at {
735
812
  */
736
813
  drawOverlay(t) {
737
814
  this.tickAnimations(performance.now());
738
- const { scope: e, timeScale: i, yScale: o, crosshair: s, dataInterval: n } = t, a = e, u = this.options.pulseMs, l = u > 0 ? performance.now() / (u * 2 * Math.PI) % 1 : 0;
815
+ const { scope: i, timeScale: e, yScale: o, crosshair: s, dataInterval: l } = t, r = i, f = this.options.pulseMs, h = f > 0 ? performance.now() / (f * 2 * Math.PI) % 1 : 0;
739
816
  if (s) {
740
- const d = this.options.stacking, r = 4 * a.horizontalPixelRatio;
741
- for (let f = 0; f < this.stores.length; f++) {
742
- const c = this.getLayerAlpha(f);
743
- if (c <= 0) continue;
744
- const y = this.stores[f].findNearest(s.time, n);
745
- if (!y) continue;
746
- const R = this.resolveLayerColor(f, y.value), { x: M, y: V } = d === "off" ? {
747
- x: i.timeToBitmapXExact(y.time),
748
- y: o.valueToBitmapYExact(this.effectiveValue(t, f, y.time, y.value))
749
- } : this.stackedPositionAt(t, f, y.time), C = c < 1;
750
- C && (e.context.save(), e.context.globalAlpha *= c), e.context.save(), e.context.globalAlpha *= 0.25, e.context.beginPath(), e.context.arc(M, V, r + 3 * a.horizontalPixelRatio, 0, Math.PI * 2), e.context.fillStyle = R, e.context.fill(), e.context.restore(), e.context.beginPath(), e.context.arc(M, V, r, 0, Math.PI * 2), e.context.fillStyle = R, e.context.fill(), C && e.context.restore();
817
+ const x = this.options.stacking, n = 4 * r.horizontalPixelRatio;
818
+ for (let p = 0; p < this.stores.length; p++) {
819
+ const a = this.getLayerAlpha(p);
820
+ if (a <= 0) continue;
821
+ const g = this.stores[p].findNearest(s.time, l);
822
+ if (!g || x === "off" && !o.isPlottable(g.value)) continue;
823
+ const A = this.resolveLayerColor(p, g.value), { x: E, y: B } = x === "off" ? {
824
+ x: e.timeToBitmapXExact(g.time),
825
+ y: o.valueToBitmapYExact(this.effectiveValue(t, p, g.time, g.value))
826
+ } : this.stackedPositionAt(t, p, g.time), L = a < 1;
827
+ L && (i.context.save(), i.context.globalAlpha *= a), i.context.save(), i.context.globalAlpha *= 0.25, i.context.beginPath(), i.context.arc(E, B, n + 3 * r.horizontalPixelRatio, 0, Math.PI * 2), i.context.fillStyle = A, i.context.fill(), i.context.restore(), i.context.beginPath(), i.context.arc(E, B, n, 0, Math.PI * 2), i.context.fillStyle = A, i.context.fill(), L && i.context.restore();
751
828
  }
752
829
  }
753
- const p = this.introWave.active && this.introDirectives?.clip !== void 0;
754
- let h = 1;
755
- if (p && (h = Math.max(0, (this.introWave.linear() - (1 - J)) / J)), this.hasPulse && u > 0 && h > 0) {
756
- const d = this.options.stacking;
757
- for (let r = 0; r < this.stores.length; r++) {
758
- const f = this.getLayerAlpha(r);
759
- if (f <= 0) continue;
760
- const c = this.stores[r].last()?.value ?? 0, y = this.resolveLayerColor(r, c);
761
- if (d === "off") {
762
- const C = this.trailingEndpoint(t, r);
763
- if (!C) continue;
830
+ const m = this.introWave.active && this.introDirectives?.clip !== void 0;
831
+ let c = 1;
832
+ if (m && (c = Math.max(0, (this.introWave.linear() - (1 - J)) / J)), this.hasPulse && f > 0 && c > 0) {
833
+ const x = this.options.stacking;
834
+ for (let n = 0; n < this.stores.length; n++) {
835
+ const p = this.getLayerAlpha(n);
836
+ if (p <= 0) continue;
837
+ const a = this.stores[n].last()?.value ?? 0, g = this.resolveLayerColor(n, a);
838
+ if (x === "off") {
839
+ if (!o.isPlottable(a)) continue;
840
+ const L = this.trailingEndpoint(t, n);
841
+ if (!L) continue;
764
842
  this.drawPulse({
765
- ctx: e.context,
766
- x: C.x,
767
- y: C.y,
768
- color: y,
769
- pixelRatio: a.horizontalPixelRatio,
770
- phase: l,
771
- alpha: f * h
843
+ ctx: i.context,
844
+ x: L.x,
845
+ y: L.y,
846
+ color: g,
847
+ pixelRatio: r.horizontalPixelRatio,
848
+ phase: h,
849
+ alpha: p * c
772
850
  });
773
851
  continue;
774
852
  }
775
- const R = this.stores[r].last();
776
- if (!R) continue;
777
- const { x: M, y: V } = this.stackedPositionAt(t, r, R.time);
853
+ const A = this.stores[n].last();
854
+ if (!A) continue;
855
+ const { x: E, y: B } = this.stackedPositionAt(t, n, A.time);
778
856
  this.drawPulse({
779
- ctx: e.context,
780
- x: M,
781
- y: V,
782
- color: y,
783
- pixelRatio: a.horizontalPixelRatio,
784
- phase: l,
785
- alpha: f * h
857
+ ctx: i.context,
858
+ x: E,
859
+ y: B,
860
+ color: g,
861
+ pixelRatio: r.horizontalPixelRatio,
862
+ phase: h,
863
+ alpha: p * c
786
864
  });
787
865
  }
788
866
  }
789
867
  }
790
868
  drawPulse({
791
869
  ctx: t,
792
- x: e,
793
- y: i,
870
+ x: i,
871
+ y: e,
794
872
  color: o,
795
873
  pixelRatio: s,
796
- phase: n,
797
- alpha: a = 1
874
+ phase: l,
875
+ alpha: r = 1
798
876
  }) {
799
- const u = 3 * s, l = 0.4 + 0.6 * Math.abs(Math.sin(n * 2 * Math.PI)), p = u + 4 * s * l, h = a < 1;
800
- h && (t.save(), t.globalAlpha *= a), t.beginPath(), t.arc(e, i, p, 0, Math.PI * 2), t.fillStyle = W(o, l * 0.3), t.fill(), t.beginPath(), t.arc(e, i, u, 0, Math.PI * 2), t.fillStyle = o, t.fill(), h && t.restore();
877
+ const f = 3 * s, h = 0.4 + 0.6 * Math.abs(Math.sin(l * 2 * Math.PI)), m = f + 4 * s * h, c = r < 1;
878
+ c && (t.save(), t.globalAlpha *= r), t.beginPath(), t.arc(i, e, m, 0, Math.PI * 2), t.fillStyle = X(o, h * 0.3), t.fill(), t.beginPath(), t.arc(i, e, f, 0, Math.PI * 2), t.fillStyle = o, t.fill(), c && t.restore();
801
879
  }
802
880
  }
803
- const wt = {
881
+ const Bt = {
804
882
  type: "line",
805
- create: ({ theme: g, layerCount: t }, e) => new dt(t, {
806
- colors: t === 1 ? [g.line.color] : g.seriesColors.slice(0, t),
807
- strokeWidth: g.line.width,
808
- ...e
883
+ create: ({ theme: y, layerCount: t }, i) => new Pt(t, {
884
+ colors: t === 1 ? [y.line.color] : y.seriesColors.slice(0, t),
885
+ strokeWidth: y.line.width,
886
+ ...i
809
887
  })
810
888
  };
811
889
  export {
812
- dt as LineRenderer,
813
- wt as LineSeriesDef
890
+ Pt as LineRenderer,
891
+ Bt as LineSeriesDef
814
892
  };