@wick-charts/vue 0.6.1 → 0.6.3

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