@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,374 @@
1
+ import { DEFAULT_LINE_ENTRY as w } from "../animation/config.js";
2
+ import { XScale as T } from "../scales/x-scale.js";
3
+ import { YScale as R } from "../scales/y-scale.js";
4
+ import { decimateCandles as k, decimateLinear as C } from "./decimate.js";
5
+ import { hitTest as y, computeSnapCenter as E, computePan as I, computeResize as M } from "./interactions.js";
6
+ import { computeWindowGeometry as $, renderBackground as V, renderMiniCandlestick as L, renderMiniBar as N, renderMiniLine as P } from "./render.js";
7
+ import { Animator as S } from "../animation/animator.js";
8
+ import { easeOutCubic as z } from "../animation/easing.js";
9
+ class G {
10
+ #s;
11
+ #t;
12
+ #z;
13
+ #e;
14
+ #o;
15
+ #d;
16
+ #r;
17
+ #l;
18
+ #a;
19
+ #c;
20
+ #x;
21
+ #v;
22
+ // Own scales — both cover the full data span. The main chart's scales move
23
+ // with the viewport; these don't.
24
+ #u = new T();
25
+ #F = new R();
26
+ #A = 0;
27
+ #m = 0;
28
+ #n = 1;
29
+ #p = null;
30
+ /** A full canvas render is owed. A queued frame with `#dirty === false`
31
+ * came from {@link #markWindowDirty} and only repositions the window DOM. */
32
+ #T = !0;
33
+ /**
34
+ * Memoized decimation results keyed by source array ref. Cleared on
35
+ * `setData` (guards in-place mutation of a re-passed array); a buckets
36
+ * mismatch (resize) recomputes per entry.
37
+ */
38
+ #R = /* @__PURE__ */ new Map();
39
+ /**
40
+ * Eases the alpha of the trailing bar/candle/line-segment from 0 → 1 over
41
+ * `DEFAULT_LINE_ENTRY` whenever {@link setData} reports a new last point
42
+ * (a `time` we haven't seen before). Mirrors the per-point entrance
43
+ * animation that the main chart's series renderers run, so a streaming
44
+ * tick reads as a smooth fade-in here too instead of a redraw pop.
45
+ *
46
+ * `null` means "no entrance in flight, draw the tail at full alpha".
47
+ */
48
+ #h = null;
49
+ /** `time` of the last point we've ever seen — initialises after the first
50
+ * `setData`/render so the first paint doesn't trigger a fade-in. */
51
+ #k = null;
52
+ /** Series index in `lineSeriesList(data)` that owns the newest last-time,
53
+ * so the tail fade applies to the series that actually grew — not always
54
+ * the last entry in the stack. -1 for candlestick (single-series). */
55
+ #C = -1;
56
+ #E;
57
+ // Active-drag state — null when idle.
58
+ #g = null;
59
+ // Bound listeners so we can remove the same references on destroy.
60
+ #I;
61
+ #M;
62
+ #$;
63
+ #V;
64
+ #L;
65
+ #b;
66
+ #N;
67
+ constructor(t) {
68
+ this.#s = t.container, this.#e = t.chart, this.#x = t.data, this.#v = t.options ?? {}, window.getComputedStyle(this.#s).position === "static" && (this.#s.style.position = "relative"), this.#t = document.createElement("canvas"), this.#t.style.position = "absolute", this.#t.style.left = "0", this.#t.style.top = "0", this.#t.style.height = "100%", this.#t.style.touchAction = "none", this.#s.appendChild(this.#t);
69
+ const e = this.#t.getContext("2d", { alpha: !0 });
70
+ if (!e) throw new Error("NavigatorController: failed to acquire 2D context");
71
+ this.#z = e, this.#o = document.createElement("div"), this.#o.dataset.chartNavigatorOverlay = "", this.#o.style.cssText = "position:absolute;left:0;top:0;height:100%;pointer-events:none;", this.#d = document.createElement("div"), this.#d.style.cssText = "position:absolute;left:0;top:0;bottom:0;", this.#r = document.createElement("div"), this.#r.style.cssText = "position:absolute;top:0;bottom:0;", this.#l = document.createElement("div"), this.#l.style.cssText = "position:absolute;top:0;bottom:0;box-sizing:border-box;", this.#a = b(), this.#c = b(), this.#o.append(this.#d, this.#r, this.#l, this.#a, this.#c), this.#s.appendChild(this.#o), this.#I = () => this.#B(), this.#M = () => this.#f(), this.#$ = () => this.#B(), this.#e.on("viewportChange", this.#I), this.#e.on("overlayChange", this.#M), this.#e.on("tickFrame", this.#$), this.#V = (s) => this.#H(s), this.#L = (s) => this.#J(s), this.#b = (s) => this.#K(s), this.#N = () => {
72
+ this.#g === null && (this.#t.style.cursor = "default");
73
+ }, this.#t.addEventListener("pointerdown", this.#V), this.#t.addEventListener("pointermove", this.#L), this.#t.addEventListener("pointerup", this.#b), this.#t.addEventListener("pointercancel", this.#b), this.#t.addEventListener("pointerleave", this.#N), this.#E = new ResizeObserver((s) => this.#U(s[0])), this.#E.observe(this.#s), this.#D();
74
+ const i = this.#s.getBoundingClientRect();
75
+ i.width > 0 && i.height > 0 && this.#W(i.width, i.height), this.#f();
76
+ }
77
+ setData(t) {
78
+ const e = F(t), i = e?.time ?? null;
79
+ if (i !== null && this.#k !== null && i !== this.#k) {
80
+ const s = this.#h?.current ?? 0;
81
+ this.#h = new S({
82
+ initial: s,
83
+ duration: w,
84
+ easing: z,
85
+ lerp: (n, h, l) => n + (h - n) * l
86
+ }), this.#h.setTarget(1);
87
+ }
88
+ this.#k = i, this.#C = e?.seriesIndex ?? -1, this.#x = t, this.#R.clear(), this.#f();
89
+ }
90
+ setOptions(t) {
91
+ this.#v = t, this.#D(), this.#f();
92
+ }
93
+ /** Push `options.height` (when set) onto the container's CSS height so
94
+ * direct core consumers see the option take effect. When the option is
95
+ * absent we leave the container alone — framework wrappers manage their
96
+ * own inline height via JSX, and overwriting it here would clobber the
97
+ * caller's value during the first layout effect. */
98
+ #D() {
99
+ const t = this.#v.height;
100
+ t !== void 0 && (this.#s.style.height = `${t}px`);
101
+ }
102
+ destroy() {
103
+ this.#e.off("viewportChange", this.#I), this.#e.off("overlayChange", this.#M), this.#e.off("tickFrame", this.#$), this.#t.removeEventListener("pointerdown", this.#V), this.#t.removeEventListener("pointermove", this.#L), this.#t.removeEventListener("pointerup", this.#b), this.#t.removeEventListener("pointercancel", this.#b), this.#t.removeEventListener("pointerleave", this.#N), this.#E.disconnect(), this.#p !== null && (cancelAnimationFrame(this.#p), this.#p = null), this.#t.remove(), this.#o.remove();
104
+ }
105
+ /** CSS pixel height of the strip — theme default unless overridden. */
106
+ get height() {
107
+ return this.#v.height ?? this.#e.getTheme().navigator.height;
108
+ }
109
+ // --- internals ---------------------------------------------------------
110
+ /** Effective drawing width — the navigator reserves the main chart's
111
+ * `yAxisWidth` on the right so its active zone lines up with the plot area. */
112
+ get #i() {
113
+ return Math.max(0, this.#A - this.#e.yAxisWidth);
114
+ }
115
+ #U(t) {
116
+ if (!t) return;
117
+ const e = t.contentBoxSize?.[0], i = e?.inlineSize ?? t.contentRect.width, s = e?.blockSize ?? t.contentRect.height;
118
+ i <= 0 || s <= 0 || (this.#W(i, s), this.#f());
119
+ }
120
+ #W(t, e) {
121
+ this.#A = t, this.#m = e, this.#n = window.devicePixelRatio || 1, this.#X();
122
+ }
123
+ /**
124
+ * Write canvas backing-store / CSS sizes only when they actually changed —
125
+ * any assignment to `canvas.width`/`height`, even with the same value,
126
+ * resets the backing store (full clear + realloc), which is pure waste on
127
+ * a repaint where nothing resized.
128
+ */
129
+ #X() {
130
+ const t = Math.round(this.#i * this.#n), e = Math.round(this.#m * this.#n);
131
+ this.#t.width !== t && (this.#t.width = t), this.#t.height !== e && (this.#t.height = e);
132
+ const i = `${this.#i}px`;
133
+ this.#t.style.width !== i && (this.#t.style.width = i, this.#o.style.width = i);
134
+ }
135
+ #f() {
136
+ this.#T = !0, this.#O();
137
+ }
138
+ /** Queue a window-DOM-only frame — a queued full render takes precedence. */
139
+ #B() {
140
+ this.#O();
141
+ }
142
+ #O() {
143
+ this.#p === null && (this.#p = requestAnimationFrame(() => {
144
+ this.#p = null;
145
+ const t = this.#T;
146
+ this.#T = !1, t ? this.#_() : this.#Q();
147
+ }));
148
+ }
149
+ // --- input -------------------------------------------------------------
150
+ /** Extract media-x from a pointer event, relative to the canvas. */
151
+ #w(t) {
152
+ const e = this.#t.getBoundingClientRect();
153
+ return t.clientX - e.left;
154
+ }
155
+ /** Keep scales synced with current data bounds + size. Safe to call ahead of
156
+ * the first RAF-driven render — pointer handlers rely on this so hit-tests
157
+ * compute against primed scales even on the opening gesture. */
158
+ #P() {
159
+ const t = this.#y(), e = this.#Z();
160
+ return this.#u.update(t, this.#i, this.#n), this.#F.update(e, this.#m, this.#n), { xRange: t, yRange: e };
161
+ }
162
+ /**
163
+ * X range for the brush window. While the user drags the brush we track the
164
+ * committed logical target so the window follows the cursor 1:1; otherwise we
165
+ * follow the engine's eased visual so the window glides with the canvas
166
+ * instead of snapping to a wheel-zoom / pan destination while the chart eases.
167
+ */
168
+ #Y() {
169
+ return this.#g !== null ? this.#e.getVisibleRange() : this.#e.getAnimationState().xRange;
170
+ }
171
+ #S() {
172
+ return this.#P(), $(this.#u, this.#Y(), this.#y());
173
+ }
174
+ #j() {
175
+ const t = this.#y(), e = t.to - t.from;
176
+ return e <= 0 || this.#i <= 0 ? 0 : this.#i / e;
177
+ }
178
+ #H(t) {
179
+ if (t.button !== void 0 && t.button !== 0) return;
180
+ const e = this.#w(t), i = this.#y();
181
+ if (i.to <= i.from) return;
182
+ const s = this.#S(), n = y(e, s), h = this.#j();
183
+ if (h === 0) return;
184
+ let l = this.#e.getVisibleRange();
185
+ if (n.snapToCenter) {
186
+ const r = this.#u.xToTime(e), a = E({ time: r, startVisible: l, xRange: i });
187
+ this.#e.setVisibleRange(a), l = a;
188
+ }
189
+ this.#g = {
190
+ pointerId: t.pointerId,
191
+ gesture: n.gesture,
192
+ startX: e,
193
+ startVisible: l,
194
+ pixelsPerTime: h
195
+ }, this.#t.setPointerCapture(t.pointerId), this.#t.style.cursor = v(
196
+ n.gesture,
197
+ /*dragging*/
198
+ !0
199
+ ), t.preventDefault();
200
+ }
201
+ #J(t) {
202
+ const e = this.#g;
203
+ if (e === null) {
204
+ this.#t.style.cursor = x(this.#w(t), this.#S());
205
+ return;
206
+ }
207
+ if (t.pointerId !== e.pointerId) return;
208
+ const i = this.#w(t) - e.startX, s = this.#y();
209
+ let n;
210
+ if (e.gesture === "pan")
211
+ n = I({
212
+ startVisible: e.startVisible,
213
+ deltaPx: i,
214
+ pixelsPerTime: e.pixelsPerTime,
215
+ dataRange: s
216
+ });
217
+ else {
218
+ const h = e.gesture === "resize-left" ? "left" : "right";
219
+ n = M({
220
+ edge: h,
221
+ startVisible: e.startVisible,
222
+ deltaPx: i,
223
+ pixelsPerTime: e.pixelsPerTime,
224
+ dataRange: s,
225
+ minSpan: 2 * this.#e.getDataInterval()
226
+ });
227
+ }
228
+ this.#e.setVisibleRange(n);
229
+ }
230
+ #K(t) {
231
+ const e = this.#g;
232
+ e === null || t.pointerId !== e.pointerId || (this.#g = null, this.#t.hasPointerCapture(t.pointerId) && this.#t.releasePointerCapture(t.pointerId), this.#t.style.cursor = x(this.#w(t), this.#S()));
233
+ }
234
+ // --- render ------------------------------------------------------------
235
+ #_() {
236
+ if (this.#i <= 0 || this.#m <= 0) return;
237
+ const t = this.#e.getTheme().navigator, { xRange: e } = this.#P();
238
+ this.#X();
239
+ const i = this.#z, s = this.#t.width, n = this.#t.height;
240
+ i.save(), i.clearRect(0, 0, s, n), i.scale(this.#n, this.#n);
241
+ const h = {
242
+ ctx: i,
243
+ timeScale: this.#u,
244
+ yScale: this.#F,
245
+ mediaWidth: this.#i,
246
+ mediaHeight: this.#m,
247
+ theme: t
248
+ };
249
+ this.#t.style.boxShadow = `inset 0 1px 0 ${t.borderColor}, inset 0 -1px 0 ${t.borderColor}`, V(h);
250
+ let l = 1;
251
+ this.#h !== null && (this.#h.tick(performance.now()), l = this.#h.current, this.#h.animating ? this.#f() : this.#h = null);
252
+ const r = Math.max(1, Math.round(this.#i)), a = this.#x;
253
+ if (a.type === "candlestick")
254
+ L(h, this.#q(a.points, r, k), l);
255
+ else {
256
+ const c = f(a), g = c.length === 1, d = this.#C >= 0 ? this.#C : c.length - 1;
257
+ for (let u = 0; u < c.length; u++) {
258
+ const p = this.#q(c[u], r, C), m = u === d ? l : 1;
259
+ a.type === "bar" ? N(h, p, m) : P(h, p, g, m);
260
+ }
261
+ }
262
+ i.restore(), this.#G(t, e);
263
+ }
264
+ /**
265
+ * Light per-frame path — reposition the window / masks / handles against
266
+ * the eased viewport without touching the canvas. Escalates to a full
267
+ * render when the canvas size went stale (e.g. `yAxisWidth` changed without
268
+ * a resize event).
269
+ */
270
+ #Q() {
271
+ if (this.#i <= 0 || this.#m <= 0) return;
272
+ const t = Math.round(this.#i * this.#n);
273
+ if (this.#t.width !== t) {
274
+ this.#_();
275
+ return;
276
+ }
277
+ const e = this.#e.getTheme().navigator, { xRange: i } = this.#P();
278
+ this.#G(e, i);
279
+ }
280
+ /** Decimate `points` into `buckets`, reusing the cached result while the
281
+ * source array ref and bucket count are unchanged. */
282
+ #q(t, e, i) {
283
+ const s = this.#R.get(t);
284
+ if (s !== void 0 && s.buckets === e)
285
+ return s.result;
286
+ const n = i(t, e);
287
+ return this.#R.set(t, { buckets: e, result: n }), n;
288
+ }
289
+ #G(t, e) {
290
+ if (e.to <= e.from) return;
291
+ const i = this.#Y(), s = Math.max(e.from, Math.min(e.to, i.from)), n = Math.max(e.from, Math.min(e.to, i.to)), h = this.#u.timeToX(s), l = this.#u.timeToX(n), r = Math.min(h, l), a = Math.max(h, l), c = Math.max(1, a - r);
292
+ this.#d.style.width = `${r}px`, this.#d.style.background = t.mask.fill, this.#d.style.display = r > 0 ? "block" : "none";
293
+ const g = Math.max(0, this.#i - (r + c));
294
+ this.#r.style.left = `${r + c}px`, this.#r.style.width = `${g}px`, this.#r.style.background = t.mask.fill, this.#r.style.display = g > 0 ? "block" : "none", this.#l.style.left = `${r}px`, this.#l.style.width = `${c}px`, this.#l.style.background = t.window.fill, this.#l.style.border = t.window.borderWidth > 0 ? `${t.window.borderWidth}px solid ${t.window.border}` : "none";
295
+ const d = t.handle.width, u = Math.max(1, d / 2), p = this.#e.getTheme().background;
296
+ this.#a.style.left = `${r - d / 2}px`, this.#a.style.width = `${d}px`, this.#a.style.background = t.handle.color, this.#a.style.borderRadius = `${u}px`, this.#c.style.left = `${r + c - d / 2}px`, this.#c.style.width = `${d}px`, this.#c.style.background = t.handle.color, this.#c.style.borderRadius = `${u}px`;
297
+ for (const m of this.#a.children)
298
+ m.style.background = p;
299
+ for (const m of this.#c.children)
300
+ m.style.background = p;
301
+ }
302
+ #y() {
303
+ const t = this.#x;
304
+ let e = Number.POSITIVE_INFINITY, i = Number.NEGATIVE_INFINITY, s = 0;
305
+ if (t.type === "candlestick")
306
+ s = t.points.length, s > 0 && (e = t.points[0].time, i = t.points[s - 1].time);
307
+ else
308
+ for (const h of f(t))
309
+ h.length !== 0 && (s += h.length, h[0].time < e && (e = h[0].time), h[h.length - 1].time > i && (i = h[h.length - 1].time));
310
+ if (s >= 2 && i > e)
311
+ return { from: e, to: i };
312
+ if (s === 1)
313
+ return { ...this.#e.getVisibleRange() };
314
+ const n = this.#e.getDataRange();
315
+ return n && n.to > n.from ? n : { ...this.#e.getVisibleRange() };
316
+ }
317
+ #Z() {
318
+ const t = this.#x;
319
+ let e = 1 / 0, i = -1 / 0;
320
+ if (t.type === "candlestick")
321
+ for (const n of t.points)
322
+ n.low < e && (e = n.low), n.high > i && (i = n.high);
323
+ else
324
+ for (const n of f(t))
325
+ for (const h of n)
326
+ h.value < e && (e = h.value), h.value > i && (i = h.value);
327
+ if (!Number.isFinite(e) || !Number.isFinite(i)) return { min: 0, max: 1 };
328
+ if (e === i) {
329
+ const n = Math.abs(e) * 0.05 || 1;
330
+ return { min: e - n, max: i + n };
331
+ }
332
+ const s = (i - e) * 0.2;
333
+ return { min: e - s, max: i + s };
334
+ }
335
+ }
336
+ function f(o) {
337
+ return "series" in o ? o.series : [o.points];
338
+ }
339
+ function F(o) {
340
+ if (o.type === "candlestick") {
341
+ const s = o.points.length;
342
+ return s === 0 ? null : { time: o.points[s - 1].time, seriesIndex: -1 };
343
+ }
344
+ const t = "series" in o ? o.series : [o.points];
345
+ let e = null, i = -1;
346
+ for (let s = 0; s < t.length; s++) {
347
+ const n = t[s];
348
+ if (n.length === 0) continue;
349
+ const h = n[n.length - 1].time;
350
+ (e === null || h > e) && (e = h, i = s);
351
+ }
352
+ return e === null ? null : { time: e, seriesIndex: i };
353
+ }
354
+ function v(o, t) {
355
+ return o === "resize-left" || o === "resize-right" ? "ew-resize" : t ? "grabbing" : "grab";
356
+ }
357
+ function x(o, t) {
358
+ return v(A(o, t), !1);
359
+ }
360
+ function A(o, t) {
361
+ return y(o, t).gesture;
362
+ }
363
+ function b() {
364
+ const o = document.createElement("div");
365
+ o.style.cssText = "position:absolute;top:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;";
366
+ for (let t = 0; t < 3; t++) {
367
+ const e = document.createElement("div");
368
+ e.style.cssText = "width:2px;height:2px;border-radius:50%;flex-shrink:0;", o.appendChild(e);
369
+ }
370
+ return o;
371
+ }
372
+ export {
373
+ G as NavigatorController
374
+ };
@@ -0,0 +1,44 @@
1
+ function m(e, i) {
2
+ if (e.length <= i || i <= 0) return e;
3
+ const h = e[0].time, c = e[e.length - 1].time, r = c - h;
4
+ if (r <= 0) return e;
5
+ const f = r / i, u = [];
6
+ let o = 0;
7
+ for (let l = 0; l < i; l++) {
8
+ const g = l === i - 1 ? c + 1 : h + (l + 1) * f;
9
+ let t = null, n = null;
10
+ for (; o < e.length && e[o].time < g; ) {
11
+ const s = e[o];
12
+ (t === null || s.value < t.value) && (t = s), (n === null || s.value > n.value) && (n = s), o++;
13
+ }
14
+ if (!(t === null || n === null)) {
15
+ if (t === n) {
16
+ u.push(t);
17
+ continue;
18
+ }
19
+ t.time < n.time ? u.push(t, n) : u.push(n, t);
20
+ }
21
+ }
22
+ return u;
23
+ }
24
+ function a(e, i) {
25
+ if (e.length <= i || i <= 0) return e;
26
+ const h = e[0].time, c = e[e.length - 1].time, r = c - h;
27
+ if (r <= 0) return e;
28
+ const f = r / i, u = [];
29
+ let o = 0;
30
+ for (let l = 0; l < i; l++) {
31
+ const g = l === i - 1 ? c + 1 : h + (l + 1) * f;
32
+ let t = null;
33
+ for (; o < e.length && e[o].time < g; ) {
34
+ const n = e[o];
35
+ t === null ? t = { time: n.time, open: n.open, high: n.high, low: n.low, close: n.close } : (n.high > t.high && (t.high = n.high), n.low < t.low && (t.low = n.low), t.close = n.close), o++;
36
+ }
37
+ t !== null && u.push(t);
38
+ }
39
+ return u;
40
+ }
41
+ export {
42
+ a as decimateCandles,
43
+ m as decimateLinear
44
+ };
@@ -0,0 +1,28 @@
1
+ function p(a, o) {
2
+ return Math.abs(a - o.left) <= 8 ? { gesture: "resize-left", snapToCenter: !1 } : Math.abs(a - o.right) <= 8 ? { gesture: "resize-right", snapToCenter: !1 } : a > o.left && a < o.right ? { gesture: "pan", snapToCenter: !1 } : { gesture: "pan", snapToCenter: !0 };
3
+ }
4
+ function g(a) {
5
+ const { startVisible: o, deltaPx: f, pixelsPerTime: n, dataRange: r } = a, t = o.to - o.from, e = f / n;
6
+ let s = o.from + e, m = o.to + e;
7
+ return s < r.from && (s = r.from, m = s + t), m > r.to && (m = r.to, s = m - t), s < r.from && (s = r.from), { from: s, to: m };
8
+ }
9
+ function c(a) {
10
+ const { edge: o, startVisible: f, deltaPx: n, pixelsPerTime: r, dataRange: t, minSpan: e } = a, s = n / r;
11
+ if (o === "left") {
12
+ let l = f.from + s, u = f.to;
13
+ return l < t.from && (l = t.from), u - l < e && (l = u - e), l < t.from && (l = t.from, u = Math.min(t.to, l + e)), { from: l, to: u };
14
+ }
15
+ let m = f.from, i = f.to + s;
16
+ return i > t.to && (i = t.to), i - m < e && (i = m + e), i > t.to && (i = t.to, m = Math.max(t.from, i - e)), { from: m, to: i };
17
+ }
18
+ function h(a) {
19
+ const { time: o, startVisible: f, xRange: n } = a, r = f.to - f.from;
20
+ let t = o - r / 2, e = t + r;
21
+ return t < n.from && (t = n.from, e = t + r), e > n.to && (e = n.to, t = e - r), t < n.from && (t = n.from), { from: t, to: e };
22
+ }
23
+ export {
24
+ g as computePan,
25
+ c as computeResize,
26
+ h as computeSnapCenter,
27
+ p as hitTest
28
+ };
@@ -0,0 +1,68 @@
1
+ import { resolveCandlestickBodyColor as x } from "../theme/resolve.js";
2
+ function k(d) {
3
+ const { ctx: o, theme: r, mediaWidth: t, mediaHeight: e } = d;
4
+ o.fillStyle = r.background, o.fillRect(0, 0, t, e);
5
+ }
6
+ function p(d, o, r = !0, t = 1) {
7
+ if (o.length < 2) return;
8
+ const { ctx: e, timeScale: a, yScale: h, mediaHeight: s, theme: n } = d, g = t < 1 && o.length >= 2, T = g ? o.length - 2 : o.length - 1;
9
+ if (r) {
10
+ const l = e.createLinearGradient(0, 0, 0, s);
11
+ l.addColorStop(0, n.line.areaTopColor), l.addColorStop(1, n.line.areaBottomColor), e.beginPath();
12
+ for (let i = 0; i <= T; i++) {
13
+ const c = o[i], m = a.timeToX(c.time), u = h.valueToY(c.value);
14
+ i === 0 ? e.moveTo(m, u) : e.lineTo(m, u);
15
+ }
16
+ if (e.lineTo(a.timeToX(o[T].time), s), e.lineTo(a.timeToX(o[0].time), s), e.closePath(), e.fillStyle = l, e.fill(), g) {
17
+ e.save(), e.globalAlpha = t, e.beginPath();
18
+ const i = o[T], c = o[o.length - 1], m = a.timeToX(i.time), u = a.timeToX(c.time);
19
+ e.moveTo(m, h.valueToY(i.value)), e.lineTo(u, h.valueToY(c.value)), e.lineTo(u, s), e.lineTo(m, s), e.closePath(), e.fillStyle = l, e.fill(), e.restore();
20
+ }
21
+ }
22
+ e.beginPath();
23
+ for (let l = 0; l <= T; l++) {
24
+ const i = o[l], c = a.timeToX(i.time), m = h.valueToY(i.value);
25
+ l === 0 ? e.moveTo(c, m) : e.lineTo(c, m);
26
+ }
27
+ if (e.strokeStyle = n.line.color, e.lineWidth = n.line.width, e.stroke(), g) {
28
+ e.save(), e.globalAlpha = t, e.beginPath();
29
+ const l = o[T], i = o[o.length - 1];
30
+ e.moveTo(a.timeToX(l.time), h.valueToY(l.value)), e.lineTo(a.timeToX(i.time), h.valueToY(i.value)), e.strokeStyle = n.line.color, e.lineWidth = n.line.width, e.stroke(), e.restore();
31
+ }
32
+ }
33
+ function Y(d, o, r = 1) {
34
+ if (o.length === 0) return;
35
+ const { ctx: t, timeScale: e, yScale: a, mediaHeight: h, theme: s } = d, n = Math.max(
36
+ 1,
37
+ o.length > 1 ? Math.abs(e.timeToX(o[1].time) - e.timeToX(o[0].time)) * 0.8 : 2
38
+ ), g = r < 1, T = o.length - 1;
39
+ t.fillStyle = s.line.color;
40
+ for (let l = 0; l < o.length; l++) {
41
+ const i = o[l], c = e.timeToX(i.time), m = a.valueToY(i.value), u = Math.max(1, h - m);
42
+ g && l === T ? (t.save(), t.globalAlpha = r, t.fillRect(c - n / 2, m, n, u), t.restore()) : t.fillRect(c - n / 2, m, n, u);
43
+ }
44
+ }
45
+ function w(d, o, r = 1) {
46
+ if (o.length === 0) return;
47
+ const { ctx: t, timeScale: e, yScale: a, theme: h } = d, s = Math.max(
48
+ 1,
49
+ o.length > 1 ? Math.abs(e.timeToX(o[1].time) - e.timeToX(o[0].time)) * 0.75 : 2
50
+ ), n = r < 1, g = o.length - 1;
51
+ for (let T = 0; T < o.length; T++) {
52
+ const l = o[T], i = l.close >= l.open ? h.candlestick.up : h.candlestick.down, c = x(i.body), m = e.timeToX(l.time), u = a.valueToY(l.open), f = a.valueToY(l.close), M = a.valueToY(l.high), S = a.valueToY(l.low), v = n && T === g;
53
+ v && (t.save(), t.globalAlpha = r), t.strokeStyle = i.wick, t.lineWidth = 1, t.beginPath(), t.moveTo(m, M), t.lineTo(m, S), t.stroke();
54
+ const X = Math.min(u, f), b = Math.max(1, Math.abs(f - u));
55
+ t.fillStyle = c, t.fillRect(m - s / 2, X, s, b), v && t.restore();
56
+ }
57
+ }
58
+ function C(d, o, r) {
59
+ const t = Math.max(r.from, Math.min(r.to, o.from)), e = Math.max(r.from, Math.min(r.to, o.to)), a = d.timeToX(t), h = d.timeToX(e), s = Math.min(a, h), n = Math.max(a, h);
60
+ return { left: s, right: n, width: Math.max(1, n - s) };
61
+ }
62
+ export {
63
+ C as computeWindowGeometry,
64
+ k as renderBackground,
65
+ Y as renderMiniBar,
66
+ w as renderMiniCandlestick,
67
+ p as renderMiniLine
68
+ };
@@ -0,0 +1,19 @@
1
+ function p(c, r) {
2
+ const o = /* @__PURE__ */ new Map();
3
+ return new Proxy(c, {
4
+ get(n, t) {
5
+ const e = Reflect.get(n, t, n);
6
+ if (typeof e != "function") return e;
7
+ const s = o.get(t);
8
+ if (s) return s;
9
+ const f = typeof t == "string" ? t : String(t), g = e, u = (...i) => (r.set(f, (r.get(f) ?? 0) + 1), g.apply(n, i));
10
+ return o.set(t, u), u;
11
+ },
12
+ set(n, t, e) {
13
+ return Reflect.set(n, t, e, n);
14
+ }
15
+ });
16
+ }
17
+ export {
18
+ p as createCountingContext
19
+ };