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 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
- if (GPU_KIND[options.type] && (options.renderer === "webgpu" || options.renderer === "auto")) Promise.resolve().then(() => require("./series-J_5Z6dah.cjs")).then(({ GpuSeries }) => GpuSeries.create(options.gpu).then((g) => {
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
- /** series rasterization on the GPU; grid/labels/hover stay on Canvas2D */
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
- const r = this.renderContext(t, scales);
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 (const s of d.series) {
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
- const pts = mapSeriesPx(d.sortedX, s.y, s.prevY, t, scales.yScale.domain[0], scales.xScale, scales.yScale, flow);
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
- const pts = seriesPoints(r, s);
2204
- if (kind === "area") {
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
- if (m > 1 && x < sortedX[m - 2]) resortXY(nd);
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;