velo-plot 1.15.0 → 1.19.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.
Files changed (80) hide show
  1. package/dist/{ChartCore-BimVvUEg.js → ChartCore-DQ691eXH.js} +1523 -996
  2. package/dist/ChartCore-DQ691eXH.js.map +1 -0
  3. package/dist/assets/downsample.worker-C70QJ04y.js +2 -0
  4. package/dist/assets/downsample.worker-C70QJ04y.js.map +1 -0
  5. package/dist/assets/indicator.worker-bv0zC4EX.js +2 -0
  6. package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -0
  7. package/dist/core/OverlayRenderer.d.ts +2 -0
  8. package/dist/core/chart/ChartAlerts.d.ts +42 -0
  9. package/dist/core/chart/ChartCore.d.ts +19 -1
  10. package/dist/core/chart/ChartRenderLoop.d.ts +4 -2
  11. package/dist/core/chart/ChartRenderer.d.ts +3 -2
  12. package/dist/core/chart/candlestickMarkers.d.ts +23 -0
  13. package/dist/core/chart/heikinAshi.d.ts +10 -0
  14. package/dist/core/chart/series/types.d.ts +2 -2
  15. package/dist/core/chart/types.d.ts +7 -0
  16. package/dist/core/indicator/addIndicator.d.ts +36 -0
  17. package/dist/core/indicator/index.d.ts +2 -0
  18. package/dist/core/indicator/indicatorPresets.d.ts +37 -0
  19. package/dist/core/series/Series.d.ts +3 -0
  20. package/dist/core/stacked/types.d.ts +8 -0
  21. package/dist/core/time/TimeScale.d.ts +31 -0
  22. package/dist/createStackedChart-BPooTQ9z.js +1164 -0
  23. package/dist/createStackedChart-BPooTQ9z.js.map +1 -0
  24. package/dist/gpu/adapter/gpuRenderer.d.ts +21 -0
  25. package/dist/gpu/backends/webgpu/WebGPUBackend.d.ts +2 -1
  26. package/dist/gpuRenderer-BpaMYz-k.js +1848 -0
  27. package/dist/gpuRenderer-BpaMYz-k.js.map +1 -0
  28. package/dist/index-D7dTq6VB.js +503 -0
  29. package/dist/index-D7dTq6VB.js.map +1 -0
  30. package/dist/{index-Ce2JgkH_.js → index-DoYxf1cV.js} +86 -43
  31. package/dist/{index-Ce2JgkH_.js.map → index-DoYxf1cV.js.map} +1 -1
  32. package/dist/{index.core-C_-CFftD.js → index.core-BtGFYMOu.js} +2 -2
  33. package/dist/{index.core-C_-CFftD.js.map → index.core-BtGFYMOu.js.map} +1 -1
  34. package/dist/index.d.ts +12 -4
  35. package/dist/indicators--eJGmVox.js +302 -0
  36. package/dist/indicators--eJGmVox.js.map +1 -0
  37. package/dist/plugins/analysis.js +530 -807
  38. package/dist/plugins/analysis.js.map +1 -1
  39. package/dist/plugins/caching.js +26 -21
  40. package/dist/plugins/caching.js.map +1 -1
  41. package/dist/plugins/drawing-tools/index.d.ts +16 -0
  42. package/dist/plugins/gpu.js +202 -1895
  43. package/dist/plugins/gpu.js.map +1 -1
  44. package/dist/plugins/index.d.ts +2 -0
  45. package/dist/plugins/keyboard/index.d.ts +1 -7
  46. package/dist/plugins/keyboard.js +1 -1
  47. package/dist/plugins/lazy-load/types.d.ts +7 -0
  48. package/dist/plugins/lazy-load.js +131 -108
  49. package/dist/plugins/lazy-load.js.map +1 -1
  50. package/dist/plugins/replay/index.d.ts +19 -0
  51. package/dist/plugins/virtualization/types.d.ts +12 -0
  52. package/dist/plugins/virtualization.js +1 -1
  53. package/dist/pool-15HMCNv8.js +88 -0
  54. package/dist/pool-15HMCNv8.js.map +1 -0
  55. package/dist/react.js +2 -2
  56. package/dist/renderer/CandlestickRenderer.d.ts +1 -1
  57. package/dist/renderer/ChartSeriesRenderer.d.ts +6 -0
  58. package/dist/renderer/GpuChartRenderer.d.ts +23 -0
  59. package/dist/renderer/index.d.ts +3 -0
  60. package/dist/renderer/spike/WebGLGridSpike.d.ts +40 -0
  61. package/dist/testing/baselines/v1.15.0.json.d.ts +51 -0
  62. package/dist/testing/gridSpikeBenchmark.d.ts +49 -0
  63. package/dist/testing/index.d.ts +5 -0
  64. package/dist/testing/rendererBenchmark.d.ts +13 -0
  65. package/dist/testing/stage1BrowserBench.d.ts +42 -0
  66. package/dist/types.d.ts +21 -1
  67. package/dist/velo-plot.full.js +1322 -789
  68. package/dist/velo-plot.full.js.map +1 -1
  69. package/dist/velo-plot.js +20 -20
  70. package/dist/workers/downsample.d.ts +38 -0
  71. package/dist/workers/downsampleAsync.d.ts +6 -0
  72. package/dist/workers/indicator.worker.d.ts +32 -0
  73. package/dist/workers/indicatorsAsync.d.ts +26 -0
  74. package/dist/workers/pool.d.ts +36 -0
  75. package/package.json +11 -1
  76. package/dist/ChartCore-BimVvUEg.js.map +0 -1
  77. package/dist/createStackedChart-CjsKcOvX.js +0 -1088
  78. package/dist/createStackedChart-CjsKcOvX.js.map +0 -1
  79. package/dist/index-ChgIdk3N.js +0 -229
  80. package/dist/index-ChgIdk3N.js.map +0 -1
@@ -1,9 +1,10 @@
1
- var L = Object.defineProperty;
2
- var F = (s, e, t) => e in s ? L(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var c = (s, e, t) => F(s, typeof e != "symbol" ? e + "" : e, t);
4
- class Te {
1
+ var B = Object.defineProperty;
2
+ var k = (p, e, i) => e in p ? B(p, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : p[e] = i;
3
+ var _ = (p, e, i) => k(p, typeof e != "symbol" ? e + "" : e, i);
4
+ import { G as q, S as W, a as I, W as Y, c as $, p as N } from "../gpuRenderer-BpaMYz-k.js";
5
+ class z {
5
6
  constructor() {
6
- c(this, "entries", /* @__PURE__ */ new Map());
7
+ _(this, "entries", /* @__PURE__ */ new Map());
7
8
  }
8
9
  getInfo(e) {
9
10
  return this.entries.get(e);
@@ -18,9 +19,9 @@ class Te {
18
19
  return this.entries.size;
19
20
  }
20
21
  }
21
- class Me {
22
+ class R {
22
23
  constructor() {
23
- c(this, "entries", /* @__PURE__ */ new Map());
24
+ _(this, "entries", /* @__PURE__ */ new Map());
24
25
  }
25
26
  getInfo(e) {
26
27
  return this.entries.get(e);
@@ -35,26 +36,26 @@ class Me {
35
36
  return this.entries.size;
36
37
  }
37
38
  }
38
- function S(s) {
39
- return s.variant ? `${s.kind}:${s.variant}` : s.kind;
39
+ function w(p) {
40
+ return p.variant ? `${p.kind}:${p.variant}` : p.kind;
40
41
  }
41
- class ke {
42
+ class E {
42
43
  constructor() {
43
- c(this, "pipelines", /* @__PURE__ */ new Map());
44
+ _(this, "pipelines", /* @__PURE__ */ new Map());
44
45
  }
45
- getOrCreate(e, t) {
46
- const i = S(e);
47
- if (!this.pipelines.has(i)) {
48
- const r = t();
49
- this.pipelines.set(i, r);
46
+ getOrCreate(e, i) {
47
+ const t = w(e);
48
+ if (!this.pipelines.has(t)) {
49
+ const a = i();
50
+ this.pipelines.set(t, a);
50
51
  }
51
- return this.pipelines.get(i);
52
+ return this.pipelines.get(t);
52
53
  }
53
54
  has(e) {
54
- return this.pipelines.has(S(e));
55
+ return this.pipelines.has(w(e));
55
56
  }
56
57
  delete(e) {
57
- this.pipelines.delete(S(e));
58
+ this.pipelines.delete(w(e));
58
59
  }
59
60
  get size() {
60
61
  return this.pipelines.size;
@@ -63,1853 +64,159 @@ class ke {
63
64
  this.pipelines.clear();
64
65
  }
65
66
  }
66
- function U(s) {
67
- if (!s)
68
- return [1, 0, 0.3, 1];
69
- if (Array.isArray(s))
70
- return [s[0], s[1], s[2], s[3] ?? 1];
71
- const e = s;
72
- if (e.startsWith("#")) {
73
- const i = e.slice(1);
74
- if (i.length === 3) {
75
- const r = parseInt(i[0] + i[0], 16) / 255, a = parseInt(i[1] + i[1], 16) / 255, n = parseInt(i[2] + i[2], 16) / 255;
76
- return [r, a, n, 1];
77
- }
78
- if (i.length === 6) {
79
- const r = parseInt(i.slice(0, 2), 16) / 255, a = parseInt(i.slice(2, 4), 16) / 255, n = parseInt(i.slice(4, 6), 16) / 255;
80
- return [r, a, n, 1];
81
- }
82
- if (i.length === 8) {
83
- const r = parseInt(i.slice(0, 2), 16) / 255, a = parseInt(i.slice(2, 4), 16) / 255, n = parseInt(i.slice(4, 6), 16) / 255, o = parseInt(i.slice(6, 8), 16) / 255;
84
- return [r, a, n, o];
85
- }
86
- }
87
- const t = e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
88
- if (t) {
89
- const i = parseInt(t[1]) / 255, r = parseInt(t[2]) / 255, a = parseInt(t[3]) / 255, n = t[4] ? parseFloat(t[4]) : 1;
90
- return [i, r, a, n];
91
- }
92
- return [1, 0, 0.3, 1];
93
- }
94
- function D(s, e) {
95
- const t = U(s.color), i = s.opacity ?? 1, r = [t[0], t[1], t[2], t[3] * i];
96
- return e === "scatter" || e === "line+scatter" || e === "step+scatter" ? {
97
- color: r,
98
- opacity: i,
99
- pointSize: s.pointSize ?? 4,
100
- symbol: s.symbol ?? "circle"
101
- } : {
102
- color: r,
103
- opacity: i,
104
- lineWidth: s.lineWidth ?? 1
105
- };
106
- }
107
- class M {
108
- constructor(e) {
109
- c(this, "backend");
110
- c(this, "seriesBufferMap", /* @__PURE__ */ new Map());
111
- c(this, "seriesStepBufferMap", /* @__PURE__ */ new Map());
112
- c(this, "seriesTextureMap", /* @__PURE__ */ new Map());
113
- this.backend = e;
114
- }
115
- /**
116
- * Get buffer ID for a series
117
- */
118
- getBufferId(e) {
119
- return this.seriesBufferMap.has(e) || this.seriesBufferMap.set(e, `series:${e}`), this.seriesBufferMap.get(e);
120
- }
121
- /**
122
- * Get step buffer ID for a series
123
- */
124
- getStepBufferId(e) {
125
- return this.seriesStepBufferMap.has(e) || this.seriesStepBufferMap.set(e, `series:${e}:step`), this.seriesStepBufferMap.get(e);
126
- }
127
- /**
128
- * Get texture ID for a series
129
- */
130
- getTextureId(e) {
131
- return this.seriesTextureMap.has(e) || this.seriesTextureMap.set(e, `texture:${e}`), this.seriesTextureMap.get(e);
132
- }
133
- /**
134
- * Update series data in GPU buffers
135
- */
136
- updateSeries(e) {
137
- const t = this.getBufferId(e.id);
138
- if (this.backend.createOrUpdateBuffer(t, e.data, { usage: "vertex" }), e.stepData && (e.type === "step" || e.type === "step+scatter")) {
139
- const i = this.getStepBufferId(e.id);
140
- this.backend.createOrUpdateBuffer(i, e.stepData, { usage: "vertex" });
141
- }
142
- if (e.type === "heatmap" && e.colormapData) {
143
- const i = this.getTextureId(e.id);
144
- this.backend.createOrUpdateTexture1D(i, e.colormapData, {
145
- width: e.colormapData.length / 4
146
- });
147
- }
148
- }
149
- /**
150
- * Remove a series from GPU resources
151
- */
152
- removeSeries(e) {
153
- const t = this.seriesBufferMap.get(e);
154
- t && (this.backend.deleteBuffer(t), this.seriesBufferMap.delete(e));
155
- const i = this.seriesStepBufferMap.get(e);
156
- i && (this.backend.deleteBuffer(i), this.seriesStepBufferMap.delete(e));
157
- const r = this.seriesTextureMap.get(e);
158
- r && (this.backend.deleteTexture(r), this.seriesTextureMap.delete(e));
159
- }
160
- /**
161
- * Build draw list from series array
162
- */
163
- buildDrawList(e) {
164
- const t = [];
165
- for (const i of e) {
166
- this.updateSeries(i);
167
- const r = this.getBufferId(i.id), a = i.data.length / 2, n = {
168
- id: i.id,
169
- kind: i.type,
170
- bufferId: r,
171
- count: i.type === "heatmap" ? i.data.length / 3 : a,
172
- visible: i.visible,
173
- style: D(i.style, i.type),
174
- yBounds: i.yBounds
175
- };
176
- i.stepData && (i.type === "step" || i.type === "step+scatter") && (n.stepBufferId = this.getStepBufferId(i.id), n.stepCount = i.stepData.length / 2), i.type === "heatmap" && (n.textureId = this.getTextureId(i.id), n.style = {
177
- zBounds: i.zBounds,
178
- colormap: i.colormap
179
- }), t.push(n);
180
- }
181
- return { items: t };
182
- }
183
- /**
184
- * Cleanup all resources
185
- */
186
- destroy() {
187
- for (const e of this.seriesBufferMap.values())
188
- this.backend.deleteBuffer(e);
189
- for (const e of this.seriesStepBufferMap.values())
190
- this.backend.deleteBuffer(e);
191
- for (const e of this.seriesTextureMap.values())
192
- this.backend.deleteTexture(e);
193
- this.seriesBufferMap.clear(), this.seriesStepBufferMap.clear(), this.seriesTextureMap.clear();
194
- }
195
- }
196
- const I = `
197
- struct VSOut {
198
- @builtin(position) pos: vec4<f32>,
199
- @location(0) color: vec4<f32>,
200
- };
201
-
202
- @vertex
203
- fn vs_main(
204
- @location(0) position: vec2<f32>,
205
- @location(1) color: vec4<f32>
206
- ) -> VSOut {
207
- var out: VSOut;
208
- out.pos = vec4<f32>(position, 0.0, 1.0);
209
- out.color = color;
210
- return out;
211
- }
212
-
213
- @fragment
214
- fn fs_main(in: VSOut) -> @location(0) vec4<f32> {
215
- return in.color;
216
- }
217
- `;
218
- function O(s, e) {
219
- const t = s.createShaderModule({ code: I }), i = 6 * 4;
220
- return { pipeline: s.createRenderPipeline({
221
- layout: "auto",
222
- vertex: {
223
- module: t,
224
- entryPoint: "vs_main",
225
- buffers: [
226
- {
227
- arrayStride: i,
228
- attributes: [
229
- { shaderLocation: 0, offset: 0, format: "float32x2" },
230
- { shaderLocation: 1, offset: 2 * 4, format: "float32x4" }
231
- ]
232
- }
233
- ]
234
- },
235
- fragment: {
236
- module: t,
237
- entryPoint: "fs_main",
238
- targets: [{ format: e }]
239
- },
240
- primitive: {
241
- topology: "triangle-list",
242
- cullMode: "none"
243
- }
244
- }), vertexStride: i };
245
- }
246
- const C = `
247
- // Uniform buffer for transforms and color
248
- struct Uniforms {
249
- scale: vec2<f32>,
250
- translate: vec2<f32>,
251
- color: vec4<f32>,
252
- };
253
-
254
- @group(0) @binding(0)
255
- var<uniform> uniforms: Uniforms;
256
-
257
- struct VSInput {
258
- @location(0) position: vec2<f32>,
259
- };
260
-
261
- struct VSOutput {
262
- @builtin(position) pos: vec4<f32>,
263
- };
264
-
265
- @vertex
266
- fn vs_main(in: VSInput) -> VSOutput {
267
- var out: VSOutput;
268
- let transformed = in.position * uniforms.scale + uniforms.translate;
269
- out.pos = vec4<f32>(transformed, 0.0, 1.0);
270
- return out;
271
- }
272
-
273
- @fragment
274
- fn fs_main(in: VSOutput) -> @location(0) vec4<f32> {
275
- return uniforms.color;
276
- }
277
- `, w = 2 * 4, z = 32;
278
- function V(s, e) {
279
- const t = s.createShaderModule({ code: C }), i = globalThis.GPUShaderStage, r = globalThis.GPUBufferUsage, a = s.createBindGroupLayout({
280
- entries: [
281
- {
282
- binding: 0,
283
- visibility: i.VERTEX | i.FRAGMENT,
284
- buffer: { type: "uniform" }
285
- }
286
- ]
287
- }), n = s.createBuffer({
288
- size: z,
289
- usage: r.UNIFORM | r.COPY_DST
290
- }), o = s.createBindGroup({
291
- layout: a,
292
- entries: [
293
- {
294
- binding: 0,
295
- resource: { buffer: n }
296
- }
297
- ]
298
- }), u = s.createPipelineLayout({
299
- bindGroupLayouts: [a]
300
- });
301
- return {
302
- pipeline: s.createRenderPipeline({
303
- layout: u,
304
- vertex: {
305
- module: t,
306
- entryPoint: "vs_main",
307
- buffers: [
308
- {
309
- arrayStride: w,
310
- attributes: [
311
- { shaderLocation: 0, offset: 0, format: "float32x2" }
312
- ]
313
- }
314
- ]
315
- },
316
- fragment: {
317
- module: t,
318
- entryPoint: "fs_main",
319
- targets: [
320
- {
321
- format: e,
322
- blend: {
323
- color: {
324
- srcFactor: "src-alpha",
325
- dstFactor: "one-minus-src-alpha",
326
- operation: "add"
327
- },
328
- alpha: {
329
- srcFactor: "one",
330
- dstFactor: "one-minus-src-alpha",
331
- operation: "add"
332
- }
333
- }
334
- }
335
- ]
336
- },
337
- primitive: {
338
- topology: "line-strip",
339
- stripIndexFormat: void 0
340
- }
341
- }),
342
- bindGroupLayout: a,
343
- uniformBuffer: n,
344
- bindGroup: o,
345
- vertexStride: w
346
- };
347
- }
348
- function W(s, e, t) {
349
- const i = new Float32Array([
350
- t.scale[0],
351
- t.scale[1],
352
- t.translate[0],
353
- t.translate[1],
354
- t.color[0],
355
- t.color[1],
356
- t.color[2],
357
- t.color[3]
358
- ]);
359
- s.queue.writeBuffer(e, 0, i);
360
- }
361
- const N = `
362
- // Uniform buffer for transforms, color, point properties
363
- struct Uniforms {
364
- scale: vec2<f32>,
365
- translate: vec2<f32>,
366
- color: vec4<f32>,
367
- pointSize: f32,
368
- symbol: i32,
369
- viewport: vec2<f32>, // viewport dimensions for proper sizing
370
- };
371
-
372
- @group(0) @binding(0)
373
- var<uniform> uniforms: Uniforms;
374
-
375
- struct VSInput {
376
- @location(0) position: vec2<f32>, // point center position
377
- @location(1) quadOffset: vec2<f32>, // quad vertex offset (-1 to 1)
378
- };
379
-
380
- struct VSOutput {
381
- @builtin(position) pos: vec4<f32>,
382
- @location(0) uv: vec2<f32>, // -0.5 to 0.5 for SDF
383
- };
384
-
385
- @vertex
386
- fn vs_main(in: VSInput) -> VSOutput {
387
- var out: VSOutput;
388
-
389
- // Transform point position to NDC
390
- let transformed = in.position * uniforms.scale + uniforms.translate;
391
-
392
- // Calculate point size in NDC
393
- let pointSizeNDC = vec2<f32>(
394
- uniforms.pointSize / uniforms.viewport.x * 2.0,
395
- uniforms.pointSize / uniforms.viewport.y * 2.0
396
- );
397
-
398
- // Apply quad offset
399
- let offset = in.quadOffset * pointSizeNDC * 0.5;
400
-
401
- out.pos = vec4<f32>(transformed + offset, 0.0, 1.0);
402
- out.uv = in.quadOffset * 0.5; // -0.5 to 0.5
403
-
404
- return out;
405
- }
406
-
407
- // SDF functions
408
- fn sdCircle(p: vec2<f32>, r: f32) -> f32 {
409
- return length(p) - r;
410
- }
411
-
412
- fn sdBox(p: vec2<f32>, b: vec2<f32>) -> f32 {
413
- let d = abs(p) - b;
414
- return length(max(d, vec2<f32>(0.0))) + min(max(d.x, d.y), 0.0);
415
- }
416
-
417
- fn sdDiamond(p: vec2<f32>, r: f32) -> f32 {
418
- return (abs(p.x) + abs(p.y)) - r;
419
- }
420
-
421
- fn sdTriangle(p_in: vec2<f32>, r: f32) -> f32 {
422
- let k = sqrt(3.0);
423
- var p = p_in;
424
- p.x = abs(p.x) - r;
425
- p.y = p.y + r / k;
426
- if (p.x + k * p.y > 0.0) {
427
- p = vec2<f32>(p.x - k * p.y, -k * p.x - p.y) / 2.0;
428
- }
429
- p.x = p.x - clamp(p.x, -2.0 * r, 0.0);
430
- return -length(p) * sign(p.y);
431
- }
432
-
433
- fn sdCross(p: vec2<f32>, r: f32, thickness: f32) -> f32 {
434
- let d = abs(p);
435
- let s1 = sdBox(d, vec2<f32>(r, thickness));
436
- let s2 = sdBox(d, vec2<f32>(thickness, r));
437
- return min(s1, s2);
438
- }
439
-
440
- fn sdX(p: vec2<f32>, r: f32, thickness: f32) -> f32 {
441
- let c = cos(0.785398);
442
- let s = sin(0.785398);
443
- let m = mat2x2<f32>(c, -s, s, c);
444
- return sdCross(m * p, r, thickness);
445
- }
446
-
447
- fn sdStar(p_in: vec2<f32>, r: f32, rf: f32) -> f32 {
448
- let k1 = vec2<f32>(0.80901699, -0.58778525);
449
- let k2 = vec2<f32>(-k1.x, k1.y);
450
- var p = p_in;
451
- p.x = abs(p.x);
452
- p = p - 2.0 * max(dot(k1, p), 0.0) * k1;
453
- p = p - 2.0 * max(dot(k2, p), 0.0) * k2;
454
- p.x = abs(p.x);
455
- p.y = p.y - r;
456
- let ba = rf * vec2<f32>(-k1.y, k1.x) - vec2<f32>(0.0, 1.0);
457
- let h = clamp(dot(p, ba) / dot(ba, ba), 0.0, r);
458
- return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y);
459
- }
460
-
461
- @fragment
462
- fn fs_main(in: VSOutput) -> @location(0) vec4<f32> {
463
- var d: f32 = 0.0;
464
-
465
- if (uniforms.symbol == 0) {
466
- d = sdCircle(in.uv, 0.45);
467
- } else if (uniforms.symbol == 1) {
468
- d = sdBox(in.uv, vec2<f32>(0.35));
469
- } else if (uniforms.symbol == 2) {
470
- d = sdDiamond(in.uv, 0.45);
471
- } else if (uniforms.symbol == 3) {
472
- d = sdTriangle(vec2<f32>(in.uv.x, in.uv.y + 0.1), 0.4);
473
- } else if (uniforms.symbol == 4) {
474
- d = sdTriangle(vec2<f32>(in.uv.x, -in.uv.y + 0.1), 0.4);
475
- } else if (uniforms.symbol == 5) {
476
- d = sdCross(in.uv, 0.45, 0.15);
477
- } else if (uniforms.symbol == 6) {
478
- d = sdX(in.uv, 0.45, 0.15);
479
- } else if (uniforms.symbol == 7) {
480
- d = sdStar(in.uv, 0.45, 0.4);
481
- }
482
-
483
- if (d > 0.02) {
484
- discard;
485
- }
486
-
487
- let alpha = 1.0 - smoothstep(0.0, 0.02, d);
488
- return vec4<f32>(uniforms.color.rgb, uniforms.color.a * alpha);
489
- }
490
- `, k = 2 * 4, q = 48, A = new Float32Array([
491
- -1,
492
- -1,
493
- // bottom-left
494
- 1,
495
- -1,
496
- // bottom-right
497
- -1,
498
- 1,
499
- // top-left
500
- -1,
501
- 1,
502
- // top-left
503
- 1,
504
- -1,
505
- // bottom-right
506
- 1,
507
- 1
508
- // top-right
509
- ]);
510
- function Y(s, e) {
511
- const t = s.createShaderModule({ code: N }), i = globalThis.GPUShaderStage, r = globalThis.GPUBufferUsage, a = s.createBindGroupLayout({
512
- entries: [
513
- {
514
- binding: 0,
515
- visibility: i.VERTEX | i.FRAGMENT,
516
- buffer: { type: "uniform" }
517
- }
518
- ]
519
- }), n = s.createBuffer({
520
- size: q,
521
- usage: r.UNIFORM | r.COPY_DST
522
- }), o = s.createBuffer({
523
- size: A.byteLength,
524
- usage: r.VERTEX | r.COPY_DST,
525
- mappedAtCreation: !0
526
- });
527
- new Float32Array(o.getMappedRange()).set(A), o.unmap();
528
- const u = s.createBindGroup({
529
- layout: a,
530
- entries: [
531
- {
532
- binding: 0,
533
- resource: { buffer: n }
534
- }
535
- ]
536
- }), l = s.createPipelineLayout({
537
- bindGroupLayouts: [a]
538
- });
539
- return {
540
- pipeline: s.createRenderPipeline({
541
- layout: l,
542
- vertex: {
543
- module: t,
544
- entryPoint: "vs_main",
545
- buffers: [
546
- // Point positions (instanced)
547
- {
548
- arrayStride: k,
549
- stepMode: "instance",
550
- attributes: [
551
- { shaderLocation: 0, offset: 0, format: "float32x2" }
552
- ]
553
- },
554
- // Quad vertex offsets (per-vertex)
555
- {
556
- arrayStride: 8,
557
- // 2 floats
558
- stepMode: "vertex",
559
- attributes: [
560
- { shaderLocation: 1, offset: 0, format: "float32x2" }
561
- ]
562
- }
563
- ]
564
- },
565
- fragment: {
566
- module: t,
567
- entryPoint: "fs_main",
568
- targets: [
569
- {
570
- format: e,
571
- blend: {
572
- color: {
573
- srcFactor: "src-alpha",
574
- dstFactor: "one-minus-src-alpha",
575
- operation: "add"
576
- },
577
- alpha: {
578
- srcFactor: "one",
579
- dstFactor: "one-minus-src-alpha",
580
- operation: "add"
581
- }
582
- }
583
- }
584
- ]
585
- },
586
- primitive: {
587
- topology: "triangle-list",
588
- cullMode: "none"
589
- }
590
- }),
591
- bindGroupLayout: a,
592
- uniformBuffer: n,
593
- bindGroup: u,
594
- quadBuffer: o,
595
- vertexStride: k
596
- };
597
- }
598
- function X(s, e, t) {
599
- const i = new Float32Array([
600
- t.scale[0],
601
- t.scale[1],
602
- t.translate[0],
603
- t.translate[1],
604
- t.color[0],
605
- t.color[1],
606
- t.color[2],
607
- t.color[3],
608
- t.pointSize,
609
- t.symbol,
610
- // Will be cast to i32 in shader via bitcast
611
- t.viewport[0],
612
- t.viewport[1]
613
- ]);
614
- s.queue.writeBuffer(e, 0, i);
615
- }
616
- const $ = {
617
- circle: 0,
618
- square: 1,
619
- diamond: 2,
620
- triangle: 3,
621
- triangleDown: 4,
622
- cross: 5,
623
- x: 6,
624
- star: 7
625
- }, H = 32;
626
- function j(s, e) {
627
- const t = s.createShaderModule({ code: C }), i = globalThis.GPUShaderStage, r = globalThis.GPUBufferUsage, a = s.createBindGroupLayout({
628
- entries: [
629
- {
630
- binding: 0,
631
- visibility: i.VERTEX | i.FRAGMENT,
632
- buffer: { type: "uniform" }
633
- }
634
- ]
635
- }), n = s.createBuffer({
636
- size: H,
637
- usage: r.UNIFORM | r.COPY_DST
638
- }), o = s.createBindGroup({
639
- layout: a,
640
- entries: [
641
- {
642
- binding: 0,
643
- resource: { buffer: n }
644
- }
645
- ]
646
- }), u = s.createPipelineLayout({
647
- bindGroupLayouts: [a]
648
- });
649
- return {
650
- pipeline: s.createRenderPipeline({
651
- layout: u,
652
- vertex: {
653
- module: t,
654
- entryPoint: "vs_main",
655
- buffers: [
656
- {
657
- arrayStride: w,
658
- attributes: [
659
- { shaderLocation: 0, offset: 0, format: "float32x2" }
660
- ]
661
- }
662
- ]
663
- },
664
- fragment: {
665
- module: t,
666
- entryPoint: "fs_main",
667
- targets: [
668
- {
669
- format: e,
670
- blend: {
671
- color: {
672
- srcFactor: "src-alpha",
673
- dstFactor: "one-minus-src-alpha",
674
- operation: "add"
675
- },
676
- alpha: {
677
- srcFactor: "one",
678
- dstFactor: "one-minus-src-alpha",
679
- operation: "add"
680
- }
681
- }
682
- }
683
- ]
684
- },
685
- primitive: {
686
- topology: "triangle-strip",
687
- // Key difference from line pipeline
688
- stripIndexFormat: void 0
689
- }
690
- }),
691
- bindGroupLayout: a,
692
- uniformBuffer: n,
693
- bindGroup: o,
694
- vertexStride: w
695
- };
696
- }
697
- function Z(s, e, t) {
698
- const i = new Float32Array([
699
- t.scale[0],
700
- t.scale[1],
701
- t.translate[0],
702
- t.translate[1],
703
- t.color[0],
704
- t.color[1],
705
- t.color[2],
706
- t.color[3]
707
- ]);
708
- s.queue.writeBuffer(e, 0, i);
709
- }
710
- const K = `
711
- // Uniform buffer for transforms and value range
712
- struct Uniforms {
713
- scale: vec2<f32>,
714
- translate: vec2<f32>,
715
- minValue: f32,
716
- maxValue: f32,
717
- _padding: vec2<f32>,
718
- };
719
-
720
- @group(0) @binding(0)
721
- var<uniform> uniforms: Uniforms;
722
-
723
- @group(0) @binding(1)
724
- var colormapSampler: sampler;
725
-
726
- @group(0) @binding(2)
727
- var colormapTexture: texture_1d<f32>;
728
-
729
- struct VSInput {
730
- @location(0) position: vec2<f32>,
731
- @location(1) value: f32,
732
- };
733
-
734
- struct VSOutput {
735
- @builtin(position) pos: vec4<f32>,
736
- @location(0) value: f32,
737
- };
738
-
739
- @vertex
740
- fn vs_main(in: VSInput) -> VSOutput {
741
- var out: VSOutput;
742
- let transformed = in.position * uniforms.scale + uniforms.translate;
743
- out.pos = vec4<f32>(transformed, 0.0, 1.0);
744
- out.value = in.value;
745
- return out;
746
- }
747
-
748
- @fragment
749
- fn fs_main(in: VSOutput) -> @location(0) vec4<f32> {
750
- let range = uniforms.maxValue - uniforms.minValue;
751
- var t: f32;
752
- if (range != 0.0) {
753
- t = (in.value - uniforms.minValue) / range;
754
- } else {
755
- t = 0.0;
756
- }
757
- t = clamp(t, 0.0, 1.0);
758
-
759
- return textureSample(colormapTexture, colormapSampler, t);
760
- }
761
- `, G = 3 * 4, Q = 32;
762
- function J(s, e) {
763
- const t = s.createShaderModule({ code: K }), i = globalThis.GPUShaderStage, r = globalThis.GPUBufferUsage, a = s.createBindGroupLayout({
764
- entries: [
765
- {
766
- binding: 0,
767
- visibility: i.VERTEX | i.FRAGMENT,
768
- buffer: { type: "uniform" }
769
- },
770
- {
771
- binding: 1,
772
- visibility: i.FRAGMENT,
773
- sampler: {}
774
- },
775
- {
776
- binding: 2,
777
- visibility: i.FRAGMENT,
778
- texture: {
779
- sampleType: "float",
780
- viewDimension: "1d"
781
- }
782
- }
783
- ]
784
- }), n = s.createBuffer({
785
- size: Q,
786
- usage: r.UNIFORM | r.COPY_DST
787
- }), o = s.createSampler({
788
- magFilter: "linear",
789
- minFilter: "linear",
790
- addressModeU: "clamp-to-edge"
791
- }), u = s.createPipelineLayout({
792
- bindGroupLayouts: [a]
793
- });
794
- return {
795
- pipeline: s.createRenderPipeline({
796
- layout: u,
797
- vertex: {
798
- module: t,
799
- entryPoint: "vs_main",
800
- buffers: [
801
- {
802
- arrayStride: G,
803
- attributes: [
804
- { shaderLocation: 0, offset: 0, format: "float32x2" },
805
- // position
806
- { shaderLocation: 1, offset: 8, format: "float32" }
807
- // value
808
- ]
809
- }
810
- ]
811
- },
812
- fragment: {
813
- module: t,
814
- entryPoint: "fs_main",
815
- targets: [
816
- {
817
- format: e,
818
- blend: {
819
- color: {
820
- srcFactor: "src-alpha",
821
- dstFactor: "one-minus-src-alpha",
822
- operation: "add"
823
- },
824
- alpha: {
825
- srcFactor: "one",
826
- dstFactor: "one-minus-src-alpha",
827
- operation: "add"
828
- }
829
- }
830
- }
831
- ]
832
- },
833
- primitive: {
834
- topology: "triangle-list",
835
- cullMode: "none"
836
- }
837
- }),
838
- bindGroupLayout: a,
839
- uniformBuffer: n,
840
- sampler: o,
841
- vertexStride: G
842
- };
843
- }
844
- function ee(s, e, t, i, r) {
845
- return s.createBindGroup({
846
- layout: e,
847
- entries: [
848
- { binding: 0, resource: { buffer: t } },
849
- { binding: 1, resource: i },
850
- { binding: 2, resource: r.createView() }
851
- ]
852
- });
853
- }
854
- function te(s, e, t) {
855
- const i = new Float32Array([
856
- t.scale[0],
857
- t.scale[1],
858
- t.translate[0],
859
- t.translate[1],
860
- t.minValue,
861
- t.maxValue,
862
- 0,
863
- // padding
864
- 0
865
- // padding
866
- ]);
867
- s.queue.writeBuffer(e, 0, i);
868
- }
869
- function ie(s) {
870
- const e = s.xMax - s.xMin, t = s.yMax - s.yMin, i = e > 0 ? 2 / e : 1, r = t > 0 ? 2 / t : 1, a = -1 - s.xMin * i, n = -1 - s.yMin * r;
871
- return {
872
- scale: [i, r],
873
- translate: [a, n]
874
- };
875
- }
876
- function re(s) {
877
- const e = (s == null ? void 0 : s.color) ?? [1, 0, 0.3, 1], t = (s == null ? void 0 : s.opacity) ?? 1;
878
- return Array.isArray(e) ? [e[0], e[1], e[2], (e[3] ?? 1) * t] : [1, 0, 0.3, t];
879
- }
880
- class _ {
881
- constructor(e, t = {}) {
882
- c(this, "info");
883
- c(this, "canvas");
884
- c(this, "opts");
885
- c(this, "viewport", null);
886
- c(this, "adapter");
887
- c(this, "device");
888
- c(this, "context");
889
- c(this, "format", null);
890
- c(this, "buffers", /* @__PURE__ */ new Map());
891
- c(this, "textures", /* @__PURE__ */ new Map());
892
- // Pipelines for different draw types
893
- c(this, "trianglePipeline", null);
894
- c(this, "linePipeline", null);
895
- c(this, "pointPipeline", null);
896
- c(this, "bandPipeline", null);
897
- c(this, "heatmapPipeline", null);
898
- // Heatmap bind groups (per texture)
899
- c(this, "heatmapBindGroups", /* @__PURE__ */ new Map());
900
- this.canvas = e, this.opts = t, this.info = {
901
- type: "webgpu",
902
- available: _.isSupported()
903
- };
904
- }
905
- static isSupported() {
906
- return typeof globalThis.navigator < "u" && typeof globalThis.navigator.gpu < "u";
907
- }
908
- async init() {
909
- if (!this.info.available)
910
- throw new Error("[gpu] WebGPU not supported");
911
- const e = globalThis.navigator.gpu;
912
- if (this.adapter = await e.requestAdapter({
913
- powerPreference: this.opts.powerPreference ?? "high-performance"
914
- }), !this.adapter)
915
- throw new Error("[gpu] Failed to request WebGPU adapter");
916
- this.device = await this.adapter.requestDevice();
917
- const t = this.canvas.getContext("webgpu");
918
- if (!t)
919
- throw new Error("[gpu] Failed to get WebGPU canvas context");
920
- this.context = t;
921
- const i = this.opts.preferredFormat ?? (e.getPreferredCanvasFormat ? e.getPreferredCanvasFormat() : "bgra8unorm");
922
- this.format = i, this.context.configure({
923
- device: this.device,
924
- format: i,
925
- alphaMode: "premultiplied"
926
- });
927
- }
928
- setViewport(e) {
929
- this.viewport = e;
930
- const t = Math.max(1, Math.floor(e.width * e.dpr)), i = Math.max(1, Math.floor(e.height * e.dpr));
931
- this.canvas.width !== t && (this.canvas.width = t), this.canvas.height !== i && (this.canvas.height = i);
932
- }
933
- createOrUpdateBuffer(e, t, i) {
934
- if (!this.device)
935
- throw new Error("[gpu] WebGPUBackend not initialized");
936
- const r = (i == null ? void 0 : i.usage) ?? "vertex", a = globalThis.GPUBufferUsage;
937
- if (!a)
938
- throw new Error(
939
- "[gpu] GPUBufferUsage not available (missing WebGPU runtime)"
940
- );
941
- const n = r === "index" ? a.INDEX | a.COPY_DST : r === "uniform" ? a.UNIFORM | a.COPY_DST : a.VERTEX | a.COPY_DST, o = t.byteLength;
942
- let u = this.buffers.get(e);
943
- if (!u || u.size < o) {
944
- if (u)
945
- try {
946
- u.destroy();
947
- } catch {
948
- }
949
- u = this.device.createBuffer({
950
- size: Math.max(4, o),
951
- usage: n
952
- }), this.buffers.set(e, u);
953
- }
954
- this.device.queue.writeBuffer(
955
- u,
956
- 0,
957
- t.buffer,
958
- t.byteOffset,
959
- t.byteLength
960
- );
961
- }
962
- deleteBuffer(e) {
963
- const t = this.buffers.get(e);
964
- if (t) {
965
- try {
966
- t.destroy();
967
- } catch {
968
- }
969
- this.buffers.delete(e);
970
- }
971
- }
972
- createOrUpdateTexture1D(e, t, i) {
973
- if (!this.device)
974
- throw new Error("[gpu] WebGPUBackend not initialized");
975
- const r = (i == null ? void 0 : i.width) ?? Math.floor(t.length / 4), a = (i == null ? void 0 : i.format) ?? "rgba8unorm", n = globalThis.GPUTextureUsage;
976
- if (!n)
977
- throw new Error(
978
- "[gpu] GPUTextureUsage not available (missing WebGPU runtime)"
979
- );
980
- let o = this.textures.get(e);
981
- o || (o = this.device.createTexture({
982
- size: { width: r, height: 1, depthOrArrayLayers: 1 },
983
- format: a,
984
- dimension: "1d",
985
- usage: n.TEXTURE_BINDING | n.COPY_DST
986
- }), this.textures.set(e, o), this.heatmapBindGroups.delete(e)), this.device.queue.writeTexture(
987
- { texture: o },
988
- t,
989
- { bytesPerRow: r * 4 },
990
- { width: r, height: 1, depthOrArrayLayers: 1 }
991
- );
992
- }
993
- deleteTexture(e) {
994
- const t = this.textures.get(e);
995
- if (t) {
996
- try {
997
- t.destroy();
998
- } catch {
999
- }
1000
- this.textures.delete(e), this.heatmapBindGroups.delete(e);
1001
- }
1002
- }
1003
- /**
1004
- * Initialize all pipelines lazily
1005
- */
1006
- ensurePipelines() {
1007
- this.trianglePipeline || (this.trianglePipeline = O(this.device, this.format)), this.linePipeline || (this.linePipeline = V(this.device, this.format)), this.pointPipeline || (this.pointPipeline = Y(this.device, this.format)), this.bandPipeline || (this.bandPipeline = j(this.device, this.format)), this.heatmapPipeline || (this.heatmapPipeline = J(this.device, this.format));
1008
- }
1009
- render(e, t) {
1010
- if (!this.device || !this.context || !this.format)
1011
- throw new Error("[gpu] WebGPUBackend not initialized");
1012
- this.viewport || this.setViewport(t.viewport), this.ensurePipelines();
1013
- const i = this.device.createCommandEncoder(), r = this.context.getCurrentTexture().createView(), a = i.beginRenderPass({
1014
- colorAttachments: [
1015
- {
1016
- view: r,
1017
- clearValue: {
1018
- r: t.clearColor[0],
1019
- g: t.clearColor[1],
1020
- b: t.clearColor[2],
1021
- a: t.clearColor[3]
1022
- },
1023
- loadOp: "clear",
1024
- storeOp: "store"
1025
- }
1026
- ]
1027
- }), n = { xMin: -1, xMax: 1, yMin: -1, yMax: 1 };
1028
- for (const o of e.items) {
1029
- if (!o.visible) continue;
1030
- const u = this.buffers.get(o.bufferId);
1031
- u && this.renderDrawCall(a, o, u, n);
1032
- }
1033
- a.end(), this.device.queue.submit([i.finish()]);
1034
- }
1035
- /**
1036
- * Render with explicit bounds (for integration with chart system)
1037
- */
1038
- renderWithBounds(e, t, i) {
1039
- if (!this.device || !this.context || !this.format)
1040
- throw new Error("[gpu] WebGPUBackend not initialized");
1041
- this.viewport || this.setViewport(t.viewport), this.ensurePipelines();
1042
- const r = this.device.createCommandEncoder(), a = this.context.getCurrentTexture().createView(), n = r.beginRenderPass({
1043
- colorAttachments: [
1044
- {
1045
- view: a,
1046
- clearValue: {
1047
- r: t.clearColor[0],
1048
- g: t.clearColor[1],
1049
- b: t.clearColor[2],
1050
- a: t.clearColor[3]
1051
- },
1052
- loadOp: "clear",
1053
- storeOp: "store"
1054
- }
1055
- ]
1056
- });
1057
- for (const o of e.items) {
1058
- if (!o.visible) continue;
1059
- const u = this.buffers.get(o.bufferId);
1060
- if (!u) continue;
1061
- const l = o.yBounds ? { ...i, yMin: o.yBounds.min, yMax: o.yBounds.max } : i;
1062
- this.renderDrawCall(n, o, u, l);
1063
- }
1064
- n.end(), this.device.queue.submit([r.finish()]);
1065
- }
1066
- /**
1067
- * Render a single draw call
1068
- */
1069
- renderDrawCall(e, t, i, r) {
1070
- const a = ie(r), n = re(t.style);
1071
- switch (t.kind) {
1072
- case "triangles":
1073
- case "bar":
1074
- this.renderTriangles(e, i, t.count);
1075
- break;
1076
- case "line":
1077
- this.renderLine(e, i, t.count, a, n);
1078
- break;
1079
- case "scatter":
1080
- case "points":
1081
- this.renderPoints(e, i, t.count, a, n, t.style);
1082
- break;
1083
- case "line+scatter":
1084
- this.renderLine(e, i, t.count, a, n), this.renderPoints(e, i, t.count, a, n, t.style);
1085
- break;
1086
- case "step":
1087
- if (t.stepBufferId && t.stepCount) {
1088
- const u = this.buffers.get(t.stepBufferId);
1089
- u && this.renderLine(e, u, t.stepCount, a, n);
1090
- } else
1091
- this.renderLine(e, i, t.count, a, n);
1092
- break;
1093
- case "step+scatter":
1094
- if (t.stepBufferId && t.stepCount) {
1095
- const u = this.buffers.get(t.stepBufferId);
1096
- u && this.renderLine(e, u, t.stepCount, a, n);
1097
- } else
1098
- this.renderLine(e, i, t.count, a, n);
1099
- this.renderPoints(e, i, t.count, a, n, t.style);
1100
- break;
1101
- case "band":
1102
- const o = [
1103
- n[0],
1104
- n[1],
1105
- n[2],
1106
- n[3] * 0.4
1107
- ];
1108
- this.renderBand(e, i, t.count, a, o);
1109
- break;
1110
- case "heatmap":
1111
- this.renderHeatmap(e, i, t.count, a, t.style, t.textureId);
1112
- break;
1113
- }
1114
- }
1115
- renderTriangles(e, t, i) {
1116
- e.setPipeline(this.trianglePipeline.pipeline), e.setVertexBuffer(0, t), e.draw(i);
1117
- }
1118
- renderLine(e, t, i, r, a) {
1119
- W(this.device, this.linePipeline.uniformBuffer, {
1120
- scale: r.scale,
1121
- translate: r.translate,
1122
- color: a
1123
- }), e.setPipeline(this.linePipeline.pipeline), e.setBindGroup(0, this.linePipeline.bindGroup), e.setVertexBuffer(0, t), e.draw(i);
1124
- }
1125
- renderPoints(e, t, i, r, a, n) {
1126
- var p;
1127
- const o = ((n == null ? void 0 : n.pointSize) ?? 4) * (((p = this.viewport) == null ? void 0 : p.dpr) ?? 1), u = $[(n == null ? void 0 : n.symbol) ?? "circle"] ?? 0, l = [
1128
- this.canvas.width,
1129
- this.canvas.height
1130
- ];
1131
- X(this.device, this.pointPipeline.uniformBuffer, {
1132
- scale: r.scale,
1133
- translate: r.translate,
1134
- color: a,
1135
- pointSize: o,
1136
- symbol: u,
1137
- viewport: l
1138
- }), e.setPipeline(this.pointPipeline.pipeline), e.setBindGroup(0, this.pointPipeline.bindGroup), e.setVertexBuffer(0, t), e.setVertexBuffer(1, this.pointPipeline.quadBuffer), e.draw(6, i);
1139
- }
1140
- renderBand(e, t, i, r, a) {
1141
- Z(this.device, this.bandPipeline.uniformBuffer, {
1142
- scale: r.scale,
1143
- translate: r.translate,
1144
- color: a
1145
- }), e.setPipeline(this.bandPipeline.pipeline), e.setBindGroup(0, this.bandPipeline.bindGroup), e.setVertexBuffer(0, t), e.draw(i);
1146
- }
1147
- renderHeatmap(e, t, i, r, a, n) {
1148
- if (!n) return;
1149
- const o = this.textures.get(n);
1150
- if (!o) return;
1151
- const u = (a == null ? void 0 : a.zBounds) ?? { min: 0, max: 1 };
1152
- te(this.device, this.heatmapPipeline.uniformBuffer, {
1153
- scale: r.scale,
1154
- translate: r.translate,
1155
- minValue: u.min,
1156
- maxValue: u.max
1157
- });
1158
- let l = this.heatmapBindGroups.get(n);
1159
- l || (l = ee(
1160
- this.device,
1161
- this.heatmapPipeline.bindGroupLayout,
1162
- this.heatmapPipeline.uniformBuffer,
1163
- this.heatmapPipeline.sampler,
1164
- o
1165
- ), this.heatmapBindGroups.set(n, l)), e.setPipeline(this.heatmapPipeline.pipeline), e.setBindGroup(0, l), e.setVertexBuffer(0, t), e.draw(i);
1166
- }
1167
- destroy() {
1168
- for (const e of Array.from(this.buffers.keys()))
1169
- this.deleteBuffer(e);
1170
- for (const e of Array.from(this.textures.keys()))
1171
- this.deleteTexture(e);
1172
- this.trianglePipeline = null, this.linePipeline = null, this.pointPipeline = null, this.bandPipeline = null, this.heatmapPipeline = null, this.heatmapBindGroups.clear(), this.device = void 0, this.adapter = void 0, this.context = void 0, this.format = null;
1173
- }
1174
- }
1175
- const ae = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1176
- __proto__: null,
1177
- WebGPUBackend: _
1178
- }, Symbol.toStringTag, { value: "Module" })), ne = `
1179
- precision highp float;
1180
- attribute vec2 aPosition;
1181
- uniform vec2 uScale;
1182
- uniform vec2 uTranslate;
1183
-
1184
- void main() {
1185
- vec2 pos = aPosition * uScale + uTranslate;
1186
- gl_Position = vec4(pos, 0.0, 1.0);
1187
- }
1188
- `, se = `
1189
- precision highp float;
1190
- uniform vec4 uColor;
1191
-
1192
- void main() {
1193
- gl_FragColor = uColor;
1194
- }
1195
- `, oe = `
1196
- precision highp float;
1197
- attribute vec2 aPosition;
1198
- uniform vec2 uScale;
1199
- uniform vec2 uTranslate;
1200
- uniform float uPointSize;
1201
-
1202
- void main() {
1203
- vec2 pos = aPosition * uScale + uTranslate;
1204
- gl_Position = vec4(pos, 0.0, 1.0);
1205
- gl_PointSize = uPointSize;
1206
- }
1207
- `, ue = `
1208
- precision highp float;
1209
- uniform vec4 uColor;
1210
- uniform int uSymbol;
1211
-
1212
- float sdCircle(vec2 p, float r) {
1213
- return length(p) - r;
1214
- }
1215
-
1216
- float sdBox(vec2 p, vec2 b) {
1217
- vec2 d = abs(p) - b;
1218
- return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
1219
- }
1220
-
1221
- float sdTriangle(vec2 p, float r) {
1222
- const float k = sqrt(3.0);
1223
- p.x = abs(p.x) - r;
1224
- p.y = p.y + r / k;
1225
- if (p.x + k * p.y > 0.0) p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0;
1226
- p.x -= clamp(p.x, -2.0 * r, 0.0);
1227
- return -length(p) * sign(p.y);
1228
- }
1229
-
1230
- float sdDiamond(vec2 p, float r) {
1231
- return (abs(p.x) + abs(p.y)) - r;
1232
- }
1233
-
1234
- float sdCross(vec2 p, float r, float thickness) {
1235
- vec2 d = abs(p);
1236
- float s1 = sdBox(d, vec2(r, thickness));
1237
- float s2 = sdBox(d, vec2(thickness, r));
1238
- return min(s1, s2);
1239
- }
1240
-
1241
- float sdX(vec2 p, float r, float thickness) {
1242
- float c = cos(0.785398);
1243
- float s = sin(0.785398);
1244
- mat2 m = mat2(c, -s, s, c);
1245
- return sdCross(m * p, r, thickness);
1246
- }
1247
-
1248
- float sdStar(vec2 p, float r, float rf) {
1249
- const vec2 k1 = vec2(0.80901699, -0.58778525);
1250
- const vec2 k2 = vec2(-k1.x, k1.y);
1251
- p.x = abs(p.x);
1252
- p -= 2.0 * max(dot(k1, p), 0.0) * k1;
1253
- p -= 2.0 * max(dot(k2, p), 0.0) * k2;
1254
- p.x = abs(p.x);
1255
- p.y -= r;
1256
- vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0, 1);
1257
- float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, r);
1258
- return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y);
1259
- }
1260
-
1261
- void main() {
1262
- vec2 p = gl_PointCoord - vec2(0.5);
1263
- float d = 0.0;
1264
-
1265
- if (uSymbol == 0) {
1266
- d = sdCircle(p, 0.45);
1267
- } else if (uSymbol == 1) {
1268
- d = sdBox(p, vec2(0.35));
1269
- } else if (uSymbol == 2) {
1270
- d = sdDiamond(p, 0.45);
1271
- } else if (uSymbol == 3) {
1272
- d = sdTriangle(vec2(p.x, p.y + 0.1), 0.4);
1273
- } else if (uSymbol == 4) {
1274
- d = sdTriangle(vec2(p.x, -p.y + 0.1), 0.4);
1275
- } else if (uSymbol == 5) {
1276
- d = sdCross(p, 0.45, 0.15);
1277
- } else if (uSymbol == 6) {
1278
- d = sdX(p, 0.45, 0.15);
1279
- } else if (uSymbol == 7) {
1280
- d = sdStar(p, 0.45, 0.4);
1281
- }
1282
-
1283
- if (d > 0.02) discard;
1284
-
1285
- float alpha = 1.0 - smoothstep(0.0, 0.02, d);
1286
- gl_FragColor = vec4(uColor.rgb, uColor.a * alpha);
1287
- }
1288
- `, le = `
1289
- precision highp float;
1290
- attribute vec2 aPosition;
1291
- attribute float aValue;
1292
- uniform vec2 uScale;
1293
- uniform vec2 uTranslate;
1294
- varying float vValue;
1295
-
1296
- void main() {
1297
- gl_Position = vec4(aPosition * uScale + uTranslate, 0.0, 1.0);
1298
- vValue = aValue;
1299
- }
1300
- `, ce = `
1301
- precision highp float;
1302
- varying float vValue;
1303
- uniform float uMinValue;
1304
- uniform float uMaxValue;
1305
- uniform sampler2D uColormap;
1306
-
1307
- void main() {
1308
- float range = uMaxValue - uMinValue;
1309
- float t = (vValue - uMinValue) / (range != 0.0 ? range : 1.0);
1310
- t = clamp(t, 0.0, 1.0);
1311
- gl_FragColor = texture2D(uColormap, vec2(t, 0.5));
1312
- }
1313
- `;
1314
- function E(s, e, t) {
1315
- const i = s.createShader(e);
1316
- if (!i)
1317
- throw new Error("[WebGL] Failed to create shader");
1318
- if (s.shaderSource(i, t), s.compileShader(i), !s.getShaderParameter(i, s.COMPILE_STATUS)) {
1319
- const r = s.getShaderInfoLog(i);
1320
- throw s.deleteShader(i), new Error(`[WebGL] Shader compilation error: ${r}`);
1321
- }
1322
- return i;
1323
- }
1324
- function pe(s, e, t) {
1325
- const i = s.createProgram();
1326
- if (!i)
1327
- throw new Error("[WebGL] Failed to create program");
1328
- if (s.attachShader(i, e), s.attachShader(i, t), s.linkProgram(i), !s.getProgramParameter(i, s.LINK_STATUS)) {
1329
- const r = s.getProgramInfoLog(i);
1330
- throw s.deleteProgram(i), new Error(`[WebGL] Program link error: ${r}`);
1331
- }
1332
- return i;
1333
- }
1334
- function T(s, e, t, i, r) {
1335
- const a = E(s, s.VERTEX_SHADER, e), n = E(s, s.FRAGMENT_SHADER, t), o = pe(s, a, n);
1336
- s.deleteShader(a), s.deleteShader(n);
1337
- const u = {};
1338
- for (const p of i)
1339
- u[p] = s.getAttribLocation(o, p);
1340
- const l = {};
1341
- for (const p of r)
1342
- l[p] = s.getUniformLocation(o, p);
1343
- return { program: o, attributes: u, uniforms: l };
1344
- }
1345
- function fe(s) {
1346
- const e = T(
1347
- s,
1348
- ne,
1349
- se,
1350
- ["aPosition"],
1351
- ["uScale", "uTranslate", "uColor"]
1352
- ), t = T(
1353
- s,
1354
- oe,
1355
- ue,
1356
- ["aPosition"],
1357
- ["uScale", "uTranslate", "uColor", "uPointSize", "uSymbol"]
1358
- ), i = T(
1359
- s,
1360
- le,
1361
- ce,
1362
- ["aPosition", "aValue"],
1363
- ["uScale", "uTranslate", "uMinValue", "uMaxValue", "uColormap"]
1364
- );
1365
- return { line: e, point: t, heatmap: i };
1366
- }
1367
- function de(s, e) {
1368
- s.deleteProgram(e.line.program), s.deleteProgram(e.point.program), s.deleteProgram(e.heatmap.program);
1369
- }
1370
- const he = {
1371
- circle: 0,
1372
- square: 1,
1373
- diamond: 2,
1374
- triangle: 3,
1375
- triangleDown: 4,
1376
- cross: 5,
1377
- x: 6,
1378
- star: 7
1379
- };
1380
- function me(s) {
1381
- const e = s.xMax - s.xMin, t = s.yMax - s.yMin, i = e > 0 ? 2 / e : 1, r = t > 0 ? 2 / t : 1, a = -1 - s.xMin * i, n = -1 - s.yMin * r;
1382
- return {
1383
- scale: [i, r],
1384
- translate: [a, n]
1385
- };
1386
- }
1387
- function ge(s) {
1388
- const e = (s == null ? void 0 : s.color) ?? [1, 0, 0.3, 1], t = (s == null ? void 0 : s.opacity) ?? 1;
1389
- return Array.isArray(e) ? [e[0], e[1], e[2], (e[3] ?? 1) * t] : [1, 0, 0.3, t];
1390
- }
1391
- class P {
1392
- constructor(e, t = {}) {
1393
- c(this, "info");
1394
- c(this, "canvas");
1395
- c(this, "opts");
1396
- c(this, "gl", null);
1397
- c(this, "viewport", null);
1398
- c(this, "dpr", 1);
1399
- c(this, "programs", null);
1400
- c(this, "buffers", /* @__PURE__ */ new Map());
1401
- c(this, "textures", /* @__PURE__ */ new Map());
1402
- this.canvas = e, this.opts = t, this.info = {
1403
- type: "webgl",
1404
- available: P.isSupported()
1405
- };
1406
- }
1407
- static isSupported() {
1408
- if (typeof document > "u") return !1;
1409
- try {
1410
- const e = document.createElement("canvas");
1411
- return !!(e.getContext("webgl") || e.getContext("experimental-webgl"));
1412
- } catch {
1413
- return !1;
1414
- }
1415
- }
1416
- async init() {
1417
- if (!this.info.available)
1418
- throw new Error("[gpu] WebGL not supported");
1419
- const e = this.canvas.getContext("webgl", {
1420
- alpha: !0,
1421
- antialias: this.opts.antialias ?? !0,
1422
- preserveDrawingBuffer: this.opts.preserveDrawingBuffer ?? !0,
1423
- powerPreference: this.opts.powerPreference ?? "high-performance"
1424
- });
1425
- if (!e)
1426
- throw new Error("[gpu] Failed to get WebGL context");
1427
- this.gl = e, e.enable(e.BLEND), e.blendFunc(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA), this.programs = fe(e);
1428
- }
1429
- setViewport(e) {
1430
- this.viewport = e, this.dpr = e.dpr;
1431
- const t = Math.max(1, Math.floor(e.width * e.dpr)), i = Math.max(1, Math.floor(e.height * e.dpr));
1432
- this.canvas.width !== t && (this.canvas.width = t), this.canvas.height !== i && (this.canvas.height = i), this.gl && this.gl.viewport(0, 0, t, i);
1433
- }
1434
- createOrUpdateBuffer(e, t, i) {
1435
- if (!this.gl)
1436
- throw new Error("[gpu] WebGLBackend not initialized");
1437
- const r = this.gl;
1438
- let a = this.buffers.get(e);
1439
- a || (a = r.createBuffer(), this.buffers.set(e, a));
1440
- const n = (i == null ? void 0 : i.usage) === "index" ? r.ELEMENT_ARRAY_BUFFER : r.ARRAY_BUFFER;
1441
- r.bindBuffer(n, a), r.bufferData(n, t, r.DYNAMIC_DRAW), r.bindBuffer(n, null);
1442
- }
1443
- deleteBuffer(e) {
1444
- if (!this.gl) return;
1445
- const t = this.buffers.get(e);
1446
- t && (this.gl.deleteBuffer(t), this.buffers.delete(e));
1447
- }
1448
- createOrUpdateTexture1D(e, t, i) {
1449
- if (!this.gl)
1450
- throw new Error("[gpu] WebGLBackend not initialized");
1451
- const r = this.gl, a = (i == null ? void 0 : i.width) ?? Math.floor(t.length / 4);
1452
- let n = this.textures.get(e);
1453
- n || (n = r.createTexture(), this.textures.set(e, n)), r.bindTexture(r.TEXTURE_2D, n), r.texImage2D(r.TEXTURE_2D, 0, r.RGBA, a, 1, 0, r.RGBA, r.UNSIGNED_BYTE, t), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_MIN_FILTER, r.LINEAR), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_MAG_FILTER, r.LINEAR), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_WRAP_S, r.CLAMP_TO_EDGE), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_WRAP_T, r.CLAMP_TO_EDGE), r.bindTexture(r.TEXTURE_2D, null);
1454
- }
1455
- deleteTexture(e) {
1456
- if (!this.gl) return;
1457
- const t = this.textures.get(e);
1458
- t && (this.gl.deleteTexture(t), this.textures.delete(e));
1459
- }
1460
- render(e, t) {
1461
- this.renderWithBounds(e, t, { xMin: -1, xMax: 1, yMin: -1, yMax: 1 });
1462
- }
1463
- renderWithBounds(e, t, i) {
1464
- if (!this.gl || !this.programs)
1465
- throw new Error("[gpu] WebGLBackend not initialized");
1466
- const r = this.gl;
1467
- this.viewport || this.setViewport(t.viewport), r.clearColor(
1468
- t.clearColor[0],
1469
- t.clearColor[1],
1470
- t.clearColor[2],
1471
- t.clearColor[3]
1472
- ), r.clear(r.COLOR_BUFFER_BIT);
1473
- for (const a of e.items) {
1474
- if (!a.visible) continue;
1475
- const n = this.buffers.get(a.bufferId);
1476
- if (!n) continue;
1477
- const o = a.yBounds ? { ...i, yMin: a.yBounds.min, yMax: a.yBounds.max } : i;
1478
- this.renderDrawCall(a, n, o);
1479
- }
1480
- }
1481
- renderDrawCall(e, t, i) {
1482
- const r = me(i), a = ge(e.style);
1483
- switch (e.kind) {
1484
- case "line":
1485
- case "step":
1486
- this.renderLine(t, e.count, r, a);
1487
- break;
1488
- case "scatter":
1489
- case "points":
1490
- this.renderPoints(t, e.count, r, a, e.style);
1491
- break;
1492
- case "line+scatter":
1493
- this.renderLine(t, e.count, r, a), this.renderPoints(t, e.count, r, a, e.style);
1494
- break;
1495
- case "step+scatter":
1496
- if (e.stepBufferId && e.stepCount) {
1497
- const o = this.buffers.get(e.stepBufferId);
1498
- o && this.renderLine(o, e.stepCount, r, a);
1499
- } else
1500
- this.renderLine(t, e.count, r, a);
1501
- this.renderPoints(t, e.count, r, a, e.style);
1502
- break;
1503
- case "band":
1504
- const n = [
1505
- a[0],
1506
- a[1],
1507
- a[2],
1508
- a[3] * 0.4
1509
- ];
1510
- this.renderBand(t, e.count, r, n);
1511
- break;
1512
- case "triangles":
1513
- case "bar":
1514
- this.renderTriangles(t, e.count, r, a);
1515
- break;
1516
- case "heatmap":
1517
- this.renderHeatmap(t, e.count, r, e.style, e.textureId);
1518
- break;
1519
- }
1520
- }
1521
- renderLine(e, t, i, r) {
1522
- const a = this.gl, n = this.programs.line;
1523
- a.useProgram(n.program), a.bindBuffer(a.ARRAY_BUFFER, e), a.enableVertexAttribArray(n.attributes.aPosition), a.vertexAttribPointer(n.attributes.aPosition, 2, a.FLOAT, !1, 0, 0), a.uniform2f(n.uniforms.uScale, i.scale[0], i.scale[1]), a.uniform2f(n.uniforms.uTranslate, i.translate[0], i.translate[1]), a.uniform4f(n.uniforms.uColor, r[0], r[1], r[2], r[3]), a.drawArrays(a.LINE_STRIP, 0, t), a.disableVertexAttribArray(n.attributes.aPosition);
1524
- }
1525
- renderPoints(e, t, i, r, a) {
1526
- const n = this.gl, o = this.programs.point, u = ((a == null ? void 0 : a.pointSize) ?? 4) * this.dpr, l = he[(a == null ? void 0 : a.symbol) ?? "circle"] ?? 0;
1527
- n.useProgram(o.program), n.bindBuffer(n.ARRAY_BUFFER, e), n.enableVertexAttribArray(o.attributes.aPosition), n.vertexAttribPointer(o.attributes.aPosition, 2, n.FLOAT, !1, 0, 0), n.uniform2f(o.uniforms.uScale, i.scale[0], i.scale[1]), n.uniform2f(o.uniforms.uTranslate, i.translate[0], i.translate[1]), n.uniform4f(o.uniforms.uColor, r[0], r[1], r[2], r[3]), n.uniform1f(o.uniforms.uPointSize, u), n.uniform1i(o.uniforms.uSymbol, l), n.drawArrays(n.POINTS, 0, t), n.disableVertexAttribArray(o.attributes.aPosition);
1528
- }
1529
- renderBand(e, t, i, r) {
1530
- const a = this.gl, n = this.programs.line;
1531
- a.useProgram(n.program), a.bindBuffer(a.ARRAY_BUFFER, e), a.enableVertexAttribArray(n.attributes.aPosition), a.vertexAttribPointer(n.attributes.aPosition, 2, a.FLOAT, !1, 0, 0), a.uniform2f(n.uniforms.uScale, i.scale[0], i.scale[1]), a.uniform2f(n.uniforms.uTranslate, i.translate[0], i.translate[1]), a.uniform4f(n.uniforms.uColor, r[0], r[1], r[2], r[3]), a.drawArrays(a.TRIANGLE_STRIP, 0, t), a.disableVertexAttribArray(n.attributes.aPosition);
1532
- }
1533
- renderTriangles(e, t, i, r) {
1534
- const a = this.gl, n = this.programs.line;
1535
- a.useProgram(n.program), a.bindBuffer(a.ARRAY_BUFFER, e), a.enableVertexAttribArray(n.attributes.aPosition), a.vertexAttribPointer(n.attributes.aPosition, 2, a.FLOAT, !1, 0, 0), a.uniform2f(n.uniforms.uScale, i.scale[0], i.scale[1]), a.uniform2f(n.uniforms.uTranslate, i.translate[0], i.translate[1]), a.uniform4f(n.uniforms.uColor, r[0], r[1], r[2], r[3]), a.drawArrays(a.TRIANGLES, 0, t), a.disableVertexAttribArray(n.attributes.aPosition);
1536
- }
1537
- renderHeatmap(e, t, i, r, a) {
1538
- if (!a) return;
1539
- const n = this.textures.get(a);
1540
- if (!n) return;
1541
- const o = this.gl, u = this.programs.heatmap, l = (r == null ? void 0 : r.zBounds) ?? { min: 0, max: 1 };
1542
- o.useProgram(u.program), o.bindBuffer(o.ARRAY_BUFFER, e), o.enableVertexAttribArray(u.attributes.aPosition), o.vertexAttribPointer(u.attributes.aPosition, 2, o.FLOAT, !1, 12, 0), u.attributes.aValue !== -1 && (o.enableVertexAttribArray(u.attributes.aValue), o.vertexAttribPointer(u.attributes.aValue, 1, o.FLOAT, !1, 12, 8)), o.uniform2f(u.uniforms.uScale, i.scale[0], i.scale[1]), o.uniform2f(u.uniforms.uTranslate, i.translate[0], i.translate[1]), o.uniform1f(u.uniforms.uMinValue, l.min), o.uniform1f(u.uniforms.uMaxValue, l.max), o.activeTexture(o.TEXTURE0), o.bindTexture(o.TEXTURE_2D, n), o.uniform1i(u.uniforms.uColormap, 0), o.drawArrays(o.TRIANGLES, 0, t), o.disableVertexAttribArray(u.attributes.aPosition), u.attributes.aValue !== -1 && o.disableVertexAttribArray(u.attributes.aValue);
1543
- }
1544
- destroy() {
1545
- if (!this.gl) return;
1546
- const e = this.gl;
1547
- for (const t of this.buffers.values())
1548
- e.deleteBuffer(t);
1549
- this.buffers.clear();
1550
- for (const t of this.textures.values())
1551
- e.deleteTexture(t);
1552
- this.textures.clear(), this.programs && (de(e, this.programs), this.programs = null), this.gl = null;
1553
- }
1554
- }
1555
- const be = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1556
- __proto__: null,
1557
- WebGLBackend: P
1558
- }, Symbol.toStringTag, { value: "Module" }));
1559
- class ve {
1560
- constructor(e, t = {}) {
1561
- c(this, "canvas");
1562
- c(this, "options");
1563
- c(this, "backend", null);
1564
- c(this, "adapter", null);
1565
- c(this, "dpr");
1566
- c(this, "isInitialized", !1);
1567
- c(this, "backendType", null);
1568
- // Buffer management
1569
- c(this, "bufferDataMap", /* @__PURE__ */ new Map());
1570
- c(this, "stepBufferDataMap", /* @__PURE__ */ new Map());
1571
- c(this, "colormapDataMap", /* @__PURE__ */ new Map());
1572
- this.canvas = e, this.options = t, this.dpr = window.devicePixelRatio || 1;
1573
- }
1574
- /**
1575
- * Initialize the renderer
1576
- */
1577
- async init() {
1578
- const e = this.options.backend ?? "auto";
1579
- if ((e === "webgpu" || e === "auto") && _.isSupported())
1580
- try {
1581
- const t = new _(this.canvas, {
1582
- powerPreference: this.options.powerPreference ?? "high-performance"
1583
- });
1584
- return await t.init(), this.backend = t, this.backendType = "webgpu", this.adapter = new M(t), this.isInitialized = !0, this.resize(), !0;
1585
- } catch (t) {
1586
- console.warn("[GpuRenderer] WebGPU init failed:", t);
1587
- }
1588
- if ((e === "webgl" || e === "auto") && P.isSupported())
1589
- try {
1590
- const t = new P(this.canvas, {
1591
- powerPreference: this.options.powerPreference ?? "high-performance"
1592
- });
1593
- return await t.init(), this.backend = t, this.backendType = "webgl", this.adapter = new M(t), this.isInitialized = !0, this.resize(), console.info("[GpuRenderer] Using WebGL backend (WebGPU not available)"), !0;
1594
- } catch (t) {
1595
- console.warn("[GpuRenderer] WebGL init failed:", t);
1596
- }
1597
- return !1;
1598
- }
1599
- /**
1600
- * Check if renderer is available
1601
- */
1602
- get available() {
1603
- return this.isInitialized;
1604
- }
1605
- /**
1606
- * Get the active backend type
1607
- */
1608
- get activeBackend() {
1609
- return this.backendType;
1610
- }
1611
- /**
1612
- * Set device pixel ratio
1613
- */
1614
- setDPR(e) {
1615
- this.dpr = e, this.resize();
1616
- }
1617
- /**
1618
- * Create or update a buffer
1619
- */
1620
- createBuffer(e, t) {
1621
- this.bufferDataMap.set(e, t);
1622
- }
1623
- /**
1624
- * Update a buffer partially
1625
- */
1626
- updateBuffer(e, t, i) {
1627
- const r = this.bufferDataMap.get(e);
1628
- if (!r) return !1;
1629
- const a = i / 4;
1630
- return r.set(t, a), !0;
1631
- }
1632
- /**
1633
- * Get a buffer's data
1634
- */
1635
- getBuffer(e) {
1636
- return this.bufferDataMap.get(e);
1637
- }
1638
- /**
1639
- * Delete a buffer
1640
- */
1641
- deleteBuffer(e) {
1642
- this.bufferDataMap.delete(e), this.backend && this.backend.deleteBuffer(e);
1643
- }
1644
- /**
1645
- * Create or update a step buffer
1646
- */
1647
- createStepBuffer(e, t) {
1648
- this.stepBufferDataMap.set(e, t);
1649
- }
1650
- /**
1651
- * Create colormap texture
1652
- */
1653
- createColormapTexture(e, t) {
1654
- this.colormapDataMap.set(e, t), this.backend && this.backend.createOrUpdateTexture1D(e, t, {
1655
- width: t.length / 4
1656
- });
1657
- }
1658
- /**
1659
- * Render a frame
1660
- */
1661
- render(e, t) {
1662
- if (!this.isInitialized || !this.backend) return;
1663
- const i = this.buildDrawList(e), r = {
1664
- viewport: {
1665
- width: this.canvas.clientWidth,
1666
- height: this.canvas.clientHeight,
1667
- dpr: this.dpr
1668
- },
1669
- clearColor: t.backgroundColor ?? [0.1, 0.1, 0.18, 1],
1670
- bounds: t.bounds,
1671
- plotArea: t.plotArea
1672
- };
1673
- "renderWithBounds" in this.backend ? this.backend.renderWithBounds(i, r, t.bounds) : this.backend.render(i, r);
1674
- }
1675
- /**
1676
- * Build draw list from series data
1677
- */
1678
- buildDrawList(e) {
1679
- const t = [];
1680
- for (const i of e) {
1681
- const r = this.bufferDataMap.get(i.id);
1682
- if (!r) continue;
1683
- this.backend.createOrUpdateBuffer(i.id, r, { usage: "vertex" });
1684
- const a = i.type === "heatmap" ? r.length / 3 : r.length / 2, n = U(i.style.color), o = i.style.opacity ?? 1, u = [
1685
- n[0],
1686
- n[1],
1687
- n[2],
1688
- n[3] * o
1689
- ], l = {
1690
- id: i.id,
1691
- kind: i.type,
1692
- bufferId: i.id,
1693
- count: a,
1694
- visible: i.visible,
1695
- yBounds: i.yBounds
1696
- };
1697
- if (i.type === "scatter" || i.type === "line+scatter" || i.type === "step+scatter")
1698
- l.style = {
1699
- color: u,
1700
- opacity: o,
1701
- pointSize: i.style.pointSize ?? 4,
1702
- symbol: i.style.symbol ?? "circle"
1703
- };
1704
- else if (i.type === "heatmap") {
1705
- l.textureId = `colormap:${i.id}`, l.style = {
1706
- zBounds: i.zBounds,
1707
- colormap: i.colormap
1708
- };
1709
- const p = this.colormapDataMap.get(i.id);
1710
- p && this.backend.createOrUpdateTexture1D(l.textureId, p, {
1711
- width: p.length / 4
1712
- });
1713
- } else
1714
- l.style = {
1715
- color: u,
1716
- opacity: o,
1717
- lineWidth: i.style.lineWidth ?? 1
1718
- };
1719
- if ((i.type === "step" || i.type === "step+scatter") && this.stepBufferDataMap.has(i.id)) {
1720
- const p = this.stepBufferDataMap.get(i.id), f = `${i.id}:step`;
1721
- this.backend.createOrUpdateBuffer(f, p, { usage: "vertex" }), l.stepBufferId = f, l.stepCount = p.length / 2;
1722
- }
1723
- t.push(l);
1724
- }
1725
- return { items: t };
1726
- }
1727
- /**
1728
- * Handle canvas resize
1729
- */
1730
- resize() {
1731
- if (!this.backend) return;
1732
- const e = this.canvas.getBoundingClientRect();
1733
- this.backend.setViewport({
1734
- width: e.width,
1735
- height: e.height,
1736
- dpr: this.dpr
1737
- });
1738
- }
1739
- /**
1740
- * Get renderer limits
1741
- */
1742
- getLimits() {
1743
- return {
1744
- backend: this.backendType,
1745
- available: this.isInitialized
1746
- };
1747
- }
1748
- /**
1749
- * Destroy the renderer
1750
- */
1751
- destroy() {
1752
- var e, t;
1753
- (e = this.adapter) == null || e.destroy(), (t = this.backend) == null || t.destroy(), this.bufferDataMap.clear(), this.stepBufferDataMap.clear(), this.colormapDataMap.clear(), this.adapter = null, this.backend = null, this.isInitialized = !1, this.backendType = null;
1754
- }
1755
- }
1756
- async function Ae(s, e) {
1757
- const t = new ve(s, e);
1758
- return await t.init() ? t : null;
1759
- }
1760
- class Ge {
67
+ class F {
1761
68
  constructor(e) {
1762
- c(this, "canvas");
1763
- c(this, "results", []);
69
+ _(this, "canvas");
70
+ _(this, "results", []);
1764
71
  this.canvas = e ?? document.createElement("canvas"), e || (this.canvas.width = 800, this.canvas.height = 600);
1765
72
  }
1766
73
  /**
1767
74
  * Generate random line data
1768
75
  */
1769
76
  generateLineData(e) {
1770
- const t = new Float32Array(e * 2);
1771
- for (let i = 0; i < e; i++)
1772
- t[i * 2] = i / (e - 1), t[i * 2 + 1] = Math.random();
1773
- return t;
77
+ const i = new Float32Array(e * 2);
78
+ for (let t = 0; t < e; t++)
79
+ i[t * 2] = t / (e - 1), i[t * 2 + 1] = Math.random();
80
+ return i;
1774
81
  }
1775
82
  /**
1776
83
  * Measure frame times
1777
84
  */
1778
- async measureFrameTimes(e, t, i = 10, r) {
1779
- const a = [];
1780
- let n = performance.now(), o = 0;
85
+ async measureFrameTimes(e, i, t = 10, a) {
86
+ const s = [];
87
+ let r = performance.now(), o = 0;
1781
88
  const u = performance.now();
1782
89
  return new Promise((l) => {
1783
- const p = () => {
1784
- const f = performance.now(), h = f - u;
1785
- if (h >= t + i * 16) {
1786
- l({ frameTimes: a, duration: h - i * 16 });
90
+ const c = () => {
91
+ const n = performance.now(), m = n - u;
92
+ if (m >= i + t * 16) {
93
+ l({ frameTimes: s, duration: m - t * 16 });
1787
94
  return;
1788
95
  }
1789
- if (e(), o >= i) {
1790
- if (a.push(f - n), r) {
1791
- const d = Math.min(1, h / t);
1792
- r(d);
96
+ if (e(), o >= t) {
97
+ if (s.push(n - r), a) {
98
+ const d = Math.min(1, m / i);
99
+ a(d);
1793
100
  }
1794
101
  } else
1795
102
  o++;
1796
- n = f, requestAnimationFrame(p);
103
+ r = n, requestAnimationFrame(c);
1797
104
  };
1798
- requestAnimationFrame(p);
105
+ requestAnimationFrame(c);
1799
106
  });
1800
107
  }
1801
108
  /**
1802
109
  * Run benchmark with WebGPU backend
1803
110
  */
1804
111
  async benchmarkWebGPU(e = {}) {
1805
- const { WebGPUBackend: t } = await Promise.resolve().then(() => ae);
1806
- if (!t.isSupported())
112
+ const { WebGPUBackend: i } = await import("../gpuRenderer-BpaMYz-k.js").then((g) => g.b);
113
+ if (!i.isSupported())
1807
114
  return console.warn("[Benchmark] WebGPU not supported"), null;
1808
- const i = e.pointCount ?? 1e5, r = e.durationMs ?? 5e3, a = e.warmupFrames ?? 30, n = new t(this.canvas);
1809
- await n.init(), n.setViewport({
115
+ const t = e.pointCount ?? 1e5, a = e.durationMs ?? 5e3, s = e.warmupFrames ?? 30, r = new i(this.canvas);
116
+ await r.init(), r.setViewport({
1810
117
  width: this.canvas.width,
1811
118
  height: this.canvas.height,
1812
119
  dpr: 1
1813
120
  });
1814
- const o = this.generateLineData(i);
1815
- n.createOrUpdateBuffer("bench-line", o, { usage: "vertex" });
121
+ const o = this.generateLineData(t);
122
+ r.createOrUpdateBuffer("bench-line", o, { usage: "vertex" });
1816
123
  const u = {
1817
124
  items: [{
1818
125
  id: "bench-line",
1819
126
  kind: "line",
1820
127
  bufferId: "bench-line",
1821
- count: i,
128
+ count: t,
1822
129
  visible: !0,
1823
130
  style: { color: [0, 0.9, 1, 1] }
1824
131
  }]
1825
132
  }, l = {
1826
133
  viewport: { width: this.canvas.width, height: this.canvas.height, dpr: 1 },
1827
134
  clearColor: [0.1, 0.1, 0.15, 1]
1828
- }, p = { xMin: 0, xMax: 1, yMin: 0, yMax: 1 }, f = () => {
1829
- n.renderWithBounds(u, l, p);
1830
- }, { frameTimes: h, duration: d } = await this.measureFrameTimes(
1831
- f,
1832
- r,
135
+ }, c = { xMin: 0, xMax: 1, yMin: 0, yMax: 1 }, n = () => {
136
+ r.renderWithBounds(u, l, c);
137
+ }, { frameTimes: m, duration: d } = await this.measureFrameTimes(
138
+ n,
1833
139
  a,
140
+ s,
1834
141
  e.onProgress
1835
142
  );
1836
- n.destroy();
1837
- const m = this.calculateResult("webgpu", i, h, d);
1838
- return this.results.push(m), m;
143
+ r.destroy();
144
+ const f = this.calculateResult("webgpu", t, m, d);
145
+ return this.results.push(f), f;
1839
146
  }
1840
147
  /**
1841
148
  * Run benchmark with WebGL backend
1842
149
  */
1843
150
  async benchmarkWebGL(e = {}) {
1844
- const { WebGLBackend: t } = await Promise.resolve().then(() => be);
1845
- if (!t.isSupported())
151
+ const { WebGLBackend: i } = await import("../gpuRenderer-BpaMYz-k.js").then((g) => g.d);
152
+ if (!i.isSupported())
1846
153
  return console.warn("[Benchmark] WebGL not supported"), null;
1847
- const i = e.pointCount ?? 1e5, r = e.durationMs ?? 5e3, a = e.warmupFrames ?? 30, n = new t(this.canvas);
1848
- await n.init(), n.setViewport({
154
+ const t = e.pointCount ?? 1e5, a = e.durationMs ?? 5e3, s = e.warmupFrames ?? 30, r = new i(this.canvas);
155
+ await r.init(), r.setViewport({
1849
156
  width: this.canvas.width,
1850
157
  height: this.canvas.height,
1851
158
  dpr: 1
1852
159
  });
1853
- const o = this.generateLineData(i);
1854
- n.createOrUpdateBuffer("bench-line", o, { usage: "vertex" });
160
+ const o = this.generateLineData(t);
161
+ r.createOrUpdateBuffer("bench-line", o, { usage: "vertex" });
1855
162
  const u = {
1856
163
  items: [{
1857
164
  id: "bench-line",
1858
165
  kind: "line",
1859
166
  bufferId: "bench-line",
1860
- count: i,
167
+ count: t,
1861
168
  visible: !0,
1862
169
  style: { color: [0, 0.9, 1, 1] }
1863
170
  }]
1864
171
  }, l = {
1865
172
  viewport: { width: this.canvas.width, height: this.canvas.height, dpr: 1 },
1866
173
  clearColor: [0.1, 0.1, 0.15, 1]
1867
- }, p = { xMin: 0, xMax: 1, yMin: 0, yMax: 1 }, f = () => {
1868
- n.renderWithBounds(u, l, p);
1869
- }, { frameTimes: h, duration: d } = await this.measureFrameTimes(
1870
- f,
1871
- r,
174
+ }, c = { xMin: 0, xMax: 1, yMin: 0, yMax: 1 }, n = () => {
175
+ r.renderWithBounds(u, l, c);
176
+ }, { frameTimes: m, duration: d } = await this.measureFrameTimes(
177
+ n,
1872
178
  a,
179
+ s,
1873
180
  e.onProgress
1874
181
  );
1875
- n.destroy();
1876
- const m = this.calculateResult("webgl", i, h, d);
1877
- return this.results.push(m), m;
182
+ r.destroy();
183
+ const f = this.calculateResult("webgl", t, m, d);
184
+ return this.results.push(f), f;
1878
185
  }
1879
186
  /**
1880
187
  * Calculate benchmark result from frame times
1881
188
  */
1882
- calculateResult(e, t, i, r) {
1883
- if (i.length === 0)
189
+ calculateResult(e, i, t, a) {
190
+ if (t.length === 0)
1884
191
  return {
1885
192
  backend: e,
1886
- pointCount: t,
193
+ pointCount: i,
1887
194
  fps: 0,
1888
195
  avgFrameTime: 0,
1889
196
  minFrameTime: 0,
1890
197
  maxFrameTime: 0,
1891
198
  totalFrames: 0,
1892
- duration: r
199
+ duration: a
1893
200
  };
1894
- const n = i.reduce((l, p) => l + p, 0) / i.length, o = Math.min(...i), u = Math.max(...i);
201
+ const r = t.reduce((l, c) => l + c, 0) / t.length, o = Math.min(...t), u = Math.max(...t);
1895
202
  return {
1896
203
  backend: e,
1897
- pointCount: t,
1898
- fps: Math.round(1e3 / n),
1899
- avgFrameTime: Math.round(n * 100) / 100,
204
+ pointCount: i,
205
+ fps: Math.round(1e3 / r),
206
+ avgFrameTime: Math.round(r * 100) / 100,
1900
207
  minFrameTime: Math.round(o * 100) / 100,
1901
208
  maxFrameTime: Math.round(u * 100) / 100,
1902
- totalFrames: i.length,
1903
- duration: Math.round(r)
209
+ totalFrames: t.length,
210
+ duration: Math.round(a)
1904
211
  };
1905
212
  }
1906
213
  /**
1907
214
  * Run comparative benchmark
1908
215
  */
1909
216
  async runComparison(e = {}) {
1910
- const t = await this.benchmarkWebGPU(e), i = await this.benchmarkWebGL(e);
1911
- let r = "unknown", a = 1;
1912
- return t && i ? t.fps > i.fps * 1.05 ? (r = "webgpu", a = t.fps / i.fps) : i.fps > t.fps * 1.05 ? (r = "webgl", a = i.fps / t.fps) : (r = "tie", a = 1) : t ? r = "webgpu" : i && (r = "webgl"), { webgpu: t, webgl: i, winner: r, speedup: Math.round(a * 100) / 100 };
217
+ const i = await this.benchmarkWebGPU(e), t = await this.benchmarkWebGL(e);
218
+ let a = "unknown", s = 1;
219
+ return i && t ? i.fps > t.fps * 1.05 ? (a = "webgpu", s = i.fps / t.fps) : t.fps > i.fps * 1.05 ? (a = "webgl", s = t.fps / i.fps) : (a = "tie", s = 1) : i ? a = "webgpu" : t && (a = "webgl"), { webgpu: i, webgl: t, winner: a, speedup: Math.round(s * 100) / 100 };
1913
220
  }
1914
221
  /**
1915
222
  * Get all results
@@ -1938,7 +245,7 @@ class Ge {
1938
245
  ].join(" | ");
1939
246
  }
1940
247
  }
1941
- const xe = `
248
+ const M = `
1942
249
  struct StatsResult {
1943
250
  min_val: f32,
1944
251
  max_val: f32,
@@ -2008,7 +315,7 @@ fn main(
2008
315
  result.count = local_count[0];
2009
316
  }
2010
317
  }
2011
- `, ye = `
318
+ `, G = `
2012
319
  struct MinMax {
2013
320
  min_x: f32,
2014
321
  max_x: f32,
@@ -2065,7 +372,7 @@ fn main(
2065
372
  result.max_y = local_max_y[0];
2066
373
  }
2067
374
  }
2068
- `, _e = `
375
+ `, C = `
2069
376
  struct Params {
2070
377
  input_count: u32,
2071
378
  output_count: u32,
@@ -2121,7 +428,7 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
2121
428
  output_points[out_base + 1u] = input_points[min_idx];
2122
429
  }
2123
430
  }
2124
- `, Pe = `
431
+ `, T = `
2125
432
  struct Params {
2126
433
  data_count: u32,
2127
434
  threshold: f32,
@@ -2178,14 +485,14 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
2178
485
  }
2179
486
  }
2180
487
  `;
2181
- class R {
488
+ class P {
2182
489
  constructor(e = {}) {
2183
- c(this, "device", null);
2184
- c(this, "statsPipeline", null);
2185
- c(this, "minmaxPipeline", null);
2186
- c(this, "downsamplePipeline", null);
2187
- c(this, "peaksPipeline", null);
2188
- c(this, "isInitialized", !1);
490
+ _(this, "device", null);
491
+ _(this, "statsPipeline", null);
492
+ _(this, "minmaxPipeline", null);
493
+ _(this, "downsamplePipeline", null);
494
+ _(this, "peaksPipeline", null);
495
+ _(this, "isInitialized", !1);
2189
496
  this.options = e;
2190
497
  }
2191
498
  /**
@@ -2201,35 +508,35 @@ class R {
2201
508
  if (this.options.device)
2202
509
  this.device = this.options.device;
2203
510
  else {
2204
- if (!R.isSupported())
511
+ if (!P.isSupported())
2205
512
  throw new Error("[GpuCompute] WebGPU not supported");
2206
- const t = await globalThis.navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
2207
- if (!t)
513
+ const i = await globalThis.navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
514
+ if (!i)
2208
515
  throw new Error("[GpuCompute] Failed to get adapter");
2209
- this.device = await t.requestDevice();
516
+ this.device = await i.requestDevice();
2210
517
  }
2211
518
  await this.createPipelines(), this.isInitialized = !0;
2212
519
  }
2213
520
  async createPipelines() {
2214
- const e = this.device.createShaderModule({ code: xe });
521
+ const e = this.device.createShaderModule({ code: M });
2215
522
  this.statsPipeline = await this.device.createComputePipelineAsync({
2216
523
  layout: "auto",
2217
524
  compute: { module: e, entryPoint: "main" }
2218
525
  });
2219
- const t = this.device.createShaderModule({ code: ye });
526
+ const i = this.device.createShaderModule({ code: G });
2220
527
  this.minmaxPipeline = await this.device.createComputePipelineAsync({
2221
528
  layout: "auto",
2222
- compute: { module: t, entryPoint: "main" }
529
+ compute: { module: i, entryPoint: "main" }
2223
530
  });
2224
- const i = this.device.createShaderModule({ code: _e });
531
+ const t = this.device.createShaderModule({ code: C });
2225
532
  this.downsamplePipeline = await this.device.createComputePipelineAsync({
2226
533
  layout: "auto",
2227
- compute: { module: i, entryPoint: "main" }
534
+ compute: { module: t, entryPoint: "main" }
2228
535
  });
2229
- const r = this.device.createShaderModule({ code: Pe });
536
+ const a = this.device.createShaderModule({ code: T });
2230
537
  this.peaksPipeline = await this.device.createComputePipelineAsync({
2231
538
  layout: "auto",
2232
- compute: { module: r, entryPoint: "main" }
539
+ compute: { module: a, entryPoint: "main" }
2233
540
  });
2234
541
  }
2235
542
  /**
@@ -2238,31 +545,31 @@ class R {
2238
545
  async calculateStats(e) {
2239
546
  if (!this.isInitialized)
2240
547
  throw new Error("[GpuCompute] Not initialized");
2241
- const t = globalThis.GPUBufferUsage, i = this.device.createBuffer({
548
+ const i = globalThis.GPUBufferUsage, t = this.device.createBuffer({
2242
549
  size: e.byteLength,
2243
- usage: t.STORAGE | t.COPY_DST
550
+ usage: i.STORAGE | i.COPY_DST
2244
551
  });
2245
- this.device.queue.writeBuffer(i, 0, e);
2246
- const r = this.device.createBuffer({
552
+ this.device.queue.writeBuffer(t, 0, e);
553
+ const a = this.device.createBuffer({
2247
554
  size: 32,
2248
- usage: t.STORAGE | t.COPY_SRC
2249
- }), a = this.device.createBuffer({
555
+ usage: i.STORAGE | i.COPY_SRC
556
+ }), s = this.device.createBuffer({
2250
557
  size: 32,
2251
- usage: t.MAP_READ | t.COPY_DST
2252
- }), n = this.device.createBindGroup({
558
+ usage: i.MAP_READ | i.COPY_DST
559
+ }), r = this.device.createBindGroup({
2253
560
  layout: this.statsPipeline.getBindGroupLayout(0),
2254
561
  entries: [
2255
- { binding: 0, resource: { buffer: i } },
2256
- { binding: 1, resource: { buffer: r } }
562
+ { binding: 0, resource: { buffer: t } },
563
+ { binding: 1, resource: { buffer: a } }
2257
564
  ]
2258
565
  }), o = this.device.createCommandEncoder(), u = o.beginComputePass();
2259
- u.setPipeline(this.statsPipeline), u.setBindGroup(0, n);
566
+ u.setPipeline(this.statsPipeline), u.setBindGroup(0, r);
2260
567
  const l = Math.ceil(e.length / 256);
2261
- u.dispatchWorkgroups(l), u.end(), o.copyBufferToBuffer(r, 0, a, 0, 32), this.device.queue.submit([o.finish()]), await a.mapAsync(globalThis.GPUMapMode.READ);
2262
- const p = new Float32Array(a.getMappedRange().slice(0));
2263
- a.unmap(), i.destroy(), r.destroy(), a.destroy();
2264
- const [f, h, d, m, b] = p, g = Math.floor(b), v = g > 0 ? d / g : 0, x = g > 1 ? (m - d * d / g) / (g - 1) : 0, y = Math.sqrt(Math.max(0, x));
2265
- return { min: f, max: h, mean: v, std: y, count: g };
568
+ u.dispatchWorkgroups(l), u.end(), o.copyBufferToBuffer(a, 0, s, 0, 32), this.device.queue.submit([o.finish()]), await s.mapAsync(globalThis.GPUMapMode.READ);
569
+ const c = new Float32Array(s.getMappedRange().slice(0));
570
+ s.unmap(), t.destroy(), a.destroy(), s.destroy();
571
+ const [n, m, d, f, g] = c, h = Math.floor(g), v = h > 0 ? d / h : 0, x = h > 1 ? (f - d * d / h) / (h - 1) : 0, y = Math.sqrt(Math.max(0, x));
572
+ return { min: n, max: m, mean: v, std: y, count: h };
2266
573
  }
2267
574
  /**
2268
575
  * Calculate bounds for 2D point data
@@ -2270,124 +577,124 @@ class R {
2270
577
  async calculateBounds(e) {
2271
578
  if (!this.isInitialized)
2272
579
  throw new Error("[GpuCompute] Not initialized");
2273
- const t = globalThis.GPUBufferUsage, i = this.device.createBuffer({
580
+ const i = globalThis.GPUBufferUsage, t = this.device.createBuffer({
2274
581
  size: e.byteLength,
2275
- usage: t.STORAGE | t.COPY_DST
582
+ usage: i.STORAGE | i.COPY_DST
2276
583
  });
2277
- this.device.queue.writeBuffer(i, 0, e);
2278
- const r = this.device.createBuffer({
584
+ this.device.queue.writeBuffer(t, 0, e);
585
+ const a = this.device.createBuffer({
2279
586
  size: 16,
2280
- usage: t.STORAGE | t.COPY_SRC
2281
- }), a = this.device.createBuffer({
587
+ usage: i.STORAGE | i.COPY_SRC
588
+ }), s = this.device.createBuffer({
2282
589
  size: 16,
2283
- usage: t.MAP_READ | t.COPY_DST
2284
- }), n = this.device.createBindGroup({
590
+ usage: i.MAP_READ | i.COPY_DST
591
+ }), r = this.device.createBindGroup({
2285
592
  layout: this.minmaxPipeline.getBindGroupLayout(0),
2286
593
  entries: [
2287
- { binding: 0, resource: { buffer: i } },
2288
- { binding: 1, resource: { buffer: r } }
594
+ { binding: 0, resource: { buffer: t } },
595
+ { binding: 1, resource: { buffer: a } }
2289
596
  ]
2290
597
  }), o = this.device.createCommandEncoder(), u = o.beginComputePass();
2291
- u.setPipeline(this.minmaxPipeline), u.setBindGroup(0, n);
2292
- const l = e.length / 2, p = Math.ceil(l / 256);
2293
- u.dispatchWorkgroups(p), u.end(), o.copyBufferToBuffer(r, 0, a, 0, 16), this.device.queue.submit([o.finish()]), await a.mapAsync(globalThis.GPUMapMode.READ);
2294
- const f = new Float32Array(a.getMappedRange().slice(0));
2295
- return a.unmap(), i.destroy(), r.destroy(), a.destroy(), {
2296
- xMin: f[0],
2297
- xMax: f[1],
2298
- yMin: f[2],
2299
- yMax: f[3]
598
+ u.setPipeline(this.minmaxPipeline), u.setBindGroup(0, r);
599
+ const l = e.length / 2, c = Math.ceil(l / 256);
600
+ u.dispatchWorkgroups(c), u.end(), o.copyBufferToBuffer(a, 0, s, 0, 16), this.device.queue.submit([o.finish()]), await s.mapAsync(globalThis.GPUMapMode.READ);
601
+ const n = new Float32Array(s.getMappedRange().slice(0));
602
+ return s.unmap(), t.destroy(), a.destroy(), s.destroy(), {
603
+ xMin: n[0],
604
+ xMax: n[1],
605
+ yMin: n[2],
606
+ yMax: n[3]
2300
607
  };
2301
608
  }
2302
609
  /**
2303
610
  * Downsample point data using min-max algorithm
2304
611
  */
2305
- async downsample(e, t) {
612
+ async downsample(e, i) {
2306
613
  if (!this.isInitialized)
2307
614
  throw new Error("[GpuCompute] Not initialized");
2308
- const i = e.length / 2;
2309
- if (i <= t)
615
+ const t = e.length / 2;
616
+ if (t <= i)
2310
617
  return e;
2311
- const r = globalThis.GPUBufferUsage, a = Math.ceil(t / 2), n = Math.ceil(i / a), o = a * 2, u = new Uint32Array([i, o, n, 0]), l = this.device.createBuffer({
618
+ const a = globalThis.GPUBufferUsage, s = Math.ceil(i / 2), r = Math.ceil(t / s), o = s * 2, u = new Uint32Array([t, o, r, 0]), l = this.device.createBuffer({
2312
619
  size: 16,
2313
- usage: r.UNIFORM | r.COPY_DST
620
+ usage: a.UNIFORM | a.COPY_DST
2314
621
  });
2315
622
  this.device.queue.writeBuffer(l, 0, u);
2316
- const p = this.device.createBuffer({
623
+ const c = this.device.createBuffer({
2317
624
  size: e.byteLength,
2318
- usage: r.STORAGE | r.COPY_DST
625
+ usage: a.STORAGE | a.COPY_DST
2319
626
  });
2320
- this.device.queue.writeBuffer(p, 0, e);
2321
- const f = o * 2 * 4, h = this.device.createBuffer({
2322
- size: f,
2323
- usage: r.STORAGE | r.COPY_SRC
627
+ this.device.queue.writeBuffer(c, 0, e);
628
+ const n = o * 2 * 4, m = this.device.createBuffer({
629
+ size: n,
630
+ usage: a.STORAGE | a.COPY_SRC
2324
631
  }), d = this.device.createBuffer({
2325
- size: f,
2326
- usage: r.MAP_READ | r.COPY_DST
2327
- }), m = this.device.createBindGroup({
632
+ size: n,
633
+ usage: a.MAP_READ | a.COPY_DST
634
+ }), f = this.device.createBindGroup({
2328
635
  layout: this.downsamplePipeline.getBindGroupLayout(0),
2329
636
  entries: [
2330
637
  { binding: 0, resource: { buffer: l } },
2331
- { binding: 1, resource: { buffer: p } },
2332
- { binding: 2, resource: { buffer: h } }
638
+ { binding: 1, resource: { buffer: c } },
639
+ { binding: 2, resource: { buffer: m } }
2333
640
  ]
2334
- }), b = this.device.createCommandEncoder(), g = b.beginComputePass();
2335
- g.setPipeline(this.downsamplePipeline), g.setBindGroup(0, m);
2336
- const v = Math.ceil(a / 64);
2337
- g.dispatchWorkgroups(v), g.end(), b.copyBufferToBuffer(h, 0, d, 0, f), this.device.queue.submit([b.finish()]), await d.mapAsync(globalThis.GPUMapMode.READ);
641
+ }), g = this.device.createCommandEncoder(), h = g.beginComputePass();
642
+ h.setPipeline(this.downsamplePipeline), h.setBindGroup(0, f);
643
+ const v = Math.ceil(s / 64);
644
+ h.dispatchWorkgroups(v), h.end(), g.copyBufferToBuffer(m, 0, d, 0, n), this.device.queue.submit([g.finish()]), await d.mapAsync(globalThis.GPUMapMode.READ);
2338
645
  const x = new Float32Array(d.getMappedRange().slice(0));
2339
- return d.unmap(), l.destroy(), p.destroy(), h.destroy(), d.destroy(), x;
646
+ return d.unmap(), l.destroy(), c.destroy(), m.destroy(), d.destroy(), x;
2340
647
  }
2341
648
  /**
2342
649
  * Detect peaks in 1D data
2343
650
  */
2344
- async detectPeaks(e, t = {}) {
651
+ async detectPeaks(e, i = {}) {
2345
652
  if (!this.isInitialized)
2346
653
  throw new Error("[GpuCompute] Not initialized");
2347
- const i = t.threshold ?? 0, r = t.minDistance ?? 1, a = globalThis.GPUBufferUsage, n = new Float32Array([
654
+ const t = i.threshold ?? 0, a = i.minDistance ?? 1, s = globalThis.GPUBufferUsage, r = new Float32Array([
2348
655
  e.length,
2349
- i,
2350
- r,
656
+ t,
657
+ a,
2351
658
  0
2352
659
  // padding
2353
660
  ]), o = this.device.createBuffer({
2354
661
  size: 16,
2355
- usage: a.UNIFORM | a.COPY_DST
662
+ usage: s.UNIFORM | s.COPY_DST
2356
663
  });
2357
- this.device.queue.writeBuffer(o, 0, new Uint8Array(n.buffer));
664
+ this.device.queue.writeBuffer(o, 0, new Uint8Array(r.buffer));
2358
665
  const u = this.device.createBuffer({
2359
666
  size: e.byteLength,
2360
- usage: a.STORAGE | a.COPY_DST
667
+ usage: s.STORAGE | s.COPY_DST
2361
668
  });
2362
669
  this.device.queue.writeBuffer(u, 0, e);
2363
- const l = e.length * 16, p = this.device.createBuffer({
670
+ const l = e.length * 16, c = this.device.createBuffer({
2364
671
  size: l,
2365
- usage: a.STORAGE | a.COPY_SRC
2366
- }), f = this.device.createBuffer({
672
+ usage: s.STORAGE | s.COPY_SRC
673
+ }), n = this.device.createBuffer({
2367
674
  size: l,
2368
- usage: a.MAP_READ | a.COPY_DST
2369
- }), h = this.device.createBindGroup({
675
+ usage: s.MAP_READ | s.COPY_DST
676
+ }), m = this.device.createBindGroup({
2370
677
  layout: this.peaksPipeline.getBindGroupLayout(0),
2371
678
  entries: [
2372
679
  { binding: 0, resource: { buffer: o } },
2373
680
  { binding: 1, resource: { buffer: u } },
2374
- { binding: 2, resource: { buffer: p } }
681
+ { binding: 2, resource: { buffer: c } }
2375
682
  ]
2376
- }), d = this.device.createCommandEncoder(), m = d.beginComputePass();
2377
- m.setPipeline(this.peaksPipeline), m.setBindGroup(0, h);
2378
- const b = Math.ceil(e.length / 64);
2379
- m.dispatchWorkgroups(b), m.end(), d.copyBufferToBuffer(p, 0, f, 0, l), this.device.queue.submit([d.finish()]), await f.mapAsync(globalThis.GPUMapMode.READ);
2380
- const g = new ArrayBuffer(l);
2381
- new Uint8Array(g).set(new Uint8Array(f.getMappedRange())), f.unmap();
2382
- const v = new DataView(g), x = [];
683
+ }), d = this.device.createCommandEncoder(), f = d.beginComputePass();
684
+ f.setPipeline(this.peaksPipeline), f.setBindGroup(0, m);
685
+ const g = Math.ceil(e.length / 64);
686
+ f.dispatchWorkgroups(g), f.end(), d.copyBufferToBuffer(c, 0, n, 0, l), this.device.queue.submit([d.finish()]), await n.mapAsync(globalThis.GPUMapMode.READ);
687
+ const h = new ArrayBuffer(l);
688
+ new Uint8Array(h).set(new Uint8Array(n.getMappedRange())), n.unmap();
689
+ const v = new DataView(h), x = [];
2383
690
  for (let y = 0; y < e.length; y++) {
2384
- const B = y * 16;
2385
- v.getUint32(B + 8, !0) && x.push({
2386
- index: v.getUint32(B, !0),
2387
- value: v.getFloat32(B + 4, !0)
691
+ const b = y * 16;
692
+ v.getUint32(b + 8, !0) && x.push({
693
+ index: v.getUint32(b, !0),
694
+ value: v.getFloat32(b + 4, !0)
2388
695
  });
2389
696
  }
2390
- return o.destroy(), u.destroy(), p.destroy(), f.destroy(), x;
697
+ return o.destroy(), u.destroy(), c.destroy(), n.destroy(), x;
2391
698
  }
2392
699
  /**
2393
700
  * Cleanup resources
@@ -2396,16 +703,16 @@ class R {
2396
703
  this.device = null, this.statsPipeline = null, this.minmaxPipeline = null, this.downsamplePipeline = null, this.peaksPipeline = null, this.isInitialized = !1;
2397
704
  }
2398
705
  }
2399
- const we = {
706
+ const S = {
2400
707
  name: "velo-plot-gpu",
2401
708
  version: "1.0.0",
2402
709
  description: "GPU acceleration and WebGPU support for velo-plot",
2403
710
  provides: ["renderer", "compute"],
2404
711
  tags: ["gpu", "webgpu", "webgl2", "performance"]
2405
712
  };
2406
- function Ee(s = {}) {
713
+ function D(p = {}) {
2407
714
  return {
2408
- manifest: we,
715
+ manifest: S,
2409
716
  onInit(e) {
2410
717
  },
2411
718
  onDestroy(e) {
@@ -2413,18 +720,18 @@ function Ee(s = {}) {
2413
720
  };
2414
721
  }
2415
722
  export {
2416
- Te as BaseBufferStore,
2417
- Me as BaseTextureStore,
2418
- Ge as GpuBenchmark,
2419
- R as GpuCompute,
2420
- ve as GpuRenderer,
2421
- ke as PipelineCache,
2422
- Ee as PluginGpu,
2423
- M as SeriesAdapter,
2424
- P as WebGLBackend,
2425
- _ as WebGPUBackend,
2426
- Ae as createGpuRenderer,
2427
- Ee as default,
2428
- U as parseColorToRGBA
723
+ z as BaseBufferStore,
724
+ R as BaseTextureStore,
725
+ F as GpuBenchmark,
726
+ P as GpuCompute,
727
+ q as GpuRenderer,
728
+ E as PipelineCache,
729
+ D as PluginGpu,
730
+ W as SeriesAdapter,
731
+ I as WebGLBackend,
732
+ Y as WebGPUBackend,
733
+ $ as createGpuRenderer,
734
+ D as default,
735
+ N as parseColorToRGBA
2429
736
  };
2430
737
  //# sourceMappingURL=gpu.js.map