@wick-charts/vue 0.6.2 → 0.6.4
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/README.md +2 -2
- package/dist/BandSeries.vue.js +50 -0
- package/dist/BandSeries.vue2.js +4 -0
- package/dist/ChartContainer.vue.js +45 -39
- package/dist/composables.js +39 -26
- package/dist/core/dist/animation/config.js +92 -75
- package/dist/core/dist/axis/dom-labels.js +56 -43
- package/dist/core/dist/chart/badge-animator.js +30 -22
- package/dist/core/dist/chart/edge-indicators.js +22 -21
- package/dist/core/dist/chart/last-value.js +33 -26
- package/dist/core/dist/chart/options.js +5 -5
- package/dist/core/dist/chart/scale-guards.js +26 -0
- package/dist/core/dist/chart/y-target.js +46 -19
- package/dist/core/dist/chart.js +670 -518
- package/dist/core/dist/components/crosshair.js +8 -8
- package/dist/core/dist/components/grid.js +26 -17
- package/dist/core/dist/components/marker.js +28 -28
- package/dist/core/dist/components/reference-line.js +16 -16
- package/dist/core/dist/data/decimation.js +58 -39
- package/dist/core/dist/interactions/handler.js +3 -2
- package/dist/core/dist/interactions/zoom.js +6 -5
- package/dist/core/dist/navigator/controller.js +47 -44
- package/dist/core/dist/perf/perf-hud.js +3 -3
- package/dist/core/dist/scales/log-scale.js +76 -0
- package/dist/core/dist/scales/y-scale.js +134 -35
- package/dist/core/dist/series/band.js +670 -0
- package/dist/core/dist/series/bar-intro.js +11 -11
- package/dist/core/dist/series/bar.js +301 -251
- package/dist/core/dist/series/base-multi-layer.js +100 -76
- package/dist/core/dist/series/candlestick.js +238 -235
- package/dist/core/dist/series/heatmap.js +5 -5
- package/dist/core/dist/series/line-intro.js +50 -40
- package/dist/core/dist/series/line.js +561 -483
- package/dist/core/dist/series/painters/builtins.js +4 -4
- package/dist/core/dist/series/painters/canvas-path.js +64 -52
- package/dist/core/dist/series/register-builtins.js +9 -8
- package/dist/core/dist/series/scale-stack.js +25 -0
- package/dist/core/dist/snapshots.js +36 -35
- package/dist/core/dist/tooltip-position.js +5 -5
- package/dist/core/dist/utils/point.js +10 -0
- package/dist/index.d.ts +501 -128
- package/dist/index.js +195 -189
- package/dist/ui/Crosshair.vue.js +14 -14
- package/dist/ui/HeatmapTooltip.vue.js +6 -6
- package/dist/ui/InfoBar.vue.js +100 -81
- package/dist/ui/PieTooltip.vue.js +4 -4
- package/dist/ui/TimeAxis.vue.js +23 -22
- package/dist/ui/Tooltip.vue.js +140 -111
- package/dist/ui/YAxis.vue.js +25 -24
- package/dist/ui/YLabel.vue.js +63 -70
- package/package.json +2 -2
- package/src/BandSeries.vue +87 -0
- package/src/ChartContainer.vue +20 -8
- package/src/composables.ts +35 -1
- package/src/index.ts +13 -0
- package/src/ui/Crosshair.vue +2 -2
- package/src/ui/InfoBar.vue +20 -1
- package/src/ui/TimeAxis.vue +7 -4
- package/src/ui/Tooltip.vue +40 -3
- package/src/ui/YAxis.vue +5 -3
- package/src/ui/YLabel.vue +5 -16
|
@@ -1,90 +1,82 @@
|
|
|
1
|
-
import { DEFAULT_HISTORY_REVEAL as
|
|
1
|
+
import { DEFAULT_HISTORY_REVEAL as nt, DEFAULT_LINE_INTRO as lt, DEFAULT_LINE_PULSE as at, DEFAULT_LINE_SMOOTH as rt, DEFAULT_LINE_ENTRY as ht } from "../animation/config.js";
|
|
2
2
|
import { easeOutCubic as U } from "../animation/easing.js";
|
|
3
|
-
import { decimateLineData as
|
|
4
|
-
import { hexToRgba as
|
|
5
|
-
import { lerp as
|
|
6
|
-
import { BaseMultiLayerSeries as
|
|
7
|
-
import { unfoldIntro as
|
|
8
|
-
import { buildCurveSegments as
|
|
9
|
-
import { resolveLinePainter as
|
|
10
|
-
|
|
3
|
+
import { decimateLineData as q } from "../data/decimation.js";
|
|
4
|
+
import { hexToRgba as X } from "../utils/color.js";
|
|
5
|
+
import { lerp as N } from "../utils/math.js";
|
|
6
|
+
import { BaseMultiLayerSeries as ut } from "./base-multi-layer.js";
|
|
7
|
+
import { unfoldIntro as ft, scaleMean as mt, backfillSweepIntro as pt } from "./line-intro.js";
|
|
8
|
+
import { buildCurveSegments as tt, replaySegmentsForward as et, replaySegmentsReversed as gt } from "./painters/canvas-path.js";
|
|
9
|
+
import { resolveLinePainter as dt } from "./painters/resolve.js";
|
|
10
|
+
import { ScaleStack as it } from "./scale-stack.js";
|
|
11
|
+
const vt = {
|
|
11
12
|
colors: ["#2962FF"],
|
|
12
13
|
strokeWidth: 1,
|
|
13
14
|
area: { visible: !0 },
|
|
14
15
|
pulse: !0,
|
|
15
16
|
stacking: "off",
|
|
16
17
|
curve: "straight",
|
|
17
|
-
entryMs:
|
|
18
|
-
smoothMs:
|
|
19
|
-
pulseMs:
|
|
20
|
-
introMs:
|
|
21
|
-
historyRevealMs:
|
|
18
|
+
entryMs: ht,
|
|
19
|
+
smoothMs: rt,
|
|
20
|
+
pulseMs: at,
|
|
21
|
+
introMs: lt,
|
|
22
|
+
historyRevealMs: nt
|
|
22
23
|
};
|
|
23
|
-
function
|
|
24
|
-
const t =
|
|
24
|
+
function ot(y) {
|
|
25
|
+
const t = y.areaFill, i = t !== void 0 && y.area === void 0 ? { visible: !!t } : y.area;
|
|
25
26
|
return {
|
|
26
|
-
...
|
|
27
|
-
area:
|
|
28
|
-
entryMs:
|
|
29
|
-
smoothMs:
|
|
30
|
-
pulseMs:
|
|
31
|
-
introMs:
|
|
32
|
-
historyRevealMs:
|
|
27
|
+
...y,
|
|
28
|
+
area: i,
|
|
29
|
+
entryMs: y.entryMs === !1 ? 0 : y.entryMs ?? ht,
|
|
30
|
+
smoothMs: y.smoothMs === !1 ? 0 : y.smoothMs ?? rt,
|
|
31
|
+
pulseMs: y.pulseMs === !1 ? 0 : y.pulseMs ?? at,
|
|
32
|
+
introMs: y.introMs === !1 ? 0 : y.introMs ?? lt,
|
|
33
|
+
historyRevealMs: y.historyRevealMs === !1 ? 0 : y.historyRevealMs ?? nt
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
|
-
function
|
|
36
|
-
return
|
|
36
|
+
function st(y) {
|
|
37
|
+
return y.map(([t, i]) => ({ x: t, y: i }));
|
|
37
38
|
}
|
|
38
|
-
const J = 0.15,
|
|
39
|
-
function j(
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
39
|
+
const J = 0.15, xt = pt();
|
|
40
|
+
function j(y, t, i) {
|
|
41
|
+
const { resolve: e, lerp: o = N } = i;
|
|
42
|
+
if (y.length === 0) return null;
|
|
43
|
+
if (t <= y[0].time) return Number.isFinite(y[0].value) ? e(y[0]) : null;
|
|
44
|
+
const s = y[y.length - 1];
|
|
45
|
+
if (t >= s.time) return Number.isFinite(s.value) ? e(s) : null;
|
|
46
|
+
let l = 0, r = y.length - 1;
|
|
47
|
+
for (; r - l > 1; ) {
|
|
48
|
+
const c = l + r >> 1;
|
|
49
|
+
y[c].time <= t ? l = c : r = c;
|
|
50
|
+
}
|
|
51
|
+
const f = y[l], h = y[r];
|
|
52
|
+
if (!Number.isFinite(f.value) || !Number.isFinite(h.value)) return null;
|
|
53
|
+
const m = h.time - f.time;
|
|
54
|
+
return m <= 0 ? e(f) : o(e(f), e(h), (t - f.time) / m);
|
|
53
55
|
}
|
|
54
|
-
function
|
|
55
|
-
let
|
|
56
|
-
for (;
|
|
57
|
-
const o =
|
|
58
|
-
if (
|
|
59
|
-
|
|
56
|
+
function yt(y, t) {
|
|
57
|
+
let i = 0, e = y.length - 1;
|
|
58
|
+
for (; i <= e; ) {
|
|
59
|
+
const o = i + e >> 1;
|
|
60
|
+
if (y[o] === t) return o;
|
|
61
|
+
y[o] < t ? i = o + 1 : e = o - 1;
|
|
60
62
|
}
|
|
61
63
|
return -1;
|
|
62
64
|
}
|
|
63
|
-
|
|
64
|
-
for (const e of t)
|
|
65
|
-
e.kind === "line" ? g.lineTo(e.x, e.y) : g.bezierCurveTo(e.cp1x, e.cp1y, e.cp2x, e.cp2y, e.x, e.y);
|
|
66
|
-
}
|
|
67
|
-
function ft(g, t, e) {
|
|
68
|
-
for (let i = e.length - 1; i >= 0; i--) {
|
|
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);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
class dt extends at {
|
|
65
|
+
class Pt extends ut {
|
|
74
66
|
kind = "line";
|
|
75
67
|
areaGradientCache = /* @__PURE__ */ new Map();
|
|
76
|
-
constructor(t,
|
|
77
|
-
super(t), this.options =
|
|
68
|
+
constructor(t, i) {
|
|
69
|
+
super(t), this.options = ot({ ...vt, ...i });
|
|
78
70
|
}
|
|
79
71
|
updateOptions(t) {
|
|
80
|
-
this.options =
|
|
72
|
+
this.options = ot({ ...this.options, ...t });
|
|
81
73
|
}
|
|
82
74
|
getStacking() {
|
|
83
75
|
return this.options.stacking;
|
|
84
76
|
}
|
|
85
|
-
applyTheme(t,
|
|
86
|
-
const
|
|
87
|
-
this.updateOptions({ colors:
|
|
77
|
+
applyTheme(t, i) {
|
|
78
|
+
const e = this.stores.length === 1 ? [t.line.color] : t.seriesColors.slice(0, this.stores.length);
|
|
79
|
+
this.updateOptions({ colors: e }), this.options.strokeWidth === i.line.width && this.updateOptions({ strokeWidth: t.line.width });
|
|
88
80
|
}
|
|
89
81
|
isEntryEnabled() {
|
|
90
82
|
return (this.options.entryAnimation ?? "grow") !== "none";
|
|
@@ -95,27 +87,27 @@ class dt extends at {
|
|
|
95
87
|
get overlayNeedsAnimation() {
|
|
96
88
|
return this.hasPulse;
|
|
97
89
|
}
|
|
98
|
-
hasOverlayContentInRange(t,
|
|
99
|
-
for (let
|
|
100
|
-
if (this.getLayerAlpha(
|
|
101
|
-
const o = this.stores[
|
|
90
|
+
hasOverlayContentInRange(t, i) {
|
|
91
|
+
for (let e = 0; e < this.stores.length; e++) {
|
|
92
|
+
if (this.getLayerAlpha(e) <= 0) continue;
|
|
93
|
+
const o = this.stores[e].last();
|
|
102
94
|
if (o && o.time >= t) return !0;
|
|
103
95
|
}
|
|
104
96
|
return !1;
|
|
105
97
|
}
|
|
106
98
|
render(t) {
|
|
107
|
-
this.tickAnimations(performance.now());
|
|
108
|
-
const { context:
|
|
99
|
+
this.tickAnimations(performance.now()), this.lastYScale = t.yScale;
|
|
100
|
+
const { context: i } = t.scope;
|
|
109
101
|
this.historyDirectives = null;
|
|
110
|
-
const
|
|
111
|
-
if (this.historyWave.active &&
|
|
112
|
-
const
|
|
113
|
-
|
|
102
|
+
const e = this.historyRange;
|
|
103
|
+
if (this.historyWave.active && e !== null) {
|
|
104
|
+
const r = this.options.historyReveal ?? xt;
|
|
105
|
+
r !== "none" && (this.historyDirectives = r(this.buildHistoryFrame(t, e)));
|
|
114
106
|
}
|
|
115
107
|
const o = this.historyDirectives, s = o?.ghostAlpha ?? 0;
|
|
116
|
-
s > 0 && (
|
|
117
|
-
const
|
|
118
|
-
this.introWave.active ? this.renderWithIntro(t) : (this.introDirectives = null, this.renderBody(t)),
|
|
108
|
+
s > 0 && (i.save(), i.globalAlpha *= s, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, i.restore());
|
|
109
|
+
const l = this.applyHistoryClip(t, o, e);
|
|
110
|
+
this.introWave.active ? this.renderWithIntro(t) : (this.introDirectives = null, this.renderBody(t)), l && i.restore(), o?.heads !== void 0 && o.heads.length > 0 && this.drawIntroHeads(t, o.heads, this.historyWave.linear());
|
|
119
111
|
}
|
|
120
112
|
/**
|
|
121
113
|
* Initial-load intro pass: the resolved LineIntroFn describes this frame
|
|
@@ -123,16 +115,16 @@ class dt extends at {
|
|
|
123
115
|
* renderer executes the directives around the untouched body pass.
|
|
124
116
|
*/
|
|
125
117
|
renderWithIntro(t) {
|
|
126
|
-
const
|
|
127
|
-
this.introDirectives =
|
|
128
|
-
const { context:
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
132
|
-
const
|
|
133
|
-
|
|
118
|
+
const i = this.resolveIntro()(this.buildIntroFrame(t));
|
|
119
|
+
this.introDirectives = i;
|
|
120
|
+
const { context: e } = t.scope, { width: o, height: s } = t.scope.bitmapSize, l = i.ghostAlpha ?? 0;
|
|
121
|
+
l > 0 && (e.save(), e.globalAlpha *= l, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, e.restore());
|
|
122
|
+
const r = i.clip, f = r !== void 0 && (r.fromX !== void 0 || r.toX !== void 0);
|
|
123
|
+
if (f) {
|
|
124
|
+
const h = r.fromX ?? 0, m = r.toX ?? o;
|
|
125
|
+
e.save(), e.beginPath(), e.rect(h, 0, Math.max(0, m - h), s), e.clip();
|
|
134
126
|
}
|
|
135
|
-
this.renderBody(t),
|
|
127
|
+
this.renderBody(t), f && e.restore(), i.heads !== void 0 && i.heads.length > 0 && this.drawIntroHeads(t, i.heads, this.introWave.linear());
|
|
136
128
|
}
|
|
137
129
|
/**
|
|
138
130
|
* Apply the history reveal's clip directive, mapped from reveal space
|
|
@@ -140,11 +132,11 @@ class dt extends at {
|
|
|
140
132
|
* to bitmap space. Everything at or after the boundary always draws; a
|
|
141
133
|
* small pad keeps the stroke cap at the reveal front from being shaved.
|
|
142
134
|
*/
|
|
143
|
-
applyHistoryClip(t,
|
|
144
|
-
const o =
|
|
145
|
-
if (o === void 0 ||
|
|
146
|
-
const { context: s } = t.scope, { width:
|
|
147
|
-
return s.save(), s.beginPath(), s.rect(
|
|
135
|
+
applyHistoryClip(t, i, e) {
|
|
136
|
+
const o = i?.clip;
|
|
137
|
+
if (o === void 0 || e === null || o.fromX === void 0 && o.toX === void 0) return !1;
|
|
138
|
+
const { context: s } = t.scope, { width: l, height: r } = t.scope.bitmapSize, f = t.timeScale.timeToBitmapXExact(e.to), h = Math.abs(f - t.timeScale.timeToBitmapXExact(e.from)), m = Math.max(2, (this.options.strokeWidth ?? 1) * t.scope.horizontalPixelRatio), c = o.fromX ?? 0, x = o.toX ?? h;
|
|
139
|
+
return s.save(), s.beginPath(), s.rect(f - x - m, 0, Math.max(0, x - c + m), r), s.rect(f, 0, Math.max(0, l - f), r), s.clip(), !0;
|
|
148
140
|
}
|
|
149
141
|
renderBody(t) {
|
|
150
142
|
this.options.stacking === "off" ? (this.stackedEdges = null, this.renderOff(t)) : this.renderStacked(t, this.options.stacking === "percent");
|
|
@@ -168,11 +160,13 @@ class dt extends at {
|
|
|
168
160
|
introDirectives = null;
|
|
169
161
|
/** Per-frame history-reveal directives; `null` when no reveal is in flight. */
|
|
170
162
|
historyDirectives = null;
|
|
163
|
+
/** Y scale of the last render — value queries run without a render context. */
|
|
164
|
+
lastYScale = null;
|
|
171
165
|
/** Default intro, built lazily — one instance per renderer. */
|
|
172
166
|
defaultIntro = null;
|
|
173
167
|
resolveIntro() {
|
|
174
168
|
const t = this.options.introAnimation;
|
|
175
|
-
return t !== void 0 ? t : (this.defaultIntro === null && (this.defaultIntro =
|
|
169
|
+
return t !== void 0 ? t : (this.defaultIntro === null && (this.defaultIntro = ft()), this.defaultIntro);
|
|
176
170
|
}
|
|
177
171
|
/**
|
|
178
172
|
* Frame context handed to the intro fn — progress plus memoized data
|
|
@@ -194,60 +188,55 @@ class dt extends at {
|
|
|
194
188
|
* accessors are scoped to that span — `layerMean` anchors an unfold to
|
|
195
189
|
* the new history, not the whole window.
|
|
196
190
|
*/
|
|
197
|
-
buildHistoryFrame(t,
|
|
191
|
+
buildHistoryFrame(t, i) {
|
|
198
192
|
return this.buildFrame(t, {
|
|
199
193
|
progress: this.historyWave.linear(),
|
|
200
|
-
range:
|
|
194
|
+
range: i,
|
|
201
195
|
width: Math.abs(
|
|
202
|
-
t.timeScale.timeToBitmapXExact(
|
|
196
|
+
t.timeScale.timeToBitmapXExact(i.to) - t.timeScale.timeToBitmapXExact(i.from)
|
|
203
197
|
)
|
|
204
198
|
});
|
|
205
199
|
}
|
|
206
|
-
buildFrame(t,
|
|
207
|
-
const { timeScale:
|
|
208
|
-
let
|
|
209
|
-
const
|
|
210
|
-
let
|
|
211
|
-
return
|
|
200
|
+
buildFrame(t, i) {
|
|
201
|
+
const { timeScale: e, yScale: o, scope: s } = t, { progress: l, range: r, width: f } = i, h = this.options.stacking === "percent", m = new Array(this.stores.length), c = new Array(this.stores.length);
|
|
202
|
+
let x, n;
|
|
203
|
+
const p = (a) => {
|
|
204
|
+
let g = m[a];
|
|
205
|
+
return g === void 0 && (g = this.stores[a]?.getVisibleData(r.from, r.to) ?? [], m[a] = g), g;
|
|
212
206
|
};
|
|
213
207
|
return {
|
|
214
|
-
progress:
|
|
215
|
-
range:
|
|
216
|
-
width:
|
|
208
|
+
progress: l,
|
|
209
|
+
range: r,
|
|
210
|
+
width: f,
|
|
217
211
|
height: o.getMediaHeight() * s.verticalPixelRatio,
|
|
218
212
|
stacking: this.options.stacking,
|
|
219
|
-
timeToX: (
|
|
220
|
-
xToTime: (
|
|
221
|
-
valueToY: (
|
|
213
|
+
timeToX: (a) => e.timeToBitmapXExact(a),
|
|
214
|
+
xToTime: (a) => e.xToTime(a / s.horizontalPixelRatio),
|
|
215
|
+
valueToY: (a) => o.valueToBitmapYExact(a),
|
|
216
|
+
lerpValue: (a, g, A) => o.lerpValue(a, g, A),
|
|
222
217
|
layerCount: this.stores.length,
|
|
223
|
-
layerData:
|
|
224
|
-
layerMean: (
|
|
225
|
-
let
|
|
226
|
-
|
|
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;
|
|
231
|
-
}
|
|
232
|
-
return f;
|
|
218
|
+
layerData: p,
|
|
219
|
+
layerMean: (a) => {
|
|
220
|
+
let g = c[a];
|
|
221
|
+
return g === void 0 && (h ? (x ??= this.meanShares(p, o), g = x[a]) : g = mt(p(a), o), c[a] = g), g;
|
|
233
222
|
},
|
|
234
223
|
primaryPath: () => {
|
|
235
|
-
if (
|
|
236
|
-
|
|
237
|
-
for (let
|
|
238
|
-
if (this.getLayerAlpha(
|
|
239
|
-
const
|
|
240
|
-
if (!(
|
|
241
|
-
|
|
242
|
-
x:
|
|
243
|
-
y: o.valueToBitmapYExact(
|
|
244
|
-
time:
|
|
224
|
+
if (n === void 0) {
|
|
225
|
+
n = null;
|
|
226
|
+
for (let a = 0; a < this.stores.length; a++) {
|
|
227
|
+
if (this.getLayerAlpha(a) <= 0 || !this.stores[a].isVisible()) continue;
|
|
228
|
+
const g = p(a).filter((A) => o.isPlottable(A.value));
|
|
229
|
+
if (!(g.length < 2)) {
|
|
230
|
+
n = g.map((A) => ({
|
|
231
|
+
x: e.timeToBitmapXExact(A.time),
|
|
232
|
+
y: o.valueToBitmapYExact(A.value),
|
|
233
|
+
time: A.time
|
|
245
234
|
}));
|
|
246
235
|
break;
|
|
247
236
|
}
|
|
248
237
|
}
|
|
249
238
|
}
|
|
250
|
-
return
|
|
239
|
+
return n;
|
|
251
240
|
}
|
|
252
241
|
};
|
|
253
242
|
}
|
|
@@ -257,51 +246,98 @@ class dt extends at {
|
|
|
257
246
|
* overlay pulse) already flows through `effectiveValue`, so one override
|
|
258
247
|
* animates the whole geometry.
|
|
259
248
|
*/
|
|
260
|
-
effectiveValue(t,
|
|
261
|
-
const s = super.effectiveValue(t,
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
249
|
+
effectiveValue(t, i, e, o) {
|
|
250
|
+
const s = super.effectiveValue(t, i, e, o);
|
|
251
|
+
return this.options.stacking === "percent" ? s : this.introValue(t, { layerIndex: i, time: e, value: s });
|
|
252
|
+
}
|
|
253
|
+
/** Layer's share of its column in percent, passed through the intro value transform. */
|
|
254
|
+
introShare(t, i) {
|
|
255
|
+
const { layerIndex: e, time: o, value: s, total: l } = i;
|
|
256
|
+
if (l <= 0) return s;
|
|
257
|
+
const r = s / l * 100;
|
|
258
|
+
return Math.max(0, this.introValue(t, { layerIndex: e, time: o, value: r }));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* What `layerMean` reports on a percent stack: each layer's mean share over
|
|
262
|
+
* the shared columns, alpha-weighted like the stacked pass, or `null` when it has none.
|
|
263
|
+
* A layer counts 0 where it has no sample yet, so the means sum to 100.
|
|
264
|
+
*/
|
|
265
|
+
meanShares(t, i) {
|
|
266
|
+
const e = this.stores.length, o = /* @__PURE__ */ new Set();
|
|
267
|
+
for (let h = 0; h < e; h++)
|
|
268
|
+
for (const m of t(h))
|
|
269
|
+
o.add(m.time);
|
|
270
|
+
const s = new Array(e).fill(0), l = new Array(e).fill(!1), r = new Array(e);
|
|
271
|
+
let f = 0;
|
|
272
|
+
for (const h of o) {
|
|
273
|
+
let m = 0;
|
|
274
|
+
for (let c = 0; c < e; c++) {
|
|
275
|
+
r[c] = null;
|
|
276
|
+
const x = this.getLayerAlpha(c), n = t(c);
|
|
277
|
+
if (x <= 0 || n.length === 0 || h < n[0].time) continue;
|
|
278
|
+
const p = j(n, h, { resolve: (a) => a.value });
|
|
279
|
+
p === null || !i.isPlottable(p) || (r[c] = p * x, m += p * x);
|
|
280
|
+
}
|
|
281
|
+
if (!(m <= 0)) {
|
|
282
|
+
f++;
|
|
283
|
+
for (let c = 0; c < e; c++) {
|
|
284
|
+
const x = r[c];
|
|
285
|
+
x !== null && (s[c] += x / m * 100, l[c] = !0);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return s.map((h, m) => l[m] ? h / f : null);
|
|
290
|
+
}
|
|
291
|
+
/** The active history-reveal or intro value transform applied to one value. */
|
|
292
|
+
introValue(t, i) {
|
|
293
|
+
const { layerIndex: e, time: o, value: s } = i, l = this.historyWave.active ? this.historyDirectives?.value : void 0, r = this.historyRange;
|
|
294
|
+
if (l !== void 0 && r !== null && o < r.to) {
|
|
295
|
+
const x = r.to - r.from, n = x > 0 ? Math.min(1, Math.max(0, (r.to - o) / x)) : 0;
|
|
296
|
+
return l({ layerIndex: e, time: o, value: s, position: n });
|
|
265
297
|
}
|
|
266
|
-
const
|
|
267
|
-
if (
|
|
268
|
-
const
|
|
269
|
-
return
|
|
298
|
+
const f = this.introWave.active ? this.introDirectives?.value : void 0;
|
|
299
|
+
if (f === void 0) return s;
|
|
300
|
+
const h = t.timeScale.getRange(), m = h.to - h.from, c = m > 0 ? Math.min(1, Math.max(0, (o - h.from) / m)) : 0;
|
|
301
|
+
return f({ layerIndex: e, time: o, value: s, position: c });
|
|
270
302
|
}
|
|
271
303
|
/**
|
|
272
304
|
* Extends the base last-value query with the 'grow' entrance's value-space
|
|
273
|
-
* equivalent of {@link chainedTailPositions}'s eased position lerp — the
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
* before the marker visually arrives there.
|
|
305
|
+
* equivalent of {@link chainedTailPositions}'s eased position lerp — the
|
|
306
|
+
* value lerps along the Y axis by the same eased progress, so mapping it
|
|
307
|
+
* through `yScale` lands on the identical pixel the renderer paints. Without
|
|
308
|
+
* this, a tooltip/YLabel query would report a freshly-appended point's raw
|
|
309
|
+
* value the instant it lands, `entryMs` before the marker visually arrives there.
|
|
279
310
|
*/
|
|
280
|
-
snapshotValue(t,
|
|
281
|
-
const o = super.snapshotValue(t,
|
|
282
|
-
return (this.options.entryAnimation ?? "grow") !== "grow" ? o : this.chainedTailValues(t)?.get(
|
|
311
|
+
snapshotValue(t, i, e) {
|
|
312
|
+
const o = super.snapshotValue(t, i, e);
|
|
313
|
+
return (this.options.entryAnimation ?? "grow") !== "grow" ? o : this.chainedTailValues(t)?.get(i) ?? o;
|
|
283
314
|
}
|
|
284
315
|
/**
|
|
285
316
|
* Value-space counterpart of {@link chainedTailPositions} — see {@link snapshotValue}.
|
|
286
317
|
* `resolve` lets the stacked renderer feed its ctx-aware `effectiveValue`
|
|
287
318
|
* in; query paths, which have no render context, keep the `liveValue` default.
|
|
288
319
|
*/
|
|
289
|
-
chainedTailValues(t,
|
|
290
|
-
const
|
|
291
|
-
if (
|
|
292
|
-
const o = this.stores[t].getAll(), s = o.length - 1 -
|
|
320
|
+
chainedTailValues(t, i = (e, o) => this.liveValue(t, e, o)) {
|
|
321
|
+
const e = this.unsettledTail(t);
|
|
322
|
+
if (e.length === 0) return null;
|
|
323
|
+
const o = this.stores[t].getAll(), s = o.length - 1 - e.length;
|
|
293
324
|
if (s < 0) return null;
|
|
294
|
-
const
|
|
295
|
-
if (!Number.isFinite(
|
|
296
|
-
let
|
|
297
|
-
const
|
|
298
|
-
for (let
|
|
299
|
-
const
|
|
300
|
-
if (!Number.isFinite(
|
|
301
|
-
const
|
|
302
|
-
|
|
325
|
+
const l = o[s];
|
|
326
|
+
if (!Number.isFinite(l.value)) return null;
|
|
327
|
+
let r = i(l.time, l.value);
|
|
328
|
+
const f = /* @__PURE__ */ new Map();
|
|
329
|
+
for (let h = 0; h < e.length; h++) {
|
|
330
|
+
const m = o[s + 1 + h];
|
|
331
|
+
if (!Number.isFinite(m.value)) return null;
|
|
332
|
+
const c = U(e[h].progress), x = i(m.time, m.value), n = this.axisLerp(r, x, c);
|
|
333
|
+
f.set(m.time, n), r = n;
|
|
303
334
|
}
|
|
304
|
-
return
|
|
335
|
+
return f;
|
|
336
|
+
}
|
|
337
|
+
/** `lerp` along the last rendered Y axis — plain before the first render. */
|
|
338
|
+
axisLerp(t, i, e) {
|
|
339
|
+
const o = this.lastYScale;
|
|
340
|
+
return o === null ? N(t, i, e) : o.lerpValue(t, i, e);
|
|
305
341
|
}
|
|
306
342
|
/**
|
|
307
343
|
* Glowing pulse dots riding the intro's head anchors — the line reads as
|
|
@@ -309,24 +345,24 @@ class dt extends at {
|
|
|
309
345
|
* the reveal lands. Off-mode only: recomputing the stacked cumulative at
|
|
310
346
|
* an arbitrary head time isn't worth it for a one-second decoration.
|
|
311
347
|
*/
|
|
312
|
-
drawIntroHeads(t,
|
|
348
|
+
drawIntroHeads(t, i, e) {
|
|
313
349
|
if (this.options.stacking !== "off") return;
|
|
314
|
-
const o = Math.min(1,
|
|
315
|
-
if (
|
|
316
|
-
const { scope:
|
|
317
|
-
for (const
|
|
318
|
-
for (let
|
|
319
|
-
const
|
|
320
|
-
if (
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
ctx:
|
|
324
|
-
x:
|
|
325
|
-
y:
|
|
326
|
-
color: this.resolveLayerColor(
|
|
327
|
-
pixelRatio:
|
|
328
|
-
phase:
|
|
329
|
-
alpha:
|
|
350
|
+
const o = Math.min(1, e / J), s = Math.min(1, (1 - e) / J), l = Math.max(0, Math.min(o, s));
|
|
351
|
+
if (l <= 0) return;
|
|
352
|
+
const { scope: r } = t;
|
|
353
|
+
for (const f of i)
|
|
354
|
+
for (let h = 0; h < this.stores.length; h++) {
|
|
355
|
+
const m = this.getLayerAlpha(h);
|
|
356
|
+
if (m <= 0 || !this.stores[h].isVisible()) continue;
|
|
357
|
+
const c = this.introHeadAnchor(t, h, f);
|
|
358
|
+
c !== null && this.drawPulse({
|
|
359
|
+
ctx: r.context,
|
|
360
|
+
x: c.x,
|
|
361
|
+
y: c.y,
|
|
362
|
+
color: this.resolveLayerColor(h, c.value),
|
|
363
|
+
pixelRatio: r.horizontalPixelRatio,
|
|
364
|
+
phase: e * 2,
|
|
365
|
+
alpha: l * m
|
|
330
366
|
});
|
|
331
367
|
}
|
|
332
368
|
}
|
|
@@ -341,27 +377,31 @@ class dt extends at {
|
|
|
341
377
|
* right-padding region beyond the line's end (the sweep front travels the
|
|
342
378
|
* visible range, not the data span) and jumps back on settle.
|
|
343
379
|
*/
|
|
344
|
-
introHeadAnchor(t,
|
|
345
|
-
const { timeScale: o, yScale: s } = t,
|
|
346
|
-
if (
|
|
347
|
-
const
|
|
348
|
-
if (
|
|
349
|
-
if (!
|
|
350
|
-
const
|
|
351
|
-
return
|
|
380
|
+
introHeadAnchor(t, i, e) {
|
|
381
|
+
const { timeScale: o, yScale: s } = t, l = o.getRange(), r = this.stores[i].getVisibleData(l.from, l.to);
|
|
382
|
+
if (r.length === 0) return null;
|
|
383
|
+
const f = this.stores[i].last();
|
|
384
|
+
if (f !== void 0 && e.time >= f.time) {
|
|
385
|
+
if (!s.isPlottable(f.value)) return null;
|
|
386
|
+
const c = this.trailingEndpoint(t, i);
|
|
387
|
+
return c === null ? null : { x: c.x, y: c.y, value: f.value };
|
|
352
388
|
}
|
|
353
|
-
const
|
|
354
|
-
if (
|
|
355
|
-
if (!
|
|
356
|
-
const
|
|
389
|
+
const h = r[0];
|
|
390
|
+
if (e.time <= h.time) {
|
|
391
|
+
if (!s.isPlottable(h.value)) return null;
|
|
392
|
+
const c = this.effectiveValue(t, i, h.time, h.value);
|
|
357
393
|
return {
|
|
358
|
-
x: o.timeToBitmapXExact(
|
|
359
|
-
y: s.valueToBitmapYExact(
|
|
360
|
-
value:
|
|
394
|
+
x: o.timeToBitmapXExact(h.time),
|
|
395
|
+
y: s.valueToBitmapYExact(c),
|
|
396
|
+
value: h.value
|
|
361
397
|
};
|
|
362
398
|
}
|
|
363
|
-
const
|
|
364
|
-
|
|
399
|
+
const m = j(r, e.time, {
|
|
400
|
+
resolve: (c) => this.effectiveValue(t, i, c.time, c.value),
|
|
401
|
+
// Along the axis, so the dot stays on the straight segment the stroke draws.
|
|
402
|
+
lerp: (c, x, n) => !s.isPlottable(c) || !s.isPlottable(x) ? Number.NaN : s.lerpValue(c, x, n)
|
|
403
|
+
});
|
|
404
|
+
return m === null || !s.isPlottable(m) ? null : { x: e.x, y: s.valueToBitmapYExact(m), value: m };
|
|
365
405
|
}
|
|
366
406
|
/**
|
|
367
407
|
* Rendered positions of the layer's still-unsettled trailing points, keyed
|
|
@@ -385,34 +425,52 @@ class dt extends at {
|
|
|
385
425
|
* lagging sibling shouldn't zero out the moment another layer ticks past
|
|
386
426
|
* it (see `renderStacked`'s `valueMaps` comment for the full rationale).
|
|
387
427
|
*/
|
|
388
|
-
stackedValueAt(t,
|
|
389
|
-
const o = this.options.stacking === "percent", s = (this.options.entryAnimation ?? "grow") === "grow",
|
|
428
|
+
stackedValueAt(t, i, e) {
|
|
429
|
+
const o = this.options.stacking === "percent", s = (this.options.entryAnimation ?? "grow") === "grow", l = new Array(this.stores.length), r = (n) => {
|
|
390
430
|
if (!s) return null;
|
|
391
|
-
const
|
|
392
|
-
if (
|
|
393
|
-
const
|
|
394
|
-
return n
|
|
395
|
-
},
|
|
396
|
-
const
|
|
397
|
-
if (
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
);
|
|
405
|
-
|
|
431
|
+
const p = l[n];
|
|
432
|
+
if (p !== void 0) return p;
|
|
433
|
+
const a = this.chainedTailValues(n, (g, A) => this.effectiveValue(t, n, g, A));
|
|
434
|
+
return l[n] = a, a;
|
|
435
|
+
}, f = (n) => {
|
|
436
|
+
const p = this.stores[n].getAll();
|
|
437
|
+
if (p.length === 0 || e < p[0].time) return null;
|
|
438
|
+
const a = r(n);
|
|
439
|
+
return j(p, e, {
|
|
440
|
+
resolve: (g) => a?.get(g.time) ?? this.effectiveValue(t, n, g.time, g.value)
|
|
441
|
+
});
|
|
442
|
+
}, { yScale: h } = t;
|
|
443
|
+
if (h.getTransform() !== null && !o) {
|
|
444
|
+
const n = new it(h);
|
|
445
|
+
for (let p = 0; p <= i; p++) {
|
|
446
|
+
const a = this.getLayerAlpha(p), g = a > 0 ? f(p) : null;
|
|
447
|
+
g !== null && h.isPlottable(g) && n.push(g, a);
|
|
448
|
+
}
|
|
449
|
+
return n.edge;
|
|
450
|
+
}
|
|
451
|
+
const m = (n) => {
|
|
452
|
+
const p = this.getLayerAlpha(n);
|
|
453
|
+
if (p <= 0) return null;
|
|
454
|
+
const a = this.stores[n].getAll();
|
|
455
|
+
if (o && a.length > 0 && e < a[0].time) return 0;
|
|
456
|
+
const g = f(n);
|
|
457
|
+
return g === null ? null : g * p;
|
|
406
458
|
};
|
|
407
|
-
let
|
|
459
|
+
let c = 0;
|
|
408
460
|
if (o)
|
|
409
|
-
for (let
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
p
|
|
461
|
+
for (let n = 0; n < this.stores.length; n++)
|
|
462
|
+
c += m(n) ?? 0;
|
|
463
|
+
let x = 0;
|
|
464
|
+
for (let n = 0; n <= i; n++) {
|
|
465
|
+
const p = m(n);
|
|
466
|
+
if (p !== null)
|
|
467
|
+
if (o) {
|
|
468
|
+
const a = this.introShare(t, { layerIndex: n, time: e, value: p, total: c });
|
|
469
|
+
x = Math.min(100, x + a);
|
|
470
|
+
} else
|
|
471
|
+
x += p;
|
|
414
472
|
}
|
|
415
|
-
return
|
|
473
|
+
return x;
|
|
416
474
|
}
|
|
417
475
|
/**
|
|
418
476
|
* Bitmap position for layer `li`'s stacked boundary at time `t`.
|
|
@@ -425,46 +483,46 @@ class dt extends at {
|
|
|
425
483
|
* feed. Falls back to the raw settled position off-column (decimated
|
|
426
484
|
* history, or before the first stacked frame).
|
|
427
485
|
*/
|
|
428
|
-
stackedPositionAt(t,
|
|
429
|
-
const o = this.paintedStackVertex(t,
|
|
486
|
+
stackedPositionAt(t, i, e) {
|
|
487
|
+
const o = this.paintedStackVertex(t, i, e);
|
|
430
488
|
if (o !== null) return o;
|
|
431
|
-
const { timeScale: s, yScale:
|
|
432
|
-
if ((this.options.entryAnimation ?? "grow") !== "grow" ||
|
|
433
|
-
let
|
|
434
|
-
for (let
|
|
435
|
-
|
|
436
|
-
return { x
|
|
489
|
+
const { timeScale: s, yScale: l } = t, r = l.valueToBitmapYExact(this.stackedValueAt(t, i, e)), f = s.timeToBitmapXExact(e), h = this.unsettledTail(i), m = this.stores[i].getAll(), c = m.length - 1 - h.length;
|
|
490
|
+
if ((this.options.entryAnimation ?? "grow") !== "grow" || e !== m[m.length - 1]?.time || h.length === 0 || c < 0) return { x: f, y: r };
|
|
491
|
+
let x = s.timeToBitmapXExact(m[c].time);
|
|
492
|
+
for (let n = 0; n < h.length; n++)
|
|
493
|
+
x = N(x, s.timeToBitmapXExact(m[c + 1 + n].time), U(h[n].progress));
|
|
494
|
+
return { x, y: r };
|
|
437
495
|
}
|
|
438
496
|
/** Upper-edge vertex of layer `li` at column `t`, replayed from the last
|
|
439
497
|
* stacked frame's data-space record against `ctx`'s scales. */
|
|
440
|
-
paintedStackVertex(t,
|
|
441
|
-
const o = this.stackedEdges, s = o?.cumulative[
|
|
498
|
+
paintedStackVertex(t, i, e) {
|
|
499
|
+
const o = this.stackedEdges, s = o?.cumulative[i];
|
|
442
500
|
if (o === null || s === void 0) return null;
|
|
443
|
-
const { times:
|
|
444
|
-
if (
|
|
445
|
-
const { timeScale:
|
|
446
|
-
if (
|
|
447
|
-
let
|
|
448
|
-
for (let
|
|
449
|
-
|
|
450
|
-
return { x:
|
|
451
|
-
}
|
|
452
|
-
chainedTailPositions(t,
|
|
453
|
-
const
|
|
454
|
-
if (
|
|
455
|
-
const o = this.stores[
|
|
501
|
+
const { times: l, growChain: r, collapse: f } = o, h = yt(l, e);
|
|
502
|
+
if (h < 0) return null;
|
|
503
|
+
const { timeScale: m, yScale: c } = t, x = t.scope.bitmapSize.height, n = f[i] ?? 1, p = c.valueToBitmapYExact(s[h]), a = n >= 1 ? p : x + (p - x) * n, g = l.length - r.length;
|
|
504
|
+
if (h < g) return { x: m.timeToBitmapXExact(e), y: a };
|
|
505
|
+
let A = m.timeToBitmapXExact(l[g - 1]);
|
|
506
|
+
for (let E = 0; E <= h - g; E++)
|
|
507
|
+
A = N(A, m.timeToBitmapXExact(l[g + E]), r[E]);
|
|
508
|
+
return { x: A, y: a };
|
|
509
|
+
}
|
|
510
|
+
chainedTailPositions(t, i) {
|
|
511
|
+
const e = this.unsettledTail(i);
|
|
512
|
+
if (e.length === 0) return null;
|
|
513
|
+
const o = this.stores[i].getAll(), s = o.length - 1 - e.length;
|
|
456
514
|
if (s < 0) return null;
|
|
457
|
-
const { timeScale:
|
|
458
|
-
if (!
|
|
459
|
-
let
|
|
460
|
-
const
|
|
461
|
-
for (let
|
|
462
|
-
const
|
|
463
|
-
if (!
|
|
464
|
-
const
|
|
465
|
-
|
|
515
|
+
const { timeScale: l, yScale: r } = t, f = o[s];
|
|
516
|
+
if (!r.isPlottable(f.value)) return null;
|
|
517
|
+
let h = l.timeToBitmapXExact(f.time), m = r.valueToBitmapYExact(this.effectiveValue(t, i, f.time, f.value));
|
|
518
|
+
const c = /* @__PURE__ */ new Map();
|
|
519
|
+
for (let x = 0; x < e.length; x++) {
|
|
520
|
+
const n = o[s + 1 + x];
|
|
521
|
+
if (!r.isPlottable(n.value)) return null;
|
|
522
|
+
const p = U(e[x].progress), a = l.timeToBitmapXExact(n.time), g = r.valueToBitmapYExact(this.effectiveValue(t, i, n.time, n.value)), A = N(h, a, p), E = N(m, g, p);
|
|
523
|
+
c.set(n.time, { x: A, y: E }), h = A, m = E;
|
|
466
524
|
}
|
|
467
|
-
return
|
|
525
|
+
return c;
|
|
468
526
|
}
|
|
469
527
|
/**
|
|
470
528
|
* Bitmap coordinates for the trailing endpoint of a layer — i.e. where the
|
|
@@ -476,11 +534,11 @@ class dt extends at {
|
|
|
476
534
|
* (pulse dot) so the pulse glides in sync with the trailing segment instead
|
|
477
535
|
* of teleporting to the raw last.time while the line still unfurls.
|
|
478
536
|
*/
|
|
479
|
-
trailingEndpoint(t,
|
|
480
|
-
const
|
|
481
|
-
if (!
|
|
482
|
-
const { timeScale: o, yScale: s } = t,
|
|
483
|
-
return (this.options.entryAnimation ?? "grow") !== "grow" ? { x:
|
|
537
|
+
trailingEndpoint(t, i) {
|
|
538
|
+
const e = this.stores[i].last();
|
|
539
|
+
if (!e) return null;
|
|
540
|
+
const { timeScale: o, yScale: s } = t, l = o.timeToBitmapXExact(e.time), r = s.valueToBitmapYExact(this.effectiveValue(t, i, e.time, e.value));
|
|
541
|
+
return (this.options.entryAnimation ?? "grow") !== "grow" ? { x: l, y: r } : this.chainedTailPositions(t, i)?.get(e.time) ?? { x: l, y: r };
|
|
484
542
|
}
|
|
485
543
|
/**
|
|
486
544
|
* Vertical stroke + area gradients for `options.threshold`, pinned to the
|
|
@@ -491,13 +549,13 @@ class dt extends at {
|
|
|
491
549
|
* the Y-axis autoscales (and during the spike's entrance), so a cache keyed on
|
|
492
550
|
* the row would miss almost every frame anyway.
|
|
493
551
|
*/
|
|
494
|
-
buildThresholdPaint(t,
|
|
495
|
-
const
|
|
496
|
-
if (!
|
|
497
|
-
const { scope: o, yScale: s } = t, { context:
|
|
498
|
-
|
|
499
|
-
const
|
|
500
|
-
return
|
|
552
|
+
buildThresholdPaint(t, i) {
|
|
553
|
+
const e = this.options.threshold;
|
|
554
|
+
if (!e) return null;
|
|
555
|
+
const { scope: o, yScale: s } = t, { context: l } = o, r = o.bitmapSize.height, f = e.above, h = e.below ?? i, m = Math.min(1, Math.max(0, s.valueToBitmapYExact(e.value) / r)), c = Math.min(6 * o.verticalPixelRatio, r * 0.02) / r, x = Math.max(0, m - c), n = Math.min(1, m + c), p = l.createLinearGradient(0, 0, 0, r);
|
|
556
|
+
p.addColorStop(0, f), p.addColorStop(x, f), p.addColorStop(n, h), p.addColorStop(1, h);
|
|
557
|
+
const a = l.createLinearGradient(0, 0, 0, r);
|
|
558
|
+
return a.addColorStop(0, X(f, 0.26)), a.addColorStop(x, X(f, 0.14)), a.addColorStop(n, X(h, 0.1)), a.addColorStop(1, X(h, 0.01)), { stroke: p, area: a };
|
|
501
559
|
}
|
|
502
560
|
/**
|
|
503
561
|
* Dot markers at each data point (`options.points`). Callers pass the same
|
|
@@ -508,226 +566,245 @@ class dt extends at {
|
|
|
508
566
|
* the stroke.
|
|
509
567
|
*/
|
|
510
568
|
drawPointMarkers(t) {
|
|
511
|
-
const
|
|
512
|
-
if (!
|
|
513
|
-
const { context:
|
|
569
|
+
const i = this.options.points;
|
|
570
|
+
if (!i?.visible) return;
|
|
571
|
+
const { context: e, points: o, pixelRatio: s, color: l } = t;
|
|
514
572
|
if (o.length === 0) return;
|
|
515
|
-
const
|
|
516
|
-
if (!(o.length > 1 && (o[o.length - 1].x - o[0].x) / (o.length - 1) <
|
|
517
|
-
|
|
518
|
-
for (const
|
|
519
|
-
|
|
520
|
-
|
|
573
|
+
const r = Math.max(1, (i.radius ?? 3) * s);
|
|
574
|
+
if (!(o.length > 1 && (o[o.length - 1].x - o[0].x) / (o.length - 1) < r * 3)) {
|
|
575
|
+
e.beginPath();
|
|
576
|
+
for (const f of o)
|
|
577
|
+
e.moveTo(f.x + r, f.y), e.arc(f.x, f.y, r, 0, Math.PI * 2);
|
|
578
|
+
e.fillStyle = i.color ?? l, e.fill();
|
|
521
579
|
}
|
|
522
580
|
}
|
|
523
581
|
/** Each layer drawn independently */
|
|
524
582
|
renderOff(t) {
|
|
525
|
-
const { scope:
|
|
583
|
+
const { scope: i, timeScale: e, yScale: o } = t, { context: s } = i, l = e.getRange(), { verticalPixelRatio: r } = i, f = this.options.strokeWidth > 0, h = Math.max(1, Math.round(this.options.strokeWidth * r)), m = this.options.entryAnimation ?? "grow", c = dt(this.options.linePainter ?? this.options.curve ?? "straight"), x = {
|
|
526
584
|
ctx: s,
|
|
527
585
|
theme: t.theme,
|
|
528
|
-
horizontalPixelRatio:
|
|
529
|
-
verticalPixelRatio:
|
|
586
|
+
horizontalPixelRatio: i.horizontalPixelRatio,
|
|
587
|
+
verticalPixelRatio: r
|
|
530
588
|
};
|
|
531
|
-
for (let
|
|
532
|
-
const
|
|
533
|
-
if (
|
|
534
|
-
let
|
|
535
|
-
const
|
|
536
|
-
if (
|
|
537
|
-
const
|
|
538
|
-
x:
|
|
539
|
-
y: o.valueToBitmapYExact(this.effectiveValue(t,
|
|
540
|
-
},
|
|
541
|
-
(
|
|
542
|
-
const
|
|
543
|
-
let
|
|
544
|
-
for (let
|
|
545
|
-
const
|
|
546
|
-
if (!
|
|
547
|
-
|
|
589
|
+
for (let n = 0; n < this.stores.length; n++) {
|
|
590
|
+
const p = this.getLayerAlpha(n);
|
|
591
|
+
if (p <= 0) continue;
|
|
592
|
+
let a = this.stores[n].getVisibleData(l.from, l.to);
|
|
593
|
+
const g = i.mediaSize.width;
|
|
594
|
+
if (a.length > g * 2 && (a = q(a, Math.round(g * 1.5))), a.length < 2) continue;
|
|
595
|
+
const A = this.stores[n].last()?.value ?? a[a.length - 1].value, E = this.resolveLayerColor(n, A), B = this.buildThresholdPaint(t, E), L = a[a.length - 1], D = this.stores[n].last(), Y = D !== void 0 && L.time === D.time, z = Y ? this.entranceProgress(n, L.time) : 1, I = Y && m === "fade" && z < 1, O = (Y ? this.trailingEndpoint(t, n) : null) ?? {
|
|
596
|
+
x: e.timeToBitmapXExact(L.time),
|
|
597
|
+
y: o.valueToBitmapYExact(this.effectiveValue(t, n, L.time, L.value))
|
|
598
|
+
}, W = O.x, C = O.y, _ = Y && m === "grow" ? this.chainedTailPositions(t, n) : null, G = p < 1;
|
|
599
|
+
(G || I) && (s.save(), G && (s.globalAlpha *= p), I && (s.globalAlpha *= z));
|
|
600
|
+
const $ = a.length - 1, u = [];
|
|
601
|
+
let v = null;
|
|
602
|
+
for (let d = 0; d < $; d++) {
|
|
603
|
+
const S = a[d].value;
|
|
604
|
+
if (!o.isPlottable(S)) {
|
|
605
|
+
v = null;
|
|
548
606
|
continue;
|
|
549
607
|
}
|
|
550
|
-
|
|
551
|
-
const
|
|
552
|
-
if (
|
|
553
|
-
|
|
608
|
+
v || (v = [], u.push(v));
|
|
609
|
+
const w = _?.get(a[d].time);
|
|
610
|
+
if (w)
|
|
611
|
+
v.push({ x: w.x, y: w.y });
|
|
554
612
|
else {
|
|
555
|
-
const
|
|
556
|
-
|
|
613
|
+
const F = o.valueToBitmapYExact(this.effectiveValue(t, n, a[d].time, S));
|
|
614
|
+
v.push({ x: e.timeToBitmapXExact(a[d].time), y: F });
|
|
557
615
|
}
|
|
558
616
|
}
|
|
559
|
-
const
|
|
560
|
-
let
|
|
561
|
-
if (
|
|
617
|
+
const M = a[$]?.value, b = Number.isFinite(W) && Number.isFinite(C) && o.isPlottable(M), P = m === "grow" && z < 1;
|
|
618
|
+
let T = null;
|
|
619
|
+
if (b && (v ? (v.push({ x: W, y: C }), T = v) : u.push([{ x: W, y: C }])), f && u.some((d) => d.length >= 2)) {
|
|
562
620
|
s.beginPath();
|
|
563
|
-
for (const
|
|
564
|
-
|
|
565
|
-
s.strokeStyle =
|
|
621
|
+
for (const d of u)
|
|
622
|
+
d.length < 2 || c(x, { points: d, color: E, lineWidth: h, closing: !1, grew: P && d === T });
|
|
623
|
+
s.strokeStyle = B ? B.stroke : E, s.lineWidth = h, s.lineJoin = "round", s.lineCap = "round", s.stroke();
|
|
566
624
|
}
|
|
567
|
-
if (
|
|
568
|
-
const
|
|
569
|
-
let
|
|
570
|
-
for (const
|
|
571
|
-
|
|
572
|
-
|
|
625
|
+
if (f) {
|
|
626
|
+
const d = Math.max(1, h / 2);
|
|
627
|
+
let S = !1;
|
|
628
|
+
for (const w of u)
|
|
629
|
+
w.length === 1 && (S || (s.beginPath(), S = !0), s.moveTo(w[0].x + d, w[0].y), s.arc(w[0].x, w[0].y, d, 0, Math.PI * 2));
|
|
630
|
+
S && (s.fillStyle = E, s.fill());
|
|
573
631
|
}
|
|
574
632
|
if (this.options.area.visible && !this.introGhostPass) {
|
|
575
|
-
const
|
|
576
|
-
let
|
|
577
|
-
if (
|
|
578
|
-
|
|
633
|
+
const d = i.bitmapSize.height;
|
|
634
|
+
let S;
|
|
635
|
+
if (B)
|
|
636
|
+
S = B.area;
|
|
579
637
|
else {
|
|
580
|
-
const
|
|
581
|
-
|
|
638
|
+
const w = String(n), F = this.areaGradientCache.get(w);
|
|
639
|
+
F && F.bottomY === d && F.color === E ? S = F.gradient : (S = s.createLinearGradient(0, 0, 0, d), S.addColorStop(0, X(E, 0.12)), S.addColorStop(1, X(E, 0.01)), this.areaGradientCache.set(w, { gradient: S, bottomY: d, color: E }));
|
|
582
640
|
}
|
|
583
|
-
s.fillStyle =
|
|
584
|
-
for (const
|
|
585
|
-
|
|
641
|
+
s.fillStyle = S;
|
|
642
|
+
for (const w of u)
|
|
643
|
+
w.length < 2 || (s.beginPath(), c(x, { points: w, color: E, lineWidth: h, closing: !0, grew: P && w === T }), s.lineTo(w[w.length - 1].x, d), s.lineTo(w[0].x, d), s.closePath(), s.fill());
|
|
586
644
|
}
|
|
587
645
|
if (this.options.points?.visible) {
|
|
588
|
-
const
|
|
589
|
-
for (const
|
|
590
|
-
for (const
|
|
591
|
-
this.drawPointMarkers({ context: s, points:
|
|
646
|
+
const d = [];
|
|
647
|
+
for (const S of u)
|
|
648
|
+
for (const w of S) d.push(w);
|
|
649
|
+
this.drawPointMarkers({ context: s, points: d, pixelRatio: i.horizontalPixelRatio, color: E });
|
|
592
650
|
}
|
|
593
|
-
(I ||
|
|
651
|
+
(I || G) && s.restore();
|
|
594
652
|
}
|
|
595
653
|
}
|
|
596
654
|
/** Stacked area rendering */
|
|
597
|
-
renderStacked(t,
|
|
598
|
-
const { scope:
|
|
655
|
+
renderStacked(t, i) {
|
|
656
|
+
const { scope: e, timeScale: o, yScale: s } = t, { context: l } = e, r = o.getRange(), { verticalPixelRatio: f } = e, h = this.options.strokeWidth > 0, m = Math.max(1, Math.round(this.options.strokeWidth * f)), c = this.options.curve ?? "straight", x = e.mediaSize.width, n = this.stores.map((u, v) => {
|
|
599
657
|
if (this.getLayerAlpha(v) <= 0) return [];
|
|
600
|
-
let
|
|
601
|
-
return
|
|
602
|
-
}),
|
|
603
|
-
for (const
|
|
604
|
-
for (const v of
|
|
605
|
-
const
|
|
606
|
-
if (
|
|
658
|
+
let M = u.getVisibleData(r.from, r.to);
|
|
659
|
+
return M.length > x * 2 && (M = q(M, Math.round(x * 1.5))), M;
|
|
660
|
+
}), p = /* @__PURE__ */ new Set();
|
|
661
|
+
for (const u of n)
|
|
662
|
+
for (const v of u) p.add(v.time);
|
|
663
|
+
const a = Array.from(p).sort((u, v) => u - v);
|
|
664
|
+
if (a.length < 2) {
|
|
607
665
|
this.stackedEdges = null;
|
|
608
666
|
return;
|
|
609
667
|
}
|
|
610
|
-
const
|
|
611
|
-
const
|
|
612
|
-
if (
|
|
613
|
-
const
|
|
614
|
-
for (const
|
|
615
|
-
if (
|
|
616
|
-
const
|
|
617
|
-
|
|
668
|
+
const g = this.options.entryAnimation ?? "grow", A = n.map((u, v) => {
|
|
669
|
+
const M = /* @__PURE__ */ new Map();
|
|
670
|
+
if (u.length === 0) return M;
|
|
671
|
+
const b = u[0].time, P = g === "grow" ? this.chainedTailValues(v, (d, S) => this.effectiveValue(t, v, d, S)) : null, T = (d) => P?.get(d.time) ?? this.effectiveValue(t, v, d.time, d.value);
|
|
672
|
+
for (const d of a) {
|
|
673
|
+
if (d < b) continue;
|
|
674
|
+
const S = j(u, d, { resolve: T });
|
|
675
|
+
S !== null && M.set(d, S);
|
|
618
676
|
}
|
|
619
|
-
return
|
|
620
|
-
}),
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
677
|
+
return M;
|
|
678
|
+
}), E = this.stores.map((u, v) => this.getLayerAlpha(v)), B = (u, v) => {
|
|
679
|
+
const M = A[u].get(v);
|
|
680
|
+
return M === void 0 ? void 0 : M * E[u];
|
|
681
|
+
}, L = s.getTransform() !== null && !i, D = Array.from({ length: this.stores.length }, () => new Array(a.length).fill(0));
|
|
682
|
+
for (let u = 0; u < a.length; u++) {
|
|
683
|
+
const v = a[u];
|
|
684
|
+
if (L) {
|
|
685
|
+
const P = new it(s);
|
|
686
|
+
for (let T = 0; T < this.stores.length; T++) {
|
|
687
|
+
const d = A[T].get(v);
|
|
688
|
+
d !== void 0 && s.isPlottable(d) && P.push(d, E[T]), D[T][u] = P.edge;
|
|
628
689
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
let M = 0;
|
|
693
|
+
if (i)
|
|
694
|
+
for (let P = 0; P < this.stores.length; P++) {
|
|
695
|
+
const T = B(P, v);
|
|
696
|
+
T !== void 0 && s.isPlottable(T) && (M += T);
|
|
697
|
+
}
|
|
698
|
+
let b = 0;
|
|
699
|
+
for (let P = 0; P < this.stores.length; P++) {
|
|
700
|
+
const T = B(P, v);
|
|
701
|
+
let d = T !== void 0 && s.isPlottable(T) ? T : null;
|
|
702
|
+
const S = n[P];
|
|
703
|
+
if (i && S.length > 0 && v < S[0].time && (d = 0), d !== null)
|
|
704
|
+
if (i) {
|
|
705
|
+
const w = this.introShare(t, { layerIndex: P, time: v, value: d, total: M });
|
|
706
|
+
b = Math.min(100, b + w);
|
|
707
|
+
} else
|
|
708
|
+
b += d;
|
|
709
|
+
D[P][u] = b;
|
|
633
710
|
}
|
|
634
711
|
}
|
|
635
|
-
const
|
|
636
|
-
for (let
|
|
637
|
-
const
|
|
638
|
-
for (let
|
|
639
|
-
if (this.getLayerAlpha(
|
|
640
|
-
const v = this.unsettledTail(
|
|
641
|
-
if (
|
|
642
|
-
let
|
|
643
|
-
for (let
|
|
644
|
-
if (
|
|
645
|
-
|
|
712
|
+
const Y = /* @__PURE__ */ new Map();
|
|
713
|
+
for (let u = 0; u < a.length; u++) Y.set(a[u], u);
|
|
714
|
+
const z = new Array(this.stores.length).fill(1);
|
|
715
|
+
for (let u = 0; u < this.stores.length; u++) {
|
|
716
|
+
if (this.getLayerAlpha(u) <= 0) continue;
|
|
717
|
+
const v = this.unsettledTail(u), M = v.length;
|
|
718
|
+
if (M === 0) continue;
|
|
719
|
+
let b = !0;
|
|
720
|
+
for (let P = 0; P < M; P++)
|
|
721
|
+
if (Y.get(v[P].time) !== a.length - M + P) {
|
|
722
|
+
b = !1;
|
|
646
723
|
break;
|
|
647
724
|
}
|
|
648
|
-
|
|
725
|
+
b && (z[u] = v[M - 1].progress);
|
|
649
726
|
}
|
|
650
|
-
const
|
|
651
|
-
if (
|
|
652
|
-
const
|
|
653
|
-
for (let v =
|
|
654
|
-
const
|
|
655
|
-
let
|
|
656
|
-
for (let
|
|
657
|
-
if (this.getLayerAlpha(
|
|
658
|
-
const
|
|
659
|
-
for (;
|
|
660
|
-
if (
|
|
661
|
-
const
|
|
662
|
-
(!
|
|
727
|
+
const I = [];
|
|
728
|
+
if (g === "grow") {
|
|
729
|
+
const u = n.map((v) => v.length - 1);
|
|
730
|
+
for (let v = a.length - 1; v >= 1; v--) {
|
|
731
|
+
const M = a[v];
|
|
732
|
+
let b = 1, P = !1;
|
|
733
|
+
for (let T = 0; T < n.length; T++) {
|
|
734
|
+
if (this.getLayerAlpha(T) <= 0) continue;
|
|
735
|
+
const d = n[T];
|
|
736
|
+
for (; u[T] >= 0 && d[u[T]].time > M; ) u[T]--;
|
|
737
|
+
if (u[T] < 0 || d[u[T]].time !== M) continue;
|
|
738
|
+
const S = this.entranceProgress(T, M);
|
|
739
|
+
(!P || S > b) && (b = S), P = !0;
|
|
663
740
|
}
|
|
664
|
-
if (!
|
|
665
|
-
|
|
741
|
+
if (!P || b >= 1) break;
|
|
742
|
+
I.unshift(U(b));
|
|
666
743
|
}
|
|
667
744
|
}
|
|
668
|
-
const
|
|
669
|
-
const
|
|
670
|
-
if (!(
|
|
671
|
-
for (let
|
|
672
|
-
const
|
|
673
|
-
|
|
745
|
+
const O = (u, v) => {
|
|
746
|
+
const M = v.length;
|
|
747
|
+
if (!(M === 0 || u.length < M + 1))
|
|
748
|
+
for (let b = 0; b < M; b++) {
|
|
749
|
+
const P = u.length - M + b;
|
|
750
|
+
u[P][0] = N(u[P - 1][0], u[P][0], v[b]);
|
|
674
751
|
}
|
|
675
|
-
},
|
|
676
|
-
let
|
|
677
|
-
for (let
|
|
678
|
-
if (!(this.getLayerAlpha(
|
|
679
|
-
if (
|
|
680
|
-
|
|
752
|
+
}, W = e.bitmapSize.height;
|
|
753
|
+
let C = -1, _ = -1;
|
|
754
|
+
for (let u = 0; u < this.stores.length; u++)
|
|
755
|
+
if (!(this.getLayerAlpha(u) <= 0))
|
|
756
|
+
if (C < 0)
|
|
757
|
+
C = u;
|
|
681
758
|
else {
|
|
682
|
-
|
|
759
|
+
_ = u;
|
|
683
760
|
break;
|
|
684
761
|
}
|
|
685
|
-
const
|
|
686
|
-
for (let
|
|
687
|
-
const v = this.getLayerAlpha(
|
|
762
|
+
const G = C >= 0 ? this.getLayerAlpha(C) : 1, $ = n.map((u, v) => v === C ? Math.min(1, this.getLayerAlpha(v)) : 1);
|
|
763
|
+
for (let u = this.stores.length - 1; u >= 0; u--) {
|
|
764
|
+
const v = this.getLayerAlpha(u);
|
|
688
765
|
if (v <= 0) continue;
|
|
689
|
-
const
|
|
690
|
-
for (let
|
|
691
|
-
const
|
|
692
|
-
let
|
|
693
|
-
|
|
766
|
+
const M = this.stores[u].last()?.value ?? 0, b = this.resolveLayerColor(u, M), P = u === C, T = _ >= 0 && u === _ && G < 1, d = [];
|
|
767
|
+
for (let R = 0; R < a.length; R++) {
|
|
768
|
+
const V = u > 0 ? s.valueToBitmapYExact(D[u - 1][R]) : W;
|
|
769
|
+
let H = V;
|
|
770
|
+
P ? H = W : T && (H = V + (W - V) * (1 - G)), d.push([o.timeToBitmapXExact(a[R]), H]);
|
|
694
771
|
}
|
|
695
|
-
|
|
696
|
-
const
|
|
697
|
-
for (let
|
|
698
|
-
let
|
|
699
|
-
|
|
772
|
+
g === "grow" && O(d, I);
|
|
773
|
+
const S = [];
|
|
774
|
+
for (let R = 0; R < a.length; R++) {
|
|
775
|
+
let V = s.valueToBitmapYExact(D[u][R]);
|
|
776
|
+
P && v < 1 && (V = W + (V - W) * v), S.push([o.timeToBitmapXExact(a[R]), V]);
|
|
700
777
|
}
|
|
701
|
-
|
|
702
|
-
const
|
|
703
|
-
if (
|
|
704
|
-
let
|
|
705
|
-
for (let
|
|
706
|
-
|
|
707
|
-
for (let
|
|
708
|
-
|
|
709
|
-
let
|
|
710
|
-
if (
|
|
711
|
-
const
|
|
712
|
-
|
|
778
|
+
g === "grow" && O(S, I);
|
|
779
|
+
const w = st(S), F = tt(w, c, g === "grow" && I.length > 0), K = g === "fade" && z[u] < 1;
|
|
780
|
+
if (K && (l.save(), l.globalAlpha *= z[u]), this.options.area.visible && !this.introGhostPass) {
|
|
781
|
+
let R = S[0][1], V = d[0][1];
|
|
782
|
+
for (let k = 1; k < S.length; k++)
|
|
783
|
+
S[k][1] < R && (R = S[k][1]);
|
|
784
|
+
for (let k = 1; k < d.length; k++)
|
|
785
|
+
d[k][1] > V && (V = d[k][1]);
|
|
786
|
+
let H = X(b, 0.25);
|
|
787
|
+
if (V > R + 0.5) {
|
|
788
|
+
const k = l.createLinearGradient(0, R, 0, V);
|
|
789
|
+
k.addColorStop(0, X(b, 0.25)), k.addColorStop(1, X(b, 0.05)), H = k;
|
|
713
790
|
}
|
|
714
|
-
if (
|
|
715
|
-
for (let
|
|
716
|
-
|
|
791
|
+
if (l.beginPath(), l.moveTo(w[0].x, w[0].y), et(l, F), P)
|
|
792
|
+
for (let k = d.length - 1; k >= 0; k--)
|
|
793
|
+
l.lineTo(d[k][0], d[k][1]);
|
|
717
794
|
else {
|
|
718
|
-
const
|
|
719
|
-
|
|
795
|
+
const k = st(d), ct = tt(k, c, g === "grow" && I.length > 0), Z = k[k.length - 1];
|
|
796
|
+
l.lineTo(Z.x, Z.y), gt(l, k, ct);
|
|
720
797
|
}
|
|
721
|
-
|
|
798
|
+
l.closePath(), l.fillStyle = H, l.fill();
|
|
722
799
|
}
|
|
723
|
-
const
|
|
724
|
-
if (
|
|
725
|
-
const
|
|
726
|
-
|
|
800
|
+
const Q = h && v < 1;
|
|
801
|
+
if (Q && (l.save(), l.globalAlpha *= v), h && (l.beginPath(), l.moveTo(w[0].x, w[0].y), et(l, F), l.strokeStyle = b, l.lineWidth = m, l.lineJoin = "round", l.lineCap = "round", l.stroke()), Q && l.restore(), this.options.points?.visible) {
|
|
802
|
+
const R = v < 1;
|
|
803
|
+
R && (l.save(), l.globalAlpha *= v), this.drawPointMarkers({ context: l, points: w, pixelRatio: e.horizontalPixelRatio, color: b }), R && l.restore();
|
|
727
804
|
}
|
|
728
|
-
|
|
805
|
+
K && l.restore();
|
|
729
806
|
}
|
|
730
|
-
this.stackedEdges = { times:
|
|
807
|
+
this.stackedEdges = { times: a, cumulative: D, growChain: I, collapse: $ };
|
|
731
808
|
}
|
|
732
809
|
/**
|
|
733
810
|
* Overlay hook: draws crosshair nearest-point dots and last-point pulse dots.
|
|
@@ -735,80 +812,81 @@ class dt extends at {
|
|
|
735
812
|
*/
|
|
736
813
|
drawOverlay(t) {
|
|
737
814
|
this.tickAnimations(performance.now());
|
|
738
|
-
const { scope:
|
|
815
|
+
const { scope: i, timeScale: e, yScale: o, crosshair: s, dataInterval: l } = t, r = i, f = this.options.pulseMs, h = f > 0 ? performance.now() / (f * 2 * Math.PI) % 1 : 0;
|
|
739
816
|
if (s) {
|
|
740
|
-
const
|
|
741
|
-
for (let
|
|
742
|
-
const
|
|
743
|
-
if (
|
|
744
|
-
const
|
|
745
|
-
if (!
|
|
746
|
-
const
|
|
747
|
-
x:
|
|
748
|
-
y: o.valueToBitmapYExact(this.effectiveValue(t,
|
|
749
|
-
} : this.stackedPositionAt(t,
|
|
750
|
-
|
|
817
|
+
const x = this.options.stacking, n = 4 * r.horizontalPixelRatio;
|
|
818
|
+
for (let p = 0; p < this.stores.length; p++) {
|
|
819
|
+
const a = this.getLayerAlpha(p);
|
|
820
|
+
if (a <= 0) continue;
|
|
821
|
+
const g = this.stores[p].findNearest(s.time, l);
|
|
822
|
+
if (!g || x === "off" && !o.isPlottable(g.value)) continue;
|
|
823
|
+
const A = this.resolveLayerColor(p, g.value), { x: E, y: B } = x === "off" ? {
|
|
824
|
+
x: e.timeToBitmapXExact(g.time),
|
|
825
|
+
y: o.valueToBitmapYExact(this.effectiveValue(t, p, g.time, g.value))
|
|
826
|
+
} : this.stackedPositionAt(t, p, g.time), L = a < 1;
|
|
827
|
+
L && (i.context.save(), i.context.globalAlpha *= a), i.context.save(), i.context.globalAlpha *= 0.25, i.context.beginPath(), i.context.arc(E, B, n + 3 * r.horizontalPixelRatio, 0, Math.PI * 2), i.context.fillStyle = A, i.context.fill(), i.context.restore(), i.context.beginPath(), i.context.arc(E, B, n, 0, Math.PI * 2), i.context.fillStyle = A, i.context.fill(), L && i.context.restore();
|
|
751
828
|
}
|
|
752
829
|
}
|
|
753
|
-
const
|
|
754
|
-
let
|
|
755
|
-
if (
|
|
756
|
-
const
|
|
757
|
-
for (let
|
|
758
|
-
const
|
|
759
|
-
if (
|
|
760
|
-
const
|
|
761
|
-
if (
|
|
762
|
-
|
|
763
|
-
|
|
830
|
+
const m = this.introWave.active && this.introDirectives?.clip !== void 0;
|
|
831
|
+
let c = 1;
|
|
832
|
+
if (m && (c = Math.max(0, (this.introWave.linear() - (1 - J)) / J)), this.hasPulse && f > 0 && c > 0) {
|
|
833
|
+
const x = this.options.stacking;
|
|
834
|
+
for (let n = 0; n < this.stores.length; n++) {
|
|
835
|
+
const p = this.getLayerAlpha(n);
|
|
836
|
+
if (p <= 0) continue;
|
|
837
|
+
const a = this.stores[n].last()?.value ?? 0, g = this.resolveLayerColor(n, a);
|
|
838
|
+
if (x === "off") {
|
|
839
|
+
if (!o.isPlottable(a)) continue;
|
|
840
|
+
const L = this.trailingEndpoint(t, n);
|
|
841
|
+
if (!L) continue;
|
|
764
842
|
this.drawPulse({
|
|
765
|
-
ctx:
|
|
766
|
-
x:
|
|
767
|
-
y:
|
|
768
|
-
color:
|
|
769
|
-
pixelRatio:
|
|
770
|
-
phase:
|
|
771
|
-
alpha:
|
|
843
|
+
ctx: i.context,
|
|
844
|
+
x: L.x,
|
|
845
|
+
y: L.y,
|
|
846
|
+
color: g,
|
|
847
|
+
pixelRatio: r.horizontalPixelRatio,
|
|
848
|
+
phase: h,
|
|
849
|
+
alpha: p * c
|
|
772
850
|
});
|
|
773
851
|
continue;
|
|
774
852
|
}
|
|
775
|
-
const
|
|
776
|
-
if (!
|
|
777
|
-
const { x:
|
|
853
|
+
const A = this.stores[n].last();
|
|
854
|
+
if (!A) continue;
|
|
855
|
+
const { x: E, y: B } = this.stackedPositionAt(t, n, A.time);
|
|
778
856
|
this.drawPulse({
|
|
779
|
-
ctx:
|
|
780
|
-
x:
|
|
781
|
-
y:
|
|
782
|
-
color:
|
|
783
|
-
pixelRatio:
|
|
784
|
-
phase:
|
|
785
|
-
alpha:
|
|
857
|
+
ctx: i.context,
|
|
858
|
+
x: E,
|
|
859
|
+
y: B,
|
|
860
|
+
color: g,
|
|
861
|
+
pixelRatio: r.horizontalPixelRatio,
|
|
862
|
+
phase: h,
|
|
863
|
+
alpha: p * c
|
|
786
864
|
});
|
|
787
865
|
}
|
|
788
866
|
}
|
|
789
867
|
}
|
|
790
868
|
drawPulse({
|
|
791
869
|
ctx: t,
|
|
792
|
-
x:
|
|
793
|
-
y:
|
|
870
|
+
x: i,
|
|
871
|
+
y: e,
|
|
794
872
|
color: o,
|
|
795
873
|
pixelRatio: s,
|
|
796
|
-
phase:
|
|
797
|
-
alpha:
|
|
874
|
+
phase: l,
|
|
875
|
+
alpha: r = 1
|
|
798
876
|
}) {
|
|
799
|
-
const
|
|
800
|
-
|
|
877
|
+
const f = 3 * s, h = 0.4 + 0.6 * Math.abs(Math.sin(l * 2 * Math.PI)), m = f + 4 * s * h, c = r < 1;
|
|
878
|
+
c && (t.save(), t.globalAlpha *= r), t.beginPath(), t.arc(i, e, m, 0, Math.PI * 2), t.fillStyle = X(o, h * 0.3), t.fill(), t.beginPath(), t.arc(i, e, f, 0, Math.PI * 2), t.fillStyle = o, t.fill(), c && t.restore();
|
|
801
879
|
}
|
|
802
880
|
}
|
|
803
|
-
const
|
|
881
|
+
const Bt = {
|
|
804
882
|
type: "line",
|
|
805
|
-
create: ({ theme:
|
|
806
|
-
colors: t === 1 ? [
|
|
807
|
-
strokeWidth:
|
|
808
|
-
...
|
|
883
|
+
create: ({ theme: y, layerCount: t }, i) => new Pt(t, {
|
|
884
|
+
colors: t === 1 ? [y.line.color] : y.seriesColors.slice(0, t),
|
|
885
|
+
strokeWidth: y.line.width,
|
|
886
|
+
...i
|
|
809
887
|
})
|
|
810
888
|
};
|
|
811
889
|
export {
|
|
812
|
-
|
|
813
|
-
|
|
890
|
+
Pt as LineRenderer,
|
|
891
|
+
Bt as LineSeriesDef
|
|
814
892
|
};
|