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