@wick-charts/vue 0.4.1 → 0.5.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 (146) hide show
  1. package/README.md +5 -3
  2. package/dist/BarSeries.vue.js +44 -0
  3. package/dist/BarSeries.vue2.js +4 -0
  4. package/dist/CandlestickSeries.vue.js +45 -0
  5. package/dist/CandlestickSeries.vue2.js +4 -0
  6. package/dist/ChartContainer.vue.js +168 -0
  7. package/dist/ChartContainer.vue2.js +4 -0
  8. package/dist/LineSeries.vue.js +44 -0
  9. package/dist/LineSeries.vue2.js +4 -0
  10. package/dist/PieSeries.vue.js +34 -0
  11. package/dist/PieSeries.vue2.js +4 -0
  12. package/dist/composables.js +44 -0
  13. package/dist/context.js +25 -0
  14. package/dist/core/dist/animation/animator.js +72 -0
  15. package/dist/core/dist/animation/config.js +145 -0
  16. package/dist/core/dist/animation/easing.js +4 -0
  17. package/dist/core/dist/animation/scalar-spring.js +57 -0
  18. package/dist/core/dist/animation/spring.js +11 -0
  19. package/dist/core/dist/animation/time.js +19 -0
  20. package/dist/core/dist/animation/viewport-engine.js +174 -0
  21. package/dist/core/dist/animation/visible-range-spring.js +64 -0
  22. package/dist/core/dist/animation/y-range-hermite.js +72 -0
  23. package/dist/core/dist/animation/y-range-snap.js +31 -0
  24. package/dist/core/dist/animation/y-range-spring.js +59 -0
  25. package/dist/core/dist/axis/dom-labels.js +60 -0
  26. package/dist/core/dist/canvas-manager.js +109 -0
  27. package/dist/core/dist/chart/edge-indicators.js +26 -0
  28. package/dist/core/dist/chart/fit-to-data.js +9 -0
  29. package/dist/core/dist/chart/last-value.js +31 -0
  30. package/dist/core/dist/chart/options.js +35 -0
  31. package/dist/core/dist/chart/pan-zoom-math.js +66 -0
  32. package/dist/core/dist/chart/streaming-cadence.js +70 -0
  33. package/dist/core/dist/chart/streaming-target.js +22 -0
  34. package/dist/core/dist/chart/viewport-padding.js +6 -0
  35. package/dist/core/dist/chart/y-target.js +24 -0
  36. package/dist/core/dist/chart.js +1495 -0
  37. package/dist/core/dist/components/crosshair.js +9 -0
  38. package/dist/core/dist/components/edge-indicator.js +36 -0
  39. package/dist/core/dist/components/grid.js +22 -0
  40. package/dist/core/dist/components/marker.js +41 -0
  41. package/dist/core/dist/components/reference-line.js +48 -0
  42. package/dist/core/dist/components/time-region.js +35 -0
  43. package/dist/core/dist/data/decimation.js +54 -0
  44. package/dist/core/dist/data/store.js +76 -0
  45. package/dist/core/dist/data/sync.js +47 -0
  46. package/dist/core/dist/events.js +19 -0
  47. package/dist/core/dist/interactions/handler.js +84 -0
  48. package/dist/core/dist/interactions/pan.js +26 -0
  49. package/dist/core/dist/interactions/zoom.js +21 -0
  50. package/dist/core/dist/navigator/controller.js +374 -0
  51. package/dist/core/dist/navigator/decimate.js +44 -0
  52. package/dist/core/dist/navigator/interactions.js +28 -0
  53. package/dist/core/dist/navigator/render.js +68 -0
  54. package/dist/core/dist/perf/counting-context.js +19 -0
  55. package/dist/core/dist/perf/perf-hud.js +453 -0
  56. package/dist/core/dist/perf/perf-monitor.js +132 -0
  57. package/dist/core/dist/render-scheduler.js +31 -0
  58. package/dist/core/dist/scales/tick-tracker.js +110 -0
  59. package/dist/core/dist/scales/x-scale.js +145 -0
  60. package/dist/core/dist/scales/y-scale.js +156 -0
  61. package/dist/core/dist/series/bar.js +341 -0
  62. package/dist/core/dist/series/base-multi-layer.js +438 -0
  63. package/dist/core/dist/series/candlestick.js +481 -0
  64. package/dist/core/dist/series/definition.js +11 -0
  65. package/dist/core/dist/series/line.js +446 -0
  66. package/dist/core/dist/series/painters/builtins.js +36 -0
  67. package/dist/core/dist/series/painters/canvas-path.js +79 -0
  68. package/dist/core/dist/series/painters/resolve.js +32 -0
  69. package/dist/core/dist/series/pie.js +545 -0
  70. package/dist/core/dist/series/register-builtins.js +11 -0
  71. package/dist/core/dist/series/stack-math.js +17 -0
  72. package/dist/core/dist/snapshots.js +107 -0
  73. package/dist/core/dist/theme/create.js +176 -0
  74. package/dist/core/dist/theme/resolve.js +14 -0
  75. package/dist/core/dist/theme/themes/andromeda.js +33 -0
  76. package/dist/core/dist/theme/themes/ayu-mirage.js +33 -0
  77. package/dist/core/dist/theme/themes/catppuccin.js +33 -0
  78. package/dist/core/dist/theme/themes/dracula.js +35 -0
  79. package/dist/core/dist/theme/themes/github-light.js +34 -0
  80. package/dist/core/dist/theme/themes/gruvbox.js +33 -0
  81. package/dist/core/dist/theme/themes/handwritten.js +101 -0
  82. package/dist/core/dist/theme/themes/high-contrast.js +33 -0
  83. package/dist/core/dist/theme/themes/lavender-mist.js +33 -0
  84. package/dist/core/dist/theme/themes/light-pink.js +34 -0
  85. package/dist/core/dist/theme/themes/material-palenight.js +33 -0
  86. package/dist/core/dist/theme/themes/minimal-light.js +34 -0
  87. package/dist/core/dist/theme/themes/mint-breeze.js +33 -0
  88. package/dist/core/dist/theme/themes/monokai-pro.js +33 -0
  89. package/dist/core/dist/theme/themes/night-owl.js +35 -0
  90. package/dist/core/dist/theme/themes/one-dark-pro.js +33 -0
  91. package/dist/core/dist/theme/themes/panda.js +33 -0
  92. package/dist/core/dist/theme/themes/peach-cream.js +33 -0
  93. package/dist/core/dist/theme/themes/quiet-light.js +37 -0
  94. package/dist/core/dist/theme/themes/rose-pine-dawn.js +33 -0
  95. package/dist/core/dist/theme/themes/sand-dune.js +33 -0
  96. package/dist/core/dist/theme/themes/solarized-light.js +34 -0
  97. package/dist/core/dist/tooltip-position.js +10 -0
  98. package/dist/core/dist/utils/color.js +37 -0
  99. package/dist/core/dist/utils/format.js +29 -0
  100. package/dist/core/dist/utils/math.js +26 -0
  101. package/dist/core/dist/utils/poisoned-data-reporter.js +15 -0
  102. package/dist/core/dist/utils/time.js +41 -0
  103. package/dist/index.d.ts +1096 -63
  104. package/dist/index.js +142 -7754
  105. package/dist/ui/Crosshair.vue.js +53 -0
  106. package/dist/ui/Crosshair.vue2.js +4 -0
  107. package/dist/ui/InfoBar.vue.js +143 -0
  108. package/dist/ui/InfoBar.vue2.js +4 -0
  109. package/dist/ui/Legend.vue.js +212 -0
  110. package/dist/ui/Legend.vue2.js +4 -0
  111. package/dist/ui/Marker.vue.js +47 -0
  112. package/dist/ui/Marker.vue2.js +4 -0
  113. package/dist/ui/Navigator.vue.js +58 -0
  114. package/dist/ui/Navigator.vue2.js +4 -0
  115. package/dist/ui/NumberFlow.vue.js +69 -0
  116. package/dist/ui/NumberFlow.vue2.js +4 -0
  117. package/dist/ui/PieLegend.vue.js +132 -0
  118. package/dist/ui/PieLegend.vue2.js +4 -0
  119. package/dist/ui/PieTooltip.vue.js +135 -0
  120. package/dist/ui/PieTooltip.vue2.js +4 -0
  121. package/dist/ui/ReferenceLine.vue.js +44 -0
  122. package/dist/ui/ReferenceLine.vue2.js +4 -0
  123. package/dist/ui/TimeAxis.vue.js +43 -0
  124. package/dist/ui/TimeAxis.vue2.js +4 -0
  125. package/dist/ui/TimeRegion.vue.js +41 -0
  126. package/dist/ui/TimeRegion.vue2.js +4 -0
  127. package/dist/ui/Title.vue.js +54 -0
  128. package/dist/ui/Title.vue2.js +4 -0
  129. package/dist/ui/Tooltip.vue.js +195 -0
  130. package/dist/ui/Tooltip.vue2.js +4 -0
  131. package/dist/ui/YAxis.vue.js +42 -0
  132. package/dist/ui/YAxis.vue2.js +4 -0
  133. package/dist/ui/YLabel.vue.js +105 -0
  134. package/dist/ui/YLabel.vue2.js +4 -0
  135. package/package.json +2 -2
  136. package/src/BarSeries.vue +12 -13
  137. package/src/CandlestickSeries.vue +17 -6
  138. package/src/LineSeries.vue +12 -13
  139. package/src/PieSeries.vue +2 -1
  140. package/src/composables.ts +12 -2
  141. package/src/index.ts +42 -0
  142. package/src/ui/Crosshair.vue +28 -3
  143. package/src/ui/Legend.vue +1 -2
  144. package/src/ui/Marker.vue +62 -0
  145. package/src/ui/ReferenceLine.vue +58 -0
  146. package/src/ui/TimeRegion.vue +54 -0
@@ -0,0 +1,446 @@
1
+ import { DEFAULT_LINE_PULSE as et, DEFAULT_LINE_SMOOTH as it, DEFAULT_LINE_ENTRY as ot } from "../animation/config.js";
2
+ import { easeOutCubic as J } from "../animation/easing.js";
3
+ import { decimateLineData as K } from "../data/decimation.js";
4
+ import { hexToRgba as D } from "../utils/color.js";
5
+ import { lerp as U } from "../utils/math.js";
6
+ import { BaseMultiLayerSeries as nt } from "./base-multi-layer.js";
7
+ import { buildCurveSegments as Q } from "./painters/canvas-path.js";
8
+ import { resolveLinePainter as lt } from "./painters/resolve.js";
9
+ const rt = {
10
+ colors: ["#2962FF"],
11
+ strokeWidth: 1,
12
+ area: { visible: !0 },
13
+ pulse: !0,
14
+ stacking: "off",
15
+ curve: "straight",
16
+ entryMs: ot,
17
+ smoothMs: it,
18
+ pulseMs: et
19
+ };
20
+ function Z(v) {
21
+ const t = v.areaFill, e = t !== void 0 && v.area === void 0 ? { visible: !!t } : v.area;
22
+ return {
23
+ ...v,
24
+ area: e,
25
+ entryMs: v.entryMs === !1 ? 0 : v.entryMs ?? ot,
26
+ smoothMs: v.smoothMs === !1 ? 0 : v.smoothMs ?? it,
27
+ pulseMs: v.pulseMs === !1 ? 0 : v.pulseMs ?? et
28
+ };
29
+ }
30
+ function $(v) {
31
+ return v.map(([t, e]) => ({ x: t, y: e }));
32
+ }
33
+ function tt(v, t) {
34
+ for (const e of t)
35
+ e.kind === "line" ? v.lineTo(e.x, e.y) : v.bezierCurveTo(e.cp1x, e.cp1y, e.cp2x, e.cp2y, e.x, e.y);
36
+ }
37
+ function at(v, t, e) {
38
+ for (let s = e.length - 1; s >= 0; s--) {
39
+ const r = e[s], n = s > 0 ? e[s - 1] : t[0];
40
+ r.kind === "line" ? v.lineTo(n.x, n.y) : v.bezierCurveTo(r.cp2x, r.cp2y, r.cp1x, r.cp1y, n.x, n.y);
41
+ }
42
+ }
43
+ class ht extends nt {
44
+ kind = "line";
45
+ areaGradientCache = /* @__PURE__ */ new Map();
46
+ constructor(t, e) {
47
+ super(t), this.options = Z({ ...rt, ...e });
48
+ }
49
+ updateOptions(t) {
50
+ this.options = Z({ ...this.options, ...t });
51
+ }
52
+ getStacking() {
53
+ return this.options.stacking;
54
+ }
55
+ applyTheme(t, e) {
56
+ const s = this.stores.length === 1 ? [t.line.color] : t.seriesColors.slice(0, this.stores.length);
57
+ this.updateOptions({ colors: s }), this.options.strokeWidth === e.line.width && this.updateOptions({ strokeWidth: t.line.width });
58
+ }
59
+ isEntryEnabled() {
60
+ return (this.options.entryAnimation ?? "grow") !== "none";
61
+ }
62
+ get hasPulse() {
63
+ return this.options.pulse && this.options.pulseMs > 0 && this.stores.some((t) => t.isVisible() && t.length > 0);
64
+ }
65
+ get overlayNeedsAnimation() {
66
+ return this.hasPulse;
67
+ }
68
+ hasOverlayContentInRange(t, e) {
69
+ for (let s = 0; s < this.stores.length; s++) {
70
+ if (this.getLayerAlpha(s) <= 0) continue;
71
+ const r = this.stores[s].last();
72
+ if (r && r.time >= t) return !0;
73
+ }
74
+ return !1;
75
+ }
76
+ render(t) {
77
+ this.tickAnimations(performance.now()), this.options.stacking === "off" ? this.renderOff(t) : this.renderStacked(t, this.options.stacking === "percent");
78
+ }
79
+ /**
80
+ * Rendered positions of the layer's still-unsettled trailing points, keyed
81
+ * by time. Each chain link lerps from the *previous link's rendered
82
+ * position* toward its own target — so when appends arrive faster than
83
+ * `entryMs` and several entrances overlap, the older heads keep unfurling
84
+ * instead of snapping to their raw spots the frame a new point lands.
85
+ *
86
+ * Targets read {@link BaseMultiLayerSeries.effectiveValue}, so the pinned
87
+ * live chase and the entrance compose. Returns `null` when nothing is
88
+ * unsettled or any value in the chain (anchor included) is non-finite —
89
+ * callers fall back to raw geometry, mirroring the old NaN guard.
90
+ */
91
+ chainedTailPositions(t, e) {
92
+ const s = this.unsettledTail(t, e);
93
+ if (s.length === 0) return null;
94
+ const r = this.stores[e].getAll(), n = r.length - 1 - s.length;
95
+ if (n < 0) return null;
96
+ const { timeScale: l, yScale: d } = t, L = r[n];
97
+ if (!Number.isFinite(L.value)) return null;
98
+ let k = l.timeToBitmapX(L.time), B = d.valueToBitmapY(this.effectiveValue(t, e, L.time, L.value));
99
+ const f = /* @__PURE__ */ new Map();
100
+ for (let m = 0; m < s.length; m++) {
101
+ const h = r[n + 1 + m];
102
+ if (!Number.isFinite(h.value)) return null;
103
+ const P = J(s[m].progress), o = l.timeToBitmapX(h.time), C = d.valueToBitmapY(this.effectiveValue(t, e, h.time, h.value)), y = U(k, o, P), g = U(B, C, P);
104
+ f.set(h.time, { x: y, y: g }), k = y, B = g;
105
+ }
106
+ return f;
107
+ }
108
+ /**
109
+ * Bitmap coordinates for the trailing endpoint of a layer — i.e. where the
110
+ * last visible point should be drawn *right now*. Accounts for live-tracking
111
+ * smoothing on Y (via {@link BaseMultiLayerSeries.effectiveValue}) and the
112
+ * `'grow'` entrance animation via the chained tail lerp.
113
+ *
114
+ * Shared between `renderOff` (last `lineTo` of the polyline) and `drawOverlay`
115
+ * (pulse dot) so the pulse glides in sync with the trailing segment instead
116
+ * of teleporting to the raw last.time while the line still unfurls.
117
+ */
118
+ trailingEndpoint(t, e) {
119
+ const s = this.stores[e].last();
120
+ if (!s) return null;
121
+ const { timeScale: r, yScale: n } = t, l = r.timeToBitmapX(s.time), d = n.valueToBitmapY(this.effectiveValue(t, e, s.time, s.value));
122
+ return (this.options.entryAnimation ?? "grow") !== "grow" ? { x: l, y: d } : this.chainedTailPositions(t, e)?.get(s.time) ?? { x: l, y: d };
123
+ }
124
+ /**
125
+ * Vertical stroke + area gradients for `options.threshold`, pinned to the
126
+ * threshold value's pixel row so the series reads calm below the level and hot
127
+ * above it. Returns `null` when no threshold is configured.
128
+ *
129
+ * Recomputed per frame: `createLinearGradient` is cheap, and the row drifts as
130
+ * the Y-axis autoscales (and during the spike's entrance), so a cache keyed on
131
+ * the row would miss almost every frame anyway.
132
+ */
133
+ buildThresholdPaint(t, e) {
134
+ const s = this.options.threshold;
135
+ if (!s) return null;
136
+ const { scope: r, yScale: n } = t, { context: l } = r, d = r.bitmapSize.height, L = s.above, k = s.below ?? e, B = Math.min(1, Math.max(0, n.valueToBitmapY(s.value) / d)), f = Math.min(6 * r.verticalPixelRatio, d * 0.02) / d, m = Math.max(0, B - f), h = Math.min(1, B + f), P = l.createLinearGradient(0, 0, 0, d);
137
+ P.addColorStop(0, L), P.addColorStop(m, L), P.addColorStop(h, k), P.addColorStop(1, k);
138
+ const o = l.createLinearGradient(0, 0, 0, d);
139
+ return o.addColorStop(0, D(L, 0.26)), o.addColorStop(m, D(L, 0.14)), o.addColorStop(h, D(k, 0.1)), o.addColorStop(1, D(k, 0.01)), { stroke: P, area: o };
140
+ }
141
+ /** Each layer drawn independently */
142
+ renderOff(t) {
143
+ const { scope: e, timeScale: s, yScale: r } = t, { context: n } = e, l = s.getRange(), { verticalPixelRatio: d } = e, L = this.options.strokeWidth > 0, k = Math.max(1, Math.round(this.options.strokeWidth * d)), B = this.options.entryAnimation ?? "grow", f = lt(this.options.linePainter ?? this.options.curve ?? "straight"), m = {
144
+ ctx: n,
145
+ theme: t.theme,
146
+ horizontalPixelRatio: e.horizontalPixelRatio,
147
+ verticalPixelRatio: d
148
+ };
149
+ for (let h = 0; h < this.stores.length; h++) {
150
+ const P = this.getLayerAlpha(h);
151
+ if (P <= 0) continue;
152
+ let o = this.stores[h].getVisibleData(l.from, l.to);
153
+ const C = e.mediaSize.width;
154
+ if (o.length > C * 2 && (o = K(o, Math.round(C * 1.5))), o.length < 2) continue;
155
+ const y = this.stores[h].last()?.value ?? o[o.length - 1].value, g = this.resolveLayerColor(h, y), I = this.buildThresholdPaint(t, g), E = o[o.length - 1], b = this.stores[h].last(), W = b !== void 0 && E.time === b.time, Y = W ? this.entranceProgress(t, h, E.time) : 1, N = W && B === "fade" && Y < 1, T = (W ? this.trailingEndpoint(t, h) : null) ?? {
156
+ x: s.timeToBitmapX(E.time),
157
+ y: r.valueToBitmapY(this.effectiveValue(t, h, E.time, E.value))
158
+ }, z = T.x, i = T.y, c = W && B === "grow" ? this.chainedTailPositions(t, h) : null, a = P < 1;
159
+ (a || N) && (n.save(), a && (n.globalAlpha *= P), N && (n.globalAlpha *= Y));
160
+ const S = o.length - 1, p = [];
161
+ let x = null;
162
+ for (let u = 0; u < S; u++) {
163
+ const w = o[u].value;
164
+ if (!Number.isFinite(w)) {
165
+ x = null;
166
+ continue;
167
+ }
168
+ x || (x = [], p.push(x));
169
+ const A = c?.get(o[u].time);
170
+ if (A)
171
+ x.push({ x: A.x, y: A.y });
172
+ else {
173
+ const O = r.valueToBitmapY(this.effectiveValue(t, h, o[u].time, w));
174
+ x.push({ x: s.timeToBitmapX(o[u].time), y: O });
175
+ }
176
+ }
177
+ const F = o[S]?.value, _ = Number.isFinite(z) && Number.isFinite(i) && Number.isFinite(F), H = B === "grow" && Y < 1;
178
+ let X = null;
179
+ if (_ && (x ? (x.push({ x: z, y: i }), X = x) : p.push([{ x: z, y: i }])), L && p.some((u) => u.length >= 2)) {
180
+ n.beginPath();
181
+ for (const u of p)
182
+ u.length < 2 || f(m, { points: u, color: g, lineWidth: k, closing: !1, grew: H && u === X });
183
+ n.strokeStyle = I ? I.stroke : g, n.lineWidth = k, n.lineJoin = "round", n.lineCap = "round", n.stroke();
184
+ }
185
+ if (L) {
186
+ const u = Math.max(1, k / 2);
187
+ let w = !1;
188
+ for (const A of p)
189
+ A.length === 1 && (w || (n.beginPath(), w = !0), n.moveTo(A[0].x + u, A[0].y), n.arc(A[0].x, A[0].y, u, 0, Math.PI * 2));
190
+ w && (n.fillStyle = g, n.fill());
191
+ }
192
+ if (this.options.area.visible) {
193
+ const u = e.bitmapSize.height;
194
+ let w;
195
+ if (I)
196
+ w = I.area;
197
+ else {
198
+ const A = String(h), O = this.areaGradientCache.get(A);
199
+ O && O.bottomY === u && O.color === g ? w = O.gradient : (w = n.createLinearGradient(0, 0, 0, u), w.addColorStop(0, D(g, 0.12)), w.addColorStop(1, D(g, 0.01)), this.areaGradientCache.set(A, { gradient: w, bottomY: u, color: g }));
200
+ }
201
+ n.fillStyle = w;
202
+ for (const A of p)
203
+ A.length < 2 || (n.beginPath(), f(m, { points: A, color: g, lineWidth: k, closing: !0, grew: H && A === X }), n.lineTo(A[A.length - 1].x, u), n.lineTo(A[0].x, u), n.closePath(), n.fill());
204
+ }
205
+ (N || a) && n.restore();
206
+ }
207
+ }
208
+ /** Stacked area rendering */
209
+ renderStacked(t, e) {
210
+ const { scope: s, timeScale: r, yScale: n } = t, { context: l } = s, d = r.getRange(), { verticalPixelRatio: L } = s, k = this.options.strokeWidth > 0, B = Math.max(1, Math.round(this.options.strokeWidth * L)), f = this.options.curve ?? "straight", m = s.mediaSize.width, h = this.stores.map((i, c) => {
211
+ if (this.getLayerAlpha(c) <= 0) return [];
212
+ let a = i.getVisibleData(d.from, d.to);
213
+ return a.length > m * 2 && (a = K(a, Math.round(m * 1.5))), a;
214
+ }), P = /* @__PURE__ */ new Set();
215
+ for (const i of h)
216
+ for (const c of i) P.add(c.time);
217
+ const o = Array.from(P).sort((i, c) => i - c);
218
+ if (o.length < 2) return;
219
+ const C = h.map((i, c) => {
220
+ const a = /* @__PURE__ */ new Map(), S = this.getLayerAlpha(c);
221
+ for (const p of i) a.set(p.time, this.effectiveValue(t, c, p.time, p.value) * S);
222
+ return a;
223
+ }), y = Array.from({ length: this.stores.length }, () => new Array(o.length).fill(0));
224
+ for (let i = 0; i < o.length; i++) {
225
+ const c = o[i];
226
+ let a = 0;
227
+ if (e)
228
+ for (let p = 0; p < this.stores.length; p++) {
229
+ const x = C[p].get(c);
230
+ Number.isFinite(x) && (a += x);
231
+ }
232
+ let S = 0;
233
+ for (let p = 0; p < this.stores.length; p++) {
234
+ const x = C[p].get(c), F = Number.isFinite(x) ? x : 0;
235
+ S += e && a > 0 ? F / a * 100 : F, y[p][i] = S;
236
+ }
237
+ }
238
+ const g = this.options.entryAnimation ?? "grow", I = /* @__PURE__ */ new Map();
239
+ for (let i = 0; i < o.length; i++) I.set(o[i], i);
240
+ const E = Array.from({ length: this.stores.length }, () => []), b = new Array(this.stores.length).fill(1);
241
+ for (let i = 0; i < this.stores.length; i++) {
242
+ if (this.getLayerAlpha(i) <= 0) continue;
243
+ const c = this.unsettledTail(t, i), a = c.length;
244
+ if (a === 0) continue;
245
+ let S = !0;
246
+ for (let F = 0; F < a; F++)
247
+ if (I.get(c[F].time) !== o.length - a + F) {
248
+ S = !1;
249
+ break;
250
+ }
251
+ if (!S) continue;
252
+ const p = this.stores[i].getAll(), x = p.length - 1 - a;
253
+ x < 0 || I.get(p[x].time) === o.length - a - 1 && (E[i] = c.map((F) => J(F.progress)), b[i] = c[a - 1].progress);
254
+ }
255
+ const W = (i, c) => {
256
+ const a = c.length;
257
+ if (!(a === 0 || i.length < a + 1))
258
+ for (let S = 0; S < a; S++) {
259
+ const p = i.length - a + S, x = i[p - 1], F = i[p];
260
+ i[p] = [U(x[0], F[0], c[S]), U(x[1], F[1], c[S])];
261
+ }
262
+ }, Y = s.bitmapSize.height;
263
+ let N = -1, T = -1;
264
+ for (let i = 0; i < this.stores.length; i++)
265
+ if (!(this.getLayerAlpha(i) <= 0))
266
+ if (N < 0)
267
+ N = i;
268
+ else {
269
+ T = i;
270
+ break;
271
+ }
272
+ const z = N >= 0 ? this.getLayerAlpha(N) : 1;
273
+ for (let i = this.stores.length - 1; i >= 0; i--) {
274
+ const c = this.getLayerAlpha(i);
275
+ if (c <= 0) continue;
276
+ const a = this.stores[i].last()?.value ?? 0, S = this.resolveLayerColor(i, a), p = E[i];
277
+ let x = -1;
278
+ for (let R = i - 1; R >= 0; R--)
279
+ if (this.getLayerAlpha(R) > 0) {
280
+ x = R;
281
+ break;
282
+ }
283
+ const F = x >= 0 ? E[x] : [], _ = i === N, H = T >= 0 && i === T && z < 1, X = [];
284
+ for (let R = 0; R < o.length; R++) {
285
+ const V = i > 0 ? n.valueToBitmapY(y[i - 1][R]) : Y;
286
+ let G = V;
287
+ _ ? G = Y : H && (G = V + (Y - V) * (1 - z)), X.push([r.timeToBitmapX(o[R]), G]);
288
+ }
289
+ g === "grow" && W(X, F);
290
+ const u = [];
291
+ for (let R = 0; R < o.length; R++) {
292
+ let V = n.valueToBitmapY(y[i][R]);
293
+ _ && c < 1 && (V = Y + (V - Y) * c), u.push([r.timeToBitmapX(o[R]), V]);
294
+ }
295
+ g === "grow" && W(u, p);
296
+ const w = $(u), A = Q(w, f, g === "grow" && p.length > 0), O = g === "fade" && b[i] < 1;
297
+ if (O && (l.save(), l.globalAlpha = b[i]), this.options.area.visible) {
298
+ let R = u[0][1], V = X[0][1];
299
+ for (let M = 1; M < u.length; M++)
300
+ u[M][1] < R && (R = u[M][1]);
301
+ for (let M = 1; M < X.length; M++)
302
+ X[M][1] > V && (V = X[M][1]);
303
+ let G = D(S, 0.25);
304
+ if (V > R + 0.5) {
305
+ const M = l.createLinearGradient(0, R, 0, V);
306
+ M.addColorStop(0, D(S, 0.25)), M.addColorStop(1, D(S, 0.05)), G = M;
307
+ }
308
+ if (l.beginPath(), l.moveTo(w[0].x, w[0].y), tt(l, A), _)
309
+ for (let M = X.length - 1; M >= 0; M--)
310
+ l.lineTo(X[M][0], X[M][1]);
311
+ else {
312
+ const M = $(X), st = Q(M, f, g === "grow" && F.length > 0), q = M[M.length - 1];
313
+ l.lineTo(q.x, q.y), at(l, M, st);
314
+ }
315
+ l.closePath(), l.fillStyle = G, l.fill();
316
+ }
317
+ const j = k && c < 1;
318
+ j && (l.save(), l.globalAlpha *= c), k && (l.beginPath(), l.moveTo(w[0].x, w[0].y), tt(l, A), l.strokeStyle = S, l.lineWidth = B, l.lineJoin = "round", l.lineCap = "round", l.stroke()), j && l.restore(), O && l.restore();
319
+ }
320
+ }
321
+ /**
322
+ * Overlay hook: draws crosshair nearest-point dots and last-point pulse dots.
323
+ * Chart invokes this during the overlay pass for any renderer that implements it.
324
+ */
325
+ drawOverlay(t) {
326
+ this.tickAnimations(performance.now());
327
+ const { scope: e, timeScale: s, yScale: r, crosshair: n, dataInterval: l } = t, d = e, L = this.options.pulseMs, k = L > 0 ? performance.now() / (L * 2 * Math.PI) % 1 : 0;
328
+ if (n) {
329
+ const B = this.options.stacking, f = 4 * d.horizontalPixelRatio, m = [], h = [];
330
+ for (let o = 0; o < this.stores.length; o++) {
331
+ const C = this.stores[o].findNearest(n.time, l);
332
+ C ? (m.push(C.value), h.push(C.time)) : (m.push(0), h.push(null));
333
+ }
334
+ const P = [];
335
+ if (B === "off")
336
+ for (const o of m) P.push(o);
337
+ else {
338
+ let o = 0;
339
+ if (B === "percent")
340
+ for (let y = 0; y < m.length; y++)
341
+ o += m[y] * this.getLayerAlpha(y);
342
+ let C = 0;
343
+ for (let y = 0; y < m.length; y++) {
344
+ const g = m[y] * this.getLayerAlpha(y);
345
+ C += B === "percent" && o > 0 ? g / o * 100 : g, P.push(C);
346
+ }
347
+ }
348
+ for (let o = 0; o < this.stores.length; o++) {
349
+ const C = h[o];
350
+ if (C === null) continue;
351
+ const y = this.getLayerAlpha(o);
352
+ if (y <= 0) continue;
353
+ const g = this.resolveLayerColor(o, m[o]), I = s.timeToBitmapX(C), E = r.valueToBitmapY(P[o]), b = y < 1;
354
+ b && (e.context.save(), e.context.globalAlpha *= y), e.context.save(), e.context.globalAlpha *= 0.25, e.context.beginPath(), e.context.arc(I, E, f + 3 * d.horizontalPixelRatio, 0, Math.PI * 2), e.context.fillStyle = g, e.context.fill(), e.context.restore(), e.context.beginPath(), e.context.arc(I, E, f, 0, Math.PI * 2), e.context.fillStyle = g, e.context.fill(), b && e.context.restore();
355
+ }
356
+ }
357
+ if (this.hasPulse && L > 0) {
358
+ const B = this.options.stacking;
359
+ for (let f = 0; f < this.stores.length; f++) {
360
+ const m = this.getLayerAlpha(f);
361
+ if (m <= 0) continue;
362
+ const h = this.stores[f].last()?.value ?? 0, P = this.resolveLayerColor(f, h);
363
+ if (B === "off") {
364
+ const b = this.trailingEndpoint(t, f);
365
+ if (!b) continue;
366
+ this.drawPulse({
367
+ ctx: e.context,
368
+ x: b.x,
369
+ y: b.y,
370
+ color: P,
371
+ pixelRatio: d.horizontalPixelRatio,
372
+ phase: k,
373
+ alpha: m
374
+ });
375
+ continue;
376
+ }
377
+ const o = this.stores[f].last();
378
+ if (!o) continue;
379
+ const C = o.time, y = B === "percent", g = (b) => {
380
+ const W = (T) => {
381
+ const z = this.getLayerAlpha(T);
382
+ if (z <= 0) return 0;
383
+ const i = T === f && b === C ? o : this.stores[T].findNearest(b, 0);
384
+ return !i || i.time !== b ? 0 : this.effectiveValue(t, T, b, i.value) * z;
385
+ };
386
+ let Y = 0;
387
+ if (y)
388
+ for (let T = 0; T < this.stores.length; T++)
389
+ Y += W(T);
390
+ let N = 0;
391
+ for (let T = 0; T <= f; T++) {
392
+ const z = W(T);
393
+ N += y && Y > 0 ? z / Y * 100 : z;
394
+ }
395
+ return N;
396
+ };
397
+ let I = s.timeToBitmapX(C), E = r.valueToBitmapY(g(C));
398
+ if ((this.options.entryAnimation ?? "grow") === "grow") {
399
+ const b = this.unsettledTail(t, f), W = this.stores[f].getAll(), Y = W.length - 1 - b.length;
400
+ if (b.length > 0 && Y >= 0) {
401
+ const N = W[Y];
402
+ let T = s.timeToBitmapX(N.time), z = r.valueToBitmapY(g(N.time));
403
+ for (let i = 0; i < b.length; i++) {
404
+ const c = W[Y + 1 + i], a = J(b[i].progress), S = s.timeToBitmapX(c.time), p = r.valueToBitmapY(g(c.time));
405
+ T = U(T, S, a), z = U(z, p, a);
406
+ }
407
+ I = T, E = z;
408
+ }
409
+ }
410
+ this.drawPulse({
411
+ ctx: e.context,
412
+ x: I,
413
+ y: E,
414
+ color: P,
415
+ pixelRatio: d.horizontalPixelRatio,
416
+ phase: k,
417
+ alpha: m
418
+ });
419
+ }
420
+ }
421
+ }
422
+ drawPulse({
423
+ ctx: t,
424
+ x: e,
425
+ y: s,
426
+ color: r,
427
+ pixelRatio: n,
428
+ phase: l,
429
+ alpha: d = 1
430
+ }) {
431
+ const L = 3 * n, k = 0.4 + 0.6 * Math.abs(Math.sin(l * 2 * Math.PI)), B = L + 4 * n * k, f = d < 1;
432
+ f && (t.save(), t.globalAlpha *= d), t.beginPath(), t.arc(e, s, B, 0, Math.PI * 2), t.fillStyle = D(r, k * 0.3), t.fill(), t.beginPath(), t.arc(e, s, L, 0, Math.PI * 2), t.fillStyle = r, t.fill(), f && t.restore();
433
+ }
434
+ }
435
+ const xt = {
436
+ type: "line",
437
+ create: ({ theme: v, layerCount: t }, e) => new ht(t, {
438
+ colors: t === 1 ? [v.line.color] : v.seriesColors.slice(0, t),
439
+ strokeWidth: v.line.width,
440
+ ...e
441
+ })
442
+ };
443
+ export {
444
+ ht as LineRenderer,
445
+ xt as LineSeriesDef
446
+ };
@@ -0,0 +1,36 @@
1
+ import { hexToRgba as h } from "../../utils/color.js";
2
+ import { fillRoundedRect as d, tracePath as n } from "./canvas-path.js";
3
+ const p = 0.25, u = (e, t) => {
4
+ n(e, { points: t.points, kind: "straight", settledOnly: !1 });
5
+ }, x = (e, t) => {
6
+ n(e, { points: t.points, kind: "stepped", settledOnly: !1 });
7
+ }, y = (e, t) => {
8
+ n(e, { points: t.points, kind: "smooth", settledOnly: t.grew });
9
+ }, f = (e, t) => {
10
+ const { ctx: i } = e, { geom: s, color: o, corners: r, radius: l, isProjected: a } = t;
11
+ i.fillStyle = a ? h(o, p) : o, d(i, {
12
+ x: s.x,
13
+ y: s.y,
14
+ width: s.width,
15
+ height: s.height,
16
+ radius: l,
17
+ corners: r
18
+ });
19
+ }, m = (e, t) => {
20
+ const { ctx: i } = e, { geom: s, fillStyle: o, corners: r, radius: l } = t;
21
+ i.fillStyle = o, d(i, {
22
+ x: s.x,
23
+ y: s.y,
24
+ width: s.width,
25
+ height: s.height,
26
+ radius: l,
27
+ corners: r
28
+ });
29
+ };
30
+ export {
31
+ f as roundedBarFill,
32
+ m as roundedCandleFill,
33
+ y as smoothCurve,
34
+ x as steppedCurve,
35
+ u as straightCurve
36
+ };
@@ -0,0 +1,79 @@
1
+ function p(t, u) {
2
+ const { x: o, y: i, width: r, height: c, corners: e } = u, n = Math.min(u.radius, r / 2, c / 2);
3
+ if (!(e.tl || e.tr || e.br || e.bl) || n < 1 || r <= 0 || c <= 0) {
4
+ t.fillRect(o, i, r, c);
5
+ return;
6
+ }
7
+ const s = e.tl ? n : 0, x = e.tr ? n : 0, l = e.br ? n : 0, y = e.bl ? n : 0, f = o + r, h = i + c;
8
+ t.beginPath(), t.moveTo(o + s, i), t.lineTo(f - x, i), x > 0 && t.arcTo(f, i, f, i + x, x), t.lineTo(f, h - l), l > 0 && t.arcTo(f, h, f - l, h, l), t.lineTo(o + y, h), y > 0 && t.arcTo(o, h, o, h - y, y), t.lineTo(o, i + s), s > 0 && t.arcTo(o, i, o + s, i, s), t.closePath(), t.fill();
9
+ }
10
+ function a(t, u, o) {
11
+ const i = [];
12
+ if (t.length < 2) return i;
13
+ if (u === "stepped") {
14
+ for (let r = 1; r < t.length; r++)
15
+ i.push({ kind: "line", x: t[r].x, y: t[r - 1].y }), i.push({ kind: "line", x: t[r].x, y: t[r].y });
16
+ return i;
17
+ }
18
+ if (u === "straight" || t.length === 2) {
19
+ for (let r = 1; r < t.length; r++)
20
+ i.push({ kind: "line", x: t[r].x, y: t[r].y });
21
+ return i;
22
+ }
23
+ return b(t, o);
24
+ }
25
+ function d(t, u) {
26
+ const { ctx: o } = t, { points: i } = u;
27
+ if (i.length === 0) return;
28
+ o.moveTo(i[0].x, i[0].y);
29
+ const r = a(i, u.kind, u.settledOnly);
30
+ for (const c of r)
31
+ c.kind === "line" ? o.lineTo(c.x, c.y) : o.bezierCurveTo(c.cp1x, c.cp1y, c.cp2x, c.cp2y, c.x, c.y);
32
+ }
33
+ function b(t, u) {
34
+ const o = t.length, i = new Array(o - 1);
35
+ for (let e = 0; e < o - 1; e++) {
36
+ const n = t[e + 1].x - t[e].x;
37
+ i[e] = n > 0 ? (t[e + 1].y - t[e].y) / n : Number.NaN;
38
+ }
39
+ const r = new Array(o);
40
+ r[0] = Number.isFinite(i[0]) ? i[0] : 0;
41
+ for (let e = 1; e < o - 1; e++) {
42
+ const n = i[e - 1], s = i[e];
43
+ !Number.isFinite(n) || !Number.isFinite(s) ? r[e] = Number.isFinite(n) ? n : Number.isFinite(s) ? s : 0 : n * s <= 0 ? r[e] = 0 : r[e] = (n + s) / 2;
44
+ }
45
+ r[o - 1] = Number.isFinite(i[o - 2]) ? i[o - 2] : 0;
46
+ for (let e = 0; e < o - 1; e++) {
47
+ const n = i[e];
48
+ if (!Number.isFinite(n) || n === 0) continue;
49
+ const s = r[e] / n, x = r[e + 1] / n, l = s * s + x * x;
50
+ if (l > 9) {
51
+ const y = 3 / Math.sqrt(l);
52
+ r[e] = y * s * n, r[e + 1] = y * x * n;
53
+ }
54
+ }
55
+ const c = [];
56
+ for (let e = 0; e < o - 1; e++) {
57
+ const n = t[e], s = t[e + 1], x = e === o - 2;
58
+ if (!Number.isFinite(i[e]) || u && x) {
59
+ c.push({ kind: "line", x: s.x, y: s.y });
60
+ continue;
61
+ }
62
+ const l = s.x - n.x;
63
+ c.push({
64
+ kind: "bezier",
65
+ cp1x: n.x + l / 3,
66
+ cp1y: n.y + r[e] * l / 3,
67
+ cp2x: s.x - l / 3,
68
+ cp2y: s.y - r[e + 1] * l / 3,
69
+ x: s.x,
70
+ y: s.y
71
+ });
72
+ }
73
+ return c;
74
+ }
75
+ export {
76
+ a as buildCurveSegments,
77
+ p as fillRoundedRect,
78
+ d as tracePath
79
+ };
@@ -0,0 +1,32 @@
1
+ import { roundedCandleFill as i, steppedCurve as f, smoothCurve as d, straightCurve as n, roundedBarFill as u } from "./builtins.js";
2
+ const h = {
3
+ straight: n,
4
+ smooth: d,
5
+ stepped: f
6
+ }, l = /* @__PURE__ */ new WeakSet();
7
+ function p(e, t, r) {
8
+ l.has(t) || (l.add(t), console.warn(`[wick-charts] a ${e} painter threw; falling back to the default for this series.`, r));
9
+ }
10
+ function a(e, t, r) {
11
+ return (o, s) => {
12
+ try {
13
+ t(o, s);
14
+ } catch (c) {
15
+ p(e, t, c), r(o, s);
16
+ }
17
+ };
18
+ }
19
+ function m(e) {
20
+ return e ? a("bar", e, u) : u;
21
+ }
22
+ function v(e) {
23
+ return e ? a("candle", e, i) : i;
24
+ }
25
+ function C(e) {
26
+ return typeof e == "function" ? a("line", e, n) : typeof e == "string" ? h[e] ?? n : n;
27
+ }
28
+ export {
29
+ m as resolveBarPainter,
30
+ v as resolveCandlePainter,
31
+ C as resolveLinePainter
32
+ };