@wick-charts/vue 0.8.1 → 0.8.2

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 (38) hide show
  1. package/dist/BandSeries.vue.js +25 -24
  2. package/dist/BarSeries.vue.js +27 -26
  3. package/dist/CandlestickSeries.vue.js +25 -24
  4. package/dist/HeatmapSeries.vue.js +21 -20
  5. package/dist/LineSeries.vue.js +24 -23
  6. package/dist/PieSeries.vue.js +25 -24
  7. package/dist/composables.js +63 -36
  8. package/dist/core/dist/axis/dom-labels.js +64 -53
  9. package/dist/core/dist/chart/options.js +1 -1
  10. package/dist/core/dist/chart/y-target.js +38 -32
  11. package/dist/core/dist/chart.js +475 -439
  12. package/dist/core/dist/data/decimation.js +52 -51
  13. package/dist/core/dist/data/store.js +38 -20
  14. package/dist/core/dist/data/sync.js +80 -69
  15. package/dist/core/dist/perf/perf-hud.js +3 -3
  16. package/dist/core/dist/scales/tick-tracker.js +2 -1
  17. package/dist/core/dist/series/band.js +1 -1
  18. package/dist/core/dist/series/bar.js +240 -211
  19. package/dist/core/dist/series/base-multi-layer.js +267 -249
  20. package/dist/core/dist/series/candlestick.js +116 -116
  21. package/dist/core/dist/series/line.js +540 -455
  22. package/dist/core/dist/snapshots.js +96 -77
  23. package/dist/index.d.ts +22 -4
  24. package/dist/ui/InfoBar.vue.js +68 -68
  25. package/dist/ui/NumberFlow.vue.js +36 -27
  26. package/dist/ui/Tooltip.vue.js +127 -130
  27. package/package.json +2 -2
  28. package/src/BandSeries.vue +5 -3
  29. package/src/BarSeries.vue +5 -3
  30. package/src/CandlestickSeries.vue +5 -4
  31. package/src/ChartContainer.vue +1 -1
  32. package/src/HeatmapSeries.vue +5 -4
  33. package/src/LineSeries.vue +5 -3
  34. package/src/PieSeries.vue +6 -5
  35. package/src/composables.ts +64 -1
  36. package/src/ui/InfoBar.vue +11 -3
  37. package/src/ui/NumberFlow.vue +17 -3
  38. package/src/ui/Tooltip.vue +23 -12
@@ -1,9 +1,9 @@
1
- import { DEFAULT_HISTORY_REVEAL as I, DEFAULT_BAR_INTRO as O, DEFAULT_BAR_SMOOTH as C, DEFAULT_BAR_ENTRY as _ } from "../animation/config.js";
2
- import { growIntro as U } from "./bar-intro.js";
3
- import { BaseMultiLayerSeries as N } from "./base-multi-layer.js";
4
- import { resolveBarPainter as $ } from "./painters/resolve.js";
1
+ import { DEFAULT_HISTORY_REVEAL as D, DEFAULT_BAR_INTRO as C, DEFAULT_BAR_SMOOTH as O, DEFAULT_BAR_ENTRY as _ } from "../animation/config.js";
2
+ import { growIntro as N } from "./bar-intro.js";
3
+ import { BaseMultiLayerSeries as U } from "./base-multi-layer.js";
4
+ import { resolveBarPainter as G } from "./painters/resolve.js";
5
5
  import { ScaleStack as z } from "./scale-stack.js";
6
- import { fadeIntro as G } from "./wave-intro.js";
6
+ import { fadeIntro as $ } from "./wave-intro.js";
7
7
  const F = 2, J = {
8
8
  // Single fallback resolver; the definition's `create` swaps in `theme.bar.color`.
9
9
  colors: ["#26a69a"],
@@ -12,34 +12,34 @@ const F = 2, J = {
12
12
  anchor: "center",
13
13
  cornerRadius: F,
14
14
  entryMs: _,
15
- smoothMs: C,
16
- introMs: O,
17
- historyRevealMs: I
15
+ smoothMs: O,
16
+ introMs: C,
17
+ historyRevealMs: D
18
18
  };
19
- function D(y) {
19
+ function I(y) {
20
20
  return {
21
21
  ...y,
22
22
  entryMs: y.entryMs === !1 ? 0 : y.entryMs ?? _,
23
- smoothMs: y.smoothMs === !1 ? 0 : y.smoothMs ?? C,
24
- introMs: y.introMs === !1 ? 0 : y.introMs ?? O,
25
- historyRevealMs: y.historyRevealMs === !1 ? 0 : y.historyRevealMs ?? I
23
+ smoothMs: y.smoothMs === !1 ? 0 : y.smoothMs ?? O,
24
+ introMs: y.introMs === !1 ? 0 : y.introMs ?? C,
25
+ historyRevealMs: y.historyRevealMs === !1 ? 0 : y.historyRevealMs ?? D
26
26
  };
27
27
  }
28
- const Q = U(), Z = G(), q = {
28
+ const Q = N(), Z = $(), q = {
29
29
  top: { tl: !0, tr: !0, br: !1, bl: !1 },
30
30
  bottom: { tl: !1, tr: !1, br: !0, bl: !0 },
31
31
  none: { tl: !1, tr: !1, br: !1, bl: !1 }
32
32
  };
33
33
  function K(y) {
34
34
  const e = [], t = [];
35
- let o = 0, r = 0;
35
+ let o = 0, s = 0;
36
36
  for (const i of y) {
37
- const l = i > 0 ? o : r;
38
- e.push(l), t.push(l + i), i > 0 ? o += i : r += i;
37
+ const h = i > 0 ? o : s;
38
+ e.push(h), t.push(h + i), i > 0 ? o += i : s += i;
39
39
  }
40
40
  return { base: e, end: t };
41
41
  }
42
- class tt extends N {
42
+ class tt extends U {
43
43
  kind = "bar";
44
44
  /** Resolved drawing context for the in-flight render pass. Set at the top of
45
45
  * {@link render}, read by {@link drawAnimatedBar}. */
@@ -53,10 +53,14 @@ class tt extends N {
53
53
  /** Per-frame history-reveal directives; `null` when no reveal is in flight. */
54
54
  #t = null;
55
55
  constructor(e, t) {
56
- super(e), this.options = D({ ...J, ...t });
56
+ super(e), this.options = I({ ...J, ...t });
57
57
  }
58
58
  updateOptions(e) {
59
- this.options = D({ ...this.options, ...e });
59
+ this.options = I({ ...this.options, ...e });
60
+ }
61
+ getValueRange(e, t, o) {
62
+ const s = super.getValueRange(e, t, o), i = o?.plottable?.(0) ?? !0;
63
+ return s === null || !i ? s : { min: Math.min(0, s.min), max: Math.max(0, s.max) };
60
64
  }
61
65
  isEntryEnabled() {
62
66
  return (this.options.entryAnimation ?? "fade-grow") !== "none";
@@ -65,10 +69,10 @@ class tt extends N {
65
69
  * Normalized x-position + eased wave progress for the intro's callbacks.
66
70
  * `null` when no intro is in flight this frame.
67
71
  */
68
- #a(e) {
72
+ #s(e) {
69
73
  const t = this.#i;
70
74
  if (t === null) return null;
71
- const o = t.to - t.from, r = o > 0 ? (e - t.from) / o : 0, i = Math.min(1, Math.max(0, r));
75
+ const o = t.to - t.from, s = o > 0 ? (e - t.from) / o : 0, i = Math.min(1, Math.max(0, s));
72
76
  return { position: i, progress: this.introWave.progressAt(i) };
73
77
  }
74
78
  /**
@@ -77,10 +81,10 @@ class tt extends N {
77
81
  * the deepest prepended point). `null` for bars outside the prepended
78
82
  * span or when no reveal is in flight this frame.
79
83
  */
80
- #s(e) {
84
+ #a(e) {
81
85
  const t = this.historyRange;
82
86
  if (this.#t === null || t === null || e >= t.to) return null;
83
- const o = t.to - t.from, r = o > 0 ? (t.to - e) / o : 0, i = Math.min(1, Math.max(0, r));
87
+ const o = t.to - t.from, s = o > 0 ? (t.to - e) / o : 0, i = Math.min(1, Math.max(0, s));
84
88
  return { position: i, progress: this.historyWave.progressAt(i) };
85
89
  }
86
90
  /**
@@ -95,19 +99,44 @@ class tt extends N {
95
99
  if (this.isProjectedTime(e.time)) return e.value;
96
100
  const t = this.#t?.value;
97
101
  if (t !== void 0) {
98
- const i = this.#s(e.time);
102
+ const i = this.#a(e.time);
99
103
  if (i !== null) return t({ ...e, ...i });
100
104
  }
101
105
  const o = this.#e?.value;
102
106
  if (o === void 0) return e.value;
103
- const r = this.#a(e.time);
104
- return r === null ? e.value : o({ ...e, ...r });
107
+ const s = this.#s(e.time);
108
+ return s === null ? e.value : o({ ...e, ...s });
105
109
  }
106
110
  applyTheme(e, t) {
107
- const o = this.stores.length === 1, r = e.seriesColors[0] ?? "#26a69a", i = o ? [e.bar?.color ?? r] : e.seriesColors.slice(0, this.stores.length);
111
+ const o = this.stores.length === 1, s = e.seriesColors[0] ?? "#26a69a", i = o ? [e.bar?.color ?? s] : e.seriesColors.slice(0, this.stores.length);
108
112
  this.updateOptions({ colors: i });
109
113
  }
110
114
  /** True when `time` is at/after the configured `projectedFrom` forecast cut. */
115
+ /**
116
+ * The bar stack's reading of a percent column (see `renderStacked`): each
117
+ * layer's sample at `time` as drawn — smoothed, faded, growing in, intro applied — with
118
+ * positives scaled to 100% and negatives to -100% on their own; `null` when
119
+ * the column draws nothing.
120
+ */
121
+ percentShares(e) {
122
+ const t = this.options.entryAnimation ?? "fade-grow", o = (t === "grow" || t === "fade-grow") && !this.isProjectedTime(e), s = /* @__PURE__ */ new Map();
123
+ let i = 0, h = 0;
124
+ for (let c = 0; c < this.stores.length; c++) {
125
+ const m = this.getLayerAlpha(c);
126
+ if (m <= 0) continue;
127
+ const l = this.stores[c].findNearest(e, 0);
128
+ if (l === null || !Number.isFinite(l.value)) continue;
129
+ const r = o ? this.entranceProgress(c, e) : 1, u = this.liveValue(c, e, l.value) * m * r, a = this.introValue({ layerIndex: c, time: e, value: u });
130
+ s.set(c, a), a > 0 && (i += a), a < 0 && (h += a);
131
+ }
132
+ if (i === 0 && h === 0) return null;
133
+ const d = /* @__PURE__ */ new Map();
134
+ for (const [c, m] of s) {
135
+ let l = 0;
136
+ m > 0 && (l = m / i * 100), m < 0 && (l = m / h * -100), d.set(c, l);
137
+ }
138
+ return d;
139
+ }
111
140
  isProjectedTime(e) {
112
141
  const t = this.options.projectedFrom;
113
142
  return t !== void 0 && e >= t;
@@ -118,21 +147,21 @@ class tt extends N {
118
147
  * each render path.
119
148
  */
120
149
  applyBarTransform(e, t) {
121
- const { baselineY: o, topY: r, barHeight: i, x: l, barWidth: m } = e, d = this.options.entryAnimation ?? "fade-grow";
122
- if (t >= 1 || d === "none")
123
- return { topY: r, barHeight: i, x: l, barWidth: m, alpha: 1 };
124
- let u = r, h = i, s = l, g = 1;
125
- if ((d === "fade" || d === "fade-grow") && (g = t), (d === "grow" || d === "fade-grow") && !e.growBaked) {
126
- const n = i * t;
127
- r < o ? u = o - n : u = o, h = Math.max(1, n);
150
+ const { baselineY: o, topY: s, barHeight: i, x: h, barWidth: d } = e, c = this.options.entryAnimation ?? "fade-grow";
151
+ if (t >= 1 || c === "none")
152
+ return { topY: s, barHeight: i, x: h, barWidth: d, alpha: 1 };
153
+ let m = s, l = i, r = h, u = 1;
154
+ if ((c === "fade" || c === "fade-grow") && (u = t), (c === "grow" || c === "fade-grow") && !e.growBaked) {
155
+ const a = i * t;
156
+ s < o ? m = o - a : m = o, l = Math.max(1, a);
128
157
  }
129
- return d === "slide" && (s = l + (1 - t) * m, g = t), { topY: u, barHeight: h, x: s, barWidth: m, alpha: g };
158
+ return c === "slide" && (r = h + (1 - t) * d, u = t), { topY: m, barHeight: l, x: r, barWidth: d, alpha: u };
130
159
  }
131
160
  render(e) {
132
161
  this.tickAnimations(performance.now());
133
- const { scope: t, timeScale: o, yScale: r } = e;
162
+ const { scope: t, timeScale: o, yScale: s } = e;
134
163
  this.#o = {
135
- painter: $(this.options.barPainter),
164
+ painter: G(this.options.barPainter),
136
165
  env: {
137
166
  ctx: t.context,
138
167
  theme: e.theme,
@@ -142,46 +171,46 @@ class tt extends N {
142
171
  radius: (this.options.cornerRadius ?? F) * t.horizontalPixelRatio
143
172
  };
144
173
  const i = {
145
- baseline: r.baselineValue(),
146
- lerpValue: (h, s, g) => r.lerpValue(h, s, g)
174
+ baseline: s.baselineValue(),
175
+ lerpValue: (l, r, u) => s.lerpValue(l, r, u)
147
176
  };
148
177
  if (this.#e = null, this.#i = null, this.introWave.active) {
149
- const h = this.options.introAnimation ?? Q, s = o.getRange();
150
- this.#i = s, this.#e = h({
178
+ const l = this.options.introAnimation ?? Q, r = o.getRange();
179
+ this.#i = r, this.#e = l({
151
180
  progress: this.introWave.linear(),
152
181
  // Plot-area extent, not the canvas bitmap — the canvas also carries
153
182
  // the axis strips, so a width-based front (wipeIntro) would overshoot
154
183
  // the data area.
155
184
  width: o.getMediaWidth() * t.horizontalPixelRatio,
156
- height: r.getMediaHeight() * t.verticalPixelRatio,
157
- range: s,
158
- timeToX: (g) => o.timeToBitmapX(g),
185
+ height: s.getMediaHeight() * t.verticalPixelRatio,
186
+ range: r,
187
+ timeToX: (u) => o.timeToBitmapX(u),
159
188
  ...i
160
189
  });
161
190
  }
162
191
  this.#t = null;
163
- const l = this.historyRange;
164
- if (this.historyWave.active && l !== null) {
165
- const h = this.options.historyReveal ?? Z;
166
- h !== "none" && (this.#t = h({
192
+ const h = this.historyRange;
193
+ if (this.historyWave.active && h !== null) {
194
+ const l = this.options.historyReveal ?? Z;
195
+ l !== "none" && (this.#t = l({
167
196
  progress: this.historyWave.linear(),
168
- width: Math.abs(o.timeToBitmapX(l.to) - o.timeToBitmapX(l.from)),
169
- height: r.getMediaHeight() * t.verticalPixelRatio,
170
- range: l,
171
- timeToX: (s) => o.timeToBitmapX(s),
197
+ width: Math.abs(o.timeToBitmapX(h.to) - o.timeToBitmapX(h.from)),
198
+ height: s.getMediaHeight() * t.verticalPixelRatio,
199
+ range: h,
200
+ timeToX: (r) => o.timeToBitmapX(r),
172
201
  ...i
173
202
  }));
174
203
  }
175
- const m = this.#e?.clip;
176
- if (m !== void 0) {
177
- const h = m.fromX ?? 0, s = m.toX ?? t.bitmapSize.width;
178
- t.context.save(), t.context.beginPath(), t.context.rect(h, 0, Math.max(0, s - h), t.bitmapSize.height), t.context.clip();
204
+ const d = this.#e?.clip;
205
+ if (d !== void 0) {
206
+ const l = d.fromX ?? 0, r = d.toX ?? t.bitmapSize.width;
207
+ t.context.save(), t.context.beginPath(), t.context.rect(l, 0, Math.max(0, r - l), t.bitmapSize.height), t.context.clip();
179
208
  }
180
- const d = this.#t?.clip;
181
- let u = !1;
182
- if (d !== void 0 && l !== null) {
183
- const h = o.timeToBitmapX(l.to), s = Math.abs(h - o.timeToBitmapX(l.from)), g = o.barWidthBitmap(e.dataInterval), n = d.fromX ?? 0, A = d.toX ?? s;
184
- t.context.save(), t.context.beginPath(), t.context.rect(h - A - g, 0, Math.max(0, A - n + g), t.bitmapSize.height), t.context.rect(h, 0, Math.max(0, t.bitmapSize.width - h), t.bitmapSize.height), t.context.clip(), u = !0;
209
+ const c = this.#t?.clip;
210
+ let m = !1;
211
+ if (c !== void 0 && h !== null) {
212
+ const l = o.timeToBitmapX(h.to), r = Math.abs(l - o.timeToBitmapX(h.from)), u = o.barWidthBitmap(e.dataInterval), a = c.fromX ?? 0, A = c.toX ?? r;
213
+ t.context.save(), t.context.beginPath(), t.context.rect(l - A - u, 0, Math.max(0, A - a + u), t.bitmapSize.height), t.context.rect(l, 0, Math.max(0, t.bitmapSize.width - l), t.bitmapSize.height), t.context.clip(), m = !0;
185
214
  }
186
215
  switch (this.options.stacking) {
187
216
  case "normal":
@@ -194,7 +223,7 @@ class tt extends N {
194
223
  this.renderOff(e);
195
224
  break;
196
225
  }
197
- u && t.context.restore(), m !== void 0 && t.context.restore();
226
+ m && t.context.restore(), d !== void 0 && t.context.restore();
198
227
  }
199
228
  /**
200
229
  * Bar body width in bitmap px. On a category axis a bar fills its band;
@@ -203,53 +232,53 @@ class tt extends N {
203
232
  * zooms must keep wide bars. See the matching comment in candlestick.ts.
204
233
  */
205
234
  #r(e) {
206
- const { scope: t, timeScale: o, dataInterval: r } = e;
235
+ const { scope: t, timeScale: o, dataInterval: s } = e;
207
236
  if (o.getType() === "category") return o.bandWidthBitmap();
208
237
  const i = o.getRange();
209
- let l = 0;
210
- for (const h of this.stores) {
211
- if (!h.isVisible()) continue;
212
- const s = h.getVisibleData(i.from, i.to).length;
213
- if (s > l && (l = s), l > 2) break;
238
+ let h = 0;
239
+ for (const l of this.stores) {
240
+ if (!l.isVisible()) continue;
241
+ const r = l.getVisibleData(i.from, i.to).length;
242
+ if (r > h && (h = r), h > 2) break;
214
243
  }
215
- const m = o.barWidthBitmap(r), d = Math.round(30 * t.horizontalPixelRatio), u = l <= 2 ? Math.min(d, m) : m;
216
- return Math.max(1, Math.round(u * this.options.barWidthRatio) - 2);
244
+ const d = o.barWidthBitmap(s), c = Math.round(30 * t.horizontalPixelRatio), m = h <= 2 ? Math.min(c, d) : d;
245
+ return Math.max(1, Math.round(m * this.options.barWidthRatio));
217
246
  }
218
247
  /** Stacking off — each layer drawn independently from zero, overlapping */
219
248
  renderOff(e) {
220
- const { scope: t, timeScale: o, yScale: r } = e, { context: i } = t, l = o.getRange(), m = this.#r(e), d = Math.floor(m / 2), u = this.options.anchor === "right" ? m : d, h = r.getRange().min < 0, s = h ? r.valueToBitmapY(0) : t.bitmapSize.height;
249
+ const { scope: t, timeScale: o, yScale: s } = e, { context: i } = t, h = o.getRange(), d = this.#r(e), c = Math.floor(d / 2), m = this.options.anchor === "right" ? d : c, l = s.getRange().min < 0, r = l ? s.valueToBitmapY(0) : t.bitmapSize.height;
221
250
  if (this.stores.length === 1) {
222
251
  if (!this.stores[0].isVisible()) return;
223
- const g = this.stores[0].getVisibleData(l.from, l.to);
224
- for (const n of g) {
225
- if (!r.isPlottable(n.value)) continue;
226
- const A = this.effectiveValue(e, 0, n.time, n.value), p = this.introValue({ layerIndex: 0, time: n.time, value: A }), b = this.entranceProgress(0, n.time), v = this.isProjectedTime(n.time), B = o.timeToBitmapX(n.time), M = this.resolveLayerColor(0, A);
227
- if (p >= 0) {
228
- const a = r.valueToBitmapY(p), f = Math.max(1, s - a);
252
+ const u = this.stores[0].getVisibleData(h.from, h.to);
253
+ for (const a of u) {
254
+ if (!s.isPlottable(a.value)) continue;
255
+ const A = this.effectiveValue(e, 0, a.time, a.value), g = this.introValue({ layerIndex: 0, time: a.time, value: A }), b = this.entranceProgress(0, a.time), v = this.isProjectedTime(a.time), w = o.timeToBitmapX(a.time), M = this.resolveLayerColor(0, A);
256
+ if (g >= 0) {
257
+ const n = s.valueToBitmapY(g), f = Math.max(1, r - n);
229
258
  this.drawAnimatedBar({
230
259
  context: i,
231
- time: n.time,
260
+ time: a.time,
232
261
  progress: b,
233
- baselineY: s,
234
- topY: a,
262
+ baselineY: r,
263
+ topY: n,
235
264
  barHeight: f,
236
- x: B - u,
237
- barWidth: m,
265
+ x: w - m,
266
+ barWidth: d,
238
267
  color: M,
239
268
  roundEdge: "top",
240
269
  isProjected: v
241
270
  });
242
271
  } else {
243
- const a = r.valueToBitmapY(p), f = Math.max(1, a - s);
272
+ const n = s.valueToBitmapY(g), f = Math.max(1, n - r);
244
273
  this.drawAnimatedBar({
245
274
  context: i,
246
- time: n.time,
275
+ time: a.time,
247
276
  progress: b,
248
- baselineY: s,
249
- topY: s,
277
+ baselineY: r,
278
+ topY: r,
250
279
  barHeight: f,
251
- x: B - u,
252
- barWidth: m,
280
+ x: w - m,
281
+ barWidth: d,
253
282
  color: M,
254
283
  roundEdge: "bottom",
255
284
  isProjected: v
@@ -257,19 +286,19 @@ class tt extends N {
257
286
  }
258
287
  }
259
288
  } else {
260
- const g = this.stores.map(
261
- (p, b) => this.getLayerAlpha(b) > 0 ? p.getVisibleData(l.from, l.to) : []
262
- ), n = /* @__PURE__ */ new Map(), A = r.baselineValue();
263
- for (let p = 0; p < g.length; p++) {
264
- const b = this.getLayerAlpha(p);
265
- for (const v of g[p]) {
266
- if (!r.isPlottable(v.value)) continue;
267
- let B = n.get(v.time);
268
- B || (B = [], n.set(v.time, B));
269
- const M = this.effectiveValue(e, p, v.time, v.value), a = b === 1 ? M : r.lerpValue(A, M, b);
270
- B.push({
271
- layer: p,
272
- value: this.introValue({ layerIndex: p, time: v.time, value: a }),
289
+ const u = this.stores.map(
290
+ (g, b) => this.getLayerAlpha(b) > 0 ? g.getVisibleData(h.from, h.to) : []
291
+ ), a = /* @__PURE__ */ new Map(), A = s.baselineValue();
292
+ for (let g = 0; g < u.length; g++) {
293
+ const b = this.getLayerAlpha(g);
294
+ for (const v of u[g]) {
295
+ if (!s.isPlottable(v.value)) continue;
296
+ let w = a.get(v.time);
297
+ w || (w = [], a.set(v.time, w));
298
+ const M = this.effectiveValue(e, g, v.time, v.value), n = b === 1 ? M : s.lerpValue(A, M, b);
299
+ w.push({
300
+ layer: g,
301
+ value: this.introValue({ layerIndex: g, time: v.time, value: n }),
273
302
  // Color resolves from the settled data value — same contract as
274
303
  // the single-layer path — so a threshold value-fn doesn't flicker
275
304
  // hues while the intro sweeps the drawn value from 0 to final.
@@ -277,135 +306,135 @@ class tt extends N {
277
306
  });
278
307
  }
279
308
  }
280
- for (const [p, b] of n) {
309
+ for (const [g, b] of a) {
281
310
  b.sort(
282
- (M, a) => Math.abs(a.value) - Math.abs(M.value)
311
+ (M, n) => Math.abs(n.value) - Math.abs(M.value)
283
312
  );
284
- const v = o.timeToBitmapX(p), B = this.isProjectedTime(p);
313
+ const v = o.timeToBitmapX(g), w = this.isProjectedTime(g);
285
314
  for (let M = 0; M < b.length; M++) {
286
- const { layer: a, value: f, colorValue: c } = b[M], Y = this.resolveLayerColor(a, c), x = this.entranceProgress(a, p);
315
+ const { layer: n, value: f, colorValue: p } = b[M], B = this.resolveLayerColor(n, p), x = this.entranceProgress(n, g);
287
316
  if (f >= 0) {
288
- const R = r.valueToBitmapY(f), T = Math.max(1, s - R);
317
+ const R = s.valueToBitmapY(f), T = Math.max(1, r - R);
289
318
  this.drawAnimatedBar({
290
319
  context: i,
291
- time: p,
320
+ time: g,
292
321
  progress: x,
293
- baselineY: s,
322
+ baselineY: r,
294
323
  topY: R,
295
324
  barHeight: T,
296
- x: v - u,
297
- barWidth: m,
298
- color: Y,
325
+ x: v - m,
326
+ barWidth: d,
327
+ color: B,
299
328
  roundEdge: "top",
300
- isProjected: B
329
+ isProjected: w
301
330
  });
302
331
  } else {
303
- const R = r.valueToBitmapY(f), T = Math.max(1, R - s);
332
+ const R = s.valueToBitmapY(f), T = Math.max(1, R - r);
304
333
  this.drawAnimatedBar({
305
334
  context: i,
306
- time: p,
335
+ time: g,
307
336
  progress: x,
308
- baselineY: s,
309
- topY: s,
337
+ baselineY: r,
338
+ topY: r,
310
339
  barHeight: T,
311
- x: v - u,
312
- barWidth: m,
313
- color: Y,
340
+ x: v - m,
341
+ barWidth: d,
342
+ color: B,
314
343
  roundEdge: "bottom",
315
- isProjected: B
344
+ isProjected: w
316
345
  });
317
346
  }
318
347
  }
319
348
  }
320
349
  }
321
- if (h) {
350
+ if (l) {
322
351
  i.strokeStyle = e.theme.grid.color, i.lineWidth = 1;
323
- const g = Math.round(s) + 0.5;
324
- i.beginPath(), i.moveTo(0, g), i.lineTo(t.bitmapSize.width, g), i.stroke();
352
+ const u = Math.round(r) + 0.5;
353
+ i.beginPath(), i.moveTo(0, u), i.lineTo(t.bitmapSize.width, u), i.stroke();
325
354
  }
326
355
  }
327
356
  /** Stacked (normal or percent) rendering */
328
357
  renderStacked(e, t) {
329
- const { scope: o, timeScale: r, yScale: i } = e, { context: l } = o, m = r.getRange(), d = this.#r(e), u = Math.floor(d / 2), h = this.options.anchor === "right" ? d : u, s = this.stores.map(
330
- (a, f) => this.getLayerAlpha(f) > 0 ? a.getVisibleData(m.from, m.to) : []
358
+ const { scope: o, timeScale: s, yScale: i } = e, { context: h } = o, d = s.getRange(), c = this.#r(e), m = Math.floor(c / 2), l = this.options.anchor === "right" ? c : m, r = this.stores.map(
359
+ (n, f) => this.getLayerAlpha(f) > 0 ? n.getVisibleData(d.from, d.to) : []
331
360
  );
332
- if (s.every((a) => a.length === 0)) return;
333
- const g = this.options.entryAnimation ?? "fade-grow", n = g === "grow" || g === "fade-grow", A = i.getTransform() !== null && !t, p = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map();
334
- for (let a = 0; a < s.length; a++) {
335
- const f = this.getLayerAlpha(a);
336
- for (const c of s[a]) {
337
- let Y = b.get(c.time);
338
- Y || (Y = new Array(s.length).fill(0), b.set(c.time, Y));
339
- const x = i.isPlottable(c.value) ? c.value : 0, R = this.effectiveValue(e, a, c.time, x);
361
+ if (r.every((n) => n.length === 0)) return;
362
+ const u = this.options.entryAnimation ?? "fade-grow", a = u === "grow" || u === "fade-grow", A = i.getTransform() !== null && !t, g = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map();
363
+ for (let n = 0; n < r.length; n++) {
364
+ const f = this.getLayerAlpha(n);
365
+ for (const p of r[n]) {
366
+ let B = b.get(p.time);
367
+ B || (B = new Array(r.length).fill(0), b.set(p.time, B));
368
+ const x = i.isPlottable(p.value) ? p.value : 0, R = this.effectiveValue(e, n, p.time, x);
340
369
  let T = R * f, V = f;
341
- if (n && !this.isProjectedTime(c.time)) {
342
- const P = this.entranceProgress(a, c.time);
370
+ if (a && !this.isProjectedTime(p.time)) {
371
+ const P = this.entranceProgress(n, p.time);
343
372
  T *= P, V *= P;
344
373
  }
345
374
  if (A) {
346
- Y[a] = T;
347
- let P = p.get(c.time);
348
- P || (P = { settled: new Array(s.length).fill(0), weights: new Array(s.length).fill(0) }, p.set(c.time, P)), P.settled[a] = R, P.weights[a] = V;
375
+ B[n] = T;
376
+ let P = g.get(p.time);
377
+ P || (P = { settled: new Array(r.length).fill(0), weights: new Array(r.length).fill(0) }, g.set(p.time, P)), P.settled[n] = R, P.weights[n] = V;
349
378
  continue;
350
379
  }
351
- Y[a] = this.introValue({ layerIndex: a, time: c.time, value: T });
380
+ B[n] = this.introValue({ layerIndex: n, time: p.time, value: T });
352
381
  }
353
382
  }
354
383
  const v = /* @__PURE__ */ new Map();
355
384
  if (!t)
356
- for (const [a, f] of b) {
357
- const c = p.get(a);
358
- v.set(a, c === void 0 ? K(f) : this.scaleEdges({ time: a, share: c, yScale: i }));
385
+ for (const [n, f] of b) {
386
+ const p = g.get(n);
387
+ v.set(n, p === void 0 ? K(f) : this.scaleEdges({ time: n, share: p, yScale: i }));
359
388
  }
360
- const B = /* @__PURE__ */ new Map(), M = /* @__PURE__ */ new Map();
361
- for (const [a, f] of b) {
362
- let c = -1, Y = -1;
389
+ const w = /* @__PURE__ */ new Map(), M = /* @__PURE__ */ new Map();
390
+ for (const [n, f] of b) {
391
+ let p = -1, B = -1;
363
392
  for (let x = 0; x < f.length; x++)
364
- f[x] > 0 && (c = x), f[x] < 0 && (Y = x);
365
- c >= 0 && B.set(a, c), Y >= 0 && M.set(a, Y);
393
+ f[x] > 0 && (p = x), f[x] < 0 && (B = x);
394
+ p >= 0 && w.set(n, p), B >= 0 && M.set(n, B);
366
395
  }
367
- for (let a = 0; a < s.length; a++) {
368
- const f = this.resolveLayerColor(a, this.lastFinitePoint(a)?.value ?? 0);
369
- for (const [c, Y] of b) {
370
- const x = Y[a];
396
+ for (let n = 0; n < r.length; n++) {
397
+ const f = this.resolveLayerColor(n, this.lastFinitePoint(n)?.value ?? 0);
398
+ for (const [p, B] of b) {
399
+ const x = B[n];
371
400
  if (x === 0) continue;
372
- const R = r.timeToBitmapX(c), T = this.entranceProgress(a, c), V = this.isProjectedTime(c), P = x > 0 ? B.get(c) === a ? "top" : "none" : M.get(c) === a ? "bottom" : "none";
401
+ const R = s.timeToBitmapX(p), T = this.entranceProgress(n, p), V = this.isProjectedTime(p), P = x > 0 ? w.get(p) === n ? "top" : "none" : M.get(p) === n ? "bottom" : "none";
373
402
  if (t) {
374
- let E = 0, k = 0;
375
- for (let w = 0; w < a; w++) {
376
- const S = Y[w];
377
- S > 0 ? E += S : k += S;
403
+ let H = 0, E = 0;
404
+ for (let Y = 0; Y < n; Y++) {
405
+ const S = B[Y];
406
+ S > 0 ? H += S : E += S;
378
407
  }
379
- let H = 0, W = 0;
380
- for (const w of Y)
381
- w > 0 ? H += w : W += w;
382
- if (x > 0 && H > 0) {
383
- const w = E / H * 100, S = (E + x) / H * 100, j = i.valueToBitmapY(S), X = i.valueToBitmapY(w), L = Math.max(1, X - j);
408
+ let k = 0, W = 0;
409
+ for (const Y of B)
410
+ Y > 0 ? k += Y : W += Y;
411
+ if (x > 0 && k > 0) {
412
+ const Y = H / k * 100, S = (H + x) / k * 100, j = i.valueToBitmapY(S), X = i.valueToBitmapY(Y), L = Math.max(1, X - j);
384
413
  this.drawAnimatedBar({
385
- context: l,
386
- time: c,
414
+ context: h,
415
+ time: p,
387
416
  progress: T,
388
417
  baselineY: X,
389
418
  topY: j,
390
419
  barHeight: L,
391
- x: R - h,
392
- barWidth: d,
420
+ x: R - l,
421
+ barWidth: c,
393
422
  color: f,
394
423
  roundEdge: P,
395
424
  isProjected: V,
396
425
  growBaked: !0
397
426
  });
398
427
  } else if (x < 0 && W < 0) {
399
- const w = k / W * -100, S = (k + x) / W * -100, j = i.valueToBitmapY(w), X = i.valueToBitmapY(S), L = Math.max(1, X - j);
428
+ const Y = E / W * -100, S = (E + x) / W * -100, j = i.valueToBitmapY(Y), X = i.valueToBitmapY(S), L = Math.max(1, X - j);
400
429
  this.drawAnimatedBar({
401
- context: l,
402
- time: c,
430
+ context: h,
431
+ time: p,
403
432
  progress: T,
404
433
  baselineY: j,
405
434
  topY: j,
406
435
  barHeight: L,
407
- x: R - h,
408
- barWidth: d,
436
+ x: R - l,
437
+ barWidth: c,
409
438
  color: f,
410
439
  roundEdge: P,
411
440
  isProjected: V,
@@ -413,36 +442,36 @@ class tt extends N {
413
442
  });
414
443
  }
415
444
  } else {
416
- const E = v.get(c);
417
- if (E === void 0) continue;
418
- const k = E.base[a], H = E.end[a];
445
+ const H = v.get(p);
446
+ if (H === void 0) continue;
447
+ const E = H.base[n], k = H.end[n];
419
448
  if (x > 0) {
420
- const W = i.valueToBitmapY(H), w = i.valueToBitmapY(k), S = Math.max(1, w - W);
449
+ const W = i.valueToBitmapY(k), Y = i.valueToBitmapY(E), S = Math.max(1, Y - W);
421
450
  this.drawAnimatedBar({
422
- context: l,
423
- time: c,
451
+ context: h,
452
+ time: p,
424
453
  progress: T,
425
- baselineY: w,
454
+ baselineY: Y,
426
455
  topY: W,
427
456
  barHeight: S,
428
- x: R - h,
429
- barWidth: d,
457
+ x: R - l,
458
+ barWidth: c,
430
459
  color: f,
431
460
  roundEdge: P,
432
461
  isProjected: V,
433
462
  growBaked: !0
434
463
  });
435
464
  } else {
436
- const W = i.valueToBitmapY(k), w = i.valueToBitmapY(H), S = Math.max(1, w - W);
465
+ const W = i.valueToBitmapY(E), Y = i.valueToBitmapY(k), S = Math.max(1, Y - W);
437
466
  this.drawAnimatedBar({
438
- context: l,
439
- time: c,
467
+ context: h,
468
+ time: p,
440
469
  progress: T,
441
470
  baselineY: W,
442
471
  topY: W,
443
472
  barHeight: S,
444
- x: R - h,
445
- barWidth: d,
473
+ x: R - l,
474
+ barWidth: c,
446
475
  color: f,
447
476
  roundEdge: P,
448
477
  isProjected: V,
@@ -459,12 +488,12 @@ class tt extends N {
459
488
  * so the column grows from the floor as one unit at an even pixel speed.
460
489
  */
461
490
  scaleEdges(e) {
462
- const { time: t, share: o, yScale: r } = e, i = { positive: new z(r), negative: new z(r) }, l = { positive: i.positive.edge, negative: i.negative.edge }, m = [], d = [];
463
- for (let u = 0; u < o.settled.length; u++) {
464
- const h = o.settled[u], s = h < 0 ? "negative" : "positive", g = i[s].push(h, o.weights[u]), n = this.introValue({ layerIndex: u, time: t, value: g });
465
- m.push(l[s]), d.push(n), l[s] = n;
491
+ const { time: t, share: o, yScale: s } = e, i = { positive: new z(s), negative: new z(s) }, h = { positive: i.positive.edge, negative: i.negative.edge }, d = [], c = [];
492
+ for (let m = 0; m < o.settled.length; m++) {
493
+ const l = o.settled[m], r = l < 0 ? "negative" : "positive", u = i[r].push(l, o.weights[m]), a = this.introValue({ layerIndex: m, time: t, value: u });
494
+ d.push(h[r]), c.push(a), h[r] = a;
466
495
  }
467
- return { base: m, end: d };
496
+ return { base: d, end: c };
468
497
  }
469
498
  /**
470
499
  * Paint one bar through the resolved painter, applying any entrance transform
@@ -475,41 +504,41 @@ class tt extends N {
475
504
  drawAnimatedBar(e) {
476
505
  const t = this.#o;
477
506
  if (t === null) return;
478
- const { context: o, baselineY: r, topY: i, barHeight: l, x: m, barWidth: d, color: u, roundEdge: h } = e, s = e.isProjected ? 1 : e.progress, g = this.options.entryAnimation ?? "fade-grow";
479
- let n = s >= 1 || g === "none" ? { x: m, topY: i, barWidth: d, barHeight: l, alpha: 1 } : this.applyBarTransform(e, s);
507
+ const { context: o, baselineY: s, topY: i, barHeight: h, x: d, barWidth: c, color: m, roundEdge: l } = e, r = e.isProjected ? 1 : e.progress, u = this.options.entryAnimation ?? "fade-grow";
508
+ let a = r >= 1 || u === "none" ? { x: d, topY: i, barWidth: c, barHeight: h, alpha: 1 } : this.applyBarTransform(e, r);
480
509
  if (!e.isProjected) {
481
- const p = this.#t?.element, b = p !== void 0 ? this.#s(e.time) : null, v = b !== null ? p : this.#e?.element, B = b ?? (v !== void 0 ? this.#a(e.time) : null);
482
- if (v !== void 0 && B !== null) {
510
+ const g = this.#t?.element, b = g !== void 0 ? this.#a(e.time) : null, v = b !== null ? g : this.#e?.element, w = b ?? (v !== void 0 ? this.#s(e.time) : null);
511
+ if (v !== void 0 && w !== null) {
483
512
  const M = v({
484
- ...B,
513
+ ...w,
485
514
  time: e.time,
486
- x: n.x,
487
- topY: n.topY,
488
- barHeight: n.barHeight,
489
- baselineY: r,
490
- barWidth: n.barWidth
515
+ x: a.x,
516
+ topY: a.topY,
517
+ barHeight: a.barHeight,
518
+ baselineY: s,
519
+ barWidth: a.barWidth
491
520
  });
492
- n = {
493
- ...n,
494
- x: n.x + (M.offsetX ?? 0),
495
- topY: n.topY + (M.offsetY ?? 0),
496
- alpha: n.alpha * (M.alpha ?? 1)
521
+ a = {
522
+ ...a,
523
+ x: a.x + (M.offsetX ?? 0),
524
+ topY: a.topY + (M.offsetY ?? 0),
525
+ alpha: a.alpha * (M.alpha ?? 1)
497
526
  };
498
527
  }
499
528
  }
500
529
  const A = {
501
- geom: { x: n.x, y: n.topY, width: n.barWidth, height: n.barHeight, baselineY: r },
502
- color: u,
503
- corners: q[h],
530
+ geom: { x: a.x, y: a.topY, width: a.barWidth, height: a.barHeight, baselineY: s },
531
+ color: m,
532
+ corners: q[l],
504
533
  // Clamp to this bar's geometry so `radius` honors its pre-clamped contract
505
534
  // for custom painters; `fillRoundedRect` re-clamps to the same bound, so
506
535
  // the built-in output is unchanged.
507
- radius: Math.min(t.radius, n.barWidth / 2, n.barHeight / 2),
508
- progress: s,
536
+ radius: Math.min(t.radius, a.barWidth / 2, a.barHeight / 2),
537
+ progress: r,
509
538
  isProjected: e.isProjected
510
539
  };
511
- if (n.alpha < 1) {
512
- o.save(), o.globalAlpha = n.alpha, t.painter(t.env, A), o.restore();
540
+ if (a.alpha < 1) {
541
+ o.save(), o.globalAlpha = a.alpha, t.painter(t.env, A), o.restore();
513
542
  return;
514
543
  }
515
544
  t.painter(t.env, A);