@wick-charts/vue 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/dist/BarSeries.vue.js +26 -20
- package/dist/CandlestickSeries.vue.js +30 -24
- package/dist/ChartContainer.vue.js +88 -65
- package/dist/HeatmapSeries.vue.js +40 -0
- package/dist/HeatmapSeries.vue2.js +4 -0
- package/dist/LineSeries.vue.js +26 -20
- package/dist/PieSeries.vue.js +24 -18
- package/dist/core/dist/animation/animator.js +21 -21
- package/dist/core/dist/animation/config.js +114 -87
- package/dist/core/dist/animation/easing.js +3 -1
- package/dist/core/dist/animation/intro-wave.js +68 -0
- package/dist/core/dist/axis/dom-labels.js +13 -14
- package/dist/core/dist/chart/badge-animator.js +56 -0
- package/dist/core/dist/chart/edge-indicators.js +28 -13
- package/dist/core/dist/chart/last-value.js +18 -17
- package/dist/core/dist/chart/y-target.js +13 -12
- package/dist/core/dist/chart.js +908 -626
- package/dist/core/dist/components/annotation-chip.js +28 -0
- package/dist/core/dist/components/edge-indicator.js +58 -26
- package/dist/core/dist/components/loading-indicator.js +46 -0
- package/dist/core/dist/components/marker.js +49 -31
- package/dist/core/dist/components/reference-line.js +27 -36
- package/dist/core/dist/components/time-region.js +30 -28
- package/dist/core/dist/data/store.js +38 -19
- package/dist/core/dist/data/sync.js +60 -38
- package/dist/core/dist/heatmap-tooltip.js +16 -0
- package/dist/core/dist/interactions/handler.js +67 -43
- package/dist/core/dist/perf/perf-hud.js +2 -2
- package/dist/core/dist/scales/x-scale.js +85 -37
- package/dist/core/dist/scales/y-scale.js +38 -27
- package/dist/core/dist/series/bar-intro.js +18 -0
- package/dist/core/dist/series/bar.js +337 -205
- package/dist/core/dist/series/base-multi-layer.js +224 -96
- package/dist/core/dist/series/candlestick-intro.js +57 -0
- package/dist/core/dist/series/candlestick.js +454 -276
- package/dist/core/dist/series/heatmap.js +387 -0
- package/dist/core/dist/series/line-intro.js +85 -0
- package/dist/core/dist/series/line.js +590 -282
- package/dist/core/dist/series/painters/builtins.js +2 -2
- package/dist/core/dist/series/pie.js +396 -259
- package/dist/core/dist/series/register-builtins.js +8 -7
- package/dist/core/dist/series/types.js +6 -0
- package/dist/core/dist/series/wave-intro.js +26 -0
- package/dist/core/dist/theme/create.js +69 -63
- package/dist/core/dist/theme/themes/mint-breeze.js +2 -2
- package/dist/core/dist/theme/themes/sand-dune.js +2 -2
- package/dist/core/dist/utils/color.js +109 -34
- package/dist/core/dist/utils/deep-equal.js +18 -0
- package/dist/core/dist/utils/time.js +25 -19
- package/dist/index.d.ts +1411 -122
- package/dist/index.js +177 -130
- package/dist/ui/Crosshair.vue.js +20 -21
- package/dist/ui/HeatmapTooltip.vue.js +96 -0
- package/dist/ui/HeatmapTooltip.vue2.js +4 -0
- package/dist/ui/InfoBar.vue.js +46 -47
- package/dist/ui/Legend.vue.js +80 -79
- package/dist/ui/PieLegend.vue.js +5 -5
- package/dist/ui/PieTooltip.vue.js +77 -67
- package/dist/ui/Tooltip.vue.js +60 -60
- package/dist/ui/YAxis.vue.js +2 -2
- package/dist/ui/YLabel.vue.js +94 -61
- package/package.json +2 -2
- package/src/BarSeries.vue +23 -7
- package/src/CandlestickSeries.vue +23 -7
- package/src/ChartContainer.vue +134 -12
- package/src/HeatmapSeries.vue +69 -0
- package/src/LineSeries.vue +23 -7
- package/src/PieSeries.vue +22 -6
- package/src/index.ts +84 -3
- package/src/ui/Crosshair.vue +1 -2
- package/src/ui/HeatmapTooltip.vue +144 -0
- package/src/ui/InfoBar.vue +1 -2
- package/src/ui/Legend.vue +13 -0
- package/src/ui/Marker.vue +1 -1
- package/src/ui/PieTooltip.vue +10 -0
- package/src/ui/ReferenceLine.vue +2 -2
- package/src/ui/TimeRegion.vue +2 -2
- package/src/ui/Tooltip.vue +2 -2
- package/src/ui/YLabel.vue +123 -8
|
@@ -1,80 +1,172 @@
|
|
|
1
|
-
import { DEFAULT_BAR_SMOOTH as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { DEFAULT_HISTORY_REVEAL as _, DEFAULT_BAR_INTRO as C, DEFAULT_BAR_SMOOTH as F, DEFAULT_BAR_ENTRY as N } from "../animation/config.js";
|
|
2
|
+
import { growIntro as Q } from "./bar-intro.js";
|
|
3
|
+
import { BaseMultiLayerSeries as $ } from "./base-multi-layer.js";
|
|
4
|
+
import { resolveBarPainter as Z } from "./painters/resolve.js";
|
|
5
|
+
import { fadeIntro as q } from "./wave-intro.js";
|
|
6
|
+
const U = 2, G = {
|
|
5
7
|
// Single fallback resolver; the definition's `create` swaps in `theme.bar.color`.
|
|
6
8
|
colors: ["#26a69a"],
|
|
7
9
|
barWidthRatio: 0.6,
|
|
8
10
|
stacking: "off",
|
|
9
11
|
anchor: "center",
|
|
10
|
-
cornerRadius:
|
|
11
|
-
entryMs:
|
|
12
|
-
smoothMs:
|
|
12
|
+
cornerRadius: U,
|
|
13
|
+
entryMs: N,
|
|
14
|
+
smoothMs: F,
|
|
15
|
+
introMs: C,
|
|
16
|
+
historyRevealMs: _
|
|
13
17
|
};
|
|
14
|
-
function
|
|
18
|
+
function I(y) {
|
|
15
19
|
return {
|
|
16
|
-
...
|
|
17
|
-
entryMs:
|
|
18
|
-
smoothMs:
|
|
20
|
+
...y,
|
|
21
|
+
entryMs: y.entryMs === !1 ? 0 : y.entryMs ?? N,
|
|
22
|
+
smoothMs: y.smoothMs === !1 ? 0 : y.smoothMs ?? F,
|
|
23
|
+
introMs: y.introMs === !1 ? 0 : y.introMs ?? C,
|
|
24
|
+
historyRevealMs: y.historyRevealMs === !1 ? 0 : y.historyRevealMs ?? _
|
|
19
25
|
};
|
|
20
26
|
}
|
|
21
|
-
const
|
|
27
|
+
const J = Q(), K = q(), tt = {
|
|
22
28
|
top: { tl: !0, tr: !0, br: !1, bl: !1 },
|
|
23
29
|
bottom: { tl: !1, tr: !1, br: !0, bl: !0 },
|
|
24
30
|
none: { tl: !1, tr: !1, br: !1, bl: !1 }
|
|
25
31
|
};
|
|
26
|
-
class
|
|
32
|
+
class et extends $ {
|
|
27
33
|
kind = "bar";
|
|
28
34
|
/** Resolved drawing context for the in-flight render pass. Set at the top of
|
|
29
35
|
* {@link render}, read by {@link drawAnimatedBar}. */
|
|
36
|
+
#o = null;
|
|
37
|
+
/** Per-frame intro directives, resolved once per render while the wave
|
|
38
|
+
* runs; `null` when no intro is in flight. */
|
|
30
39
|
#e = null;
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
/** Visible range captured alongside {@link #introDirectives} — positions
|
|
41
|
+
* the per-bar wave stagger. */
|
|
42
|
+
#i = null;
|
|
43
|
+
/** Per-frame history-reveal directives; `null` when no reveal is in flight. */
|
|
44
|
+
#t = null;
|
|
45
|
+
constructor(e, t) {
|
|
46
|
+
super(e), this.options = I({ ...G, ...t });
|
|
33
47
|
}
|
|
34
48
|
updateOptions(e) {
|
|
35
|
-
this.options =
|
|
49
|
+
this.options = I({ ...this.options, ...e });
|
|
36
50
|
}
|
|
37
51
|
isEntryEnabled() {
|
|
38
52
|
return (this.options.entryAnimation ?? "fade-grow") !== "none";
|
|
39
53
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Normalized x-position + eased wave progress for the intro's callbacks.
|
|
56
|
+
* `null` when no intro is in flight this frame.
|
|
57
|
+
*/
|
|
58
|
+
#a(e) {
|
|
59
|
+
const t = this.#i;
|
|
60
|
+
if (t === null) return null;
|
|
61
|
+
const o = t.to - t.from, n = o > 0 ? (e - t.from) / o : 0, a = Math.min(1, Math.max(0, n));
|
|
62
|
+
return { position: a, progress: this.introWave.progressAt(a) };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Stagger position + eased wave progress for the history reveal's
|
|
66
|
+
* callbacks — position anchored at the data boundary (`0` there, `1` at
|
|
67
|
+
* the deepest prepended point). `null` for bars outside the prepended
|
|
68
|
+
* span or when no reveal is in flight this frame.
|
|
69
|
+
*/
|
|
70
|
+
#r(e) {
|
|
71
|
+
const t = this.historyRange;
|
|
72
|
+
if (this.#t === null || t === null || e >= t.to) return null;
|
|
73
|
+
const o = t.to - t.from, n = o > 0 ? (t.to - e) / o : 0, a = Math.min(1, Math.max(0, n));
|
|
74
|
+
return { position: a, progress: this.historyWave.progressAt(a) };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Apply the intro's `value` directive to one rendered value. Scaling here
|
|
78
|
+
* (before geometry and stacking) grows the bar from the baseline on every
|
|
79
|
+
* render path — off / stacked / percent — without touching their geometry
|
|
80
|
+
* code. Projected (forecast) bars stay settled, like streaming entrances.
|
|
81
|
+
* A bar inside an in-flight history reveal is owned by the reveal's value
|
|
82
|
+
* directive instead.
|
|
83
|
+
*/
|
|
84
|
+
introValue(e) {
|
|
85
|
+
if (this.isProjectedTime(e.time)) return e.value;
|
|
86
|
+
const t = this.#t?.value;
|
|
87
|
+
if (t !== void 0) {
|
|
88
|
+
const a = this.#r(e.time);
|
|
89
|
+
if (a !== null) return t({ ...e, ...a });
|
|
90
|
+
}
|
|
91
|
+
const o = this.#e?.value;
|
|
92
|
+
if (o === void 0) return e.value;
|
|
93
|
+
const n = this.#a(e.time);
|
|
94
|
+
return n === null ? e.value : o({ ...e, ...n });
|
|
95
|
+
}
|
|
96
|
+
applyTheme(e, t) {
|
|
97
|
+
const o = this.stores.length === 1, n = e.seriesColors[0] ?? "#26a69a", a = o ? [e.bar?.color ?? n] : e.seriesColors.slice(0, this.stores.length);
|
|
98
|
+
this.updateOptions({ colors: a });
|
|
43
99
|
}
|
|
44
100
|
/** True when `time` is at/after the configured `projectedFrom` forecast cut. */
|
|
45
101
|
isProjectedTime(e) {
|
|
46
|
-
const
|
|
47
|
-
return
|
|
102
|
+
const t = this.options.projectedFrom;
|
|
103
|
+
return t !== void 0 && e >= t;
|
|
48
104
|
}
|
|
49
105
|
/**
|
|
50
106
|
* Shape of the per-bar entrance transform. Centralized so the entrance style
|
|
51
107
|
* is a single switch; new styles like 'slide' drop in here without touching
|
|
52
108
|
* each render path.
|
|
53
109
|
*/
|
|
54
|
-
applyBarTransform(e,
|
|
55
|
-
const { baselineY:
|
|
56
|
-
if (
|
|
57
|
-
return { topY:
|
|
58
|
-
let
|
|
59
|
-
if ((
|
|
60
|
-
const
|
|
61
|
-
|
|
110
|
+
applyBarTransform(e, t) {
|
|
111
|
+
const { baselineY: o, topY: n, barHeight: a, x: m, barWidth: v } = e, b = this.options.entryAnimation ?? "fade-grow";
|
|
112
|
+
if (t >= 1 || b === "none")
|
|
113
|
+
return { topY: n, barHeight: a, x: m, barWidth: v, alpha: 1 };
|
|
114
|
+
let l = n, u = a, x = m, R = 1;
|
|
115
|
+
if ((b === "fade" || b === "fade-grow") && (R = t), (b === "grow" || b === "fade-grow") && !e.growBaked) {
|
|
116
|
+
const r = a * t;
|
|
117
|
+
n < o ? l = o - r : l = o, u = Math.max(1, r);
|
|
62
118
|
}
|
|
63
|
-
return
|
|
119
|
+
return b === "slide" && (x = m + (1 - t) * v, R = t), { topY: l, barHeight: u, x, barWidth: v, alpha: R };
|
|
64
120
|
}
|
|
65
121
|
render(e) {
|
|
66
122
|
this.tickAnimations(performance.now());
|
|
67
|
-
const { scope: o } = e;
|
|
68
|
-
|
|
69
|
-
painter:
|
|
123
|
+
const { scope: t, timeScale: o, yScale: n } = e;
|
|
124
|
+
if (this.#o = {
|
|
125
|
+
painter: Z(this.options.barPainter),
|
|
70
126
|
env: {
|
|
71
|
-
ctx:
|
|
127
|
+
ctx: t.context,
|
|
72
128
|
theme: e.theme,
|
|
73
|
-
horizontalPixelRatio:
|
|
74
|
-
verticalPixelRatio:
|
|
129
|
+
horizontalPixelRatio: t.horizontalPixelRatio,
|
|
130
|
+
verticalPixelRatio: t.verticalPixelRatio
|
|
75
131
|
},
|
|
76
|
-
radius: (this.options.cornerRadius ??
|
|
77
|
-
}, this.
|
|
132
|
+
radius: (this.options.cornerRadius ?? U) * t.horizontalPixelRatio
|
|
133
|
+
}, this.#e = null, this.#i = null, this.introWave.active) {
|
|
134
|
+
const l = this.options.introAnimation ?? J, u = o.getRange();
|
|
135
|
+
this.#i = u, this.#e = l({
|
|
136
|
+
progress: this.introWave.linear(),
|
|
137
|
+
// Plot-area extent, not the canvas bitmap — the canvas also carries
|
|
138
|
+
// the axis strips, so a width-based front (wipeIntro) would overshoot
|
|
139
|
+
// the data area.
|
|
140
|
+
width: o.getMediaWidth() * t.horizontalPixelRatio,
|
|
141
|
+
height: n.getMediaHeight() * t.verticalPixelRatio,
|
|
142
|
+
range: u,
|
|
143
|
+
timeToX: (x) => o.timeToBitmapX(x)
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
this.#t = null;
|
|
147
|
+
const a = this.historyRange;
|
|
148
|
+
if (this.historyWave.active && a !== null) {
|
|
149
|
+
const l = this.options.historyReveal ?? K;
|
|
150
|
+
l !== "none" && (this.#t = l({
|
|
151
|
+
progress: this.historyWave.linear(),
|
|
152
|
+
width: Math.abs(o.timeToBitmapX(a.to) - o.timeToBitmapX(a.from)),
|
|
153
|
+
height: n.getMediaHeight() * t.verticalPixelRatio,
|
|
154
|
+
range: a,
|
|
155
|
+
timeToX: (u) => o.timeToBitmapX(u)
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
const m = this.#e?.clip;
|
|
159
|
+
if (m !== void 0) {
|
|
160
|
+
const l = m.fromX ?? 0, u = m.toX ?? t.bitmapSize.width;
|
|
161
|
+
t.context.save(), t.context.beginPath(), t.context.rect(l, 0, Math.max(0, u - l), t.bitmapSize.height), t.context.clip();
|
|
162
|
+
}
|
|
163
|
+
const v = this.#t?.clip;
|
|
164
|
+
let b = !1;
|
|
165
|
+
if (v !== void 0 && a !== null) {
|
|
166
|
+
const l = o.timeToBitmapX(a.to), u = Math.abs(l - o.timeToBitmapX(a.from)), x = o.barWidthBitmap(e.dataInterval), R = v.fromX ?? 0, r = v.toX ?? u;
|
|
167
|
+
t.context.save(), t.context.beginPath(), t.context.rect(l - r - x, 0, Math.max(0, r - R + x), t.bitmapSize.height), t.context.rect(l, 0, Math.max(0, t.bitmapSize.width - l), t.bitmapSize.height), t.context.clip(), b = !0;
|
|
168
|
+
}
|
|
169
|
+
switch (this.options.stacking) {
|
|
78
170
|
case "normal":
|
|
79
171
|
this.renderStacked(e, !1);
|
|
80
172
|
break;
|
|
@@ -85,216 +177,234 @@ class K extends U {
|
|
|
85
177
|
this.renderOff(e);
|
|
86
178
|
break;
|
|
87
179
|
}
|
|
180
|
+
b && t.context.restore(), m !== void 0 && t.context.restore();
|
|
88
181
|
}
|
|
89
182
|
/** Stacking off — each layer drawn independently from zero, overlapping */
|
|
90
183
|
renderOff(e) {
|
|
91
|
-
const { scope:
|
|
92
|
-
let
|
|
93
|
-
for (const
|
|
94
|
-
if (!
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
184
|
+
const { scope: t, timeScale: o, yScale: n, dataInterval: a } = e, { context: m, horizontalPixelRatio: v } = t, b = o.getRange();
|
|
185
|
+
let l = 0;
|
|
186
|
+
for (const M of this.stores) {
|
|
187
|
+
if (!M.isVisible()) continue;
|
|
188
|
+
const p = M.getVisibleData(b.from, b.to).length;
|
|
189
|
+
if (p > l && (l = p), l > 2) break;
|
|
97
190
|
}
|
|
98
|
-
const
|
|
191
|
+
const u = o.barWidthBitmap(a), x = Math.round(30 * v), R = l <= 2 ? Math.min(x, u) : u, r = Math.max(1, Math.round(R * this.options.barWidthRatio) - 2), W = Math.floor(r / 2), H = this.options.anchor === "right" ? r : W, T = n.getRange().min < 0, f = T ? n.valueToBitmapY(0) : t.bitmapSize.height;
|
|
99
192
|
if (this.stores.length === 1) {
|
|
100
193
|
if (!this.stores[0].isVisible()) return;
|
|
101
|
-
const
|
|
102
|
-
for (const
|
|
103
|
-
if (!Number.isFinite(
|
|
104
|
-
const
|
|
105
|
-
if (
|
|
106
|
-
const
|
|
194
|
+
const M = this.stores[0].getVisibleData(b.from, b.to);
|
|
195
|
+
for (const p of M) {
|
|
196
|
+
if (!Number.isFinite(p.value)) continue;
|
|
197
|
+
const d = this.effectiveValue(e, 0, p.time, p.value), P = this.introValue({ layerIndex: 0, time: p.time, value: d }), B = this.entranceProgress(0, p.time), i = this.isProjectedTime(p.time), h = o.timeToBitmapX(p.time), s = this.resolveLayerColor(0, d);
|
|
198
|
+
if (P >= 0) {
|
|
199
|
+
const g = n.valueToBitmapY(P), c = Math.max(1, f - g);
|
|
107
200
|
this.drawAnimatedBar({
|
|
108
201
|
context: m,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
202
|
+
time: p.time,
|
|
203
|
+
progress: B,
|
|
204
|
+
baselineY: f,
|
|
205
|
+
topY: g,
|
|
206
|
+
barHeight: c,
|
|
207
|
+
x: h - H,
|
|
208
|
+
barWidth: r,
|
|
209
|
+
color: s,
|
|
116
210
|
roundEdge: "top",
|
|
117
|
-
isProjected:
|
|
211
|
+
isProjected: i
|
|
118
212
|
});
|
|
119
213
|
} else {
|
|
120
|
-
const
|
|
214
|
+
const g = n.valueToBitmapY(P), c = Math.max(1, g - f);
|
|
121
215
|
this.drawAnimatedBar({
|
|
122
216
|
context: m,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
217
|
+
time: p.time,
|
|
218
|
+
progress: B,
|
|
219
|
+
baselineY: f,
|
|
220
|
+
topY: f,
|
|
221
|
+
barHeight: c,
|
|
222
|
+
x: h - H,
|
|
223
|
+
barWidth: r,
|
|
224
|
+
color: s,
|
|
130
225
|
roundEdge: "bottom",
|
|
131
|
-
isProjected:
|
|
226
|
+
isProjected: i
|
|
132
227
|
});
|
|
133
228
|
}
|
|
134
229
|
}
|
|
135
230
|
} else {
|
|
136
|
-
const
|
|
137
|
-
(
|
|
138
|
-
),
|
|
139
|
-
for (let
|
|
140
|
-
const
|
|
141
|
-
for (const
|
|
142
|
-
if (!Number.isFinite(
|
|
143
|
-
let
|
|
144
|
-
|
|
231
|
+
const M = this.stores.map(
|
|
232
|
+
(d, P) => this.getLayerAlpha(P) > 0 ? d.getVisibleData(b.from, b.to) : []
|
|
233
|
+
), p = /* @__PURE__ */ new Map();
|
|
234
|
+
for (let d = 0; d < M.length; d++) {
|
|
235
|
+
const P = this.getLayerAlpha(d);
|
|
236
|
+
for (const B of M[d]) {
|
|
237
|
+
if (!Number.isFinite(B.value)) continue;
|
|
238
|
+
let i = p.get(B.time);
|
|
239
|
+
i || (i = [], p.set(B.time, i));
|
|
240
|
+
const h = this.effectiveValue(e, d, B.time, B.value) * P;
|
|
241
|
+
i.push({
|
|
242
|
+
layer: d,
|
|
243
|
+
value: this.introValue({ layerIndex: d, time: B.time, value: h }),
|
|
244
|
+
// Color resolves from the settled data value — same contract as
|
|
245
|
+
// the single-layer path — so a threshold value-fn doesn't flicker
|
|
246
|
+
// hues while the intro sweeps the drawn value from 0 to final.
|
|
247
|
+
colorValue: B.value
|
|
248
|
+
});
|
|
145
249
|
}
|
|
146
250
|
}
|
|
147
|
-
for (const [
|
|
148
|
-
|
|
149
|
-
(
|
|
251
|
+
for (const [d, P] of p) {
|
|
252
|
+
P.sort(
|
|
253
|
+
(h, s) => Math.abs(s.value) - Math.abs(h.value)
|
|
150
254
|
);
|
|
151
|
-
const
|
|
152
|
-
for (let
|
|
153
|
-
const { layer:
|
|
154
|
-
if (
|
|
155
|
-
const
|
|
255
|
+
const B = o.timeToBitmapX(d), i = this.isProjectedTime(d);
|
|
256
|
+
for (let h = 0; h < P.length; h++) {
|
|
257
|
+
const { layer: s, value: g, colorValue: c } = P[h], S = this.resolveLayerColor(s, c), E = this.entranceProgress(s, d);
|
|
258
|
+
if (g >= 0) {
|
|
259
|
+
const k = n.valueToBitmapY(g), V = Math.max(1, f - k);
|
|
156
260
|
this.drawAnimatedBar({
|
|
157
261
|
context: m,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
262
|
+
time: d,
|
|
263
|
+
progress: E,
|
|
264
|
+
baselineY: f,
|
|
265
|
+
topY: k,
|
|
266
|
+
barHeight: V,
|
|
267
|
+
x: B - H,
|
|
268
|
+
barWidth: r,
|
|
269
|
+
color: S,
|
|
165
270
|
roundEdge: "top",
|
|
166
|
-
isProjected:
|
|
271
|
+
isProjected: i
|
|
167
272
|
});
|
|
168
273
|
} else {
|
|
169
|
-
const
|
|
274
|
+
const k = n.valueToBitmapY(g), V = Math.max(1, k - f);
|
|
170
275
|
this.drawAnimatedBar({
|
|
171
276
|
context: m,
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
277
|
+
time: d,
|
|
278
|
+
progress: E,
|
|
279
|
+
baselineY: f,
|
|
280
|
+
topY: f,
|
|
281
|
+
barHeight: V,
|
|
282
|
+
x: B - H,
|
|
283
|
+
barWidth: r,
|
|
284
|
+
color: S,
|
|
179
285
|
roundEdge: "bottom",
|
|
180
|
-
isProjected:
|
|
286
|
+
isProjected: i
|
|
181
287
|
});
|
|
182
288
|
}
|
|
183
289
|
}
|
|
184
290
|
}
|
|
185
291
|
}
|
|
186
|
-
if (
|
|
292
|
+
if (T) {
|
|
187
293
|
m.strokeStyle = e.theme.grid.color, m.lineWidth = 1;
|
|
188
|
-
const
|
|
189
|
-
m.beginPath(), m.moveTo(0,
|
|
294
|
+
const M = Math.round(f) + 0.5;
|
|
295
|
+
m.beginPath(), m.moveTo(0, M), m.lineTo(t.bitmapSize.width, M), m.stroke();
|
|
190
296
|
}
|
|
191
297
|
}
|
|
192
298
|
/** Stacked (normal or percent) rendering */
|
|
193
|
-
renderStacked(e,
|
|
194
|
-
const { scope:
|
|
195
|
-
let
|
|
196
|
-
for (const
|
|
197
|
-
if (!
|
|
198
|
-
const
|
|
199
|
-
if (
|
|
299
|
+
renderStacked(e, t) {
|
|
300
|
+
const { scope: o, timeScale: n, yScale: a, dataInterval: m } = e, { context: v, horizontalPixelRatio: b } = o, l = n.getRange();
|
|
301
|
+
let u = 0;
|
|
302
|
+
for (const i of this.stores) {
|
|
303
|
+
if (!i.isVisible()) continue;
|
|
304
|
+
const h = i.getVisibleData(l.from, l.to).length;
|
|
305
|
+
if (h > u && (u = h), u > 2) break;
|
|
200
306
|
}
|
|
201
|
-
const
|
|
202
|
-
(
|
|
307
|
+
const x = n.barWidthBitmap(m), R = Math.round(30 * b), r = u <= 2 ? Math.min(R, x) : x, W = Math.max(1, Math.round(r * this.options.barWidthRatio) - 2), H = Math.floor(W / 2), T = this.options.anchor === "right" ? W : H, f = this.stores.map(
|
|
308
|
+
(i, h) => this.getLayerAlpha(h) > 0 ? i.getVisibleData(l.from, l.to) : []
|
|
203
309
|
);
|
|
204
|
-
if (
|
|
205
|
-
const
|
|
206
|
-
for (let
|
|
207
|
-
const
|
|
208
|
-
for (const
|
|
209
|
-
let
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
let
|
|
213
|
-
|
|
310
|
+
if (f.every((i) => i.length === 0)) return;
|
|
311
|
+
const M = this.options.entryAnimation ?? "fade-grow", p = M === "grow" || M === "fade-grow", d = /* @__PURE__ */ new Map();
|
|
312
|
+
for (let i = 0; i < f.length; i++) {
|
|
313
|
+
const h = this.getLayerAlpha(i);
|
|
314
|
+
for (const s of f[i]) {
|
|
315
|
+
let g = d.get(s.time);
|
|
316
|
+
g || (g = new Array(f.length).fill(0), d.set(s.time, g));
|
|
317
|
+
const c = Number.isFinite(s.value) ? s.value : 0;
|
|
318
|
+
let S = this.effectiveValue(e, i, s.time, c) * h;
|
|
319
|
+
p && !this.isProjectedTime(s.time) && (S *= this.entranceProgress(i, s.time)), g[i] = this.introValue({ layerIndex: i, time: s.time, value: S });
|
|
214
320
|
}
|
|
215
321
|
}
|
|
216
|
-
const
|
|
217
|
-
for (const [
|
|
218
|
-
let
|
|
219
|
-
for (let
|
|
220
|
-
|
|
221
|
-
|
|
322
|
+
const P = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map();
|
|
323
|
+
for (const [i, h] of d) {
|
|
324
|
+
let s = -1, g = -1;
|
|
325
|
+
for (let c = 0; c < h.length; c++)
|
|
326
|
+
h[c] > 0 && (s = c), h[c] < 0 && (g = c);
|
|
327
|
+
s >= 0 && P.set(i, s), g >= 0 && B.set(i, g);
|
|
222
328
|
}
|
|
223
|
-
for (let
|
|
224
|
-
const
|
|
225
|
-
for (const [
|
|
226
|
-
const
|
|
227
|
-
if (
|
|
228
|
-
const
|
|
229
|
-
let
|
|
230
|
-
for (let
|
|
231
|
-
const
|
|
232
|
-
|
|
329
|
+
for (let i = 0; i < f.length; i++) {
|
|
330
|
+
const h = this.resolveLayerColor(i, this.stores[i].last()?.value ?? 0);
|
|
331
|
+
for (const [s, g] of d) {
|
|
332
|
+
const c = g[i];
|
|
333
|
+
if (c === 0) continue;
|
|
334
|
+
const S = n.timeToBitmapX(s);
|
|
335
|
+
let E = 0, k = 0;
|
|
336
|
+
for (let Y = 0; Y < i; Y++) {
|
|
337
|
+
const w = g[Y];
|
|
338
|
+
w > 0 ? E += w : k += w;
|
|
233
339
|
}
|
|
234
|
-
const
|
|
235
|
-
if (
|
|
236
|
-
let
|
|
237
|
-
for (const A of
|
|
238
|
-
A > 0 ?
|
|
239
|
-
if (
|
|
240
|
-
const A =
|
|
340
|
+
const V = this.entranceProgress(i, s), X = this.isProjectedTime(s), z = c > 0 ? P.get(s) === i ? "top" : "none" : B.get(s) === i ? "bottom" : "none";
|
|
341
|
+
if (t) {
|
|
342
|
+
let Y = 0, w = 0;
|
|
343
|
+
for (const A of g)
|
|
344
|
+
A > 0 ? Y += A : w += A;
|
|
345
|
+
if (c > 0 && Y > 0) {
|
|
346
|
+
const A = E / Y * 100, D = (E + c) / Y * 100, j = a.valueToBitmapY(D), L = a.valueToBitmapY(A), O = Math.max(1, L - j);
|
|
241
347
|
this.drawAnimatedBar({
|
|
242
|
-
context:
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
348
|
+
context: v,
|
|
349
|
+
time: s,
|
|
350
|
+
progress: V,
|
|
351
|
+
baselineY: L,
|
|
352
|
+
topY: j,
|
|
246
353
|
barHeight: O,
|
|
247
|
-
x:
|
|
248
|
-
barWidth:
|
|
249
|
-
color:
|
|
250
|
-
roundEdge:
|
|
251
|
-
isProjected:
|
|
354
|
+
x: S - T,
|
|
355
|
+
barWidth: W,
|
|
356
|
+
color: h,
|
|
357
|
+
roundEdge: z,
|
|
358
|
+
isProjected: X,
|
|
252
359
|
growBaked: !0
|
|
253
360
|
});
|
|
254
|
-
} else if (
|
|
255
|
-
const A =
|
|
361
|
+
} else if (c < 0 && w < 0) {
|
|
362
|
+
const A = k / w * -100, D = (k + c) / w * -100, j = a.valueToBitmapY(A), L = a.valueToBitmapY(D), O = Math.max(1, L - j);
|
|
256
363
|
this.drawAnimatedBar({
|
|
257
|
-
context:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
364
|
+
context: v,
|
|
365
|
+
time: s,
|
|
366
|
+
progress: V,
|
|
367
|
+
baselineY: j,
|
|
368
|
+
topY: j,
|
|
261
369
|
barHeight: O,
|
|
262
|
-
x:
|
|
263
|
-
barWidth:
|
|
264
|
-
color:
|
|
265
|
-
roundEdge:
|
|
266
|
-
isProjected:
|
|
370
|
+
x: S - T,
|
|
371
|
+
barWidth: W,
|
|
372
|
+
color: h,
|
|
373
|
+
roundEdge: z,
|
|
374
|
+
isProjected: X,
|
|
267
375
|
growBaked: !0
|
|
268
376
|
});
|
|
269
377
|
}
|
|
270
|
-
} else if (
|
|
271
|
-
const
|
|
378
|
+
} else if (c > 0) {
|
|
379
|
+
const Y = a.valueToBitmapY(E + c), w = a.valueToBitmapY(E), A = Math.max(1, w - Y);
|
|
272
380
|
this.drawAnimatedBar({
|
|
273
|
-
context:
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
381
|
+
context: v,
|
|
382
|
+
time: s,
|
|
383
|
+
progress: V,
|
|
384
|
+
baselineY: w,
|
|
385
|
+
topY: Y,
|
|
277
386
|
barHeight: A,
|
|
278
|
-
x:
|
|
279
|
-
barWidth:
|
|
280
|
-
color:
|
|
281
|
-
roundEdge:
|
|
282
|
-
isProjected:
|
|
387
|
+
x: S - T,
|
|
388
|
+
barWidth: W,
|
|
389
|
+
color: h,
|
|
390
|
+
roundEdge: z,
|
|
391
|
+
isProjected: X,
|
|
283
392
|
growBaked: !0
|
|
284
393
|
});
|
|
285
394
|
} else {
|
|
286
|
-
const
|
|
395
|
+
const Y = a.valueToBitmapY(k), w = a.valueToBitmapY(k + c), A = Math.max(1, w - Y);
|
|
287
396
|
this.drawAnimatedBar({
|
|
288
|
-
context:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
397
|
+
context: v,
|
|
398
|
+
time: s,
|
|
399
|
+
progress: V,
|
|
400
|
+
baselineY: Y,
|
|
401
|
+
topY: Y,
|
|
292
402
|
barHeight: A,
|
|
293
|
-
x:
|
|
294
|
-
barWidth:
|
|
295
|
-
color:
|
|
296
|
-
roundEdge:
|
|
297
|
-
isProjected:
|
|
403
|
+
x: S - T,
|
|
404
|
+
barWidth: W,
|
|
405
|
+
color: h,
|
|
406
|
+
roundEdge: z,
|
|
407
|
+
isProjected: X,
|
|
298
408
|
growBaked: !0
|
|
299
409
|
});
|
|
300
410
|
}
|
|
@@ -308,34 +418,56 @@ class K extends U {
|
|
|
308
418
|
* painter's translucent fill rather than a `globalAlpha` fade.
|
|
309
419
|
*/
|
|
310
420
|
drawAnimatedBar(e) {
|
|
311
|
-
const
|
|
312
|
-
if (
|
|
313
|
-
const { context:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
421
|
+
const t = this.#o;
|
|
422
|
+
if (t === null) return;
|
|
423
|
+
const { context: o, baselineY: n, topY: a, barHeight: m, x: v, barWidth: b, color: l, roundEdge: u } = e, x = e.isProjected ? 1 : e.progress, R = this.options.entryAnimation ?? "fade-grow";
|
|
424
|
+
let r = x >= 1 || R === "none" ? { x: v, topY: a, barWidth: b, barHeight: m, alpha: 1 } : this.applyBarTransform(e, x);
|
|
425
|
+
if (!e.isProjected) {
|
|
426
|
+
const H = this.#t?.element, T = H !== void 0 ? this.#r(e.time) : null, f = T !== null ? H : this.#e?.element, M = T ?? (f !== void 0 ? this.#a(e.time) : null);
|
|
427
|
+
if (f !== void 0 && M !== null) {
|
|
428
|
+
const p = f({
|
|
429
|
+
...M,
|
|
430
|
+
time: e.time,
|
|
431
|
+
x: r.x,
|
|
432
|
+
topY: r.topY,
|
|
433
|
+
barHeight: r.barHeight,
|
|
434
|
+
baselineY: n,
|
|
435
|
+
barWidth: r.barWidth
|
|
436
|
+
});
|
|
437
|
+
r = {
|
|
438
|
+
...r,
|
|
439
|
+
x: r.x + (p.offsetX ?? 0),
|
|
440
|
+
topY: r.topY + (p.offsetY ?? 0),
|
|
441
|
+
alpha: r.alpha * (p.alpha ?? 1)
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const W = {
|
|
446
|
+
geom: { x: r.x, y: r.topY, width: r.barWidth, height: r.barHeight, baselineY: n },
|
|
447
|
+
color: l,
|
|
448
|
+
corners: tt[u],
|
|
317
449
|
// Clamp to this bar's geometry so `radius` honors its pre-clamped contract
|
|
318
450
|
// for custom painters; `fillRoundedRect` re-clamps to the same bound, so
|
|
319
451
|
// the built-in output is unchanged.
|
|
320
|
-
radius: Math.min(
|
|
321
|
-
progress:
|
|
452
|
+
radius: Math.min(t.radius, r.barWidth / 2, r.barHeight / 2),
|
|
453
|
+
progress: x,
|
|
322
454
|
isProjected: e.isProjected
|
|
323
455
|
};
|
|
324
|
-
if (
|
|
325
|
-
|
|
456
|
+
if (r.alpha < 1) {
|
|
457
|
+
o.save(), o.globalAlpha = r.alpha, t.painter(t.env, W), o.restore();
|
|
326
458
|
return;
|
|
327
459
|
}
|
|
328
|
-
|
|
460
|
+
t.painter(t.env, W);
|
|
329
461
|
}
|
|
330
462
|
}
|
|
331
|
-
const
|
|
463
|
+
const nt = {
|
|
332
464
|
type: "bar",
|
|
333
|
-
create: ({ theme:
|
|
334
|
-
const
|
|
335
|
-
return new
|
|
465
|
+
create: ({ theme: y, layerCount: e }, t) => {
|
|
466
|
+
const o = e === 1 ? [y.bar?.color ?? y.seriesColors[0] ?? "#26a69a"] : y.seriesColors.slice(0, e);
|
|
467
|
+
return new et(e, { colors: o, ...t });
|
|
336
468
|
}
|
|
337
469
|
};
|
|
338
470
|
export {
|
|
339
|
-
|
|
340
|
-
|
|
471
|
+
et as BarRenderer,
|
|
472
|
+
nt as BarSeriesDef
|
|
341
473
|
};
|