@wick-charts/vue 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +18 -3
  2. package/dist/BarSeries.vue.js +26 -20
  3. package/dist/CandlestickSeries.vue.js +30 -24
  4. package/dist/ChartContainer.vue.js +88 -65
  5. package/dist/HeatmapSeries.vue.js +40 -0
  6. package/dist/HeatmapSeries.vue2.js +4 -0
  7. package/dist/LineSeries.vue.js +26 -20
  8. package/dist/PieSeries.vue.js +24 -18
  9. package/dist/core/dist/animation/animator.js +21 -21
  10. package/dist/core/dist/animation/config.js +114 -87
  11. package/dist/core/dist/animation/easing.js +3 -1
  12. package/dist/core/dist/animation/intro-wave.js +68 -0
  13. package/dist/core/dist/axis/dom-labels.js +13 -14
  14. package/dist/core/dist/chart/badge-animator.js +56 -0
  15. package/dist/core/dist/chart/edge-indicators.js +28 -13
  16. package/dist/core/dist/chart/last-value.js +18 -17
  17. package/dist/core/dist/chart/y-target.js +13 -12
  18. package/dist/core/dist/chart.js +679 -452
  19. package/dist/core/dist/components/annotation-chip.js +28 -0
  20. package/dist/core/dist/components/edge-indicator.js +58 -26
  21. package/dist/core/dist/components/loading-indicator.js +46 -0
  22. package/dist/core/dist/components/marker.js +49 -31
  23. package/dist/core/dist/components/reference-line.js +27 -36
  24. package/dist/core/dist/components/time-region.js +30 -28
  25. package/dist/core/dist/data/store.js +38 -19
  26. package/dist/core/dist/data/sync.js +60 -38
  27. package/dist/core/dist/heatmap-tooltip.js +16 -0
  28. package/dist/core/dist/interactions/handler.js +67 -43
  29. package/dist/core/dist/perf/perf-hud.js +5 -5
  30. package/dist/core/dist/scales/x-scale.js +85 -37
  31. package/dist/core/dist/scales/y-scale.js +38 -27
  32. package/dist/core/dist/series/bar-intro.js +18 -0
  33. package/dist/core/dist/series/bar.js +337 -205
  34. package/dist/core/dist/series/base-multi-layer.js +224 -96
  35. package/dist/core/dist/series/candlestick-intro.js +57 -0
  36. package/dist/core/dist/series/candlestick.js +454 -276
  37. package/dist/core/dist/series/heatmap.js +387 -0
  38. package/dist/core/dist/series/line-intro.js +85 -0
  39. package/dist/core/dist/series/line.js +590 -282
  40. package/dist/core/dist/series/painters/builtins.js +2 -2
  41. package/dist/core/dist/series/pie.js +396 -259
  42. package/dist/core/dist/series/register-builtins.js +8 -7
  43. package/dist/core/dist/series/types.js +6 -0
  44. package/dist/core/dist/series/wave-intro.js +26 -0
  45. package/dist/core/dist/theme/create.js +69 -63
  46. package/dist/core/dist/theme/themes/mint-breeze.js +2 -2
  47. package/dist/core/dist/theme/themes/sand-dune.js +2 -2
  48. package/dist/core/dist/utils/color.js +109 -34
  49. package/dist/core/dist/utils/deep-equal.js +18 -0
  50. package/dist/core/dist/utils/time.js +25 -19
  51. package/dist/index.d.ts +1405 -123
  52. package/dist/index.js +177 -130
  53. package/dist/ui/Crosshair.vue.js +20 -21
  54. package/dist/ui/HeatmapTooltip.vue.js +96 -0
  55. package/dist/ui/HeatmapTooltip.vue2.js +4 -0
  56. package/dist/ui/InfoBar.vue.js +46 -47
  57. package/dist/ui/Legend.vue.js +80 -79
  58. package/dist/ui/PieLegend.vue.js +5 -5
  59. package/dist/ui/PieTooltip.vue.js +77 -67
  60. package/dist/ui/Tooltip.vue.js +60 -60
  61. package/dist/ui/YAxis.vue.js +2 -2
  62. package/dist/ui/YLabel.vue.js +94 -61
  63. package/package.json +2 -2
  64. package/src/BarSeries.vue +23 -7
  65. package/src/CandlestickSeries.vue +23 -7
  66. package/src/ChartContainer.vue +134 -12
  67. package/src/HeatmapSeries.vue +69 -0
  68. package/src/LineSeries.vue +23 -7
  69. package/src/PieSeries.vue +22 -6
  70. package/src/index.ts +84 -3
  71. package/src/ui/Crosshair.vue +1 -2
  72. package/src/ui/HeatmapTooltip.vue +144 -0
  73. package/src/ui/InfoBar.vue +1 -2
  74. package/src/ui/Legend.vue +13 -0
  75. package/src/ui/Marker.vue +1 -1
  76. package/src/ui/PieTooltip.vue +10 -0
  77. package/src/ui/ReferenceLine.vue +2 -2
  78. package/src/ui/TimeRegion.vue +2 -2
  79. package/src/ui/Tooltip.vue +2 -2
  80. package/src/ui/YLabel.vue +123 -8
@@ -1,80 +1,172 @@
1
- import { DEFAULT_BAR_SMOOTH as N, DEFAULT_BAR_ENTRY as _ } from "../animation/config.js";
2
- import { BaseMultiLayerSeries as U } from "./base-multi-layer.js";
3
- import { resolveBarPainter as X } from "./painters/resolve.js";
4
- const I = 2, q = {
1
+ import { DEFAULT_HISTORY_REVEAL as _, DEFAULT_BAR_INTRO as C, DEFAULT_BAR_SMOOTH as F, DEFAULT_BAR_ENTRY as N } from "../animation/config.js";
2
+ import { growIntro as Q } from "./bar-intro.js";
3
+ import { BaseMultiLayerSeries as $ } from "./base-multi-layer.js";
4
+ import { resolveBarPainter as Z } from "./painters/resolve.js";
5
+ import { fadeIntro as q } from "./wave-intro.js";
6
+ const U = 2, G = {
5
7
  // Single fallback resolver; the definition's `create` swaps in `theme.bar.color`.
6
8
  colors: ["#26a69a"],
7
9
  barWidthRatio: 0.6,
8
10
  stacking: "off",
9
11
  anchor: "center",
10
- cornerRadius: I,
11
- entryMs: _,
12
- smoothMs: N
12
+ cornerRadius: U,
13
+ entryMs: N,
14
+ smoothMs: F,
15
+ introMs: C,
16
+ historyRevealMs: _
13
17
  };
14
- function F(P) {
18
+ function I(y) {
15
19
  return {
16
- ...P,
17
- entryMs: P.entryMs === !1 ? 0 : P.entryMs ?? _,
18
- smoothMs: P.smoothMs === !1 ? 0 : P.smoothMs ?? N
20
+ ...y,
21
+ entryMs: y.entryMs === !1 ? 0 : y.entryMs ?? N,
22
+ smoothMs: y.smoothMs === !1 ? 0 : y.smoothMs ?? F,
23
+ introMs: y.introMs === !1 ? 0 : y.introMs ?? C,
24
+ historyRevealMs: y.historyRevealMs === !1 ? 0 : y.historyRevealMs ?? _
19
25
  };
20
26
  }
21
- const G = {
27
+ const J = Q(), K = q(), tt = {
22
28
  top: { tl: !0, tr: !0, br: !1, bl: !1 },
23
29
  bottom: { tl: !1, tr: !1, br: !0, bl: !0 },
24
30
  none: { tl: !1, tr: !1, br: !1, bl: !1 }
25
31
  };
26
- class K extends U {
32
+ class et extends $ {
27
33
  kind = "bar";
28
34
  /** Resolved drawing context for the in-flight render pass. Set at the top of
29
35
  * {@link render}, read by {@link drawAnimatedBar}. */
36
+ #o = null;
37
+ /** Per-frame intro directives, resolved once per render while the wave
38
+ * runs; `null` when no intro is in flight. */
30
39
  #e = null;
31
- constructor(e, o) {
32
- super(e), this.options = F({ ...q, ...o });
40
+ /** Visible range captured alongside {@link #introDirectives} — positions
41
+ * the per-bar wave stagger. */
42
+ #i = null;
43
+ /** Per-frame history-reveal directives; `null` when no reveal is in flight. */
44
+ #t = null;
45
+ constructor(e, t) {
46
+ super(e), this.options = I({ ...G, ...t });
33
47
  }
34
48
  updateOptions(e) {
35
- this.options = F({ ...this.options, ...e });
49
+ this.options = I({ ...this.options, ...e });
36
50
  }
37
51
  isEntryEnabled() {
38
52
  return (this.options.entryAnimation ?? "fade-grow") !== "none";
39
53
  }
40
- applyTheme(e, o) {
41
- const h = this.stores.length === 1, c = e.seriesColors[0] ?? "#26a69a", d = h ? [e.bar?.color ?? c] : e.seriesColors.slice(0, this.stores.length);
42
- this.updateOptions({ colors: d });
54
+ /**
55
+ * Normalized x-position + eased wave progress for the intro's callbacks.
56
+ * `null` when no intro is in flight this frame.
57
+ */
58
+ #a(e) {
59
+ const t = this.#i;
60
+ if (t === null) return null;
61
+ const o = t.to - t.from, n = o > 0 ? (e - t.from) / o : 0, a = Math.min(1, Math.max(0, n));
62
+ return { position: a, progress: this.introWave.progressAt(a) };
63
+ }
64
+ /**
65
+ * Stagger position + eased wave progress for the history reveal's
66
+ * callbacks — position anchored at the data boundary (`0` there, `1` at
67
+ * the deepest prepended point). `null` for bars outside the prepended
68
+ * span or when no reveal is in flight this frame.
69
+ */
70
+ #r(e) {
71
+ const t = this.historyRange;
72
+ if (this.#t === null || t === null || e >= t.to) return null;
73
+ const o = t.to - t.from, n = o > 0 ? (t.to - e) / o : 0, a = Math.min(1, Math.max(0, n));
74
+ return { position: a, progress: this.historyWave.progressAt(a) };
75
+ }
76
+ /**
77
+ * Apply the intro's `value` directive to one rendered value. Scaling here
78
+ * (before geometry and stacking) grows the bar from the baseline on every
79
+ * render path — off / stacked / percent — without touching their geometry
80
+ * code. Projected (forecast) bars stay settled, like streaming entrances.
81
+ * A bar inside an in-flight history reveal is owned by the reveal's value
82
+ * directive instead.
83
+ */
84
+ introValue(e) {
85
+ if (this.isProjectedTime(e.time)) return e.value;
86
+ const t = this.#t?.value;
87
+ if (t !== void 0) {
88
+ const a = this.#r(e.time);
89
+ if (a !== null) return t({ ...e, ...a });
90
+ }
91
+ const o = this.#e?.value;
92
+ if (o === void 0) return e.value;
93
+ const n = this.#a(e.time);
94
+ return n === null ? e.value : o({ ...e, ...n });
95
+ }
96
+ applyTheme(e, t) {
97
+ const o = this.stores.length === 1, n = e.seriesColors[0] ?? "#26a69a", a = o ? [e.bar?.color ?? n] : e.seriesColors.slice(0, this.stores.length);
98
+ this.updateOptions({ colors: a });
43
99
  }
44
100
  /** True when `time` is at/after the configured `projectedFrom` forecast cut. */
45
101
  isProjectedTime(e) {
46
- const o = this.options.projectedFrom;
47
- return o !== void 0 && e >= o;
102
+ const t = this.options.projectedFrom;
103
+ return t !== void 0 && e >= t;
48
104
  }
49
105
  /**
50
106
  * Shape of the per-bar entrance transform. Centralized so the entrance style
51
107
  * is a single switch; new styles like 'slide' drop in here without touching
52
108
  * each render path.
53
109
  */
54
- applyBarTransform(e, o) {
55
- const { baselineY: h, topY: c, barHeight: d, x: m, barWidth: M } = e, p = this.options.entryAnimation ?? "fade-grow";
56
- if (o >= 1 || p === "none")
57
- return { topY: c, barHeight: d, x: m, barWidth: M, alpha: 1 };
58
- let f = c, w = d, y = m, k = 1;
59
- if ((p === "fade" || p === "fade-grow") && (k = o), (p === "grow" || p === "fade-grow") && !e.growBaked) {
60
- const l = d * o;
61
- c < h ? f = h - l : f = h, w = Math.max(1, l);
110
+ applyBarTransform(e, t) {
111
+ const { baselineY: o, topY: n, barHeight: a, x: m, barWidth: v } = e, b = this.options.entryAnimation ?? "fade-grow";
112
+ if (t >= 1 || b === "none")
113
+ return { topY: n, barHeight: a, x: m, barWidth: v, alpha: 1 };
114
+ let l = n, u = a, x = m, R = 1;
115
+ if ((b === "fade" || b === "fade-grow") && (R = t), (b === "grow" || b === "fade-grow") && !e.growBaked) {
116
+ const r = a * t;
117
+ n < o ? l = o - r : l = o, u = Math.max(1, r);
62
118
  }
63
- return p === "slide" && (y = m + (1 - o) * M, k = o), { topY: f, barHeight: w, x: y, barWidth: M, alpha: k };
119
+ return b === "slide" && (x = m + (1 - t) * v, R = t), { topY: l, barHeight: u, x, barWidth: v, alpha: R };
64
120
  }
65
121
  render(e) {
66
122
  this.tickAnimations(performance.now());
67
- const { scope: o } = e;
68
- switch (this.#e = {
69
- painter: X(this.options.barPainter),
123
+ const { scope: t, timeScale: o, yScale: n } = e;
124
+ if (this.#o = {
125
+ painter: Z(this.options.barPainter),
70
126
  env: {
71
- ctx: o.context,
127
+ ctx: t.context,
72
128
  theme: e.theme,
73
- horizontalPixelRatio: o.horizontalPixelRatio,
74
- verticalPixelRatio: o.verticalPixelRatio
129
+ horizontalPixelRatio: t.horizontalPixelRatio,
130
+ verticalPixelRatio: t.verticalPixelRatio
75
131
  },
76
- radius: (this.options.cornerRadius ?? I) * o.horizontalPixelRatio
77
- }, this.options.stacking) {
132
+ radius: (this.options.cornerRadius ?? U) * t.horizontalPixelRatio
133
+ }, this.#e = null, this.#i = null, this.introWave.active) {
134
+ const l = this.options.introAnimation ?? J, u = o.getRange();
135
+ this.#i = u, this.#e = l({
136
+ progress: this.introWave.linear(),
137
+ // Plot-area extent, not the canvas bitmap — the canvas also carries
138
+ // the axis strips, so a width-based front (wipeIntro) would overshoot
139
+ // the data area.
140
+ width: o.getMediaWidth() * t.horizontalPixelRatio,
141
+ height: n.getMediaHeight() * t.verticalPixelRatio,
142
+ range: u,
143
+ timeToX: (x) => o.timeToBitmapX(x)
144
+ });
145
+ }
146
+ this.#t = null;
147
+ const a = this.historyRange;
148
+ if (this.historyWave.active && a !== null) {
149
+ const l = this.options.historyReveal ?? K;
150
+ l !== "none" && (this.#t = l({
151
+ progress: this.historyWave.linear(),
152
+ width: Math.abs(o.timeToBitmapX(a.to) - o.timeToBitmapX(a.from)),
153
+ height: n.getMediaHeight() * t.verticalPixelRatio,
154
+ range: a,
155
+ timeToX: (u) => o.timeToBitmapX(u)
156
+ }));
157
+ }
158
+ const m = this.#e?.clip;
159
+ if (m !== void 0) {
160
+ const l = m.fromX ?? 0, u = m.toX ?? t.bitmapSize.width;
161
+ t.context.save(), t.context.beginPath(), t.context.rect(l, 0, Math.max(0, u - l), t.bitmapSize.height), t.context.clip();
162
+ }
163
+ const v = this.#t?.clip;
164
+ let b = !1;
165
+ if (v !== void 0 && a !== null) {
166
+ const l = o.timeToBitmapX(a.to), u = Math.abs(l - o.timeToBitmapX(a.from)), x = o.barWidthBitmap(e.dataInterval), R = v.fromX ?? 0, r = v.toX ?? u;
167
+ t.context.save(), t.context.beginPath(), t.context.rect(l - r - x, 0, Math.max(0, r - R + x), t.bitmapSize.height), t.context.rect(l, 0, Math.max(0, t.bitmapSize.width - l), t.bitmapSize.height), t.context.clip(), b = !0;
168
+ }
169
+ switch (this.options.stacking) {
78
170
  case "normal":
79
171
  this.renderStacked(e, !1);
80
172
  break;
@@ -85,216 +177,234 @@ class K extends U {
85
177
  this.renderOff(e);
86
178
  break;
87
179
  }
180
+ b && t.context.restore(), m !== void 0 && t.context.restore();
88
181
  }
89
182
  /** Stacking off — each layer drawn independently from zero, overlapping */
90
183
  renderOff(e) {
91
- const { scope: o, timeScale: h, yScale: c, dataInterval: d } = e, { context: m, horizontalPixelRatio: M } = o, p = h.getRange();
92
- let f = 0;
93
- for (const v of this.stores) {
94
- if (!v.isVisible()) continue;
95
- const u = v.getVisibleData(p.from, p.to).length;
96
- if (u > f && (f = u), f > 2) break;
184
+ const { scope: t, timeScale: o, yScale: n, dataInterval: a } = e, { context: m, horizontalPixelRatio: v } = t, b = o.getRange();
185
+ let l = 0;
186
+ for (const M of this.stores) {
187
+ if (!M.isVisible()) continue;
188
+ const p = M.getVisibleData(b.from, b.to).length;
189
+ if (p > l && (l = p), l > 2) break;
97
190
  }
98
- const w = h.barWidthBitmap(d), y = Math.round(30 * M), k = f <= 2 ? Math.min(y, w) : w, l = Math.max(1, Math.round(k * this.options.barWidthRatio) - 2), T = Math.floor(l / 2), E = this.options.anchor === "right" ? l : T, H = c.getRange().min < 0, g = H ? c.valueToBitmapY(0) : o.bitmapSize.height;
191
+ const u = o.barWidthBitmap(a), x = Math.round(30 * v), R = l <= 2 ? Math.min(x, u) : u, r = Math.max(1, Math.round(R * this.options.barWidthRatio) - 2), W = Math.floor(r / 2), H = this.options.anchor === "right" ? r : W, T = n.getRange().min < 0, f = T ? n.valueToBitmapY(0) : t.bitmapSize.height;
99
192
  if (this.stores.length === 1) {
100
193
  if (!this.stores[0].isVisible()) return;
101
- const v = this.stores[0].getVisibleData(p.from, p.to);
102
- for (const u of v) {
103
- if (!Number.isFinite(u.value)) continue;
104
- const a = this.effectiveValue(e, 0, u.time, u.value), Y = this.entranceProgress(e, 0, u.time), x = this.isProjectedTime(u.time), t = h.timeToBitmapX(u.time), i = this.resolveLayerColor(0, a);
105
- if (a >= 0) {
106
- const r = c.valueToBitmapY(a), s = Math.max(1, g - r);
194
+ const M = this.stores[0].getVisibleData(b.from, b.to);
195
+ for (const p of M) {
196
+ if (!Number.isFinite(p.value)) continue;
197
+ const d = this.effectiveValue(e, 0, p.time, p.value), P = this.introValue({ layerIndex: 0, time: p.time, value: d }), B = this.entranceProgress(0, p.time), i = this.isProjectedTime(p.time), h = o.timeToBitmapX(p.time), s = this.resolveLayerColor(0, d);
198
+ if (P >= 0) {
199
+ const g = n.valueToBitmapY(P), c = Math.max(1, f - g);
107
200
  this.drawAnimatedBar({
108
201
  context: m,
109
- progress: Y,
110
- baselineY: g,
111
- topY: r,
112
- barHeight: s,
113
- x: t - E,
114
- barWidth: l,
115
- color: i,
202
+ time: p.time,
203
+ progress: B,
204
+ baselineY: f,
205
+ topY: g,
206
+ barHeight: c,
207
+ x: h - H,
208
+ barWidth: r,
209
+ color: s,
116
210
  roundEdge: "top",
117
- isProjected: x
211
+ isProjected: i
118
212
  });
119
213
  } else {
120
- const r = c.valueToBitmapY(a), s = Math.max(1, r - g);
214
+ const g = n.valueToBitmapY(P), c = Math.max(1, g - f);
121
215
  this.drawAnimatedBar({
122
216
  context: m,
123
- progress: Y,
124
- baselineY: g,
125
- topY: g,
126
- barHeight: s,
127
- x: t - E,
128
- barWidth: l,
129
- color: i,
217
+ time: p.time,
218
+ progress: B,
219
+ baselineY: f,
220
+ topY: f,
221
+ barHeight: c,
222
+ x: h - H,
223
+ barWidth: r,
224
+ color: s,
130
225
  roundEdge: "bottom",
131
- isProjected: x
226
+ isProjected: i
132
227
  });
133
228
  }
134
229
  }
135
230
  } else {
136
- const v = this.stores.map(
137
- (a, Y) => this.getLayerAlpha(Y) > 0 ? a.getVisibleData(p.from, p.to) : []
138
- ), u = /* @__PURE__ */ new Map();
139
- for (let a = 0; a < v.length; a++) {
140
- const Y = this.getLayerAlpha(a);
141
- for (const x of v[a]) {
142
- if (!Number.isFinite(x.value)) continue;
143
- let t = u.get(x.time);
144
- t || (t = [], u.set(x.time, t)), t.push({ layer: a, value: this.effectiveValue(e, a, x.time, x.value) * Y });
231
+ const M = this.stores.map(
232
+ (d, P) => this.getLayerAlpha(P) > 0 ? d.getVisibleData(b.from, b.to) : []
233
+ ), p = /* @__PURE__ */ new Map();
234
+ for (let d = 0; d < M.length; d++) {
235
+ const P = this.getLayerAlpha(d);
236
+ for (const B of M[d]) {
237
+ if (!Number.isFinite(B.value)) continue;
238
+ let i = p.get(B.time);
239
+ i || (i = [], p.set(B.time, i));
240
+ const h = this.effectiveValue(e, d, B.time, B.value) * P;
241
+ i.push({
242
+ layer: d,
243
+ value: this.introValue({ layerIndex: d, time: B.time, value: h }),
244
+ // Color resolves from the settled data value — same contract as
245
+ // the single-layer path — so a threshold value-fn doesn't flicker
246
+ // hues while the intro sweeps the drawn value from 0 to final.
247
+ colorValue: B.value
248
+ });
145
249
  }
146
250
  }
147
- for (const [a, Y] of u) {
148
- Y.sort(
149
- (i, r) => Math.abs(r.value) - Math.abs(i.value)
251
+ for (const [d, P] of p) {
252
+ P.sort(
253
+ (h, s) => Math.abs(s.value) - Math.abs(h.value)
150
254
  );
151
- const x = h.timeToBitmapX(a), t = this.isProjectedTime(a);
152
- for (let i = 0; i < Y.length; i++) {
153
- const { layer: r, value: s } = Y[i], n = this.resolveLayerColor(r, s), W = this.entranceProgress(e, r, a);
154
- if (s >= 0) {
155
- const R = c.valueToBitmapY(s), j = Math.max(1, g - R);
255
+ const B = o.timeToBitmapX(d), i = this.isProjectedTime(d);
256
+ for (let h = 0; h < P.length; h++) {
257
+ const { layer: s, value: g, colorValue: c } = P[h], S = this.resolveLayerColor(s, c), E = this.entranceProgress(s, d);
258
+ if (g >= 0) {
259
+ const k = n.valueToBitmapY(g), V = Math.max(1, f - k);
156
260
  this.drawAnimatedBar({
157
261
  context: m,
158
- progress: W,
159
- baselineY: g,
160
- topY: R,
161
- barHeight: j,
162
- x: x - E,
163
- barWidth: l,
164
- color: n,
262
+ time: d,
263
+ progress: E,
264
+ baselineY: f,
265
+ topY: k,
266
+ barHeight: V,
267
+ x: B - H,
268
+ barWidth: r,
269
+ color: S,
165
270
  roundEdge: "top",
166
- isProjected: t
271
+ isProjected: i
167
272
  });
168
273
  } else {
169
- const R = c.valueToBitmapY(s), j = Math.max(1, R - g);
274
+ const k = n.valueToBitmapY(g), V = Math.max(1, k - f);
170
275
  this.drawAnimatedBar({
171
276
  context: m,
172
- progress: W,
173
- baselineY: g,
174
- topY: g,
175
- barHeight: j,
176
- x: x - E,
177
- barWidth: l,
178
- color: n,
277
+ time: d,
278
+ progress: E,
279
+ baselineY: f,
280
+ topY: f,
281
+ barHeight: V,
282
+ x: B - H,
283
+ barWidth: r,
284
+ color: S,
179
285
  roundEdge: "bottom",
180
- isProjected: t
286
+ isProjected: i
181
287
  });
182
288
  }
183
289
  }
184
290
  }
185
291
  }
186
- if (H) {
292
+ if (T) {
187
293
  m.strokeStyle = e.theme.grid.color, m.lineWidth = 1;
188
- const v = Math.round(g) + 0.5;
189
- m.beginPath(), m.moveTo(0, v), m.lineTo(o.bitmapSize.width, v), m.stroke();
294
+ const M = Math.round(f) + 0.5;
295
+ m.beginPath(), m.moveTo(0, M), m.lineTo(t.bitmapSize.width, M), m.stroke();
190
296
  }
191
297
  }
192
298
  /** Stacked (normal or percent) rendering */
193
- renderStacked(e, o) {
194
- const { scope: h, timeScale: c, yScale: d, dataInterval: m } = e, { context: M, horizontalPixelRatio: p } = h, f = c.getRange();
195
- let w = 0;
196
- for (const t of this.stores) {
197
- if (!t.isVisible()) continue;
198
- const i = t.getVisibleData(f.from, f.to).length;
199
- if (i > w && (w = i), w > 2) break;
299
+ renderStacked(e, t) {
300
+ const { scope: o, timeScale: n, yScale: a, dataInterval: m } = e, { context: v, horizontalPixelRatio: b } = o, l = n.getRange();
301
+ let u = 0;
302
+ for (const i of this.stores) {
303
+ if (!i.isVisible()) continue;
304
+ const h = i.getVisibleData(l.from, l.to).length;
305
+ if (h > u && (u = h), u > 2) break;
200
306
  }
201
- const y = c.barWidthBitmap(m), k = Math.round(30 * p), l = w <= 2 ? Math.min(k, y) : y, T = Math.max(1, Math.round(l * this.options.barWidthRatio) - 2), E = Math.floor(T / 2), H = this.options.anchor === "right" ? T : E, g = this.stores.map(
202
- (t, i) => this.getLayerAlpha(i) > 0 ? t.getVisibleData(f.from, f.to) : []
307
+ const x = n.barWidthBitmap(m), R = Math.round(30 * b), r = u <= 2 ? Math.min(R, x) : x, W = Math.max(1, Math.round(r * this.options.barWidthRatio) - 2), H = Math.floor(W / 2), T = this.options.anchor === "right" ? W : H, f = this.stores.map(
308
+ (i, h) => this.getLayerAlpha(h) > 0 ? i.getVisibleData(l.from, l.to) : []
203
309
  );
204
- if (g.every((t) => t.length === 0)) return;
205
- const v = this.options.entryAnimation ?? "fade-grow", u = v === "grow" || v === "fade-grow", a = /* @__PURE__ */ new Map();
206
- for (let t = 0; t < g.length; t++) {
207
- const i = this.getLayerAlpha(t);
208
- for (const r of g[t]) {
209
- let s = a.get(r.time);
210
- s || (s = new Array(g.length).fill(0), a.set(r.time, s));
211
- const n = Number.isFinite(r.value) ? r.value : 0;
212
- let W = this.effectiveValue(e, t, r.time, n) * i;
213
- u && !this.isProjectedTime(r.time) && (W *= this.entranceProgress(e, t, r.time)), s[t] = W;
310
+ if (f.every((i) => i.length === 0)) return;
311
+ const M = this.options.entryAnimation ?? "fade-grow", p = M === "grow" || M === "fade-grow", d = /* @__PURE__ */ new Map();
312
+ for (let i = 0; i < f.length; i++) {
313
+ const h = this.getLayerAlpha(i);
314
+ for (const s of f[i]) {
315
+ let g = d.get(s.time);
316
+ g || (g = new Array(f.length).fill(0), d.set(s.time, g));
317
+ const c = Number.isFinite(s.value) ? s.value : 0;
318
+ let S = this.effectiveValue(e, i, s.time, c) * h;
319
+ p && !this.isProjectedTime(s.time) && (S *= this.entranceProgress(i, s.time)), g[i] = this.introValue({ layerIndex: i, time: s.time, value: S });
214
320
  }
215
321
  }
216
- const Y = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map();
217
- for (const [t, i] of a) {
218
- let r = -1, s = -1;
219
- for (let n = 0; n < i.length; n++)
220
- i[n] > 0 && (r = n), i[n] < 0 && (s = n);
221
- r >= 0 && Y.set(t, r), s >= 0 && x.set(t, s);
322
+ const P = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map();
323
+ for (const [i, h] of d) {
324
+ let s = -1, g = -1;
325
+ for (let c = 0; c < h.length; c++)
326
+ h[c] > 0 && (s = c), h[c] < 0 && (g = c);
327
+ s >= 0 && P.set(i, s), g >= 0 && B.set(i, g);
222
328
  }
223
- for (let t = 0; t < g.length; t++) {
224
- const i = this.resolveLayerColor(t, this.stores[t].last()?.value ?? 0);
225
- for (const [r, s] of a) {
226
- const n = s[t];
227
- if (n === 0) continue;
228
- const W = c.timeToBitmapX(r);
229
- let R = 0, j = 0;
230
- for (let b = 0; b < t; b++) {
231
- const B = s[b];
232
- B > 0 ? R += B : j += B;
329
+ for (let i = 0; i < f.length; i++) {
330
+ const h = this.resolveLayerColor(i, this.stores[i].last()?.value ?? 0);
331
+ for (const [s, g] of d) {
332
+ const c = g[i];
333
+ if (c === 0) continue;
334
+ const S = n.timeToBitmapX(s);
335
+ let E = 0, k = 0;
336
+ for (let Y = 0; Y < i; Y++) {
337
+ const w = g[Y];
338
+ w > 0 ? E += w : k += w;
233
339
  }
234
- const L = this.entranceProgress(e, t, r), V = this.isProjectedTime(r), D = n > 0 ? Y.get(r) === t ? "top" : "none" : x.get(r) === t ? "bottom" : "none";
235
- if (o) {
236
- let b = 0, B = 0;
237
- for (const A of s)
238
- A > 0 ? b += A : B += A;
239
- if (n > 0 && b > 0) {
240
- const A = R / b * 100, z = (R + n) / b * 100, S = d.valueToBitmapY(z), C = d.valueToBitmapY(A), O = Math.max(1, C - S);
340
+ const V = this.entranceProgress(i, s), X = this.isProjectedTime(s), z = c > 0 ? P.get(s) === i ? "top" : "none" : B.get(s) === i ? "bottom" : "none";
341
+ if (t) {
342
+ let Y = 0, w = 0;
343
+ for (const A of g)
344
+ A > 0 ? Y += A : w += A;
345
+ if (c > 0 && Y > 0) {
346
+ const A = E / Y * 100, D = (E + c) / Y * 100, j = a.valueToBitmapY(D), L = a.valueToBitmapY(A), O = Math.max(1, L - j);
241
347
  this.drawAnimatedBar({
242
- context: M,
243
- progress: L,
244
- baselineY: C,
245
- topY: S,
348
+ context: v,
349
+ time: s,
350
+ progress: V,
351
+ baselineY: L,
352
+ topY: j,
246
353
  barHeight: O,
247
- x: W - H,
248
- barWidth: T,
249
- color: i,
250
- roundEdge: D,
251
- isProjected: V,
354
+ x: S - T,
355
+ barWidth: W,
356
+ color: h,
357
+ roundEdge: z,
358
+ isProjected: X,
252
359
  growBaked: !0
253
360
  });
254
- } else if (n < 0 && B < 0) {
255
- const A = j / B * -100, z = (j + n) / B * -100, S = d.valueToBitmapY(A), C = d.valueToBitmapY(z), O = Math.max(1, C - S);
361
+ } else if (c < 0 && w < 0) {
362
+ const A = k / w * -100, D = (k + c) / w * -100, j = a.valueToBitmapY(A), L = a.valueToBitmapY(D), O = Math.max(1, L - j);
256
363
  this.drawAnimatedBar({
257
- context: M,
258
- progress: L,
259
- baselineY: S,
260
- topY: S,
364
+ context: v,
365
+ time: s,
366
+ progress: V,
367
+ baselineY: j,
368
+ topY: j,
261
369
  barHeight: O,
262
- x: W - H,
263
- barWidth: T,
264
- color: i,
265
- roundEdge: D,
266
- isProjected: V,
370
+ x: S - T,
371
+ barWidth: W,
372
+ color: h,
373
+ roundEdge: z,
374
+ isProjected: X,
267
375
  growBaked: !0
268
376
  });
269
377
  }
270
- } else if (n > 0) {
271
- const b = d.valueToBitmapY(R + n), B = d.valueToBitmapY(R), A = Math.max(1, B - b);
378
+ } else if (c > 0) {
379
+ const Y = a.valueToBitmapY(E + c), w = a.valueToBitmapY(E), A = Math.max(1, w - Y);
272
380
  this.drawAnimatedBar({
273
- context: M,
274
- progress: L,
275
- baselineY: B,
276
- topY: b,
381
+ context: v,
382
+ time: s,
383
+ progress: V,
384
+ baselineY: w,
385
+ topY: Y,
277
386
  barHeight: A,
278
- x: W - H,
279
- barWidth: T,
280
- color: i,
281
- roundEdge: D,
282
- isProjected: V,
387
+ x: S - T,
388
+ barWidth: W,
389
+ color: h,
390
+ roundEdge: z,
391
+ isProjected: X,
283
392
  growBaked: !0
284
393
  });
285
394
  } else {
286
- const b = d.valueToBitmapY(j), B = d.valueToBitmapY(j + n), A = Math.max(1, B - b);
395
+ const Y = a.valueToBitmapY(k), w = a.valueToBitmapY(k + c), A = Math.max(1, w - Y);
287
396
  this.drawAnimatedBar({
288
- context: M,
289
- progress: L,
290
- baselineY: b,
291
- topY: b,
397
+ context: v,
398
+ time: s,
399
+ progress: V,
400
+ baselineY: Y,
401
+ topY: Y,
292
402
  barHeight: A,
293
- x: W - H,
294
- barWidth: T,
295
- color: i,
296
- roundEdge: D,
297
- isProjected: V,
403
+ x: S - T,
404
+ barWidth: W,
405
+ color: h,
406
+ roundEdge: z,
407
+ isProjected: X,
298
408
  growBaked: !0
299
409
  });
300
410
  }
@@ -308,34 +418,56 @@ class K extends U {
308
418
  * painter's translucent fill rather than a `globalAlpha` fade.
309
419
  */
310
420
  drawAnimatedBar(e) {
311
- const o = this.#e;
312
- if (o === null) return;
313
- const { context: h, baselineY: c, topY: d, barHeight: m, x: M, barWidth: p, color: f, roundEdge: w } = e, y = e.isProjected ? 1 : e.progress, k = this.options.entryAnimation ?? "fade-grow", l = y >= 1 || k === "none" ? { x: M, topY: d, barWidth: p, barHeight: m, alpha: 1 } : this.applyBarTransform(e, y), T = {
314
- geom: { x: l.x, y: l.topY, width: l.barWidth, height: l.barHeight, baselineY: c },
315
- color: f,
316
- corners: G[w],
421
+ const t = this.#o;
422
+ if (t === null) return;
423
+ const { context: o, baselineY: n, topY: a, barHeight: m, x: v, barWidth: b, color: l, roundEdge: u } = e, x = e.isProjected ? 1 : e.progress, R = this.options.entryAnimation ?? "fade-grow";
424
+ let r = x >= 1 || R === "none" ? { x: v, topY: a, barWidth: b, barHeight: m, alpha: 1 } : this.applyBarTransform(e, x);
425
+ if (!e.isProjected) {
426
+ const H = this.#t?.element, T = H !== void 0 ? this.#r(e.time) : null, f = T !== null ? H : this.#e?.element, M = T ?? (f !== void 0 ? this.#a(e.time) : null);
427
+ if (f !== void 0 && M !== null) {
428
+ const p = f({
429
+ ...M,
430
+ time: e.time,
431
+ x: r.x,
432
+ topY: r.topY,
433
+ barHeight: r.barHeight,
434
+ baselineY: n,
435
+ barWidth: r.barWidth
436
+ });
437
+ r = {
438
+ ...r,
439
+ x: r.x + (p.offsetX ?? 0),
440
+ topY: r.topY + (p.offsetY ?? 0),
441
+ alpha: r.alpha * (p.alpha ?? 1)
442
+ };
443
+ }
444
+ }
445
+ const W = {
446
+ geom: { x: r.x, y: r.topY, width: r.barWidth, height: r.barHeight, baselineY: n },
447
+ color: l,
448
+ corners: tt[u],
317
449
  // Clamp to this bar's geometry so `radius` honors its pre-clamped contract
318
450
  // for custom painters; `fillRoundedRect` re-clamps to the same bound, so
319
451
  // the built-in output is unchanged.
320
- radius: Math.min(o.radius, l.barWidth / 2, l.barHeight / 2),
321
- progress: y,
452
+ radius: Math.min(t.radius, r.barWidth / 2, r.barHeight / 2),
453
+ progress: x,
322
454
  isProjected: e.isProjected
323
455
  };
324
- if (l.alpha < 1) {
325
- h.save(), h.globalAlpha = l.alpha, o.painter(o.env, T), h.restore();
456
+ if (r.alpha < 1) {
457
+ o.save(), o.globalAlpha = r.alpha, t.painter(t.env, W), o.restore();
326
458
  return;
327
459
  }
328
- o.painter(o.env, T);
460
+ t.painter(t.env, W);
329
461
  }
330
462
  }
331
- const Z = {
463
+ const nt = {
332
464
  type: "bar",
333
- create: ({ theme: P, layerCount: e }, o) => {
334
- const h = e === 1 ? [P.bar?.color ?? P.seriesColors[0] ?? "#26a69a"] : P.seriesColors.slice(0, e);
335
- return new K(e, { colors: h, ...o });
465
+ create: ({ theme: y, layerCount: e }, t) => {
466
+ const o = e === 1 ? [y.bar?.color ?? y.seriesColors[0] ?? "#26a69a"] : y.seriesColors.slice(0, e);
467
+ return new et(e, { colors: o, ...t });
336
468
  }
337
469
  };
338
470
  export {
339
- K as BarRenderer,
340
- Z as BarSeriesDef
471
+ et as BarRenderer,
472
+ nt as BarSeriesDef
341
473
  };