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.d.cts CHANGED
@@ -209,24 +209,35 @@ interface ChartOptions {
209
209
  maxPoints?: number;
210
210
  /**
211
211
  * Render backend for xy series (line/area/sparkline/scatter). `"canvas"`
212
- * (default) uses Canvas2D. `"webgpu"` rasterizes series on the GPU —
213
- * instanced lines and point sprites — while axes, grid, and tooltips stay
214
- * on Canvas2D. `"auto"` uses WebGPU when available, else Canvas2D.
212
+ * uses Canvas2D. `"webgpu"` rasterizes series on the GPU — instanced
213
+ * lines, point sprites, compute decimation — while axes, grid, and
214
+ * tooltips stay on Canvas2D. `"auto"` (default) engages WebGPU once the
215
+ * point count crosses `gpuThreshold`, else Canvas2D.
215
216
  * Unknown to older browsers → silent fallback to Canvas2D.
216
217
  */
217
218
  renderer?: "auto" | "canvas" | "webgpu";
219
+ /**
220
+ * For `renderer: "auto"`: total visible xy points (x-length × series) at
221
+ * which the GPU path engages. Below this, Canvas2D is faster. Once the
222
+ * GPU attaches it stays attached for the chart's lifetime.
223
+ * Default: 100,000.
224
+ */
225
+ gpuThreshold?: number;
218
226
  /**
219
227
  * WebGPU adapter options — only used when `renderer` resolves to WebGPU.
220
228
  * `powerPreference` picks the discrete GPU on dual-GPU systems;
221
229
  * `compat` requests compatibility mode (GLES 3.1 / D3D11 reach);
222
230
  * `timing` enables GPU-side pass timing via "timestamp-query" when the
223
- * adapter supports it (note: browsers quantize to ~100 µs unless the
224
- * WebGPU developer-features flag is enabled).
231
+ * adapter supports it (note: browsers require cross-origin isolation and
232
+ * quantize to ~100 µs — dev/profiling use only);
233
+ * `allowFallback` accepts software adapters like SwiftShader (off by
234
+ * default — usually slower than Canvas2D).
225
235
  */
226
236
  gpu?: {
227
237
  powerPreference?: "default" | "low-power" | "high-performance";
228
238
  compat?: boolean;
229
239
  timing?: boolean;
240
+ allowFallback?: boolean;
230
241
  };
231
242
  /**
232
243
  * Canvas2D context settings passed to `getContext("2d", …)` for all layers.
@@ -247,6 +258,14 @@ interface ChartOptions {
247
258
  x?: (v: number) => string;
248
259
  y?: (v: number) => string;
249
260
  };
261
+ /**
262
+ * Pin the y-axis domain. Each bound overrides the auto-fitted value —
263
+ * unset ends still auto-fit. E.g. `{ yMin: 0, yMax: 100 }` frames a
264
+ * utilization chart honestly; `{ yMin: 0 }` zero-anchors without a
265
+ * ceiling. Values exceeding the bounds are clipped at the plot edge.
266
+ */
267
+ yMin?: number;
268
+ yMax?: number;
250
269
  /** Called on pointer hover with the nearest hit, or `null` on leave. */
251
270
  onHover?: (info: HoverInfo | null) => void;
252
271
  }
@@ -294,23 +313,37 @@ export declare class Chart {
294
313
  private destroyed;
295
314
  private pendingView;
296
315
  private gpu;
316
+ private gpuInit;
317
+ /** bumped whenever xy data is replaced or reordered — triggers GPU re-upload */
318
+ private dataRev;
297
319
  private lastAppendAt;
298
320
  private estInterval;
299
321
  private onScroll;
300
322
  private frame;
301
323
  constructor(el: HTMLElement, options: ChartOptions);
324
+ /**
325
+ * Lazily acquire the WebGPU backend. `"webgpu"` attaches unconditionally;
326
+ * `"auto"` waits until the xy point count crosses `gpuThreshold` — small
327
+ * charts never pay adapter/device acquisition.
328
+ */
329
+ private maybeInitGpu;
302
330
  private normalize;
303
331
  private bindEvents;
304
332
  private onMove;
305
333
  private onLeave;
306
334
  private layout;
307
335
  private domains;
336
+ private yDomain;
308
337
  private lerpView;
309
338
  private makeScales;
310
339
  private renderContext;
311
340
  private drawStatic;
312
341
  private render;
313
- /** series rasterization on the GPU; grid/labels/hover stay on Canvas2D */
342
+ /**
343
+ * Series rasterization on the GPU; grid/labels/hover stay on Canvas2D.
344
+ * Raw data lives in GPU buffers — the per-frame cost is uniform writes +
345
+ * instanced draws, with compute decimation above the density threshold.
346
+ */
314
347
  private gpuRender;
315
348
  private drawHover;
316
349
  private applyHover;
@@ -387,6 +420,9 @@ export declare function extent(values: ArrayLike<number>): [number, number];
387
420
  /** @category Utilities
388
421
  * Pad a domain by 5% on each end; `includeZero` anchors the axis at 0. */
389
422
  export declare function padDomain(min: number, max: number, includeZero?: boolean): [number, number];
423
+ /** @category Utilities
424
+ * Pin domain ends — each defined bound overrides the fitted value. */
425
+ export declare function boundDomain(dom: [number, number], min?: number, max?: number): [number, number];
390
426
  //#endregion
391
427
  //#region src/core/theme.d.ts
392
428
  /** Built-in light theme.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/core/types.ts","../src/core/chart.ts","../src/core/decimate.ts","../src/core/format.ts","../src/core/hit.ts","../src/core/scales.ts","../src/core/theme.ts","../src/core/ticks.ts"],"mappings":";;;;;KAIY;;;;;UAiBK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;UAOe;EACf;EACA;EACA,GAAG;;;;;UAMY;EACf,GAAG;EACH,QAAQ;;;;;;KAOE;;;;;UAMK;EACf;EACA;;EAEA,OAAO;EACP,QAAQ;;;;;;UAOO;EACf;EACA,QAAQ;;;;;;UAOO;EACf;EACA;EACA;;;;;;UAOe;EACf,QAAQ;;;;;;UAOO;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;UAOe;EACf,SAAS;;;;;;UAOM;EACf;;EAEA,QAAQ;;EAER;;;;;KAMU,YACR,SACA,eACA,YACA,WACA;;;;;KAMQ;;;;;KAMA;EAEN;EACA;EACA;EACA;EACA;EACA;IAAU;IAAe;IAAe;;;EAExC;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;;EAGN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;UAOW;EACf,MAAM;EACN,MAAM;EACN,2BAA2B,QAAQ;;EAEnC;EACA,QAAQ;EACR;EACA;EACA;;EAEA;;;;;;;;EAQA;;;;;;EAMA;;;;;;;EAOA;;;;;;;;EASA;;;;;;;;;EASA;IACE;IACA;IACA;;;;;;;;;EASF,SAAS;;EAET;;EAEA;;EAEA;;EAEA;IACE,KAAK;IACL,KAAK;;;EAGP,WAAW,MAAM;;;;;UAMF;EACf;EACA;EACA;EACA;;;;;UAMe;GACd;EACD,OAAO;EACP;EACA;;;;;;;qBCnLW;WACF,IAAI;WACJ,SAAS;UACV;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UAIA;UACA;UAIA;UACA;UACA;UACA;UACA;UACA;UACA;UAGA;EAkCR,YAAY,IAAI,aAAa,SAAS;UA6C9B;UAmIA;UAUA;UASA;UAUA;UAkCA;UAoGA;UAiBA;UAmBA;UAeA;UA8EA;;UAUA;UA0CA;UA8DA;UA4DA;UAaA;;EAcR,QAAQ,MAAM;;;;;;EAYd,OAAO,WAAW;;EAoFlB;;EAoBA;;;;;;;;;;;;;;;;;;wBAmDc,YAAY,IAAI,aAAa,SAAS,eAAe;;;;;;;;;;;;;;wBC9zBrD,WACd,IAAI,mBACJ,IAAI,mBACJ,qBACC;;;;;wBCpMa,aAAa;;;wBAcb,SAAS;;;;;;;;wBCXT,aAAa,IAAI,mBAAmB;;;;;wBCDpC,YACd,YACA,YACA,YACA,aACC;;;wBAYa,OAAO,QAAQ;;;wBAkBf,UACd,aACA,aACA;;;;;;qBCnCW,YAAY;;;;qBAsBZ,WAAW;;;;wBAmCR,aACd,KAAK,uBACL,6BACC;;;;;;wBC/Ca,aAAa,aAAa,aAAa"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/core/types.ts","../src/core/chart.ts","../src/core/decimate.ts","../src/core/format.ts","../src/core/hit.ts","../src/core/scales.ts","../src/core/theme.ts","../src/core/ticks.ts"],"mappings":";;;;;KAIY;;;;;UAiBK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;UAOe;EACf;EACA;EACA,GAAG;;;;;UAMY;EACf,GAAG;EACH,QAAQ;;;;;;KAOE;;;;;UAMK;EACf;EACA;;EAEA,OAAO;EACP,QAAQ;;;;;;UAOO;EACf;EACA,QAAQ;;;;;;UAOO;EACf;EACA;EACA;;;;;;UAOe;EACf,QAAQ;;;;;;UAOO;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;UAOe;EACf,SAAS;;;;;;UAOM;EACf;;EAEA,QAAQ;;EAER;;;;;KAMU,YACR,SACA,eACA,YACA,WACA;;;;;KAMQ;;;;;KAMA;EAEN;EACA;EACA;EACA;EACA;EACA;IAAU;IAAe;IAAe;;;EAExC;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;;EAGN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;UAOW;EACf,MAAM;EACN,MAAM;EACN,2BAA2B,QAAQ;;EAEnC;EACA,QAAQ;EACR;EACA;EACA;;EAEA;;;;;;;;EAQA;;;;;;EAMA;;;;;;;EAOA;;;;;;;;;EAUA;;;;;;;EAOA;;;;;;;;;;;EAWA;IACE;IACA;IACA;IACA;;;;;;;;;EASF,SAAS;;EAET;;EAEA;;EAEA;;EAEA;IACE,KAAK;IACL,KAAK;;;;;;;;EAQP;EACA;;EAEA,WAAW,MAAM;;;;;UAMF;EACf;EACA;EACA;EACA;;;;;UAMe;GACd;EACD,OAAO;EACP;EACA;;;;;;;qBCrMW;WACF,IAAI;WACJ,SAAS;UACV;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UAIA;UACA;UAIA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;UACA;UAGA;EAkCR,YAAY,IAAI,aAAa,SAAS;;;;;;UA8B9B;UA8BA;UAmIA;UAUA;UASA;UAUA;UAkCA;UA0GA;UAIA;UAiBA;UAmBA;UAeA;UA8EA;;;;;;UAcA;UAiCA;UA8DA;UA4DA;UAaA;;EAcR,QAAQ,MAAM;;;;;;EAcd,OAAO,WAAW;;EAoGlB;;EAoBA;;;;;;;;;;;;;;;;;;wBAmDc,YAAY,IAAI,aAAa,SAAS,eAAe;;;;;;;;;;;;;;wBCx2BrD,WACd,IAAI,mBACJ,IAAI,mBACJ,qBACC;;;;;wBCpMa,aAAa;;;wBAcb,SAAS;;;;;;;;wBCXT,aAAa,IAAI,mBAAmB;;;;;wBCDpC,YACd,YACA,YACA,YACA,aACC;;;wBAYa,OAAO,QAAQ;;;wBAkBf,UACd,aACA,aACA;;;wBAoBc,YACd,uBACA,cACA;;;;;;qBC1DW,YAAY;;;;qBAsBZ,WAAW;;;;wBAmCR,aACd,KAAK,uBACL,6BACC;;;;;;wBC/Ca,aAAa,aAAa,aAAa"}
package/dist/index.d.mts CHANGED
@@ -209,24 +209,35 @@ interface ChartOptions {
209
209
  maxPoints?: number;
210
210
  /**
211
211
  * Render backend for xy series (line/area/sparkline/scatter). `"canvas"`
212
- * (default) uses Canvas2D. `"webgpu"` rasterizes series on the GPU —
213
- * instanced lines and point sprites — while axes, grid, and tooltips stay
214
- * on Canvas2D. `"auto"` uses WebGPU when available, else Canvas2D.
212
+ * uses Canvas2D. `"webgpu"` rasterizes series on the GPU — instanced
213
+ * lines, point sprites, compute decimation — while axes, grid, and
214
+ * tooltips stay on Canvas2D. `"auto"` (default) engages WebGPU once the
215
+ * point count crosses `gpuThreshold`, else Canvas2D.
215
216
  * Unknown to older browsers → silent fallback to Canvas2D.
216
217
  */
217
218
  renderer?: "auto" | "canvas" | "webgpu";
219
+ /**
220
+ * For `renderer: "auto"`: total visible xy points (x-length × series) at
221
+ * which the GPU path engages. Below this, Canvas2D is faster. Once the
222
+ * GPU attaches it stays attached for the chart's lifetime.
223
+ * Default: 100,000.
224
+ */
225
+ gpuThreshold?: number;
218
226
  /**
219
227
  * WebGPU adapter options — only used when `renderer` resolves to WebGPU.
220
228
  * `powerPreference` picks the discrete GPU on dual-GPU systems;
221
229
  * `compat` requests compatibility mode (GLES 3.1 / D3D11 reach);
222
230
  * `timing` enables GPU-side pass timing via "timestamp-query" when the
223
- * adapter supports it (note: browsers quantize to ~100 µs unless the
224
- * WebGPU developer-features flag is enabled).
231
+ * adapter supports it (note: browsers require cross-origin isolation and
232
+ * quantize to ~100 µs — dev/profiling use only);
233
+ * `allowFallback` accepts software adapters like SwiftShader (off by
234
+ * default — usually slower than Canvas2D).
225
235
  */
226
236
  gpu?: {
227
237
  powerPreference?: "default" | "low-power" | "high-performance";
228
238
  compat?: boolean;
229
239
  timing?: boolean;
240
+ allowFallback?: boolean;
230
241
  };
231
242
  /**
232
243
  * Canvas2D context settings passed to `getContext("2d", …)` for all layers.
@@ -247,6 +258,14 @@ interface ChartOptions {
247
258
  x?: (v: number) => string;
248
259
  y?: (v: number) => string;
249
260
  };
261
+ /**
262
+ * Pin the y-axis domain. Each bound overrides the auto-fitted value —
263
+ * unset ends still auto-fit. E.g. `{ yMin: 0, yMax: 100 }` frames a
264
+ * utilization chart honestly; `{ yMin: 0 }` zero-anchors without a
265
+ * ceiling. Values exceeding the bounds are clipped at the plot edge.
266
+ */
267
+ yMin?: number;
268
+ yMax?: number;
250
269
  /** Called on pointer hover with the nearest hit, or `null` on leave. */
251
270
  onHover?: (info: HoverInfo | null) => void;
252
271
  }
@@ -294,23 +313,37 @@ export declare class Chart {
294
313
  private destroyed;
295
314
  private pendingView;
296
315
  private gpu;
316
+ private gpuInit;
317
+ /** bumped whenever xy data is replaced or reordered — triggers GPU re-upload */
318
+ private dataRev;
297
319
  private lastAppendAt;
298
320
  private estInterval;
299
321
  private onScroll;
300
322
  private frame;
301
323
  constructor(el: HTMLElement, options: ChartOptions);
324
+ /**
325
+ * Lazily acquire the WebGPU backend. `"webgpu"` attaches unconditionally;
326
+ * `"auto"` waits until the xy point count crosses `gpuThreshold` — small
327
+ * charts never pay adapter/device acquisition.
328
+ */
329
+ private maybeInitGpu;
302
330
  private normalize;
303
331
  private bindEvents;
304
332
  private onMove;
305
333
  private onLeave;
306
334
  private layout;
307
335
  private domains;
336
+ private yDomain;
308
337
  private lerpView;
309
338
  private makeScales;
310
339
  private renderContext;
311
340
  private drawStatic;
312
341
  private render;
313
- /** series rasterization on the GPU; grid/labels/hover stay on Canvas2D */
342
+ /**
343
+ * Series rasterization on the GPU; grid/labels/hover stay on Canvas2D.
344
+ * Raw data lives in GPU buffers — the per-frame cost is uniform writes +
345
+ * instanced draws, with compute decimation above the density threshold.
346
+ */
314
347
  private gpuRender;
315
348
  private drawHover;
316
349
  private applyHover;
@@ -387,6 +420,9 @@ export declare function extent(values: ArrayLike<number>): [number, number];
387
420
  /** @category Utilities
388
421
  * Pad a domain by 5% on each end; `includeZero` anchors the axis at 0. */
389
422
  export declare function padDomain(min: number, max: number, includeZero?: boolean): [number, number];
423
+ /** @category Utilities
424
+ * Pin domain ends — each defined bound overrides the fitted value. */
425
+ export declare function boundDomain(dom: [number, number], min?: number, max?: number): [number, number];
390
426
  //#endregion
391
427
  //#region src/core/theme.d.ts
392
428
  /** Built-in light theme.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/types.ts","../src/core/chart.ts","../src/core/decimate.ts","../src/core/format.ts","../src/core/hit.ts","../src/core/scales.ts","../src/core/theme.ts","../src/core/ticks.ts"],"mappings":";;;;;KAIY;;;;;UAiBK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;UAOe;EACf;EACA;EACA,GAAG;;;;;UAMY;EACf,GAAG;EACH,QAAQ;;;;;;KAOE;;;;;UAMK;EACf;EACA;;EAEA,OAAO;EACP,QAAQ;;;;;;UAOO;EACf;EACA,QAAQ;;;;;;UAOO;EACf;EACA;EACA;;;;;;UAOe;EACf,QAAQ;;;;;;UAOO;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;UAOe;EACf,SAAS;;;;;;UAOM;EACf;;EAEA,QAAQ;;EAER;;;;;KAMU,YACR,SACA,eACA,YACA,WACA;;;;;KAMQ;;;;;KAMA;EAEN;EACA;EACA;EACA;EACA;EACA;IAAU;IAAe;IAAe;;;EAExC;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;;EAGN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;UAOW;EACf,MAAM;EACN,MAAM;EACN,2BAA2B,QAAQ;;EAEnC;EACA,QAAQ;EACR;EACA;EACA;;EAEA;;;;;;;;EAQA;;;;;;EAMA;;;;;;;EAOA;;;;;;;;EASA;;;;;;;;;EASA;IACE;IACA;IACA;;;;;;;;;EASF,SAAS;;EAET;;EAEA;;EAEA;;EAEA;IACE,KAAK;IACL,KAAK;;;EAGP,WAAW,MAAM;;;;;UAMF;EACf;EACA;EACA;EACA;;;;;UAMe;GACd;EACD,OAAO;EACP;EACA;;;;;;;qBCnLW;WACF,IAAI;WACJ,SAAS;UACV;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UAIA;UACA;UAIA;UACA;UACA;UACA;UACA;UACA;UACA;UAGA;EAkCR,YAAY,IAAI,aAAa,SAAS;UA6C9B;UAmIA;UAUA;UASA;UAUA;UAkCA;UAoGA;UAiBA;UAmBA;UAeA;UA8EA;;UAUA;UA0CA;UA8DA;UA4DA;UAaA;;EAcR,QAAQ,MAAM;;;;;;EAYd,OAAO,WAAW;;EAoFlB;;EAoBA;;;;;;;;;;;;;;;;;;wBAmDc,YAAY,IAAI,aAAa,SAAS,eAAe;;;;;;;;;;;;;;wBC9zBrD,WACd,IAAI,mBACJ,IAAI,mBACJ,qBACC;;;;;wBCpMa,aAAa;;;wBAcb,SAAS;;;;;;;;wBCXT,aAAa,IAAI,mBAAmB;;;;;wBCDpC,YACd,YACA,YACA,YACA,aACC;;;wBAYa,OAAO,QAAQ;;;wBAkBf,UACd,aACA,aACA;;;;;;qBCnCW,YAAY;;;;qBAsBZ,WAAW;;;;wBAmCR,aACd,KAAK,uBACL,6BACC;;;;;;wBC/Ca,aAAa,aAAa,aAAa"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/types.ts","../src/core/chart.ts","../src/core/decimate.ts","../src/core/format.ts","../src/core/hit.ts","../src/core/scales.ts","../src/core/theme.ts","../src/core/ticks.ts"],"mappings":";;;;;KAIY;;;;;UAiBK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;UAOe;EACf;EACA;EACA,GAAG;;;;;UAMY;EACf,GAAG;EACH,QAAQ;;;;;;KAOE;;;;;UAMK;EACf;EACA;;EAEA,OAAO;EACP,QAAQ;;;;;;UAOO;EACf;EACA,QAAQ;;;;;;UAOO;EACf;EACA;EACA;;;;;;UAOe;EACf,QAAQ;;;;;;UAOO;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;UAOe;EACf,SAAS;;;;;;UAOM;EACf;;EAEA,QAAQ;;EAER;;;;;KAMU,YACR,SACA,eACA,YACA,WACA;;;;;KAMQ;;;;;KAMA;EAEN;EACA;EACA;EACA;EACA;EACA;IAAU;IAAe;IAAe;;;EAExC;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;;EAGN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;UAOW;EACf,MAAM;EACN,MAAM;EACN,2BAA2B,QAAQ;;EAEnC;EACA,QAAQ;EACR;EACA;EACA;;EAEA;;;;;;;;EAQA;;;;;;EAMA;;;;;;;EAOA;;;;;;;;;EAUA;;;;;;;EAOA;;;;;;;;;;;EAWA;IACE;IACA;IACA;IACA;;;;;;;;;EASF,SAAS;;EAET;;EAEA;;EAEA;;EAEA;IACE,KAAK;IACL,KAAK;;;;;;;;EAQP;EACA;;EAEA,WAAW,MAAM;;;;;UAMF;EACf;EACA;EACA;EACA;;;;;UAMe;GACd;EACD,OAAO;EACP;EACA;;;;;;;qBCrMW;WACF,IAAI;WACJ,SAAS;UACV;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UAIA;UACA;UAIA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;UACA;UAGA;EAkCR,YAAY,IAAI,aAAa,SAAS;;;;;;UA8B9B;UA8BA;UAmIA;UAUA;UASA;UAUA;UAkCA;UA0GA;UAIA;UAiBA;UAmBA;UAeA;UA8EA;;;;;;UAcA;UAiCA;UA8DA;UA4DA;UAaA;;EAcR,QAAQ,MAAM;;;;;;EAcd,OAAO,WAAW;;EAoGlB;;EAoBA;;;;;;;;;;;;;;;;;;wBAmDc,YAAY,IAAI,aAAa,SAAS,eAAe;;;;;;;;;;;;;;wBCx2BrD,WACd,IAAI,mBACJ,IAAI,mBACJ,qBACC;;;;;wBCpMa,aAAa;;;wBAcb,SAAS;;;;;;;;wBCXT,aAAa,IAAI,mBAAmB;;;;;wBCDpC,YACd,YACA,YACA,YACA,aACC;;;wBAYa,OAAO,QAAQ;;;wBAkBf,UACd,aACA,aACA;;;wBAoBc,YACd,uBACA,cACA;;;;;;qBC1DW,YAAY;;;;qBAsBZ,WAAW;;;;wBAmCR,aACd,KAAK,uBACL,6BACC;;;;;;wBC/Ca,aAAa,aAAa,aAAa"}
package/dist/index.mjs CHANGED
@@ -1380,6 +1380,11 @@ function padDomain(min, max, includeZero = false) {
1380
1380
  }
1381
1381
  return [lo, hi];
1382
1382
  }
1383
+ /** @category Utilities
1384
+ * Pin domain ends — each defined bound overrides the fitted value. */
1385
+ function boundDomain(dom, min, max) {
1386
+ return [min ?? dom[0], max ?? dom[1]];
1387
+ }
1383
1388
  //#endregion
1384
1389
  //#region src/core/scheduler.ts
1385
1390
  const raf = typeof requestAnimationFrame === "function" ? (cb) => requestAnimationFrame(cb) : (cb) => setTimeout(() => cb(Date.now()), 16);
@@ -1695,6 +1700,8 @@ const GPU_KIND = {
1695
1700
  };
1696
1701
  /** points retained beyond the window's left edge so they slide off-screen instead of vanishing mid-plot */
1697
1702
  const EDGE_KEEP = 3;
1703
+ /** default point count at which `renderer: "auto"` engages the GPU path */
1704
+ const GPU_THRESHOLD = 1e5;
1698
1705
  /** Chart instance. Create via {@link createChart}.
1699
1706
  * @category Charts
1700
1707
  */
@@ -1720,6 +1727,8 @@ var Chart = class {
1720
1727
  this.destroyed = false;
1721
1728
  this.pendingView = false;
1722
1729
  this.gpu = null;
1730
+ this.gpuInit = false;
1731
+ this.dataRev = 0;
1723
1732
  this.lastAppendAt = 0;
1724
1733
  this.estInterval = 400;
1725
1734
  this.onScroll = () => {
@@ -1782,7 +1791,35 @@ var Chart = class {
1782
1791
  this.reduced = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
1783
1792
  if (options.tooltip ?? this.mod.defaultTooltip) this.tooltip = new Tooltip(el, this.theme);
1784
1793
  this.data = this.normalize(options.data, null);
1785
- if (GPU_KIND[options.type] && (options.renderer === "webgpu" || options.renderer === "auto")) import("./series-BdprL87H.mjs").then(({ GpuSeries }) => GpuSeries.create(options.gpu).then((g) => {
1794
+ this.maybeInitGpu();
1795
+ this.bindEvents();
1796
+ const dom = this.layout();
1797
+ this.view = {
1798
+ x: [...dom.x],
1799
+ y: [...dom.y]
1800
+ };
1801
+ this.viewTo = {
1802
+ x: [...dom.x],
1803
+ y: [...dom.y]
1804
+ };
1805
+ this.startAnimation(dom);
1806
+ }
1807
+ /**
1808
+ * Lazily acquire the WebGPU backend. `"webgpu"` attaches unconditionally;
1809
+ * `"auto"` waits until the xy point count crosses `gpuThreshold` — small
1810
+ * charts never pay adapter/device acquisition.
1811
+ */
1812
+ maybeInitGpu() {
1813
+ if (this.gpu || this.gpuInit || this.destroyed) return;
1814
+ if (!GPU_KIND[this.options.type]) return;
1815
+ const r = this.options.renderer ?? "auto";
1816
+ if (r !== "auto" && r !== "webgpu") return;
1817
+ if (r === "auto") {
1818
+ const d = this.data;
1819
+ if ((d.kind === "xy" ? d.sortedX.length * Math.max(1, d.series.length) : 0) < (this.options.gpuThreshold ?? GPU_THRESHOLD)) return;
1820
+ }
1821
+ this.gpuInit = true;
1822
+ import("./series-wyqYpkXm.mjs").then(({ GpuSeries }) => GpuSeries.create(this.options.gpu).then((g) => {
1786
1823
  if (!g || this.destroyed) {
1787
1824
  g?.destroy();
1788
1825
  return;
@@ -1795,17 +1832,6 @@ var Chart = class {
1795
1832
  return false;
1796
1833
  });
1797
1834
  }));
1798
- this.bindEvents();
1799
- const dom = this.layout();
1800
- this.view = {
1801
- x: [...dom.x],
1802
- y: [...dom.y]
1803
- };
1804
- this.viewTo = {
1805
- x: [...dom.x],
1806
- y: [...dom.y]
1807
- };
1808
- this.startAnimation(dom);
1809
1835
  }
1810
1836
  normalize(data, prev) {
1811
1837
  const t = this.options.type;
@@ -2001,7 +2027,7 @@ var Chart = class {
2001
2027
  const includeZero = this.options.type === "area" || this.options.type === "sparkline";
2002
2028
  return {
2003
2029
  x,
2004
- y: padDomain(min, max, includeZero)
2030
+ y: this.yDomain(padDomain(min, max, includeZero))
2005
2031
  };
2006
2032
  }
2007
2033
  if (d.kind === "category") {
@@ -2037,7 +2063,7 @@ var Chart = class {
2037
2063
  }
2038
2064
  return {
2039
2065
  x: [0, d.categories.length],
2040
- y: padDomain(min, max, true)
2066
+ y: this.yDomain(padDomain(min, max, true))
2041
2067
  };
2042
2068
  }
2043
2069
  if (d.kind === "ohlc") {
@@ -2056,7 +2082,7 @@ var Chart = class {
2056
2082
  }
2057
2083
  return {
2058
2084
  x,
2059
- y: padDomain(min, max)
2085
+ y: this.yDomain(padDomain(min, max))
2060
2086
  };
2061
2087
  }
2062
2088
  if (d.kind === "waterfall") {
@@ -2072,14 +2098,17 @@ var Chart = class {
2072
2098
  }
2073
2099
  return {
2074
2100
  x: [0, d.bars.length],
2075
- y: padDomain(min, max, true)
2101
+ y: this.yDomain(padDomain(min, max, true))
2076
2102
  };
2077
2103
  }
2078
2104
  return {
2079
2105
  x: [0, 1],
2080
- y: [0, 1]
2106
+ y: this.yDomain([0, 1])
2081
2107
  };
2082
2108
  }
2109
+ yDomain(y) {
2110
+ return boundDomain(y, this.options.yMin, this.options.yMax);
2111
+ }
2083
2112
  lerpView(eased) {
2084
2113
  const f = this.viewFrom;
2085
2114
  const to = this.viewTo;
@@ -2181,30 +2210,35 @@ var Chart = class {
2181
2210
  else this.mod.render(this.renderContext(t, scales));
2182
2211
  if (this.hover) this.drawHover(this.hover, scales.yScale);
2183
2212
  }
2184
- /** series rasterization on the GPU; grid/labels/hover stay on Canvas2D */
2213
+ /**
2214
+ * Series rasterization on the GPU; grid/labels/hover stay on Canvas2D.
2215
+ * Raw data lives in GPU buffers — the per-frame cost is uniform writes +
2216
+ * instanced draws, with compute decimation above the density threshold.
2217
+ */
2185
2218
  gpuRender(t, scales) {
2186
2219
  const g = this.gpu;
2187
2220
  const d = this.data;
2188
2221
  const kind = GPU_KIND[this.options.type];
2189
- if (!g || !kind || d.kind !== "xy") {
2222
+ if (!g || g.unavailable || !kind || d.kind !== "xy") {
2190
2223
  this.mod.render(this.renderContext(t, scales));
2191
2224
  return;
2192
2225
  }
2193
- const r = this.renderContext(t, scales);
2226
+ g.syncData(d, this.dataRev);
2227
+ const view = {
2228
+ x: scales.xScale.domain,
2229
+ y: scales.yScale.domain
2230
+ };
2194
2231
  const flow = this.options.flow ? FLOW_RIPPLE : 0;
2195
- g.begin(this.backend.plot);
2196
- for (const s of d.series) {
2232
+ g.begin(this.backend.plot, t, flow);
2233
+ for (let i = 0; i < d.series.length; i++) {
2234
+ const s = d.series[i];
2235
+ if (!s) continue;
2197
2236
  if (kind === "points") {
2198
- const pts = mapSeriesPx(d.sortedX, s.y, s.prevY, t, scales.yScale.domain[0], scales.xScale, scales.yScale, flow);
2199
- g.points(pts, s.color, 2.5, .65);
2237
+ g.points(i, s.color, 2.5, .65, view);
2200
2238
  continue;
2201
2239
  }
2202
- const pts = seriesPoints(r, s);
2203
- if (kind === "area") {
2204
- const base = scales.yScale(Math.max(0, scales.yScale.domain[0]));
2205
- g.area(pts, s.color, base, this.backend.plot);
2206
- }
2207
- g.line(pts, s.color, 2);
2240
+ if (kind === "area") g.area(i, s.color, Math.max(0, scales.yScale.domain[0]), view);
2241
+ g.line(i, s.color, 2, view);
2208
2242
  }
2209
2243
  g.end();
2210
2244
  }
@@ -2339,6 +2373,8 @@ var Chart = class {
2339
2373
  setData(data) {
2340
2374
  const prev = this.data;
2341
2375
  this.data = this.normalize(data, prev);
2376
+ this.dataRev++;
2377
+ this.maybeInitGpu();
2342
2378
  const dom = this.layout();
2343
2379
  this.startAnimation(dom);
2344
2380
  }
@@ -2404,8 +2440,14 @@ var Chart = class {
2404
2440
  sortedX,
2405
2441
  series
2406
2442
  };
2407
- if (m > 1 && x < sortedX[m - 2]) resortXY(nd);
2443
+ const resort = m > 1 && x < sortedX[m - 2];
2444
+ if (resort) resortXY(nd);
2408
2445
  this.data = nd;
2446
+ if (resort) this.dataRev++;
2447
+ else if (this.gpu && !this.gpu.unavailable) {
2448
+ 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++;
2449
+ }
2450
+ this.maybeInitGpu();
2409
2451
  this.pendingView = true;
2410
2452
  sharedScheduler.add(this.frame);
2411
2453
  }
@@ -2480,6 +2522,6 @@ function createChart(el, options) {
2480
2522
  return new Chart(el, options);
2481
2523
  }
2482
2524
  //#endregion
2483
- export { Chart, computeTicks, createChart, darkTheme, decimateM4, extent, formatNumber, formatSI, lightTheme, linearScale, nearestIndex, padDomain, resolveTheme };
2525
+ export { Chart, boundDomain, computeTicks, createChart, darkTheme, decimateM4, extent, formatNumber, formatSI, lightTheme, linearScale, nearestIndex, padDomain, resolveTheme };
2484
2526
 
2485
2527
  //# sourceMappingURL=index.mjs.map