resolvcharts 0.2.0 → 0.3.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/dist/index.cjs +74 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -6
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +42 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +74 -32
- package/dist/index.mjs.map +1 -1
- package/dist/resolvcharts.global.min.js +195 -25
- package/dist/resolvcharts.global.min.js.map +1 -1
- package/dist/series-PmAjztEh.cjs +1191 -0
- package/dist/series-PmAjztEh.cjs.map +1 -0
- package/dist/series-wyqYpkXm.mjs +1191 -0
- package/dist/series-wyqYpkXm.mjs.map +1 -0
- package/package.json +17 -14
- package/dist/series-BdprL87H.mjs +0 -479
- package/dist/series-BdprL87H.mjs.map +0 -1
- package/dist/series-J_5Z6dah.cjs +0 -479
- package/dist/series-J_5Z6dah.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1381,6 +1381,11 @@ function padDomain(min, max, includeZero = false) {
|
|
|
1381
1381
|
}
|
|
1382
1382
|
return [lo, hi];
|
|
1383
1383
|
}
|
|
1384
|
+
/** @category Utilities
|
|
1385
|
+
* Pin domain ends — each defined bound overrides the fitted value. */
|
|
1386
|
+
function boundDomain(dom, min, max) {
|
|
1387
|
+
return [min ?? dom[0], max ?? dom[1]];
|
|
1388
|
+
}
|
|
1384
1389
|
//#endregion
|
|
1385
1390
|
//#region src/core/scheduler.ts
|
|
1386
1391
|
const raf = typeof requestAnimationFrame === "function" ? (cb) => requestAnimationFrame(cb) : (cb) => setTimeout(() => cb(Date.now()), 16);
|
|
@@ -1696,6 +1701,8 @@ const GPU_KIND = {
|
|
|
1696
1701
|
};
|
|
1697
1702
|
/** points retained beyond the window's left edge so they slide off-screen instead of vanishing mid-plot */
|
|
1698
1703
|
const EDGE_KEEP = 3;
|
|
1704
|
+
/** default point count at which `renderer: "auto"` engages the GPU path */
|
|
1705
|
+
const GPU_THRESHOLD = 1e5;
|
|
1699
1706
|
/** Chart instance. Create via {@link createChart}.
|
|
1700
1707
|
* @category Charts
|
|
1701
1708
|
*/
|
|
@@ -1721,6 +1728,8 @@ var Chart = class {
|
|
|
1721
1728
|
this.destroyed = false;
|
|
1722
1729
|
this.pendingView = false;
|
|
1723
1730
|
this.gpu = null;
|
|
1731
|
+
this.gpuInit = false;
|
|
1732
|
+
this.dataRev = 0;
|
|
1724
1733
|
this.lastAppendAt = 0;
|
|
1725
1734
|
this.estInterval = 400;
|
|
1726
1735
|
this.onScroll = () => {
|
|
@@ -1783,7 +1792,35 @@ var Chart = class {
|
|
|
1783
1792
|
this.reduced = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1784
1793
|
if (options.tooltip ?? this.mod.defaultTooltip) this.tooltip = new Tooltip(el, this.theme);
|
|
1785
1794
|
this.data = this.normalize(options.data, null);
|
|
1786
|
-
|
|
1795
|
+
this.maybeInitGpu();
|
|
1796
|
+
this.bindEvents();
|
|
1797
|
+
const dom = this.layout();
|
|
1798
|
+
this.view = {
|
|
1799
|
+
x: [...dom.x],
|
|
1800
|
+
y: [...dom.y]
|
|
1801
|
+
};
|
|
1802
|
+
this.viewTo = {
|
|
1803
|
+
x: [...dom.x],
|
|
1804
|
+
y: [...dom.y]
|
|
1805
|
+
};
|
|
1806
|
+
this.startAnimation(dom);
|
|
1807
|
+
}
|
|
1808
|
+
/**
|
|
1809
|
+
* Lazily acquire the WebGPU backend. `"webgpu"` attaches unconditionally;
|
|
1810
|
+
* `"auto"` waits until the xy point count crosses `gpuThreshold` — small
|
|
1811
|
+
* charts never pay adapter/device acquisition.
|
|
1812
|
+
*/
|
|
1813
|
+
maybeInitGpu() {
|
|
1814
|
+
if (this.gpu || this.gpuInit || this.destroyed) return;
|
|
1815
|
+
if (!GPU_KIND[this.options.type]) return;
|
|
1816
|
+
const r = this.options.renderer ?? "auto";
|
|
1817
|
+
if (r !== "auto" && r !== "webgpu") return;
|
|
1818
|
+
if (r === "auto") {
|
|
1819
|
+
const d = this.data;
|
|
1820
|
+
if ((d.kind === "xy" ? d.sortedX.length * Math.max(1, d.series.length) : 0) < (this.options.gpuThreshold ?? GPU_THRESHOLD)) return;
|
|
1821
|
+
}
|
|
1822
|
+
this.gpuInit = true;
|
|
1823
|
+
Promise.resolve().then(() => require("./series-PmAjztEh.cjs")).then(({ GpuSeries }) => GpuSeries.create(this.options.gpu).then((g) => {
|
|
1787
1824
|
if (!g || this.destroyed) {
|
|
1788
1825
|
g?.destroy();
|
|
1789
1826
|
return;
|
|
@@ -1796,17 +1833,6 @@ var Chart = class {
|
|
|
1796
1833
|
return false;
|
|
1797
1834
|
});
|
|
1798
1835
|
}));
|
|
1799
|
-
this.bindEvents();
|
|
1800
|
-
const dom = this.layout();
|
|
1801
|
-
this.view = {
|
|
1802
|
-
x: [...dom.x],
|
|
1803
|
-
y: [...dom.y]
|
|
1804
|
-
};
|
|
1805
|
-
this.viewTo = {
|
|
1806
|
-
x: [...dom.x],
|
|
1807
|
-
y: [...dom.y]
|
|
1808
|
-
};
|
|
1809
|
-
this.startAnimation(dom);
|
|
1810
1836
|
}
|
|
1811
1837
|
normalize(data, prev) {
|
|
1812
1838
|
const t = this.options.type;
|
|
@@ -2002,7 +2028,7 @@ var Chart = class {
|
|
|
2002
2028
|
const includeZero = this.options.type === "area" || this.options.type === "sparkline";
|
|
2003
2029
|
return {
|
|
2004
2030
|
x,
|
|
2005
|
-
y: padDomain(min, max, includeZero)
|
|
2031
|
+
y: this.yDomain(padDomain(min, max, includeZero))
|
|
2006
2032
|
};
|
|
2007
2033
|
}
|
|
2008
2034
|
if (d.kind === "category") {
|
|
@@ -2038,7 +2064,7 @@ var Chart = class {
|
|
|
2038
2064
|
}
|
|
2039
2065
|
return {
|
|
2040
2066
|
x: [0, d.categories.length],
|
|
2041
|
-
y: padDomain(min, max, true)
|
|
2067
|
+
y: this.yDomain(padDomain(min, max, true))
|
|
2042
2068
|
};
|
|
2043
2069
|
}
|
|
2044
2070
|
if (d.kind === "ohlc") {
|
|
@@ -2057,7 +2083,7 @@ var Chart = class {
|
|
|
2057
2083
|
}
|
|
2058
2084
|
return {
|
|
2059
2085
|
x,
|
|
2060
|
-
y: padDomain(min, max)
|
|
2086
|
+
y: this.yDomain(padDomain(min, max))
|
|
2061
2087
|
};
|
|
2062
2088
|
}
|
|
2063
2089
|
if (d.kind === "waterfall") {
|
|
@@ -2073,14 +2099,17 @@ var Chart = class {
|
|
|
2073
2099
|
}
|
|
2074
2100
|
return {
|
|
2075
2101
|
x: [0, d.bars.length],
|
|
2076
|
-
y: padDomain(min, max, true)
|
|
2102
|
+
y: this.yDomain(padDomain(min, max, true))
|
|
2077
2103
|
};
|
|
2078
2104
|
}
|
|
2079
2105
|
return {
|
|
2080
2106
|
x: [0, 1],
|
|
2081
|
-
y: [0, 1]
|
|
2107
|
+
y: this.yDomain([0, 1])
|
|
2082
2108
|
};
|
|
2083
2109
|
}
|
|
2110
|
+
yDomain(y) {
|
|
2111
|
+
return boundDomain(y, this.options.yMin, this.options.yMax);
|
|
2112
|
+
}
|
|
2084
2113
|
lerpView(eased) {
|
|
2085
2114
|
const f = this.viewFrom;
|
|
2086
2115
|
const to = this.viewTo;
|
|
@@ -2182,30 +2211,35 @@ var Chart = class {
|
|
|
2182
2211
|
else this.mod.render(this.renderContext(t, scales));
|
|
2183
2212
|
if (this.hover) this.drawHover(this.hover, scales.yScale);
|
|
2184
2213
|
}
|
|
2185
|
-
/**
|
|
2214
|
+
/**
|
|
2215
|
+
* Series rasterization on the GPU; grid/labels/hover stay on Canvas2D.
|
|
2216
|
+
* Raw data lives in GPU buffers — the per-frame cost is uniform writes +
|
|
2217
|
+
* instanced draws, with compute decimation above the density threshold.
|
|
2218
|
+
*/
|
|
2186
2219
|
gpuRender(t, scales) {
|
|
2187
2220
|
const g = this.gpu;
|
|
2188
2221
|
const d = this.data;
|
|
2189
2222
|
const kind = GPU_KIND[this.options.type];
|
|
2190
|
-
if (!g || !kind || d.kind !== "xy") {
|
|
2223
|
+
if (!g || g.unavailable || !kind || d.kind !== "xy") {
|
|
2191
2224
|
this.mod.render(this.renderContext(t, scales));
|
|
2192
2225
|
return;
|
|
2193
2226
|
}
|
|
2194
|
-
|
|
2227
|
+
g.syncData(d, this.dataRev);
|
|
2228
|
+
const view = {
|
|
2229
|
+
x: scales.xScale.domain,
|
|
2230
|
+
y: scales.yScale.domain
|
|
2231
|
+
};
|
|
2195
2232
|
const flow = this.options.flow ? FLOW_RIPPLE : 0;
|
|
2196
|
-
g.begin(this.backend.plot);
|
|
2197
|
-
for (
|
|
2233
|
+
g.begin(this.backend.plot, t, flow);
|
|
2234
|
+
for (let i = 0; i < d.series.length; i++) {
|
|
2235
|
+
const s = d.series[i];
|
|
2236
|
+
if (!s) continue;
|
|
2198
2237
|
if (kind === "points") {
|
|
2199
|
-
|
|
2200
|
-
g.points(pts, s.color, 2.5, .65);
|
|
2238
|
+
g.points(i, s.color, 2.5, .65, view);
|
|
2201
2239
|
continue;
|
|
2202
2240
|
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
const base = scales.yScale(Math.max(0, scales.yScale.domain[0]));
|
|
2206
|
-
g.area(pts, s.color, base, this.backend.plot);
|
|
2207
|
-
}
|
|
2208
|
-
g.line(pts, s.color, 2);
|
|
2241
|
+
if (kind === "area") g.area(i, s.color, Math.max(0, scales.yScale.domain[0]), view);
|
|
2242
|
+
g.line(i, s.color, 2, view);
|
|
2209
2243
|
}
|
|
2210
2244
|
g.end();
|
|
2211
2245
|
}
|
|
@@ -2340,6 +2374,8 @@ var Chart = class {
|
|
|
2340
2374
|
setData(data) {
|
|
2341
2375
|
const prev = this.data;
|
|
2342
2376
|
this.data = this.normalize(data, prev);
|
|
2377
|
+
this.dataRev++;
|
|
2378
|
+
this.maybeInitGpu();
|
|
2343
2379
|
const dom = this.layout();
|
|
2344
2380
|
this.startAnimation(dom);
|
|
2345
2381
|
}
|
|
@@ -2405,8 +2441,14 @@ var Chart = class {
|
|
|
2405
2441
|
sortedX,
|
|
2406
2442
|
series
|
|
2407
2443
|
};
|
|
2408
|
-
|
|
2444
|
+
const resort = m > 1 && x < sortedX[m - 2];
|
|
2445
|
+
if (resort) resortXY(nd);
|
|
2409
2446
|
this.data = nd;
|
|
2447
|
+
if (resort) this.dataRev++;
|
|
2448
|
+
else if (this.gpu && !this.gpu.unavailable) {
|
|
2449
|
+
if (!this.gpu.appended(x, d.series.map((s, i) => ys[i] ?? s.y[n - 1]), d.series.map((s) => s.y[n - 1]), drop)) this.dataRev++;
|
|
2450
|
+
}
|
|
2451
|
+
this.maybeInitGpu();
|
|
2410
2452
|
this.pendingView = true;
|
|
2411
2453
|
sharedScheduler.add(this.frame);
|
|
2412
2454
|
}
|
|
@@ -2482,6 +2524,7 @@ function createChart(el, options) {
|
|
|
2482
2524
|
}
|
|
2483
2525
|
//#endregion
|
|
2484
2526
|
exports.Chart = Chart;
|
|
2527
|
+
exports.boundDomain = boundDomain;
|
|
2485
2528
|
exports.computeTicks = computeTicks;
|
|
2486
2529
|
exports.createChart = createChart;
|
|
2487
2530
|
exports.darkTheme = darkTheme;
|