@wick-charts/vue 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/dist/animation/config.js +66 -64
- package/dist/core/dist/animation/intro-wave.js +19 -21
- package/dist/core/dist/animation/reduced-motion.js +6 -0
- package/dist/core/dist/axis/dom-labels.js +14 -14
- package/dist/core/dist/chart/badge-animator.js +15 -19
- package/dist/core/dist/chart.js +448 -417
- package/dist/core/dist/components/grid.js +21 -17
- package/dist/core/dist/navigator/controller.js +12 -12
- package/dist/core/dist/scales/tick-tracker.js +2 -2
- package/dist/core/dist/scales/x-scale.js +47 -32
- package/dist/core/dist/scales/y-scale.js +39 -21
- package/dist/core/dist/series/bar.js +24 -24
- package/dist/core/dist/series/candlestick.js +20 -20
- package/dist/core/dist/series/heatmap.js +16 -16
- package/dist/core/dist/series/line.js +461 -401
- package/dist/core/dist/utils/pixel-grid.js +10 -0
- package/dist/index.d.ts +33 -1
- package/dist/ui/YLabel.vue.js +19 -18
- package/package.json +2 -2
|
@@ -1,74 +1,83 @@
|
|
|
1
|
-
import { DEFAULT_HISTORY_REVEAL as
|
|
2
|
-
import { easeOutCubic as
|
|
3
|
-
import { decimateLineData as
|
|
4
|
-
import { hexToRgba as
|
|
1
|
+
import { DEFAULT_HISTORY_REVEAL as et, DEFAULT_LINE_INTRO as it, DEFAULT_LINE_PULSE as ot, DEFAULT_LINE_SMOOTH as st, DEFAULT_LINE_ENTRY as nt } from "../animation/config.js";
|
|
2
|
+
import { easeOutCubic as U } from "../animation/easing.js";
|
|
3
|
+
import { decimateLineData as K } from "../data/decimation.js";
|
|
4
|
+
import { hexToRgba as W } from "../utils/color.js";
|
|
5
5
|
import { lerp as Y } from "../utils/math.js";
|
|
6
|
-
import { BaseMultiLayerSeries as
|
|
7
|
-
import { unfoldIntro as lt, backfillSweepIntro as
|
|
8
|
-
import { buildCurveSegments as
|
|
9
|
-
import { resolveLinePainter as
|
|
10
|
-
const
|
|
6
|
+
import { BaseMultiLayerSeries as at } from "./base-multi-layer.js";
|
|
7
|
+
import { unfoldIntro as lt, backfillSweepIntro as ht } from "./line-intro.js";
|
|
8
|
+
import { buildCurveSegments as Q } from "./painters/canvas-path.js";
|
|
9
|
+
import { resolveLinePainter as ct } from "./painters/resolve.js";
|
|
10
|
+
const ut = {
|
|
11
11
|
colors: ["#2962FF"],
|
|
12
12
|
strokeWidth: 1,
|
|
13
13
|
area: { visible: !0 },
|
|
14
14
|
pulse: !0,
|
|
15
15
|
stacking: "off",
|
|
16
16
|
curve: "straight",
|
|
17
|
-
entryMs:
|
|
18
|
-
smoothMs:
|
|
19
|
-
pulseMs:
|
|
20
|
-
introMs:
|
|
21
|
-
historyRevealMs:
|
|
17
|
+
entryMs: nt,
|
|
18
|
+
smoothMs: st,
|
|
19
|
+
pulseMs: ot,
|
|
20
|
+
introMs: it,
|
|
21
|
+
historyRevealMs: et
|
|
22
22
|
};
|
|
23
|
-
function
|
|
24
|
-
const t =
|
|
23
|
+
function Z(g) {
|
|
24
|
+
const t = g.areaFill, e = t !== void 0 && g.area === void 0 ? { visible: !!t } : g.area;
|
|
25
25
|
return {
|
|
26
|
-
...
|
|
26
|
+
...g,
|
|
27
27
|
area: e,
|
|
28
|
-
entryMs:
|
|
29
|
-
smoothMs:
|
|
30
|
-
pulseMs:
|
|
31
|
-
introMs:
|
|
32
|
-
historyRevealMs:
|
|
28
|
+
entryMs: g.entryMs === !1 ? 0 : g.entryMs ?? nt,
|
|
29
|
+
smoothMs: g.smoothMs === !1 ? 0 : g.smoothMs ?? st,
|
|
30
|
+
pulseMs: g.pulseMs === !1 ? 0 : g.pulseMs ?? ot,
|
|
31
|
+
introMs: g.introMs === !1 ? 0 : g.introMs ?? it,
|
|
32
|
+
historyRevealMs: g.historyRevealMs === !1 ? 0 : g.historyRevealMs ?? et
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
function
|
|
36
|
-
return
|
|
35
|
+
function $(g) {
|
|
36
|
+
return g.map(([t, e]) => ({ x: t, y: e }));
|
|
37
37
|
}
|
|
38
|
-
const
|
|
39
|
-
function
|
|
40
|
-
if (
|
|
41
|
-
if (t <=
|
|
42
|
-
const i =
|
|
38
|
+
const J = 0.15, mt = ht();
|
|
39
|
+
function j(g, t, e) {
|
|
40
|
+
if (g.length === 0) return null;
|
|
41
|
+
if (t <= g[0].time) return Number.isFinite(g[0].value) ? e(g[0]) : null;
|
|
42
|
+
const i = g[g.length - 1];
|
|
43
43
|
if (t >= i.time) return Number.isFinite(i.value) ? e(i) : null;
|
|
44
|
-
let
|
|
45
|
-
for (;
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
const n =
|
|
50
|
-
if (!Number.isFinite(n.value) || !Number.isFinite(
|
|
51
|
-
const
|
|
52
|
-
return
|
|
44
|
+
let o = 0, s = g.length - 1;
|
|
45
|
+
for (; s - o > 1; ) {
|
|
46
|
+
const l = o + s >> 1;
|
|
47
|
+
g[l].time <= t ? o = l : s = l;
|
|
48
|
+
}
|
|
49
|
+
const n = g[o], a = g[s];
|
|
50
|
+
if (!Number.isFinite(n.value) || !Number.isFinite(a.value)) return null;
|
|
51
|
+
const u = a.time - n.time;
|
|
52
|
+
return u <= 0 ? e(n) : Y(e(n), e(a), (t - n.time) / u);
|
|
53
53
|
}
|
|
54
|
-
function
|
|
54
|
+
function pt(g, t) {
|
|
55
|
+
let e = 0, i = g.length - 1;
|
|
56
|
+
for (; e <= i; ) {
|
|
57
|
+
const o = e + i >> 1;
|
|
58
|
+
if (g[o] === t) return o;
|
|
59
|
+
g[o] < t ? e = o + 1 : i = o - 1;
|
|
60
|
+
}
|
|
61
|
+
return -1;
|
|
62
|
+
}
|
|
63
|
+
function tt(g, t) {
|
|
55
64
|
for (const e of t)
|
|
56
|
-
e.kind === "line" ?
|
|
65
|
+
e.kind === "line" ? g.lineTo(e.x, e.y) : g.bezierCurveTo(e.cp1x, e.cp1y, e.cp2x, e.cp2y, e.x, e.y);
|
|
57
66
|
}
|
|
58
|
-
function ft(
|
|
67
|
+
function ft(g, t, e) {
|
|
59
68
|
for (let i = e.length - 1; i >= 0; i--) {
|
|
60
|
-
const
|
|
61
|
-
|
|
69
|
+
const o = e[i], s = i > 0 ? e[i - 1] : t[0];
|
|
70
|
+
o.kind === "line" ? g.lineTo(s.x, s.y) : g.bezierCurveTo(o.cp2x, o.cp2y, o.cp1x, o.cp1y, s.x, s.y);
|
|
62
71
|
}
|
|
63
72
|
}
|
|
64
|
-
class
|
|
73
|
+
class dt extends at {
|
|
65
74
|
kind = "line";
|
|
66
75
|
areaGradientCache = /* @__PURE__ */ new Map();
|
|
67
76
|
constructor(t, e) {
|
|
68
|
-
super(t), this.options =
|
|
77
|
+
super(t), this.options = Z({ ...ut, ...e });
|
|
69
78
|
}
|
|
70
79
|
updateOptions(t) {
|
|
71
|
-
this.options =
|
|
80
|
+
this.options = Z({ ...this.options, ...t });
|
|
72
81
|
}
|
|
73
82
|
getStacking() {
|
|
74
83
|
return this.options.stacking;
|
|
@@ -89,8 +98,8 @@ class mt extends rt {
|
|
|
89
98
|
hasOverlayContentInRange(t, e) {
|
|
90
99
|
for (let i = 0; i < this.stores.length; i++) {
|
|
91
100
|
if (this.getLayerAlpha(i) <= 0) continue;
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
101
|
+
const o = this.stores[i].last();
|
|
102
|
+
if (o && o.time >= t) return !0;
|
|
94
103
|
}
|
|
95
104
|
return !1;
|
|
96
105
|
}
|
|
@@ -100,13 +109,13 @@ class mt extends rt {
|
|
|
100
109
|
this.historyDirectives = null;
|
|
101
110
|
const i = this.historyRange;
|
|
102
111
|
if (this.historyWave.active && i !== null) {
|
|
103
|
-
const
|
|
104
|
-
|
|
112
|
+
const a = this.options.historyReveal ?? mt;
|
|
113
|
+
a !== "none" && (this.historyDirectives = a(this.buildHistoryFrame(t, i)));
|
|
105
114
|
}
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const n = this.applyHistoryClip(t,
|
|
109
|
-
this.introWave.active ? this.renderWithIntro(t) : (this.introDirectives = null, this.renderBody(t)), n && e.restore(),
|
|
115
|
+
const o = this.historyDirectives, s = o?.ghostAlpha ?? 0;
|
|
116
|
+
s > 0 && (e.save(), e.globalAlpha *= s, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, e.restore());
|
|
117
|
+
const n = this.applyHistoryClip(t, o, i);
|
|
118
|
+
this.introWave.active ? this.renderWithIntro(t) : (this.introDirectives = null, this.renderBody(t)), n && e.restore(), o?.heads !== void 0 && o.heads.length > 0 && this.drawIntroHeads(t, o.heads, this.historyWave.linear());
|
|
110
119
|
}
|
|
111
120
|
/**
|
|
112
121
|
* Initial-load intro pass: the resolved LineIntroFn describes this frame
|
|
@@ -116,14 +125,14 @@ class mt extends rt {
|
|
|
116
125
|
renderWithIntro(t) {
|
|
117
126
|
const e = this.resolveIntro()(this.buildIntroFrame(t));
|
|
118
127
|
this.introDirectives = e;
|
|
119
|
-
const { context: i } = t.scope, { width:
|
|
128
|
+
const { context: i } = t.scope, { width: o, height: s } = t.scope.bitmapSize, n = e.ghostAlpha ?? 0;
|
|
120
129
|
n > 0 && (i.save(), i.globalAlpha *= n, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, i.restore());
|
|
121
|
-
const
|
|
122
|
-
if (
|
|
123
|
-
const
|
|
124
|
-
i.save(), i.beginPath(), i.rect(
|
|
130
|
+
const a = e.clip, u = a !== void 0 && (a.fromX !== void 0 || a.toX !== void 0);
|
|
131
|
+
if (u) {
|
|
132
|
+
const l = a.fromX ?? 0, p = a.toX ?? o;
|
|
133
|
+
i.save(), i.beginPath(), i.rect(l, 0, Math.max(0, p - l), s), i.clip();
|
|
125
134
|
}
|
|
126
|
-
this.renderBody(t),
|
|
135
|
+
this.renderBody(t), u && i.restore(), e.heads !== void 0 && e.heads.length > 0 && this.drawIntroHeads(t, e.heads, this.introWave.linear());
|
|
127
136
|
}
|
|
128
137
|
/**
|
|
129
138
|
* Apply the history reveal's clip directive, mapped from reveal space
|
|
@@ -132,14 +141,22 @@ class mt extends rt {
|
|
|
132
141
|
* small pad keeps the stroke cap at the reveal front from being shaved.
|
|
133
142
|
*/
|
|
134
143
|
applyHistoryClip(t, e, i) {
|
|
135
|
-
const
|
|
136
|
-
if (
|
|
137
|
-
const { context:
|
|
138
|
-
return
|
|
144
|
+
const o = e?.clip;
|
|
145
|
+
if (o === void 0 || i === null || o.fromX === void 0 && o.toX === void 0) return !1;
|
|
146
|
+
const { context: s } = t.scope, { width: n, height: a } = t.scope.bitmapSize, u = t.timeScale.timeToBitmapXExact(i.to), l = Math.abs(u - t.timeScale.timeToBitmapXExact(i.from)), p = Math.max(2, (this.options.strokeWidth ?? 1) * t.scope.horizontalPixelRatio), h = o.fromX ?? 0, d = o.toX ?? l;
|
|
147
|
+
return s.save(), s.beginPath(), s.rect(u - d - p, 0, Math.max(0, d - h + p), a), s.rect(u, 0, Math.max(0, n - u), a), s.clip(), !0;
|
|
139
148
|
}
|
|
140
149
|
renderBody(t) {
|
|
141
|
-
this.options.stacking === "off" ? this.renderOff(t) : this.renderStacked(t, this.options.stacking === "percent");
|
|
150
|
+
this.options.stacking === "off" ? (this.stackedEdges = null, this.renderOff(t)) : this.renderStacked(t, this.options.stacking === "percent");
|
|
142
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* What the stacked pass drew this frame, in data space — shared columns,
|
|
154
|
+
* their eased cumulative per layer, and the per-column grow chain. Lets the
|
|
155
|
+
* overlay's dots reproduce the painted geometry against its own scales
|
|
156
|
+
* instead of re-deriving the entrance from a different chain.
|
|
157
|
+
* `null` when the stacked path didn't run.
|
|
158
|
+
*/
|
|
159
|
+
stackedEdges = null;
|
|
143
160
|
/** True while a ghost pre-pass is drawing — skips the area fill so the
|
|
144
161
|
* translucent pass shows only the stroke skeleton. */
|
|
145
162
|
introGhostPass = !1;
|
|
@@ -181,54 +198,56 @@ class mt extends rt {
|
|
|
181
198
|
return this.buildFrame(t, {
|
|
182
199
|
progress: this.historyWave.linear(),
|
|
183
200
|
range: e,
|
|
184
|
-
width: Math.abs(
|
|
201
|
+
width: Math.abs(
|
|
202
|
+
t.timeScale.timeToBitmapXExact(e.to) - t.timeScale.timeToBitmapXExact(e.from)
|
|
203
|
+
)
|
|
185
204
|
});
|
|
186
205
|
}
|
|
187
206
|
buildFrame(t, e) {
|
|
188
|
-
const { timeScale: i, yScale:
|
|
189
|
-
let
|
|
190
|
-
const
|
|
191
|
-
let
|
|
192
|
-
return
|
|
207
|
+
const { timeScale: i, yScale: o, scope: s } = t, { progress: n, range: a, width: u } = e, l = new Array(this.stores.length), p = new Array(this.stores.length);
|
|
208
|
+
let h;
|
|
209
|
+
const d = (r) => {
|
|
210
|
+
let f = l[r];
|
|
211
|
+
return f === void 0 && (f = this.stores[r]?.getVisibleData(a.from, a.to) ?? [], l[r] = f), f;
|
|
193
212
|
};
|
|
194
213
|
return {
|
|
195
214
|
progress: n,
|
|
196
|
-
range:
|
|
197
|
-
width:
|
|
198
|
-
height:
|
|
215
|
+
range: a,
|
|
216
|
+
width: u,
|
|
217
|
+
height: o.getMediaHeight() * s.verticalPixelRatio,
|
|
199
218
|
stacking: this.options.stacking,
|
|
200
|
-
timeToX: (
|
|
201
|
-
xToTime: (
|
|
202
|
-
valueToY: (
|
|
219
|
+
timeToX: (r) => i.timeToBitmapXExact(r),
|
|
220
|
+
xToTime: (r) => i.xToTime(r / s.horizontalPixelRatio),
|
|
221
|
+
valueToY: (r) => o.valueToBitmapYExact(r),
|
|
203
222
|
layerCount: this.stores.length,
|
|
204
|
-
layerData:
|
|
205
|
-
layerMean: (
|
|
206
|
-
let
|
|
207
|
-
if (
|
|
208
|
-
let
|
|
209
|
-
for (const R of
|
|
210
|
-
Number.isFinite(R.value) && (
|
|
211
|
-
|
|
223
|
+
layerData: d,
|
|
224
|
+
layerMean: (r) => {
|
|
225
|
+
let f = p[r];
|
|
226
|
+
if (f === void 0) {
|
|
227
|
+
let c = 0, y = 0;
|
|
228
|
+
for (const R of d(r))
|
|
229
|
+
Number.isFinite(R.value) && (c += R.value, y++);
|
|
230
|
+
f = y > 0 ? c / y : null, p[r] = f;
|
|
212
231
|
}
|
|
213
|
-
return
|
|
232
|
+
return f;
|
|
214
233
|
},
|
|
215
234
|
primaryPath: () => {
|
|
216
|
-
if (
|
|
217
|
-
|
|
218
|
-
for (let
|
|
219
|
-
if (this.getLayerAlpha(
|
|
220
|
-
const
|
|
221
|
-
if (!(
|
|
222
|
-
|
|
223
|
-
x: i.
|
|
224
|
-
y:
|
|
225
|
-
time:
|
|
235
|
+
if (h === void 0) {
|
|
236
|
+
h = null;
|
|
237
|
+
for (let r = 0; r < this.stores.length; r++) {
|
|
238
|
+
if (this.getLayerAlpha(r) <= 0 || !this.stores[r].isVisible()) continue;
|
|
239
|
+
const f = d(r).filter((c) => Number.isFinite(c.value));
|
|
240
|
+
if (!(f.length < 2)) {
|
|
241
|
+
h = f.map((c) => ({
|
|
242
|
+
x: i.timeToBitmapXExact(c.time),
|
|
243
|
+
y: o.valueToBitmapYExact(c.value),
|
|
244
|
+
time: c.time
|
|
226
245
|
}));
|
|
227
246
|
break;
|
|
228
247
|
}
|
|
229
248
|
}
|
|
230
249
|
}
|
|
231
|
-
return
|
|
250
|
+
return h;
|
|
232
251
|
}
|
|
233
252
|
};
|
|
234
253
|
}
|
|
@@ -238,16 +257,16 @@ class mt extends rt {
|
|
|
238
257
|
* overlay pulse) already flows through `effectiveValue`, so one override
|
|
239
258
|
* animates the whole geometry.
|
|
240
259
|
*/
|
|
241
|
-
effectiveValue(t, e, i,
|
|
242
|
-
const
|
|
243
|
-
if (n !== void 0 &&
|
|
244
|
-
const
|
|
245
|
-
return n({ layerIndex: e, time: i, value:
|
|
260
|
+
effectiveValue(t, e, i, o) {
|
|
261
|
+
const s = super.effectiveValue(t, e, i, o), n = this.historyWave.active ? this.historyDirectives?.value : void 0, a = this.historyRange;
|
|
262
|
+
if (n !== void 0 && a !== null && i < a.to) {
|
|
263
|
+
const d = a.to - a.from, r = d > 0 ? Math.min(1, Math.max(0, (a.to - i) / d)) : 0;
|
|
264
|
+
return n({ layerIndex: e, time: i, value: s, position: r });
|
|
246
265
|
}
|
|
247
|
-
const
|
|
248
|
-
if (
|
|
249
|
-
const
|
|
250
|
-
return
|
|
266
|
+
const u = this.introWave.active ? this.introDirectives?.value : void 0;
|
|
267
|
+
if (u === void 0) return s;
|
|
268
|
+
const l = t.timeScale.getRange(), p = l.to - l.from, h = p > 0 ? Math.min(1, Math.max(0, (i - l.from) / p)) : 0;
|
|
269
|
+
return u({ layerIndex: e, time: i, value: s, position: h });
|
|
251
270
|
}
|
|
252
271
|
/**
|
|
253
272
|
* Extends the base last-value query with the 'grow' entrance's value-space
|
|
@@ -259,26 +278,30 @@ class mt extends rt {
|
|
|
259
278
|
* before the marker visually arrives there.
|
|
260
279
|
*/
|
|
261
280
|
snapshotValue(t, e, i) {
|
|
262
|
-
const
|
|
263
|
-
return (this.options.entryAnimation ?? "grow") !== "grow" ?
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
281
|
+
const o = super.snapshotValue(t, e, i);
|
|
282
|
+
return (this.options.entryAnimation ?? "grow") !== "grow" ? o : this.chainedTailValues(t)?.get(e) ?? o;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Value-space counterpart of {@link chainedTailPositions} — see {@link snapshotValue}.
|
|
286
|
+
* `resolve` lets the stacked renderer feed its ctx-aware `effectiveValue`
|
|
287
|
+
* in; query paths, which have no render context, keep the `liveValue` default.
|
|
288
|
+
*/
|
|
289
|
+
chainedTailValues(t, e = (i, o) => this.liveValue(t, i, o)) {
|
|
290
|
+
const i = this.unsettledTail(t);
|
|
291
|
+
if (i.length === 0) return null;
|
|
292
|
+
const o = this.stores[t].getAll(), s = o.length - 1 - i.length;
|
|
270
293
|
if (s < 0) return null;
|
|
271
|
-
const
|
|
272
|
-
if (!Number.isFinite(
|
|
273
|
-
let
|
|
274
|
-
const
|
|
275
|
-
for (let l = 0; l <
|
|
276
|
-
const
|
|
277
|
-
if (!Number.isFinite(
|
|
278
|
-
const
|
|
279
|
-
|
|
294
|
+
const n = o[s];
|
|
295
|
+
if (!Number.isFinite(n.value)) return null;
|
|
296
|
+
let a = e(n.time, n.value);
|
|
297
|
+
const u = /* @__PURE__ */ new Map();
|
|
298
|
+
for (let l = 0; l < i.length; l++) {
|
|
299
|
+
const p = o[s + 1 + l];
|
|
300
|
+
if (!Number.isFinite(p.value)) return null;
|
|
301
|
+
const h = U(i[l].progress), d = e(p.time, p.value), r = Y(a, d, h);
|
|
302
|
+
u.set(p.time, r), a = r;
|
|
280
303
|
}
|
|
281
|
-
return
|
|
304
|
+
return u;
|
|
282
305
|
}
|
|
283
306
|
/**
|
|
284
307
|
* Glowing pulse dots riding the intro's head anchors — the line reads as
|
|
@@ -288,20 +311,20 @@ class mt extends rt {
|
|
|
288
311
|
*/
|
|
289
312
|
drawIntroHeads(t, e, i) {
|
|
290
313
|
if (this.options.stacking !== "off") return;
|
|
291
|
-
const
|
|
314
|
+
const o = Math.min(1, i / J), s = Math.min(1, (1 - i) / J), n = Math.max(0, Math.min(o, s));
|
|
292
315
|
if (n <= 0) return;
|
|
293
|
-
const { scope:
|
|
294
|
-
for (const
|
|
295
|
-
for (let
|
|
296
|
-
const p = this.getLayerAlpha(
|
|
297
|
-
if (p <= 0 || !this.stores[
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
ctx:
|
|
301
|
-
x:
|
|
302
|
-
y:
|
|
303
|
-
color: this.resolveLayerColor(
|
|
304
|
-
pixelRatio:
|
|
316
|
+
const { scope: a } = t;
|
|
317
|
+
for (const u of e)
|
|
318
|
+
for (let l = 0; l < this.stores.length; l++) {
|
|
319
|
+
const p = this.getLayerAlpha(l);
|
|
320
|
+
if (p <= 0 || !this.stores[l].isVisible()) continue;
|
|
321
|
+
const h = this.introHeadAnchor(t, l, u);
|
|
322
|
+
h !== null && this.drawPulse({
|
|
323
|
+
ctx: a.context,
|
|
324
|
+
x: h.x,
|
|
325
|
+
y: h.y,
|
|
326
|
+
color: this.resolveLayerColor(l, h.value),
|
|
327
|
+
pixelRatio: a.horizontalPixelRatio,
|
|
305
328
|
phase: i * 2,
|
|
306
329
|
alpha: n * p
|
|
307
330
|
});
|
|
@@ -319,22 +342,26 @@ class mt extends rt {
|
|
|
319
342
|
* visible range, not the data span) and jumps back on settle.
|
|
320
343
|
*/
|
|
321
344
|
introHeadAnchor(t, e, i) {
|
|
322
|
-
const { timeScale:
|
|
323
|
-
if (
|
|
324
|
-
const
|
|
325
|
-
if (
|
|
326
|
-
if (!Number.isFinite(
|
|
327
|
-
const
|
|
328
|
-
return
|
|
345
|
+
const { timeScale: o, yScale: s } = t, n = o.getRange(), a = this.stores[e].getVisibleData(n.from, n.to);
|
|
346
|
+
if (a.length === 0) return null;
|
|
347
|
+
const u = this.stores[e].last();
|
|
348
|
+
if (u !== void 0 && i.time >= u.time) {
|
|
349
|
+
if (!Number.isFinite(u.value)) return null;
|
|
350
|
+
const h = this.trailingEndpoint(t, e);
|
|
351
|
+
return h === null ? null : { x: h.x, y: h.y, value: u.value };
|
|
329
352
|
}
|
|
330
|
-
const
|
|
331
|
-
if (i.time <=
|
|
332
|
-
if (!Number.isFinite(
|
|
333
|
-
const
|
|
334
|
-
return {
|
|
353
|
+
const l = a[0];
|
|
354
|
+
if (i.time <= l.time) {
|
|
355
|
+
if (!Number.isFinite(l.value)) return null;
|
|
356
|
+
const h = this.effectiveValue(t, e, l.time, l.value);
|
|
357
|
+
return {
|
|
358
|
+
x: o.timeToBitmapXExact(l.time),
|
|
359
|
+
y: s.valueToBitmapYExact(h),
|
|
360
|
+
value: l.value
|
|
361
|
+
};
|
|
335
362
|
}
|
|
336
|
-
const p =
|
|
337
|
-
return p === null ? null : { x: i.x, y:
|
|
363
|
+
const p = j(a, i.time, (h) => this.effectiveValue(t, e, h.time, h.value));
|
|
364
|
+
return p === null ? null : { x: i.x, y: s.valueToBitmapYExact(p), value: p };
|
|
338
365
|
}
|
|
339
366
|
/**
|
|
340
367
|
* Rendered positions of the layer's still-unsettled trailing points, keyed
|
|
@@ -359,61 +386,85 @@ class mt extends rt {
|
|
|
359
386
|
* it (see `renderStacked`'s `valueMaps` comment for the full rationale).
|
|
360
387
|
*/
|
|
361
388
|
stackedValueAt(t, e, i) {
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
389
|
+
const o = this.options.stacking === "percent", s = (this.options.entryAnimation ?? "grow") === "grow", n = new Array(this.stores.length), a = (h) => {
|
|
390
|
+
if (!s) return null;
|
|
391
|
+
const d = n[h];
|
|
392
|
+
if (d !== void 0) return d;
|
|
393
|
+
const r = this.chainedTailValues(h, (f, c) => this.effectiveValue(t, h, f, c));
|
|
394
|
+
return n[h] = r, r;
|
|
395
|
+
}, u = (h) => {
|
|
396
|
+
const d = this.getLayerAlpha(h);
|
|
397
|
+
if (d <= 0) return 0;
|
|
398
|
+
const r = this.stores[h].getAll();
|
|
399
|
+
if (r.length === 0 || i < r[0].time) return 0;
|
|
400
|
+
const f = a(h), c = j(
|
|
401
|
+
r,
|
|
402
|
+
i,
|
|
403
|
+
(y) => f?.get(y.time) ?? this.effectiveValue(t, h, y.time, y.value)
|
|
404
|
+
);
|
|
405
|
+
return c === null ? 0 : c * d;
|
|
369
406
|
};
|
|
370
|
-
let
|
|
371
|
-
if (
|
|
372
|
-
for (let
|
|
373
|
-
let
|
|
374
|
-
for (let
|
|
375
|
-
const
|
|
376
|
-
|
|
407
|
+
let l = 0;
|
|
408
|
+
if (o)
|
|
409
|
+
for (let h = 0; h < this.stores.length; h++) l += u(h);
|
|
410
|
+
let p = 0;
|
|
411
|
+
for (let h = 0; h <= e; h++) {
|
|
412
|
+
const d = u(h);
|
|
413
|
+
p += o && l > 0 ? d / l * 100 : d;
|
|
377
414
|
}
|
|
378
|
-
return
|
|
415
|
+
return p;
|
|
379
416
|
}
|
|
380
417
|
/**
|
|
381
|
-
* Bitmap position for layer `li`'s stacked boundary at time `t
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
418
|
+
* Bitmap position for layer `li`'s stacked boundary at time `t`.
|
|
419
|
+
*
|
|
420
|
+
* Reads back the vertex {@link renderStacked} actually painted this frame
|
|
421
|
+
* whenever `t` is one of its columns. The stacked entrance is driven by a
|
|
422
|
+
* *shared* per-column chain (columns are common to every layer), which this
|
|
423
|
+
* layer's own entrance state cannot reconstruct — deriving it here is what
|
|
424
|
+
* left the pulse dots hanging a column ahead of the stroke on a ragged
|
|
425
|
+
* feed. Falls back to the raw settled position off-column (decimated
|
|
426
|
+
* history, or before the first stacked frame).
|
|
387
427
|
*/
|
|
388
428
|
stackedPositionAt(t, e, i) {
|
|
389
|
-
const
|
|
390
|
-
if (
|
|
391
|
-
const a = this.unsettledTail(e), p = this.stores[e].getAll(),
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
let
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
429
|
+
const o = this.paintedStackVertex(t, e, i);
|
|
430
|
+
if (o !== null) return o;
|
|
431
|
+
const { timeScale: s, yScale: n } = t, a = n.valueToBitmapYExact(this.stackedValueAt(t, e, i)), u = s.timeToBitmapXExact(i), l = this.unsettledTail(e), p = this.stores[e].getAll(), h = p.length - 1 - l.length;
|
|
432
|
+
if ((this.options.entryAnimation ?? "grow") !== "grow" || i !== p[p.length - 1]?.time || l.length === 0 || h < 0) return { x: u, y: a };
|
|
433
|
+
let d = s.timeToBitmapXExact(p[h].time);
|
|
434
|
+
for (let r = 0; r < l.length; r++)
|
|
435
|
+
d = Y(d, s.timeToBitmapXExact(p[h + 1 + r].time), U(l[r].progress));
|
|
436
|
+
return { x: d, y: a };
|
|
437
|
+
}
|
|
438
|
+
/** Upper-edge vertex of layer `li` at column `t`, replayed from the last
|
|
439
|
+
* stacked frame's data-space record against `ctx`'s scales. */
|
|
440
|
+
paintedStackVertex(t, e, i) {
|
|
441
|
+
const o = this.stackedEdges, s = o?.cumulative[e];
|
|
442
|
+
if (o === null || s === void 0) return null;
|
|
443
|
+
const { times: n, growChain: a, collapse: u } = o, l = pt(n, i);
|
|
444
|
+
if (l < 0) return null;
|
|
445
|
+
const { timeScale: p, yScale: h } = t, d = t.scope.bitmapSize.height, r = u[e] ?? 1, f = h.valueToBitmapYExact(s[l]), c = r >= 1 ? f : d + (f - d) * r, y = n.length - a.length;
|
|
446
|
+
if (l < y) return { x: p.timeToBitmapXExact(i), y: c };
|
|
447
|
+
let R = p.timeToBitmapXExact(n[y - 1]);
|
|
448
|
+
for (let M = 0; M <= l - y; M++)
|
|
449
|
+
R = Y(R, p.timeToBitmapXExact(n[y + M]), a[M]);
|
|
450
|
+
return { x: R, y: c };
|
|
400
451
|
}
|
|
401
452
|
chainedTailPositions(t, e) {
|
|
402
453
|
const i = this.unsettledTail(e);
|
|
403
454
|
if (i.length === 0) return null;
|
|
404
|
-
const
|
|
405
|
-
if (
|
|
406
|
-
const { timeScale: n, yScale:
|
|
407
|
-
if (!Number.isFinite(
|
|
408
|
-
let
|
|
409
|
-
const
|
|
410
|
-
for (let
|
|
411
|
-
const
|
|
412
|
-
if (!Number.isFinite(
|
|
413
|
-
const
|
|
414
|
-
|
|
455
|
+
const o = this.stores[e].getAll(), s = o.length - 1 - i.length;
|
|
456
|
+
if (s < 0) return null;
|
|
457
|
+
const { timeScale: n, yScale: a } = t, u = o[s];
|
|
458
|
+
if (!Number.isFinite(u.value)) return null;
|
|
459
|
+
let l = n.timeToBitmapXExact(u.time), p = a.valueToBitmapYExact(this.effectiveValue(t, e, u.time, u.value));
|
|
460
|
+
const h = /* @__PURE__ */ new Map();
|
|
461
|
+
for (let d = 0; d < i.length; d++) {
|
|
462
|
+
const r = o[s + 1 + d];
|
|
463
|
+
if (!Number.isFinite(r.value)) return null;
|
|
464
|
+
const f = U(i[d].progress), c = n.timeToBitmapXExact(r.time), y = a.valueToBitmapYExact(this.effectiveValue(t, e, r.time, r.value)), R = Y(l, c, f), M = Y(p, y, f);
|
|
465
|
+
h.set(r.time, { x: R, y: M }), l = R, p = M;
|
|
415
466
|
}
|
|
416
|
-
return
|
|
467
|
+
return h;
|
|
417
468
|
}
|
|
418
469
|
/**
|
|
419
470
|
* Bitmap coordinates for the trailing endpoint of a layer — i.e. where the
|
|
@@ -428,8 +479,8 @@ class mt extends rt {
|
|
|
428
479
|
trailingEndpoint(t, e) {
|
|
429
480
|
const i = this.stores[e].last();
|
|
430
481
|
if (!i) return null;
|
|
431
|
-
const { timeScale:
|
|
432
|
-
return (this.options.entryAnimation ?? "grow") !== "grow" ? { x: n, y:
|
|
482
|
+
const { timeScale: o, yScale: s } = t, n = o.timeToBitmapXExact(i.time), a = s.valueToBitmapYExact(this.effectiveValue(t, e, i.time, i.value));
|
|
483
|
+
return (this.options.entryAnimation ?? "grow") !== "grow" ? { x: n, y: a } : this.chainedTailPositions(t, e)?.get(i.time) ?? { x: n, y: a };
|
|
433
484
|
}
|
|
434
485
|
/**
|
|
435
486
|
* Vertical stroke + area gradients for `options.threshold`, pinned to the
|
|
@@ -443,10 +494,10 @@ class mt extends rt {
|
|
|
443
494
|
buildThresholdPaint(t, e) {
|
|
444
495
|
const i = this.options.threshold;
|
|
445
496
|
if (!i) return null;
|
|
446
|
-
const { scope:
|
|
447
|
-
|
|
448
|
-
const
|
|
449
|
-
return
|
|
497
|
+
const { scope: o, yScale: s } = t, { context: n } = o, a = o.bitmapSize.height, u = i.above, l = i.below ?? e, p = Math.min(1, Math.max(0, s.valueToBitmapYExact(i.value) / a)), h = Math.min(6 * o.verticalPixelRatio, a * 0.02) / a, d = Math.max(0, p - h), r = Math.min(1, p + h), f = n.createLinearGradient(0, 0, 0, a);
|
|
498
|
+
f.addColorStop(0, u), f.addColorStop(d, u), f.addColorStop(r, l), f.addColorStop(1, l);
|
|
499
|
+
const c = n.createLinearGradient(0, 0, 0, a);
|
|
500
|
+
return c.addColorStop(0, W(u, 0.26)), c.addColorStop(d, W(u, 0.14)), c.addColorStop(r, W(l, 0.1)), c.addColorStop(1, W(l, 0.01)), { stroke: f, area: c };
|
|
450
501
|
}
|
|
451
502
|
/**
|
|
452
503
|
* Dot markers at each data point (`options.points`). Callers pass the same
|
|
@@ -459,215 +510,224 @@ class mt extends rt {
|
|
|
459
510
|
drawPointMarkers(t) {
|
|
460
511
|
const e = this.options.points;
|
|
461
512
|
if (!e?.visible) return;
|
|
462
|
-
const { context: i, points:
|
|
463
|
-
if (
|
|
464
|
-
const
|
|
465
|
-
if (!(
|
|
513
|
+
const { context: i, points: o, pixelRatio: s, color: n } = t;
|
|
514
|
+
if (o.length === 0) return;
|
|
515
|
+
const a = Math.max(1, (e.radius ?? 3) * s);
|
|
516
|
+
if (!(o.length > 1 && (o[o.length - 1].x - o[0].x) / (o.length - 1) < a * 3)) {
|
|
466
517
|
i.beginPath();
|
|
467
|
-
for (const
|
|
468
|
-
i.moveTo(
|
|
518
|
+
for (const u of o)
|
|
519
|
+
i.moveTo(u.x + a, u.y), i.arc(u.x, u.y, a, 0, Math.PI * 2);
|
|
469
520
|
i.fillStyle = e.color ?? n, i.fill();
|
|
470
521
|
}
|
|
471
522
|
}
|
|
472
523
|
/** Each layer drawn independently */
|
|
473
524
|
renderOff(t) {
|
|
474
|
-
const { scope: e, timeScale: i, yScale:
|
|
475
|
-
ctx:
|
|
525
|
+
const { scope: e, timeScale: i, yScale: o } = t, { context: s } = e, n = i.getRange(), { verticalPixelRatio: a } = e, u = this.options.strokeWidth > 0, l = Math.max(1, Math.round(this.options.strokeWidth * a)), p = this.options.entryAnimation ?? "grow", h = ct(this.options.linePainter ?? this.options.curve ?? "straight"), d = {
|
|
526
|
+
ctx: s,
|
|
476
527
|
theme: t.theme,
|
|
477
528
|
horizontalPixelRatio: e.horizontalPixelRatio,
|
|
478
|
-
verticalPixelRatio:
|
|
529
|
+
verticalPixelRatio: a
|
|
479
530
|
};
|
|
480
|
-
for (let
|
|
481
|
-
const
|
|
482
|
-
if (
|
|
483
|
-
let
|
|
484
|
-
const
|
|
485
|
-
if (
|
|
486
|
-
const R = this.stores[
|
|
487
|
-
x: i.
|
|
488
|
-
y:
|
|
489
|
-
},
|
|
490
|
-
(
|
|
491
|
-
const
|
|
492
|
-
let
|
|
493
|
-
for (let
|
|
494
|
-
const B =
|
|
531
|
+
for (let r = 0; r < this.stores.length; r++) {
|
|
532
|
+
const f = this.getLayerAlpha(r);
|
|
533
|
+
if (f <= 0) continue;
|
|
534
|
+
let c = this.stores[r].getVisibleData(n.from, n.to);
|
|
535
|
+
const y = e.mediaSize.width;
|
|
536
|
+
if (c.length > y * 2 && (c = K(c, Math.round(y * 1.5))), c.length < 2) continue;
|
|
537
|
+
const R = this.stores[r].last()?.value ?? c[c.length - 1].value, M = this.resolveLayerColor(r, R), V = this.buildThresholdPaint(t, M), C = c[c.length - 1], N = this.stores[r].last(), D = N !== void 0 && C.time === N.time, z = D ? this.entranceProgress(r, C.time) : 1, I = D && p === "fade" && z < 1, G = (D ? this.trailingEndpoint(t, r) : null) ?? {
|
|
538
|
+
x: i.timeToBitmapXExact(C.time),
|
|
539
|
+
y: o.valueToBitmapYExact(this.effectiveValue(t, r, C.time, C.value))
|
|
540
|
+
}, H = G.x, _ = G.y, m = D && p === "grow" ? this.chainedTailPositions(t, r) : null, v = f < 1;
|
|
541
|
+
(v || I) && (s.save(), v && (s.globalAlpha *= f), I && (s.globalAlpha *= z));
|
|
542
|
+
const b = c.length - 1, T = [];
|
|
543
|
+
let x = null;
|
|
544
|
+
for (let S = 0; S < b; S++) {
|
|
545
|
+
const B = c[S].value;
|
|
495
546
|
if (!Number.isFinite(B)) {
|
|
496
|
-
|
|
547
|
+
x = null;
|
|
497
548
|
continue;
|
|
498
549
|
}
|
|
499
|
-
|
|
500
|
-
const
|
|
501
|
-
if (
|
|
502
|
-
|
|
550
|
+
x || (x = [], T.push(x));
|
|
551
|
+
const P = m?.get(c[S].time);
|
|
552
|
+
if (P)
|
|
553
|
+
x.push({ x: P.x, y: P.y });
|
|
503
554
|
else {
|
|
504
|
-
const
|
|
505
|
-
|
|
555
|
+
const w = o.valueToBitmapYExact(this.effectiveValue(t, r, c[S].time, B));
|
|
556
|
+
x.push({ x: i.timeToBitmapXExact(c[S].time), y: w });
|
|
506
557
|
}
|
|
507
558
|
}
|
|
508
|
-
const k =
|
|
509
|
-
let
|
|
510
|
-
if (
|
|
511
|
-
|
|
512
|
-
for (const
|
|
513
|
-
|
|
514
|
-
|
|
559
|
+
const k = c[b]?.value, L = Number.isFinite(H) && Number.isFinite(_) && Number.isFinite(k), A = p === "grow" && z < 1;
|
|
560
|
+
let F = null;
|
|
561
|
+
if (L && (x ? (x.push({ x: H, y: _ }), F = x) : T.push([{ x: H, y: _ }])), u && T.some((S) => S.length >= 2)) {
|
|
562
|
+
s.beginPath();
|
|
563
|
+
for (const S of T)
|
|
564
|
+
S.length < 2 || h(d, { points: S, color: M, lineWidth: l, closing: !1, grew: A && S === F });
|
|
565
|
+
s.strokeStyle = V ? V.stroke : M, s.lineWidth = l, s.lineJoin = "round", s.lineCap = "round", s.stroke();
|
|
515
566
|
}
|
|
516
|
-
if (
|
|
517
|
-
const
|
|
567
|
+
if (u) {
|
|
568
|
+
const S = Math.max(1, l / 2);
|
|
518
569
|
let B = !1;
|
|
519
|
-
for (const
|
|
520
|
-
|
|
521
|
-
B && (
|
|
570
|
+
for (const P of T)
|
|
571
|
+
P.length === 1 && (B || (s.beginPath(), B = !0), s.moveTo(P[0].x + S, P[0].y), s.arc(P[0].x, P[0].y, S, 0, Math.PI * 2));
|
|
572
|
+
B && (s.fillStyle = M, s.fill());
|
|
522
573
|
}
|
|
523
574
|
if (this.options.area.visible && !this.introGhostPass) {
|
|
524
|
-
const
|
|
575
|
+
const S = e.bitmapSize.height;
|
|
525
576
|
let B;
|
|
526
|
-
if (
|
|
527
|
-
B =
|
|
577
|
+
if (V)
|
|
578
|
+
B = V.area;
|
|
528
579
|
else {
|
|
529
|
-
const
|
|
530
|
-
|
|
580
|
+
const P = String(r), w = this.areaGradientCache.get(P);
|
|
581
|
+
w && w.bottomY === S && w.color === M ? B = w.gradient : (B = s.createLinearGradient(0, 0, 0, S), B.addColorStop(0, W(M, 0.12)), B.addColorStop(1, W(M, 0.01)), this.areaGradientCache.set(P, { gradient: B, bottomY: S, color: M }));
|
|
531
582
|
}
|
|
532
|
-
|
|
533
|
-
for (const
|
|
534
|
-
|
|
583
|
+
s.fillStyle = B;
|
|
584
|
+
for (const P of T)
|
|
585
|
+
P.length < 2 || (s.beginPath(), h(d, { points: P, color: M, lineWidth: l, closing: !0, grew: A && P === F }), s.lineTo(P[P.length - 1].x, S), s.lineTo(P[0].x, S), s.closePath(), s.fill());
|
|
535
586
|
}
|
|
536
587
|
if (this.options.points?.visible) {
|
|
537
|
-
const
|
|
538
|
-
for (const B of
|
|
539
|
-
for (const
|
|
540
|
-
this.drawPointMarkers({ context:
|
|
588
|
+
const S = [];
|
|
589
|
+
for (const B of T)
|
|
590
|
+
for (const P of B) S.push(P);
|
|
591
|
+
this.drawPointMarkers({ context: s, points: S, pixelRatio: e.horizontalPixelRatio, color: M });
|
|
541
592
|
}
|
|
542
|
-
(
|
|
593
|
+
(I || v) && s.restore();
|
|
543
594
|
}
|
|
544
595
|
}
|
|
545
596
|
/** Stacked area rendering */
|
|
546
597
|
renderStacked(t, e) {
|
|
547
|
-
const { scope: i, timeScale:
|
|
548
|
-
if (this.getLayerAlpha(
|
|
549
|
-
let b =
|
|
550
|
-
return b.length >
|
|
551
|
-
}),
|
|
552
|
-
for (const
|
|
553
|
-
for (const
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
556
|
-
|
|
598
|
+
const { scope: i, timeScale: o, yScale: s } = t, { context: n } = i, a = o.getRange(), { verticalPixelRatio: u } = i, l = this.options.strokeWidth > 0, p = Math.max(1, Math.round(this.options.strokeWidth * u)), h = this.options.curve ?? "straight", d = i.mediaSize.width, r = this.stores.map((m, v) => {
|
|
599
|
+
if (this.getLayerAlpha(v) <= 0) return [];
|
|
600
|
+
let b = m.getVisibleData(a.from, a.to);
|
|
601
|
+
return b.length > d * 2 && (b = K(b, Math.round(d * 1.5))), b;
|
|
602
|
+
}), f = /* @__PURE__ */ new Set();
|
|
603
|
+
for (const m of r)
|
|
604
|
+
for (const v of m) f.add(v.time);
|
|
605
|
+
const c = Array.from(f).sort((m, v) => m - v);
|
|
606
|
+
if (c.length < 2) {
|
|
607
|
+
this.stackedEdges = null;
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
const y = this.options.entryAnimation ?? "grow", R = r.map((m, v) => {
|
|
557
611
|
const b = /* @__PURE__ */ new Map();
|
|
558
|
-
if (
|
|
559
|
-
const
|
|
560
|
-
for (const
|
|
561
|
-
if (
|
|
562
|
-
const
|
|
563
|
-
|
|
612
|
+
if (m.length === 0) return b;
|
|
613
|
+
const T = this.getLayerAlpha(v), x = m[0].time, k = y === "grow" ? this.chainedTailValues(v, (A, F) => this.effectiveValue(t, v, A, F)) : null, L = (A) => k?.get(A.time) ?? this.effectiveValue(t, v, A.time, A.value);
|
|
614
|
+
for (const A of c) {
|
|
615
|
+
if (A < x) continue;
|
|
616
|
+
const F = j(m, A, L);
|
|
617
|
+
F !== null && b.set(A, F * T);
|
|
564
618
|
}
|
|
565
619
|
return b;
|
|
566
|
-
}),
|
|
567
|
-
for (let
|
|
568
|
-
const
|
|
620
|
+
}), M = Array.from({ length: this.stores.length }, () => new Array(c.length).fill(0));
|
|
621
|
+
for (let m = 0; m < c.length; m++) {
|
|
622
|
+
const v = c[m];
|
|
569
623
|
let b = 0;
|
|
570
624
|
if (e)
|
|
571
|
-
for (let
|
|
572
|
-
const
|
|
573
|
-
Number.isFinite(
|
|
625
|
+
for (let x = 0; x < this.stores.length; x++) {
|
|
626
|
+
const k = R[x].get(v);
|
|
627
|
+
Number.isFinite(k) && (b += k);
|
|
574
628
|
}
|
|
575
|
-
let
|
|
576
|
-
for (let
|
|
577
|
-
const
|
|
578
|
-
|
|
629
|
+
let T = 0;
|
|
630
|
+
for (let x = 0; x < this.stores.length; x++) {
|
|
631
|
+
const k = R[x].get(v), L = Number.isFinite(k) ? k : 0;
|
|
632
|
+
T += e && b > 0 ? L / b * 100 : L, M[x][m] = T;
|
|
579
633
|
}
|
|
580
634
|
}
|
|
581
|
-
const
|
|
582
|
-
for (let
|
|
583
|
-
const
|
|
584
|
-
for (let
|
|
585
|
-
if (this.getLayerAlpha(
|
|
586
|
-
const
|
|
635
|
+
const V = /* @__PURE__ */ new Map();
|
|
636
|
+
for (let m = 0; m < c.length; m++) V.set(c[m], m);
|
|
637
|
+
const C = new Array(this.stores.length).fill(1);
|
|
638
|
+
for (let m = 0; m < this.stores.length; m++) {
|
|
639
|
+
if (this.getLayerAlpha(m) <= 0) continue;
|
|
640
|
+
const v = this.unsettledTail(m), b = v.length;
|
|
587
641
|
if (b === 0) continue;
|
|
588
|
-
let
|
|
589
|
-
for (let
|
|
590
|
-
if (
|
|
591
|
-
|
|
642
|
+
let T = !0;
|
|
643
|
+
for (let x = 0; x < b; x++)
|
|
644
|
+
if (V.get(v[x].time) !== c.length - b + x) {
|
|
645
|
+
T = !1;
|
|
592
646
|
break;
|
|
593
647
|
}
|
|
594
|
-
|
|
648
|
+
T && (C[m] = v[b - 1].progress);
|
|
595
649
|
}
|
|
596
|
-
const
|
|
597
|
-
if (
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
650
|
+
const N = [];
|
|
651
|
+
if (y === "grow") {
|
|
652
|
+
const m = r.map((v) => v.length - 1);
|
|
653
|
+
for (let v = c.length - 1; v >= 1; v--) {
|
|
654
|
+
const b = c[v];
|
|
655
|
+
let T = 1, x = !1;
|
|
656
|
+
for (let k = 0; k < r.length; k++) {
|
|
657
|
+
if (this.getLayerAlpha(k) <= 0) continue;
|
|
658
|
+
const L = r[k];
|
|
659
|
+
for (; m[k] >= 0 && L[m[k]].time > b; ) m[k]--;
|
|
660
|
+
if (m[k] < 0 || L[m[k]].time !== b) continue;
|
|
661
|
+
const A = this.entranceProgress(k, b);
|
|
662
|
+
(!x || A > T) && (T = A), x = !0;
|
|
605
663
|
}
|
|
606
|
-
if (!
|
|
607
|
-
|
|
664
|
+
if (!x || T >= 1) break;
|
|
665
|
+
N.unshift(U(T));
|
|
608
666
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
667
|
+
}
|
|
668
|
+
const D = (m, v) => {
|
|
669
|
+
const b = v.length;
|
|
670
|
+
if (!(b === 0 || m.length < b + 1))
|
|
671
|
+
for (let T = 0; T < b; T++) {
|
|
672
|
+
const x = m.length - b + T;
|
|
673
|
+
m[x][0] = Y(m[x - 1][0], m[x][0], v[T]);
|
|
615
674
|
}
|
|
616
|
-
},
|
|
617
|
-
let
|
|
618
|
-
for (let
|
|
619
|
-
if (!(this.getLayerAlpha(
|
|
620
|
-
if (
|
|
621
|
-
|
|
675
|
+
}, z = i.bitmapSize.height;
|
|
676
|
+
let I = -1, G = -1;
|
|
677
|
+
for (let m = 0; m < this.stores.length; m++)
|
|
678
|
+
if (!(this.getLayerAlpha(m) <= 0))
|
|
679
|
+
if (I < 0)
|
|
680
|
+
I = m;
|
|
622
681
|
else {
|
|
623
|
-
|
|
682
|
+
G = m;
|
|
624
683
|
break;
|
|
625
684
|
}
|
|
626
|
-
const
|
|
627
|
-
for (let
|
|
628
|
-
const
|
|
629
|
-
if (
|
|
630
|
-
const b = this.stores[
|
|
631
|
-
for (let
|
|
632
|
-
const
|
|
633
|
-
let O =
|
|
634
|
-
|
|
685
|
+
const H = I >= 0 ? this.getLayerAlpha(I) : 1, _ = r.map((m, v) => v === I ? Math.min(1, this.getLayerAlpha(v)) : 1);
|
|
686
|
+
for (let m = this.stores.length - 1; m >= 0; m--) {
|
|
687
|
+
const v = this.getLayerAlpha(m);
|
|
688
|
+
if (v <= 0) continue;
|
|
689
|
+
const b = this.stores[m].last()?.value ?? 0, T = this.resolveLayerColor(m, b), x = m === I, k = G >= 0 && m === G && H < 1, L = [];
|
|
690
|
+
for (let w = 0; w < c.length; w++) {
|
|
691
|
+
const X = m > 0 ? s.valueToBitmapYExact(M[m - 1][w]) : z;
|
|
692
|
+
let O = X;
|
|
693
|
+
x ? O = z : k && (O = X + (z - X) * (1 - H)), L.push([o.timeToBitmapXExact(c[w]), O]);
|
|
635
694
|
}
|
|
636
|
-
|
|
637
|
-
const
|
|
638
|
-
for (let
|
|
639
|
-
let
|
|
640
|
-
|
|
695
|
+
y === "grow" && D(L, N);
|
|
696
|
+
const A = [];
|
|
697
|
+
for (let w = 0; w < c.length; w++) {
|
|
698
|
+
let X = s.valueToBitmapYExact(M[m][w]);
|
|
699
|
+
x && v < 1 && (X = z + (X - z) * v), A.push([o.timeToBitmapXExact(c[w]), X]);
|
|
641
700
|
}
|
|
642
|
-
|
|
643
|
-
const
|
|
644
|
-
if (
|
|
645
|
-
let
|
|
646
|
-
for (let
|
|
647
|
-
|
|
648
|
-
for (let
|
|
649
|
-
|
|
650
|
-
let O =
|
|
651
|
-
if (
|
|
652
|
-
const
|
|
653
|
-
|
|
701
|
+
y === "grow" && D(A, N);
|
|
702
|
+
const F = $(A), S = Q(F, h, y === "grow" && N.length > 0), B = y === "fade" && C[m] < 1;
|
|
703
|
+
if (B && (n.save(), n.globalAlpha *= C[m]), this.options.area.visible && !this.introGhostPass) {
|
|
704
|
+
let w = A[0][1], X = L[0][1];
|
|
705
|
+
for (let E = 1; E < A.length; E++)
|
|
706
|
+
A[E][1] < w && (w = A[E][1]);
|
|
707
|
+
for (let E = 1; E < L.length; E++)
|
|
708
|
+
L[E][1] > X && (X = L[E][1]);
|
|
709
|
+
let O = W(T, 0.25);
|
|
710
|
+
if (X > w + 0.5) {
|
|
711
|
+
const E = n.createLinearGradient(0, w, 0, X);
|
|
712
|
+
E.addColorStop(0, W(T, 0.25)), E.addColorStop(1, W(T, 0.05)), O = E;
|
|
654
713
|
}
|
|
655
|
-
if (n.beginPath(), n.moveTo(
|
|
656
|
-
for (let
|
|
657
|
-
n.lineTo(
|
|
714
|
+
if (n.beginPath(), n.moveTo(F[0].x, F[0].y), tt(n, S), x)
|
|
715
|
+
for (let E = L.length - 1; E >= 0; E--)
|
|
716
|
+
n.lineTo(L[E][0], L[E][1]);
|
|
658
717
|
else {
|
|
659
|
-
const
|
|
660
|
-
n.lineTo(
|
|
718
|
+
const E = $(L), rt = Q(E, h, y === "grow" && N.length > 0), q = E[E.length - 1];
|
|
719
|
+
n.lineTo(q.x, q.y), ft(n, E, rt);
|
|
661
720
|
}
|
|
662
721
|
n.closePath(), n.fillStyle = O, n.fill();
|
|
663
722
|
}
|
|
664
|
-
const
|
|
665
|
-
if (
|
|
666
|
-
const
|
|
667
|
-
|
|
723
|
+
const P = l && v < 1;
|
|
724
|
+
if (P && (n.save(), n.globalAlpha *= v), l && (n.beginPath(), n.moveTo(F[0].x, F[0].y), tt(n, S), n.strokeStyle = T, n.lineWidth = p, n.lineJoin = "round", n.lineCap = "round", n.stroke()), P && n.restore(), this.options.points?.visible) {
|
|
725
|
+
const w = v < 1;
|
|
726
|
+
w && (n.save(), n.globalAlpha *= v), this.drawPointMarkers({ context: n, points: F, pixelRatio: i.horizontalPixelRatio, color: T }), w && n.restore();
|
|
668
727
|
}
|
|
669
|
-
|
|
728
|
+
B && n.restore();
|
|
670
729
|
}
|
|
730
|
+
this.stackedEdges = { times: c, cumulative: M, growChain: N, collapse: _ };
|
|
671
731
|
}
|
|
672
732
|
/**
|
|
673
733
|
* Overlay hook: draws crosshair nearest-point dots and last-point pulse dots.
|
|
@@ -675,54 +735,54 @@ class mt extends rt {
|
|
|
675
735
|
*/
|
|
676
736
|
drawOverlay(t) {
|
|
677
737
|
this.tickAnimations(performance.now());
|
|
678
|
-
const { scope: e, timeScale: i, yScale:
|
|
679
|
-
if (
|
|
680
|
-
const
|
|
681
|
-
for (let
|
|
682
|
-
const
|
|
683
|
-
if (
|
|
684
|
-
const
|
|
685
|
-
if (!
|
|
686
|
-
const R = this.resolveLayerColor(
|
|
687
|
-
x: i.
|
|
688
|
-
y:
|
|
689
|
-
} : this.stackedPositionAt(t,
|
|
690
|
-
|
|
738
|
+
const { scope: e, timeScale: i, yScale: o, crosshair: s, dataInterval: n } = t, a = e, u = this.options.pulseMs, l = u > 0 ? performance.now() / (u * 2 * Math.PI) % 1 : 0;
|
|
739
|
+
if (s) {
|
|
740
|
+
const d = this.options.stacking, r = 4 * a.horizontalPixelRatio;
|
|
741
|
+
for (let f = 0; f < this.stores.length; f++) {
|
|
742
|
+
const c = this.getLayerAlpha(f);
|
|
743
|
+
if (c <= 0) continue;
|
|
744
|
+
const y = this.stores[f].findNearest(s.time, n);
|
|
745
|
+
if (!y) continue;
|
|
746
|
+
const R = this.resolveLayerColor(f, y.value), { x: M, y: V } = d === "off" ? {
|
|
747
|
+
x: i.timeToBitmapXExact(y.time),
|
|
748
|
+
y: o.valueToBitmapYExact(this.effectiveValue(t, f, y.time, y.value))
|
|
749
|
+
} : this.stackedPositionAt(t, f, y.time), C = c < 1;
|
|
750
|
+
C && (e.context.save(), e.context.globalAlpha *= c), e.context.save(), e.context.globalAlpha *= 0.25, e.context.beginPath(), e.context.arc(M, V, r + 3 * a.horizontalPixelRatio, 0, Math.PI * 2), e.context.fillStyle = R, e.context.fill(), e.context.restore(), e.context.beginPath(), e.context.arc(M, V, r, 0, Math.PI * 2), e.context.fillStyle = R, e.context.fill(), C && e.context.restore();
|
|
691
751
|
}
|
|
692
752
|
}
|
|
693
753
|
const p = this.introWave.active && this.introDirectives?.clip !== void 0;
|
|
694
|
-
let
|
|
695
|
-
if (p && (
|
|
696
|
-
const
|
|
697
|
-
for (let
|
|
698
|
-
const
|
|
699
|
-
if (
|
|
700
|
-
const
|
|
701
|
-
if (
|
|
702
|
-
const
|
|
703
|
-
if (!
|
|
754
|
+
let h = 1;
|
|
755
|
+
if (p && (h = Math.max(0, (this.introWave.linear() - (1 - J)) / J)), this.hasPulse && u > 0 && h > 0) {
|
|
756
|
+
const d = this.options.stacking;
|
|
757
|
+
for (let r = 0; r < this.stores.length; r++) {
|
|
758
|
+
const f = this.getLayerAlpha(r);
|
|
759
|
+
if (f <= 0) continue;
|
|
760
|
+
const c = this.stores[r].last()?.value ?? 0, y = this.resolveLayerColor(r, c);
|
|
761
|
+
if (d === "off") {
|
|
762
|
+
const C = this.trailingEndpoint(t, r);
|
|
763
|
+
if (!C) continue;
|
|
704
764
|
this.drawPulse({
|
|
705
765
|
ctx: e.context,
|
|
706
|
-
x:
|
|
707
|
-
y:
|
|
708
|
-
color:
|
|
709
|
-
pixelRatio:
|
|
710
|
-
phase:
|
|
711
|
-
alpha:
|
|
766
|
+
x: C.x,
|
|
767
|
+
y: C.y,
|
|
768
|
+
color: y,
|
|
769
|
+
pixelRatio: a.horizontalPixelRatio,
|
|
770
|
+
phase: l,
|
|
771
|
+
alpha: f * h
|
|
712
772
|
});
|
|
713
773
|
continue;
|
|
714
774
|
}
|
|
715
|
-
const R = this.stores[
|
|
775
|
+
const R = this.stores[r].last();
|
|
716
776
|
if (!R) continue;
|
|
717
|
-
const { x: M, y:
|
|
777
|
+
const { x: M, y: V } = this.stackedPositionAt(t, r, R.time);
|
|
718
778
|
this.drawPulse({
|
|
719
779
|
ctx: e.context,
|
|
720
780
|
x: M,
|
|
721
|
-
y:
|
|
722
|
-
color:
|
|
723
|
-
pixelRatio:
|
|
724
|
-
phase:
|
|
725
|
-
alpha:
|
|
781
|
+
y: V,
|
|
782
|
+
color: y,
|
|
783
|
+
pixelRatio: a.horizontalPixelRatio,
|
|
784
|
+
phase: l,
|
|
785
|
+
alpha: f * h
|
|
726
786
|
});
|
|
727
787
|
}
|
|
728
788
|
}
|
|
@@ -731,24 +791,24 @@ class mt extends rt {
|
|
|
731
791
|
ctx: t,
|
|
732
792
|
x: e,
|
|
733
793
|
y: i,
|
|
734
|
-
color:
|
|
735
|
-
pixelRatio:
|
|
794
|
+
color: o,
|
|
795
|
+
pixelRatio: s,
|
|
736
796
|
phase: n,
|
|
737
|
-
alpha:
|
|
797
|
+
alpha: a = 1
|
|
738
798
|
}) {
|
|
739
|
-
const
|
|
740
|
-
|
|
799
|
+
const u = 3 * s, l = 0.4 + 0.6 * Math.abs(Math.sin(n * 2 * Math.PI)), p = u + 4 * s * l, h = a < 1;
|
|
800
|
+
h && (t.save(), t.globalAlpha *= a), t.beginPath(), t.arc(e, i, p, 0, Math.PI * 2), t.fillStyle = W(o, l * 0.3), t.fill(), t.beginPath(), t.arc(e, i, u, 0, Math.PI * 2), t.fillStyle = o, t.fill(), h && t.restore();
|
|
741
801
|
}
|
|
742
802
|
}
|
|
743
|
-
const
|
|
803
|
+
const wt = {
|
|
744
804
|
type: "line",
|
|
745
|
-
create: ({ theme:
|
|
746
|
-
colors: t === 1 ? [
|
|
747
|
-
strokeWidth:
|
|
805
|
+
create: ({ theme: g, layerCount: t }, e) => new dt(t, {
|
|
806
|
+
colors: t === 1 ? [g.line.color] : g.seriesColors.slice(0, t),
|
|
807
|
+
strokeWidth: g.line.width,
|
|
748
808
|
...e
|
|
749
809
|
})
|
|
750
810
|
};
|
|
751
811
|
export {
|
|
752
|
-
|
|
753
|
-
|
|
812
|
+
dt as LineRenderer,
|
|
813
|
+
wt as LineSeriesDef
|
|
754
814
|
};
|