blazeplot 0.1.7 → 0.1.8

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.js CHANGED
@@ -81,6 +81,32 @@ var t = 16, n = class {
81
81
  let i = new Float32Array(n);
82
82
  r && i.set(r.subarray(0, Math.min(r.length, n))), this.levels[e] = i;
83
83
  }
84
+ rangeMinMax(e, t, n) {
85
+ let r = Math.max(0, Math.floor(t)), i = Math.min(e.length, Math.ceil(n));
86
+ if (i <= r) return null;
87
+ let a = Infinity, o = -Infinity, s = r;
88
+ for (; s < i;) {
89
+ let t = -1, n = 1;
90
+ for (let e = this.levels.length - 1; e >= 0; e--) {
91
+ let r = this.levelSampleWidths[e], a = Math.floor(s / r);
92
+ if (r > 0 && s % r === 0 && s + r <= i && a < this.levelLengths[e]) {
93
+ t = e, n = r;
94
+ break;
95
+ }
96
+ }
97
+ if (t >= 0) {
98
+ let e = Math.floor(s / n), r = this.levels[t], i = r[e * 2], c = r[e * 2 + 1];
99
+ i < a && (a = i), c > o && (o = c), s += n;
100
+ } else {
101
+ let t = e.getY(s);
102
+ t < a && (a = t), t > o && (o = t), s++;
103
+ }
104
+ }
105
+ return Number.isFinite(a) && Number.isFinite(o) ? {
106
+ minY: a,
107
+ maxY: o
108
+ } : null;
109
+ }
84
110
  query(e, t, n) {
85
111
  if (t <= 0 || n.length <= 0) return {
86
112
  buckets: new Float32Array(),
@@ -114,15 +140,24 @@ var t = 16, n = class {
114
140
  samplesPerPixel: i
115
141
  };
116
142
  }
117
- }, r = class {
143
+ };
144
+ //#endregion
145
+ //#region src/core/SeriesStore.ts
146
+ function r(e) {
147
+ return "rangeMinMaxY" in e;
148
+ }
149
+ var i = class {
118
150
  config;
119
151
  style;
120
152
  dataset;
121
153
  pyramid;
122
154
  _dirty = !1;
155
+ _useRawMinMaxScan = !1;
156
+ _lastBuildLength = 0;
157
+ _lastBuildRangeStart = NaN;
123
158
  _visible = !0;
124
159
  constructor(e, t, r) {
125
- this.dataset = e, this.config = t, this.pyramid = t.mode === "line" && t.downsample !== "none" ? new n() : null, this.style = r, this.pyramid && e.length > 0 && this.pyramid.build(e);
160
+ this.dataset = e, this.config = t, this.pyramid = (t.mode === "line" || t.mode === "bar") && t.downsample !== "none" ? new n() : null, this.style = r, this.pyramid && e.length > 0 && this.pyramid.build(e), this._lastBuildLength = e.length, this._lastBuildRangeStart = e.range?.start ?? NaN;
126
161
  }
127
162
  get hasLOD() {
128
163
  return this.pyramid !== null;
@@ -145,10 +180,16 @@ var t = 16, n = class {
145
180
  }
146
181
  clear() {
147
182
  if (!("clear" in this.dataset)) throw TypeError("SeriesStore dataset is not clearable.");
148
- this.dataset.clear(), this.pyramid && this.pyramid.build(this.dataset), this._dirty = !1;
183
+ this.dataset.clear(), this.pyramid && this.pyramid.build(this.dataset), this._useRawMinMaxScan = !1, this._lastBuildLength = this.dataset.length, this._lastBuildRangeStart = this.dataset.range?.start ?? NaN, this._dirty = !1;
149
184
  }
150
185
  rebuildPyramid() {
151
- this._dirty &&= (this.pyramid && this.pyramid.incrementalBuild(this.dataset), !1);
186
+ if (this._dirty) {
187
+ if (this.pyramid) {
188
+ let e = this.dataset.length, t = this.dataset.range?.start ?? NaN;
189
+ e === this._lastBuildLength && t !== this._lastBuildRangeStart ? this._useRawMinMaxScan = !0 : (this.pyramid.incrementalBuild(this.dataset), this._useRawMinMaxScan = !1), this._lastBuildLength = e, this._lastBuildRangeStart = t;
190
+ }
191
+ this._dirty = !1;
192
+ }
152
193
  }
153
194
  query(e, t) {
154
195
  if (!this.pyramid || !this.dataset.range) return {
@@ -167,6 +208,38 @@ var t = 16, n = class {
167
208
  let t = this.dataset.lowerBoundX(e.xMin), n = this.dataset.upperBoundX(e.xMax);
168
209
  return Math.max(0, n - t);
169
210
  }
211
+ sampleAt(e) {
212
+ return e < 0 || e >= this.dataset.length ? null : {
213
+ index: e,
214
+ x: this.dataset.getX(e),
215
+ y: this.dataset.getY(e)
216
+ };
217
+ }
218
+ nearestSampleByX(e, t) {
219
+ let n = this.visibleIndexRange(t);
220
+ if (n.start >= n.end) return null;
221
+ let r = this.dataset.lowerBoundX(e), i = Math.min(Math.max(r, n.start), n.end - 1), a = i - 1;
222
+ if (a >= n.start) {
223
+ let t = Math.abs(this.dataset.getX(i) - e);
224
+ Math.abs(this.dataset.getX(a) - e) <= t && (i = a);
225
+ }
226
+ return this.sampleAt(i);
227
+ }
228
+ nearestSampleByPoint(e, t, n, r, i) {
229
+ let a = this.visibleIndexRange(n);
230
+ if (a.start >= a.end || r <= 0 || i <= 0) return null;
231
+ let o = r / (n.xMax - n.xMin), s = i / (n.yMax - n.yMin), c = -1, l = Infinity;
232
+ for (let n = a.start; n < a.end; n++) {
233
+ let r = (this.dataset.getX(n) - e) * o, i = (this.dataset.getY(n) - t) * s, a = r * r + i * i;
234
+ a < l && (l = a, c = n);
235
+ }
236
+ if (c < 0) return null;
237
+ let u = this.sampleAt(c);
238
+ return u ? {
239
+ ...u,
240
+ distancePx: Math.sqrt(l)
241
+ } : null;
242
+ }
170
243
  copyRawVisible(e, t, n) {
171
244
  return this.copyVisibleSamples(e, t, n, "points", 0);
172
245
  }
@@ -179,6 +252,15 @@ var t = 16, n = class {
179
252
  copyMinMaxInstanced(e, t, n) {
180
253
  return this.copyMinMaxSegments(e, t, n, "instanced");
181
254
  }
255
+ visibleIndexRange(e) {
256
+ return e ? {
257
+ start: this.dataset.lowerBoundX(e.xMin),
258
+ end: this.dataset.upperBoundX(e.xMax)
259
+ } : {
260
+ start: 0,
261
+ end: this.dataset.length
262
+ };
263
+ }
182
264
  copyVisibleSamples(e, t, n, r, i) {
183
265
  let a = r === "points" ? 2 : 4;
184
266
  if (n <= 0 || t.length < n * a) return 0;
@@ -205,31 +287,48 @@ var t = 16, n = class {
205
287
  if (s <= 0) return 0;
206
288
  let c = Math.min(n, s);
207
289
  for (let e = 0; e < c; e++) {
208
- let n = a + Math.floor(e * s / c), i = a + Math.max(Math.floor((e + 1) * s / c), Math.floor(e * s / c) + 1), l = Math.min(o, i), u = Infinity, d = -Infinity;
209
- for (let e = n; e < l; e++) {
210
- let t = this.dataset.getY(e);
211
- t < u && (u = t), t > d && (d = t);
212
- }
213
- let f = this.dataset.getX(n + (l - n >> 1));
290
+ let n = a + Math.floor(e * s / c), i = a + Math.max(Math.floor((e + 1) * s / c), Math.floor(e * s / c) + 1), l = Math.min(o, i), u = this.minMaxForRange(n, l);
291
+ if (!u) continue;
292
+ let d = this.dataset.getX(n + (l - n >> 1)), { minY: f, maxY: p } = u;
214
293
  if (r === "line-list") {
215
294
  let n = e * 4;
216
- t[n] = f, t[n + 1] = u, t[n + 2] = f, t[n + 3] = d;
295
+ t[n] = d, t[n + 1] = f, t[n + 2] = d, t[n + 3] = p;
217
296
  } else {
218
297
  let n = e * 3;
219
- t[n] = f, t[n + 1] = u, t[n + 2] = d;
298
+ t[n] = d, t[n + 1] = f, t[n + 2] = p;
220
299
  }
221
300
  }
222
301
  return c;
223
302
  }
224
- }, i = class {
303
+ minMaxForRange(e, t) {
304
+ return !this.pyramid || this._useRawMinMaxScan ? this.rawMinMaxForRange(e, t) : this.pyramid.rangeMinMax(this.dataset, e, t);
305
+ }
306
+ rawMinMaxForRange(e, t) {
307
+ if (r(this.dataset)) return this.dataset.rangeMinMaxY(e, t);
308
+ let n = Math.max(0, Math.floor(e)), i = Math.min(this.dataset.length, Math.ceil(t));
309
+ if (i <= n) return null;
310
+ let a = Infinity, o = -Infinity;
311
+ for (let e = n; e < i; e++) {
312
+ let t = this.dataset.getY(e);
313
+ t < a && (a = t), t > o && (o = t);
314
+ }
315
+ return {
316
+ minY: a,
317
+ maxY: o
318
+ };
319
+ }
320
+ }, a = class e {
225
321
  capacity;
226
322
  _length = 0;
227
323
  _head = 0;
228
324
  xData;
229
325
  yData;
230
- constructor(e) {
231
- if (!Number.isInteger(e) || e <= 0) throw RangeError("RingBuffer capacity must be a positive integer.");
232
- this.capacity = e, this.xData = new Float64Array(e), this.yData = new Float32Array(e);
326
+ treeBase;
327
+ minTree;
328
+ maxTree;
329
+ constructor(t) {
330
+ if (!Number.isInteger(t) || t <= 0) throw RangeError("RingBuffer capacity must be a positive integer.");
331
+ this.capacity = t, this.xData = new Float64Array(t), this.yData = new Float32Array(t), this.treeBase = e.nextPowerOfTwo(t), this.minTree = new Float32Array(this.treeBase * 2), this.maxTree = new Float32Array(this.treeBase * 2), this.minTree.fill(Infinity), this.maxTree.fill(-Infinity);
233
332
  }
234
333
  get length() {
235
334
  return this._length;
@@ -241,11 +340,21 @@ var t = 16, n = class {
241
340
  };
242
341
  }
243
342
  push(e, t) {
244
- this.xData[this._head] = e, this.yData[this._head] = t, this._head = (this._head + 1) % this.capacity, this._length < this.capacity && this._length++;
343
+ this.xData[this._head] = e, this.yData[this._head] = t, this.setTreeLeaf(this._head, t), this._head = (this._head + 1) % this.capacity, this._length < this.capacity && this._length++;
245
344
  }
246
345
  append(e, t) {
247
346
  let n = Math.min(e.length, t.length);
248
- for (let r = 0; r < n; r++) this.push(e[r], t[r]);
347
+ if (n <= 0) return;
348
+ if (n >= this.capacity) {
349
+ let r = n - this.capacity;
350
+ this._head = 0, this._length = this.capacity, this.copyIntoPhysical(0, e, t, r, this.capacity);
351
+ return;
352
+ }
353
+ let r = 0, i = n;
354
+ for (; i > 0;) {
355
+ let n = Math.min(i, this.capacity - this._head);
356
+ this.copyIntoPhysical(this._head, e, t, r, n), this._head = (this._head + n) % this.capacity, this._length = Math.min(this.capacity, this._length + n), r += n, i -= n;
357
+ }
249
358
  }
250
359
  get(e) {
251
360
  return e < 0 || e >= this._length ? null : {
@@ -275,8 +384,64 @@ var t = 16, n = class {
275
384
  }
276
385
  return t;
277
386
  }
387
+ rangeMinMaxY(e, t) {
388
+ let n = Math.max(0, Math.floor(e)), r = Math.min(this._length, Math.ceil(t));
389
+ if (r <= n) return null;
390
+ let i = this.logicalToPhysical(n), a = r - n;
391
+ if (i + a <= this.capacity) return this.queryPhysicalMinMax(i, i + a);
392
+ let o = this.queryPhysicalMinMax(i, this.capacity), s = this.queryPhysicalMinMax(0, (i + a) % this.capacity);
393
+ return o ? s ? {
394
+ minY: Math.min(o.minY, s.minY),
395
+ maxY: Math.max(o.maxY, s.maxY)
396
+ } : o : s;
397
+ }
278
398
  clear() {
279
- this._length = 0, this._head = 0;
399
+ this._length = 0, this._head = 0, this.minTree.fill(Infinity), this.maxTree.fill(-Infinity);
400
+ }
401
+ copyIntoPhysical(e, t, n, r, i) {
402
+ for (let a = 0; a < i; a++) {
403
+ let i = e + a, o = n[r + a];
404
+ this.xData[i] = t[r + a], this.yData[i] = o;
405
+ let s = this.treeBase + i;
406
+ this.minTree[s] = o, this.maxTree[s] = o;
407
+ }
408
+ this.recomputeTreeRange(e, e + i);
409
+ }
410
+ setTreeLeaf(e, t) {
411
+ let n = this.treeBase + e;
412
+ for (this.minTree[n] = t, this.maxTree[n] = t, n >>= 1; n >= 1;) this.recomputeTreeNode(n), n >>= 1;
413
+ }
414
+ recomputeTreeRange(e, t) {
415
+ let n = this.treeBase + e >> 1, r = this.treeBase + t - 1 >> 1;
416
+ for (; n >= 1;) {
417
+ for (let e = n; e <= r; e++) this.recomputeTreeNode(e);
418
+ if (n === 1) break;
419
+ n >>= 1, r >>= 1;
420
+ }
421
+ }
422
+ recomputeTreeNode(e) {
423
+ let t = e << 1, n = t + 1, r = this.minTree[t], i = this.minTree[n], a = this.maxTree[t], o = this.maxTree[n];
424
+ this.minTree[e] = r < i ? r : i, this.maxTree[e] = a > o ? a : o;
425
+ }
426
+ queryPhysicalMinMax(e, t) {
427
+ if (t <= e) return null;
428
+ let n = this.treeBase + e, r = this.treeBase + t, i = Infinity, a = -Infinity;
429
+ for (; n < r;) {
430
+ if (n & 1) {
431
+ let e = this.minTree[n], t = this.maxTree[n];
432
+ e < i && (i = e), t > a && (a = t), n++;
433
+ }
434
+ if (r & 1) {
435
+ r--;
436
+ let e = this.minTree[r], t = this.maxTree[r];
437
+ e < i && (i = e), t > a && (a = t);
438
+ }
439
+ n >>= 1, r >>= 1;
440
+ }
441
+ return Number.isFinite(i) && Number.isFinite(a) ? {
442
+ minY: i,
443
+ maxY: a
444
+ } : null;
280
445
  }
281
446
  logicalToPhysical(e) {
282
447
  return (this._head - this._length + e + this.capacity) % this.capacity;
@@ -284,29 +449,42 @@ var t = 16, n = class {
284
449
  assertValidIndex(e) {
285
450
  if (!Number.isInteger(e) || e < 0 || e >= this._length) throw RangeError(`RingBuffer index out of range: ${e}`);
286
451
  }
287
- }, a = {
452
+ static nextPowerOfTwo(e) {
453
+ return 2 ** Math.ceil(Math.log2(e));
454
+ }
455
+ }, o = "attribute vec2 position;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\n\nvoid main() {\n vec2 clipSpace = position * uScale + uOffset;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n", s = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", c = "attribute float aX;\nattribute float aMinY;\nattribute float aMaxY;\nattribute float aSelect;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\n\nvoid main() {\n float y = (aSelect < 0.5) ? aMinY : aMaxY;\n vec2 position = vec2(aX, y);\n vec2 clipSpace = position * uScale + uOffset;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n", l = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", u = "attribute vec2 aPosition;\nattribute vec2 aCorner;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\nuniform vec2 uCanvasSize;\nuniform float uPointSize;\n\nvoid main() {\n vec2 centerClip = aPosition * uScale + uOffset;\n vec2 pointSizeClip = vec2(2.0 / uCanvasSize.x, 2.0 / uCanvasSize.y) * uPointSize * 0.5;\n vec2 clipSpace = centerClip + aCorner * pointSizeClip;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n", d = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", f = "attribute vec2 aPosition;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\nuniform float uPointSize;\n\nvoid main() {\n vec2 clipSpace = aPosition * uScale + uOffset;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n gl_PointSize = uPointSize;\n}\n", p = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n vec2 p = gl_PointCoord * 2.0 - 1.0;\n if (dot(p, p) > 1.0) discard;\n gl_FragColor = uColor;\n}\n", m = "attribute vec2 aPosition;\nattribute vec2 aCorner;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\nuniform float uBarWidth;\nuniform float uBaseline;\n\nvoid main() {\n float x = aPosition.x + aCorner.x * uBarWidth;\n float y = mix(uBaseline, aPosition.y, aCorner.y);\n vec2 clipSpace = vec2(x, y) * uScale + uOffset;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n", h = "attribute float aX;\nattribute float aMinY;\nattribute float aMaxY;\nattribute vec2 aCorner;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\nuniform float uBarWidth;\n\nvoid main() {\n float x = aX + aCorner.x * uBarWidth;\n float y = mix(aMinY, aMaxY, aCorner.y);\n vec2 clipSpace = vec2(x, y) * uScale + uOffset;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n", g = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", _ = {
288
456
  line: {
289
- vert: "attribute vec2 position;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\n\nvoid main() {\n vec2 clipSpace = position * uScale + uOffset;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n",
290
- frag: "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n"
457
+ vert: o,
458
+ frag: s
291
459
  },
292
460
  segment: {
293
- vert: "attribute float aX;\nattribute float aMinY;\nattribute float aMaxY;\nattribute float aSelect;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\n\nvoid main() {\n float y = (aSelect < 0.5) ? aMinY : aMaxY;\n vec2 position = vec2(aX, y);\n vec2 clipSpace = position * uScale + uOffset;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n",
294
- frag: "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n"
461
+ vert: c,
462
+ frag: l
295
463
  },
296
464
  point: {
297
- vert: "attribute vec2 aPosition;\nattribute vec2 aCorner;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\nuniform vec2 uCanvasSize;\nuniform float uPointSize;\n\nvoid main() {\n vec2 centerClip = aPosition * uScale + uOffset;\n vec2 pointSizeClip = vec2(2.0 / uCanvasSize.x, 2.0 / uCanvasSize.y) * uPointSize * 0.5;\n vec2 clipSpace = centerClip + aCorner * pointSizeClip;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n",
298
- frag: "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n"
465
+ vert: u,
466
+ frag: d
467
+ },
468
+ pointSprite: {
469
+ vert: f,
470
+ frag: p
299
471
  },
300
472
  bar: {
301
- vert: "attribute vec2 aPosition;\nattribute vec2 aCorner;\n\nuniform vec2 uScale;\nuniform vec2 uOffset;\nuniform float uBarWidth;\nuniform float uBaseline;\n\nvoid main() {\n float x = aPosition.x + aCorner.x * uBarWidth;\n float y = mix(uBaseline, aPosition.y, aCorner.y);\n vec2 clipSpace = vec2(x, y) * uScale + uOffset;\n gl_Position = vec4(clipSpace, 0.0, 1.0);\n}\n",
302
- frag: "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n"
473
+ vert: m,
474
+ frag: g
475
+ },
476
+ barRange: {
477
+ vert: h,
478
+ frag: g
303
479
  }
304
- }, o = 3, s = 2, c = 4, l = 4, u = .8, d = 0, f = class {
480
+ }, v = 3, y = 2, b = 4, x = 4, S = .8, C = 0, w = class {
305
481
  backend;
306
482
  lineProgram;
307
483
  segmentProgram;
308
484
  pointProgram;
485
+ pointSpriteProgram;
309
486
  barProgram;
487
+ barRangeProgram;
310
488
  segmentSelectBuffer;
311
489
  pointCornerBuffer;
312
490
  barCornerBuffer;
@@ -314,7 +492,7 @@ var t = 16, n = class {
314
492
  offsetUniform = new Float32Array(2);
315
493
  canvasSizeUniform = new Float32Array(2);
316
494
  constructor(e) {
317
- this.backend = e, this.lineProgram = this.backend.createProgram(a.line.vert, a.line.frag), this.segmentProgram = this.backend.createProgram(a.segment.vert, a.segment.frag), this.pointProgram = this.backend.createProgram(a.point.vert, a.point.frag), this.barProgram = this.backend.createProgram(a.bar.vert, a.bar.frag), this.segmentSelectBuffer = this.backend.createBuffer({
495
+ this.backend = e, this.lineProgram = this.backend.createProgram(_.line.vert, _.line.frag), this.segmentProgram = this.backend.createProgram(_.segment.vert, _.segment.frag), this.pointProgram = this.backend.createProgram(_.point.vert, _.point.frag), this.pointSpriteProgram = this.backend.createProgram(_.pointSprite.vert, _.pointSprite.frag), this.barProgram = this.backend.createProgram(_.bar.vert, _.bar.frag), this.barRangeProgram = this.backend.createProgram(_.barRange.vert, _.barRange.frag), this.segmentSelectBuffer = this.backend.createBuffer({
318
496
  usage: "static",
319
497
  type: "float",
320
498
  length: 2
@@ -382,25 +560,25 @@ var t = 16, n = class {
382
560
  }
383
561
  drawMinMaxSegmentsInstanced(e, t, n, r) {
384
562
  this.writeCameraUniforms(r);
385
- let i = o * c, a = {
563
+ let i = v * b, a = {
386
564
  buffer: e,
387
565
  divisor: 1,
388
566
  stride: i,
389
567
  offset: 0
390
- }, s = {
568
+ }, o = {
391
569
  buffer: e,
392
570
  divisor: 1,
393
571
  stride: i,
394
- offset: c
395
- }, l = {
572
+ offset: b
573
+ }, s = {
396
574
  buffer: e,
397
575
  divisor: 1,
398
576
  stride: i,
399
- offset: c * 2
400
- }, u = {
577
+ offset: b * 2
578
+ }, c = {
401
579
  buffer: this.segmentSelectBuffer,
402
580
  divisor: 0,
403
- stride: c,
581
+ stride: b,
404
582
  offset: 0
405
583
  };
406
584
  this.backend.draw({
@@ -409,9 +587,9 @@ var t = 16, n = class {
409
587
  count: 2,
410
588
  instances: t,
411
589
  attributes: {
412
- aMaxY: l,
413
- aMinY: s,
414
- aSelect: u,
590
+ aMaxY: s,
591
+ aMinY: o,
592
+ aSelect: c,
415
593
  aX: a
416
594
  },
417
595
  uniforms: {
@@ -426,13 +604,13 @@ var t = 16, n = class {
426
604
  let o = {
427
605
  buffer: e,
428
606
  divisor: 1,
429
- stride: s * c,
607
+ stride: y * b,
430
608
  offset: 0,
431
609
  size: 2
432
- }, u = {
610
+ }, s = {
433
611
  buffer: this.pointCornerBuffer,
434
612
  divisor: 0,
435
- stride: s * c,
613
+ stride: y * b,
436
614
  offset: 0,
437
615
  size: 2
438
616
  };
@@ -442,14 +620,28 @@ var t = 16, n = class {
442
620
  count: 4,
443
621
  instances: t,
444
622
  attributes: {
445
- aCorner: u,
623
+ aCorner: s,
446
624
  aPosition: o
447
625
  },
448
626
  uniforms: {
449
627
  uScale: this.scaleUniform,
450
628
  uOffset: this.offsetUniform,
451
629
  uCanvasSize: this.canvasSizeUniform,
452
- uPointSize: n.pointSize ?? l,
630
+ uPointSize: n.pointSize ?? x,
631
+ uColor: n.color
632
+ }
633
+ });
634
+ }
635
+ drawPointSprites(e, t, n, r) {
636
+ this.writeCameraUniforms(r), this.backend.draw({
637
+ program: this.pointSpriteProgram,
638
+ primitive: "points",
639
+ count: t,
640
+ attributes: { aPosition: e },
641
+ uniforms: {
642
+ uScale: this.scaleUniform,
643
+ uOffset: this.offsetUniform,
644
+ uPointSize: n.pointSize ?? x,
453
645
  uColor: n.color
454
646
  }
455
647
  });
@@ -472,13 +664,13 @@ var t = 16, n = class {
472
664
  let i = {
473
665
  buffer: e,
474
666
  divisor: 1,
475
- stride: s * c,
667
+ stride: y * b,
476
668
  offset: 0,
477
669
  size: 2
478
670
  }, a = {
479
671
  buffer: this.barCornerBuffer,
480
672
  divisor: 0,
481
- stride: s * c,
673
+ stride: y * b,
482
674
  offset: 0,
483
675
  size: 2
484
676
  };
@@ -494,12 +686,58 @@ var t = 16, n = class {
494
686
  uniforms: {
495
687
  uScale: this.scaleUniform,
496
688
  uOffset: this.offsetUniform,
497
- uBarWidth: n.barWidth ?? u,
498
- uBaseline: n.baseline ?? d,
689
+ uBarWidth: n.barWidth ?? S,
690
+ uBaseline: n.baseline ?? C,
499
691
  uColor: n.color
500
692
  }
501
693
  });
502
694
  }
695
+ drawBarRangesInstanced(e, t, n, r) {
696
+ this.writeCameraUniforms(r);
697
+ let i = v * b, a = {
698
+ buffer: e,
699
+ divisor: 1,
700
+ stride: i,
701
+ offset: 0
702
+ }, o = {
703
+ buffer: e,
704
+ divisor: 1,
705
+ stride: i,
706
+ offset: b
707
+ }, s = {
708
+ buffer: e,
709
+ divisor: 1,
710
+ stride: i,
711
+ offset: b * 2
712
+ }, c = {
713
+ buffer: this.barCornerBuffer,
714
+ divisor: 0,
715
+ stride: y * b,
716
+ offset: 0,
717
+ size: 2
718
+ };
719
+ this.backend.draw({
720
+ program: this.barRangeProgram,
721
+ primitive: "triangle_strip",
722
+ count: 4,
723
+ instances: t,
724
+ attributes: {
725
+ aCorner: c,
726
+ aMaxY: s,
727
+ aMinY: o,
728
+ aX: a
729
+ },
730
+ uniforms: {
731
+ uScale: this.scaleUniform,
732
+ uOffset: this.offsetUniform,
733
+ uBarWidth: n.barWidth ?? S,
734
+ uColor: n.color
735
+ }
736
+ });
737
+ }
738
+ drawBarTriangles(e, t, n, r) {
739
+ this.drawTrianglePrimitive(e, t, n, r);
740
+ }
503
741
  drawLinePrimitive(e, t, n, r, i) {
504
742
  this.writeCameraUniforms(i), this.backend.draw({
505
743
  program: this.lineProgram,
@@ -513,19 +751,32 @@ var t = 16, n = class {
513
751
  }
514
752
  });
515
753
  }
754
+ drawTrianglePrimitive(e, t, n, r) {
755
+ this.writeCameraUniforms(r), this.backend.draw({
756
+ program: this.lineProgram,
757
+ primitive: "triangles",
758
+ count: t,
759
+ attributes: { position: e },
760
+ uniforms: {
761
+ uScale: this.scaleUniform,
762
+ uOffset: this.offsetUniform,
763
+ uColor: n.color
764
+ }
765
+ });
766
+ }
516
767
  writeCameraUniforms(e) {
517
768
  this.scaleUniform[0] = e.xScale, this.scaleUniform[1] = e.yScale, this.offsetUniform[0] = e.xOffset, this.offsetUniform[1] = e.yOffset;
518
769
  }
519
770
  dispose() {
520
771
  this.backend.destroy();
521
772
  }
522
- }, p = [
773
+ }, T = [
523
774
  1024,
524
775
  4096,
525
776
  16384,
526
777
  32768,
527
778
  131072
528
- ], m = class {
779
+ ], E = class {
529
780
  regl;
530
781
  pool = [];
531
782
  preAllocated = !1;
@@ -538,7 +789,7 @@ var t = 16, n = class {
538
789
  preAllocate() {
539
790
  if (!this.preAllocated) {
540
791
  this.preAllocated = !0;
541
- for (let e of p) this.pool.push(this.createEntry(e, "stream"));
792
+ for (let e of T) this.pool.push(this.createEntry(e, "stream"));
542
793
  }
543
794
  }
544
795
  acquire(e, t = "stream") {
@@ -578,17 +829,17 @@ var t = 16, n = class {
578
829
  return this.pool.find((t) => !t.inUse && t.floatCapacity >= e);
579
830
  }
580
831
  roundUp(e) {
581
- for (let t of p) if (t >= e) return t;
582
- let t = p[p.length - 1], n = 1 << 32 - Math.clz32(e - 1);
832
+ for (let t of T) if (t >= e) return t;
833
+ let t = T[T.length - 1], n = 1 << 32 - Math.clz32(e - 1);
583
834
  return Math.max(t * 2, n);
584
835
  }
585
836
  };
586
837
  //#endregion
587
838
  //#region src/render/ReglBackend.ts
588
- function h(e) {
839
+ function D(e) {
589
840
  return e;
590
841
  }
591
- var g = class {
842
+ var O = class {
592
843
  gl;
593
844
  regl;
594
845
  resources;
@@ -608,10 +859,10 @@ var g = class {
608
859
  });
609
860
  if (!n) throw Error("BlazePlot requires WebGL2, but this browser/context does not support it.");
610
861
  this.gl = n, this.regl = e({
611
- gl: h(this.gl),
862
+ gl: D(this.gl),
612
863
  extensions: [],
613
864
  optionalExtensions: ["angle_instanced_arrays", "ext_disjoint_timer_query_webgl2"]
614
- }), this.capabilities = { instancing: this.regl.hasExtension("angle_instanced_arrays") }, this.resources = new m(this.regl), this.resources.preAllocate();
865
+ }), this.capabilities = { instancing: this.regl.hasExtension("angle_instanced_arrays") }, this.resources = new E(this.regl), this.resources.preAllocate();
615
866
  }
616
867
  createBuffer(e) {
617
868
  let { buffer: t } = this.resources.acquire(e.length, e.usage);
@@ -730,7 +981,7 @@ var g = class {
730
981
  default: return e;
731
982
  }
732
983
  }
733
- }, _ = class {
984
+ }, k = class {
734
985
  canvas;
735
986
  camera;
736
987
  policy;
@@ -784,7 +1035,7 @@ var g = class {
784
1035
  dispose() {
785
1036
  this.canvas.removeEventListener("pointerdown", this.onPointerDown), this.canvas.removeEventListener("pointermove", this.onPointerMove), this.canvas.removeEventListener("pointerup", this.onPointerUp), this.canvas.removeEventListener("pointercancel", this.onPointerUp), this.canvas.removeEventListener("wheel", this.onWheel);
786
1037
  }
787
- }, v = class e {
1038
+ }, A = class e {
788
1039
  _xMin = 0;
789
1040
  _xMax = 1;
790
1041
  _yMin = 0;
@@ -869,7 +1120,7 @@ var g = class {
869
1120
  static assertFinite(e, t) {
870
1121
  if (!Number.isFinite(t)) throw RangeError(`Camera2D ${e} must be finite.`);
871
1122
  }
872
- }, y = class {
1123
+ }, j = class {
873
1124
  camera;
874
1125
  constructor(e) {
875
1126
  this.camera = e;
@@ -901,7 +1152,7 @@ var g = class {
901
1152
  let n = Math.max(0, -Math.floor(Math.log10(t)) + 2), r = Number(e.toFixed(n));
902
1153
  return Object.is(r, -0) ? 0 : r;
903
1154
  }
904
- }, b = class {
1155
+ }, M = class {
905
1156
  layout;
906
1157
  config;
907
1158
  options;
@@ -943,7 +1194,7 @@ var g = class {
943
1194
  }
944
1195
  }
945
1196
  }
946
- }, x = class {
1197
+ }, N = class {
947
1198
  root;
948
1199
  plot;
949
1200
  canvas;
@@ -968,10 +1219,10 @@ var g = class {
968
1219
  this.externalCanvas ? this.originalCanvasParent?.insertBefore(this.root, e) : e.appendChild(this.root), this.root.appendChild(this.yAxis), this.root.appendChild(this.plot), this.root.appendChild(this.corner), this.root.appendChild(this.xAxis), this.plot.appendChild(this.canvas);
969
1220
  }
970
1221
  applyBaseStyles() {
971
- this.root.style.display = "grid", this.root.style.width = "100%", this.root.style.height = "100%", this.root.style.minWidth = "0", this.root.style.minHeight = "0", this.root.style.overflow = "hidden", this.plot.style.position = "relative", this.plot.style.gridColumn = "2", this.plot.style.gridRow = "1", this.plot.style.minWidth = "0", this.plot.style.minHeight = "0", this.plot.style.overflow = "hidden", this.canvas.style.position = "absolute", this.canvas.style.inset = "0", this.canvas.style.display = "block", this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.canvas.style.touchAction = "none", this.yAxis.style.position = "relative", this.yAxis.style.gridColumn = "1", this.yAxis.style.gridRow = "1", this.yAxis.style.minWidth = "0", this.yAxis.style.minHeight = "0", this.yAxis.style.overflow = "hidden", this.yAxis.style.pointerEvents = "none", this.xAxis.style.position = "relative", this.xAxis.style.gridColumn = "2", this.xAxis.style.gridRow = "2", this.xAxis.style.minWidth = "0", this.xAxis.style.minHeight = "0", this.xAxis.style.overflow = "hidden", this.xAxis.style.pointerEvents = "none", this.corner.style.gridColumn = "1", this.corner.style.gridRow = "2", this.corner.style.minWidth = "0", this.corner.style.minHeight = "0", this.corner.style.pointerEvents = "none";
1222
+ this.root.style.position = "relative", this.root.style.display = "grid", this.root.style.width = "100%", this.root.style.height = "100%", this.root.style.minWidth = "0", this.root.style.minHeight = "0", this.root.style.overflow = "hidden", this.plot.style.position = "relative", this.plot.style.gridColumn = "2", this.plot.style.gridRow = "1", this.plot.style.minWidth = "0", this.plot.style.minHeight = "0", this.plot.style.overflow = "hidden", this.canvas.style.position = "absolute", this.canvas.style.inset = "0", this.canvas.style.display = "block", this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.canvas.style.touchAction = "none", this.yAxis.style.position = "relative", this.yAxis.style.gridColumn = "1", this.yAxis.style.gridRow = "1", this.yAxis.style.minWidth = "0", this.yAxis.style.minHeight = "0", this.yAxis.style.overflow = "hidden", this.yAxis.style.pointerEvents = "none", this.xAxis.style.position = "relative", this.xAxis.style.gridColumn = "2", this.xAxis.style.gridRow = "2", this.xAxis.style.minWidth = "0", this.xAxis.style.minHeight = "0", this.xAxis.style.overflow = "hidden", this.xAxis.style.pointerEvents = "none", this.corner.style.gridColumn = "1", this.corner.style.gridRow = "2", this.corner.style.minWidth = "0", this.corner.style.minHeight = "0", this.corner.style.pointerEvents = "none";
972
1223
  }
973
- }, S = 16384, C = S >> 1, w = S >> 1, T = 3, E = 64;
974
- function D(e) {
1224
+ }, P = 16384, F = P >> 1, I = P >> 1, L = 3, R = 4096, z = 12, B = 64;
1225
+ function V(e) {
975
1226
  return e === !1 ? {
976
1227
  visible: !1,
977
1228
  position: "inside"
@@ -983,7 +1234,7 @@ function D(e) {
983
1234
  position: e.position ?? "inside"
984
1235
  };
985
1236
  }
986
- var O = class {
1237
+ var H = class {
987
1238
  options;
988
1239
  series = [];
989
1240
  camera;
@@ -994,6 +1245,8 @@ var O = class {
994
1245
  rawLineData;
995
1246
  minMaxInstanceBuffer;
996
1247
  minMaxInstanceData;
1248
+ barTriangleBuffer;
1249
+ barTriangleData;
997
1250
  gridBuffer;
998
1251
  gridData;
999
1252
  gridStyle;
@@ -1011,8 +1264,21 @@ var O = class {
1011
1264
  renderMode: "none"
1012
1265
  };
1013
1266
  resizeObserver = null;
1267
+ pluginDisposers = [];
1268
+ hoverSubscribers = /* @__PURE__ */ new Set();
1269
+ seriesSubscribers = /* @__PURE__ */ new Set();
1270
+ currentHover = null;
1271
+ lastPointerClientX = 0;
1272
+ lastPointerClientY = 0;
1273
+ pointerInPlot = !1;
1014
1274
  lastFrameAt = 0;
1015
1275
  _rafId = 0;
1276
+ handlePointerMove = (e) => {
1277
+ this.pointerInPlot = !0, this.lastPointerClientX = e.clientX, this.lastPointerClientY = e.clientY, this.refreshHover();
1278
+ };
1279
+ handlePointerLeave = () => {
1280
+ this.pointerInPlot = !1, this.emitHover(null);
1281
+ };
1016
1282
  constructor(e, t = {}) {
1017
1283
  this.options = t;
1018
1284
  let n = t.axes;
@@ -1035,9 +1301,9 @@ var O = class {
1035
1301
  position: "inside"
1036
1302
  }
1037
1303
  } : this.normalizedAxes = {
1038
- x: D(n.x),
1039
- y: D(n.y)
1040
- }, this.layout = new x(e, this.normalizedAxes), this.applyCanvasSize(), this.camera = new v(), this.axis = new y(this.camera), this.renderer = new f(new g(this.layout.canvas)), this.input = new _(this.layout.canvas, this.camera, t.viewportPolicy), this.rawLineData = new Float32Array(S * 2), this.rawLineBuffer = this.renderer.createFloatBuffer(this.rawLineData.length), this.minMaxInstanceData = new Float32Array(w * T), this.minMaxInstanceBuffer = this.renderer.createFloatBuffer(this.minMaxInstanceData.length), this.gridData = new Float32Array(E * 2), this.gridBuffer = this.renderer.createFloatBuffer(this.gridData.length), this.gridStyle = {
1304
+ x: V(n.x),
1305
+ y: V(n.y)
1306
+ }, this.layout = new N(e, this.normalizedAxes), this.applyCanvasSize(), this.camera = new A(), this.axis = new j(this.camera), this.renderer = new w(new O(this.layout.canvas)), this.input = new k(this.layout.canvas, this.camera, t.viewportPolicy), this.rawLineData = new Float32Array(P * 2), this.rawLineBuffer = this.renderer.createFloatBuffer(this.rawLineData.length), this.minMaxInstanceData = new Float32Array(I * L), this.minMaxInstanceBuffer = this.renderer.createFloatBuffer(this.minMaxInstanceData.length), this.barTriangleData = new Float32Array(R * z), this.barTriangleBuffer = this.renderer.createFloatBuffer(this.barTriangleData.length), this.gridData = new Float32Array(B * 2), this.gridBuffer = this.renderer.createFloatBuffer(this.gridData.length), this.gridStyle = {
1041
1307
  color: t.gridStyle?.color ?? [
1042
1308
  .22,
1043
1309
  .3,
@@ -1045,35 +1311,87 @@ var O = class {
1045
1311
  .45
1046
1312
  ],
1047
1313
  lineWidth: t.gridStyle?.lineWidth ?? 1
1048
- }, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible) && (this.axisOverlay = new b(this.layout, this.normalizedAxes)), typeof ResizeObserver < "u" && (this.resizeObserver = new ResizeObserver(() => this.resize()), this.resizeObserver.observe(this.layout.plot));
1314
+ }, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible) && (this.axisOverlay = new M(this.layout, this.normalizedAxes)), this.canvas.addEventListener("pointermove", this.handlePointerMove), this.canvas.addEventListener("pointerleave", this.handlePointerLeave), typeof ResizeObserver < "u" && (this.resizeObserver = new ResizeObserver(() => this.resize()), this.resizeObserver.observe(this.layout.plot));
1315
+ for (let e of t.plugins ?? []) {
1316
+ let t = e.install(this);
1317
+ typeof t == "function" ? this.pluginDisposers.push(t) : t && this.pluginDisposers.push(() => t.dispose());
1318
+ }
1049
1319
  }
1050
1320
  get canvas() {
1051
1321
  return this.layout.canvas;
1052
1322
  }
1323
+ get rootElement() {
1324
+ return this.layout.root;
1325
+ }
1326
+ get plotElement() {
1327
+ return this.layout.plot;
1328
+ }
1329
+ dataToPlot(e, t) {
1330
+ let [n, r] = this.camera.toClip(e, t);
1331
+ return this.camera.toScreen(n, r, this.canvas.clientWidth, this.canvas.clientHeight);
1332
+ }
1053
1333
  addSeries(e, t) {
1054
- let n = e.dataset ?? new i(e.capacity), a = t?.color ?? [
1334
+ let n = e.dataset ?? new a(e.capacity), r = t?.color ?? [
1055
1335
  .3,
1056
1336
  .6,
1057
1337
  1,
1058
1338
  1
1059
- ], o = new r(n, e, {
1060
- color: a,
1339
+ ], o = new i(n, e, {
1340
+ color: r,
1061
1341
  lineWidth: t?.lineWidth ?? 1,
1062
1342
  pointSize: t?.pointSize ?? 4,
1063
1343
  barWidth: t?.barWidth ?? .8,
1064
1344
  baseline: t?.baseline ?? 0,
1065
1345
  fillColor: t?.fillColor ?? [
1066
- a[0],
1067
- a[1],
1068
- a[2],
1069
- a[3] * .25
1346
+ r[0],
1347
+ r[1],
1348
+ r[2],
1349
+ r[3] * .25
1070
1350
  ]
1071
1351
  });
1072
- return this.series.push(o), o;
1352
+ return this.series.push(o), this.emitSeriesChange(), o;
1353
+ }
1354
+ addLine(e, t) {
1355
+ return this.addSeries({
1356
+ ...e,
1357
+ mode: "line"
1358
+ }, t);
1359
+ }
1360
+ addArea(e, t) {
1361
+ return this.addSeries({
1362
+ ...e,
1363
+ mode: "area"
1364
+ }, t);
1365
+ }
1366
+ addScatter(e, t) {
1367
+ return this.addSeries({
1368
+ ...e,
1369
+ mode: "scatter"
1370
+ }, t);
1371
+ }
1372
+ addBar(e, t) {
1373
+ return this.addSeries({
1374
+ ...e,
1375
+ mode: "bar"
1376
+ }, t);
1073
1377
  }
1074
1378
  removeSeries(e) {
1075
1379
  let t = this.series.indexOf(e);
1076
- return t === -1 ? !1 : (this.series.splice(t, 1), !0);
1380
+ return t === -1 ? !1 : (this.series.splice(t, 1), this.emitSeriesChange(), !0);
1381
+ }
1382
+ setSeriesVisible(e, t) {
1383
+ return this.series.includes(e) ? e.visible === t ? !0 : (e.setVisible(t), this.emitSeriesChange(), !0) : !1;
1384
+ }
1385
+ getSeriesState() {
1386
+ return this.series.map((e, t) => ({
1387
+ series: e,
1388
+ index: t,
1389
+ id: e.config.id,
1390
+ name: e.config.name,
1391
+ mode: e.config.mode,
1392
+ visible: e.visible,
1393
+ color: e.style.color
1394
+ }));
1077
1395
  }
1078
1396
  setViewport(e) {
1079
1397
  this.camera.setViewport(e);
@@ -1091,6 +1409,45 @@ var O = class {
1091
1409
  }) {
1092
1410
  return e.fps = this.stats.fps, e.frameMs = this.stats.frameMs, e.pointsRendered = this.stats.pointsRendered, e.drawCalls = this.stats.drawCalls, e.uploadBytes = this.stats.uploadBytes, e.renderMode = this.stats.renderMode, e;
1093
1411
  }
1412
+ getHoverState() {
1413
+ return this.currentHover;
1414
+ }
1415
+ subscribe(e, t) {
1416
+ if (e === "hover") {
1417
+ let e = t;
1418
+ return this.hoverSubscribers.add(e), () => this.hoverSubscribers.delete(e);
1419
+ }
1420
+ let n = t;
1421
+ return this.seriesSubscribers.add(n), () => this.seriesSubscribers.delete(n);
1422
+ }
1423
+ pick(e, t, n = {}) {
1424
+ let r = this.canvas.getBoundingClientRect();
1425
+ if (r.width <= 0 || r.height <= 0) return null;
1426
+ let i = e - r.left, a = t - r.top;
1427
+ if (i < 0 || a < 0 || i > r.width || a > r.height) return null;
1428
+ let o = this.camera.viewport, s = o.xMin + i / r.width * (o.xMax - o.xMin), c = o.yMax - a / r.height * (o.yMax - o.yMin), l = n.mode ?? this.options.hover?.mode ?? "nearest-x", u = n.maxDistancePx ?? this.options.hover?.maxDistancePx ?? Infinity, d = l === "nearest-point" ? this.findNearestPointAnchor(s, c, o, r.width, r.height, u) : this.findNearestXAnchor(s, o, r.width, u);
1429
+ return d === null ? null : {
1430
+ clientX: e,
1431
+ clientY: t,
1432
+ plotX: i,
1433
+ plotY: a,
1434
+ dataX: s,
1435
+ dataY: c,
1436
+ anchorX: d,
1437
+ mode: l,
1438
+ items: this.collectPickItems(d, e, t, o, r)
1439
+ };
1440
+ }
1441
+ async screenshot(e = {}) {
1442
+ this.render();
1443
+ let t = this.layout.root.getBoundingClientRect(), n = this.layout.plot.getBoundingClientRect(), r = Number.isFinite(e.dpr) ? Math.max(1, e.dpr) : Math.max(1, globalThis.devicePixelRatio || 1), i = Math.max(1, Math.round(t.width * r)), a = Math.max(1, Math.round(t.height * r)), o = document.createElement("canvas");
1444
+ o.width = i, o.height = a;
1445
+ let s = o.getContext("2d");
1446
+ if (!s) throw Error("Unable to create a 2D canvas context for screenshot export.");
1447
+ return e.background ? (s.fillStyle = e.background, s.fillRect(0, 0, i, a)) : s.clearRect(0, 0, i, a), s.drawImage(this.canvas, (n.left - t.left) * r, (n.top - t.top) * r, n.width * r, n.height * r), this.drawDomTextForScreenshot(s, t, r), new Promise((t, n) => {
1448
+ o.toBlob((e) => e ? t(e) : n(/* @__PURE__ */ Error("Unable to encode chart screenshot.")), e.type ?? "image/png", e.quality);
1449
+ });
1450
+ }
1094
1451
  start() {
1095
1452
  let e = () => {
1096
1453
  this._rafId = requestAnimationFrame(e), this.render();
@@ -1110,7 +1467,7 @@ var O = class {
1110
1467
  }
1111
1468
  for (let e of this.series) {
1112
1469
  if (!e.visible) continue;
1113
- if (e.config.mode === "scatter") {
1470
+ if (e.rebuildPyramid(), e.config.mode === "scatter") {
1114
1471
  this.drawScatterSeries(e, t);
1115
1472
  continue;
1116
1473
  }
@@ -1122,62 +1479,175 @@ var O = class {
1122
1479
  this.drawAreaSeries(e, t);
1123
1480
  continue;
1124
1481
  }
1125
- let n = e.visibleSampleCount(t), r = e.hasLOD && n > S;
1482
+ let n = e.visibleSampleCount(t), r = e.hasLOD && n > P;
1126
1483
  if (r && this.renderer.supportsInstancedSegments) {
1127
1484
  let n = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxMinMaxSegments());
1128
1485
  if (n <= 0) continue;
1129
1486
  this.renderer.updateFloatBuffer(this.minMaxInstanceBuffer, this.minMaxInstanceData), this.renderer.drawMinMaxSegmentsInstanced(this.minMaxInstanceBuffer, n, e.style, this.camera), this.recordRenderMode("minmax"), this.stats.pointsRendered += n * 2, this.stats.drawCalls++, this.stats.uploadBytes += this.minMaxInstanceData.byteLength;
1130
1487
  continue;
1131
1488
  }
1132
- let i = r ? e.copyMinMaxVisible(t, this.rawLineData, this.maxMinMaxSegments()) : e.copyRawVisible(t, this.rawLineData, S);
1489
+ let i = r ? e.copyMinMaxVisible(t, this.rawLineData, this.maxMinMaxSegments()) : e.copyRawVisible(t, this.rawLineData, P);
1133
1490
  i < 2 || (this.renderer.updateFloatBuffer(this.rawLineBuffer, this.rawLineData), r ? (this.renderer.drawMinMaxSegments(this.rawLineBuffer, i, e.style, this.camera), this.recordRenderMode("minmax")) : (this.renderer.drawLineStrip(this.rawLineBuffer, i, e.style, this.camera), this.recordRenderMode("raw")), this.stats.pointsRendered += i, this.stats.drawCalls++, this.stats.uploadBytes += this.rawLineData.byteLength);
1134
1491
  }
1135
- this.axisOverlay?.update(this.camera, this.axis), this.stats.frameMs = performance.now() - e;
1492
+ this.axisOverlay?.update(this.camera, this.axis), this.stats.frameMs = performance.now() - e, this.refreshHover();
1136
1493
  }
1137
1494
  dispose() {
1138
- this.stop(), this.resizeObserver?.disconnect(), this.input.dispose(), this.axisOverlay?.dispose(), this.renderer.dispose(), this.layout.dispose();
1495
+ this.stop(), this.resizeObserver?.disconnect(), this.canvas.removeEventListener("pointermove", this.handlePointerMove), this.canvas.removeEventListener("pointerleave", this.handlePointerLeave);
1496
+ for (let e of this.pluginDisposers.splice(0)) e();
1497
+ this.input.dispose(), this.axisOverlay?.dispose(), this.renderer.dispose(), this.layout.dispose();
1139
1498
  }
1140
1499
  applyCanvasSize(e = globalThis.devicePixelRatio) {
1141
1500
  let t = Number.isFinite(e) ? Math.max(1, e) : 1, n = Math.max(1, Math.floor(this.canvas.clientWidth * t)), r = Math.max(1, Math.floor(this.canvas.clientHeight * t));
1142
1501
  return this.canvas.width === n && this.canvas.height === r ? !1 : (this.canvas.width = n, this.canvas.height = r, !0);
1143
1502
  }
1144
1503
  drawAreaSeries(e, t) {
1145
- let n = e.style.baseline ?? 0, r = e.copyAreaVisible(t, this.rawLineData, C, n);
1504
+ let n = e.style.baseline ?? 0, r = e.copyAreaVisible(t, this.rawLineData, F, n);
1146
1505
  if (r < 4) return;
1147
1506
  this.renderer.updateFloatBuffer(this.rawLineBuffer, this.rawLineData), this.renderer.drawAreaStrip(this.rawLineBuffer, r, e.style, this.camera), this.stats.pointsRendered += r, this.stats.drawCalls++, this.stats.uploadBytes += this.rawLineData.byteLength;
1148
- let i = this.uploadRawInstances(e, t, C);
1507
+ let i = this.uploadRawInstances(e, t, F);
1149
1508
  i >= 2 && (this.renderer.drawLineStrip(this.rawLineBuffer, i, e.style, this.camera), this.stats.pointsRendered += i, this.stats.drawCalls++), this.recordRenderMode("area");
1150
1509
  }
1151
1510
  drawScatterSeries(e, t) {
1152
- if (!this.renderer.supportsInstancedPoints) return;
1153
- let n = this.uploadRawInstances(e, t, S);
1154
- n <= 0 || (this.renderer.drawPointsInstanced(this.rawLineBuffer, n, e.style, this.camera, this.canvas.width, this.canvas.height), this.recordInstancedDraw("points", n));
1511
+ let n = this.uploadRawInstances(e, t, P);
1512
+ n <= 0 || (this.renderer.supportsInstancedPoints ? this.renderer.drawPointsInstanced(this.rawLineBuffer, n, e.style, this.camera, this.canvas.width, this.canvas.height) : this.renderer.drawPointSprites(this.rawLineBuffer, n, e.style, this.camera), this.recordInstancedDraw("points", n));
1155
1513
  }
1156
1514
  drawBarSeries(e, t) {
1157
- if (!this.renderer.supportsInstancedBars) return;
1158
- let n = this.uploadRawInstances(e, t, S);
1159
- n <= 0 || (this.renderer.drawBarsInstanced(this.rawLineBuffer, n, e.style, this.camera), this.recordInstancedDraw("bars", n));
1515
+ let n = e.visibleSampleCount(t);
1516
+ if (e.hasLOD && n > P) {
1517
+ let n = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxBarFallbackBars());
1518
+ if (n <= 0) return;
1519
+ this.includeBaselineInBarRanges(n, e.style.baseline ?? 0);
1520
+ let r = this.writeBarBucketTriangles(n, t);
1521
+ this.drawBarTriangleFallback(r, e.style);
1522
+ return;
1523
+ }
1524
+ let r = this.uploadRawInstances(e, t, this.maxBarFallbackBars());
1525
+ if (r <= 0) return;
1526
+ if (this.renderer.supportsInstancedBars) {
1527
+ this.renderer.drawBarsInstanced(this.rawLineBuffer, r, e.style, this.camera), this.recordInstancedDraw("bars", r);
1528
+ return;
1529
+ }
1530
+ let i = this.writeBarTriangles(r, e.style.baseline ?? 0, e.style.barWidth ?? .8);
1531
+ this.drawBarTriangleFallback(i, e.style);
1160
1532
  }
1161
1533
  uploadRawInstances(e, t, n) {
1162
1534
  let r = e.copyRawVisible(t, this.rawLineData, n);
1163
1535
  return r <= 0 ? 0 : (this.renderer.updateFloatBuffer(this.rawLineBuffer, this.rawLineData), this.stats.uploadBytes += this.rawLineData.byteLength, r);
1164
1536
  }
1537
+ includeBaselineInBarRanges(e, t) {
1538
+ for (let n = 0; n < e; n++) {
1539
+ let e = n * L, r = this.minMaxInstanceData[e + 1], i = this.minMaxInstanceData[e + 2];
1540
+ this.minMaxInstanceData[e + 1] = Math.min(t, r), this.minMaxInstanceData[e + 2] = Math.max(t, i);
1541
+ }
1542
+ }
1543
+ writeBarTriangles(e, t, n) {
1544
+ let r = Math.min(e, this.maxBarFallbackBars());
1545
+ for (let e = 0; e < r; e++) {
1546
+ let r = this.rawLineData[e * 2], i = this.rawLineData[e * 2 + 1];
1547
+ this.writeBarTriangle(e, r - n * .5, r + n * .5, t, i);
1548
+ }
1549
+ return r * 6;
1550
+ }
1551
+ writeBarBucketTriangles(e, t) {
1552
+ let n = Math.min(e, this.maxBarFallbackBars()), r = (t.xMax - t.xMin) / Math.max(1, n);
1553
+ for (let e = 0; e < n; e++) {
1554
+ let i = this.minMaxInstanceData[e * 3 + 1], a = this.minMaxInstanceData[e * 3 + 2], o = t.xMin + e * r, s = e === n - 1 ? t.xMax : o + r;
1555
+ this.writeBarTriangle(e, o, s, i, a);
1556
+ }
1557
+ return n * 6;
1558
+ }
1559
+ writeBarTriangle(e, t, n, r, i) {
1560
+ let a = e * z;
1561
+ this.barTriangleData[a] = t, this.barTriangleData[a + 1] = r, this.barTriangleData[a + 2] = n, this.barTriangleData[a + 3] = r, this.barTriangleData[a + 4] = t, this.barTriangleData[a + 5] = i, this.barTriangleData[a + 6] = t, this.barTriangleData[a + 7] = i, this.barTriangleData[a + 8] = n, this.barTriangleData[a + 9] = r, this.barTriangleData[a + 10] = n, this.barTriangleData[a + 11] = i;
1562
+ }
1563
+ drawBarTriangleFallback(e, t) {
1564
+ e <= 0 || (this.renderer.updateFloatBuffer(this.barTriangleBuffer, this.barTriangleData), this.stats.uploadBytes += this.barTriangleData.byteLength, this.renderer.drawBarTriangles(this.barTriangleBuffer, e, t, this.camera), this.recordInstancedDraw("bars", e));
1565
+ }
1165
1566
  recordInstancedDraw(e, t) {
1166
1567
  this.recordRenderMode(e), this.stats.pointsRendered += t, this.stats.drawCalls++;
1167
1568
  }
1569
+ findNearestXAnchor(e, t, n, r) {
1570
+ let i = null, a = Infinity, o = n / (t.xMax - t.xMin);
1571
+ for (let n of this.series) {
1572
+ if (!n.visible) continue;
1573
+ let r = n.nearestSampleByX(e, t);
1574
+ if (!r) continue;
1575
+ let s = Math.abs(r.x - e) * o;
1576
+ s < a && (i = r, a = s);
1577
+ }
1578
+ return !i || a > r ? null : i.x;
1579
+ }
1580
+ findNearestPointAnchor(e, t, n, r, i, a) {
1581
+ let o = null;
1582
+ for (let a of this.series) {
1583
+ if (!a.visible) continue;
1584
+ let s = a.nearestSampleByPoint(e, t, n, r, i);
1585
+ s && (!o || (s.distancePx ?? Infinity) < (o.distancePx ?? Infinity)) && (o = s);
1586
+ }
1587
+ return !o || (o.distancePx ?? Infinity) > a ? null : o.x;
1588
+ }
1589
+ collectPickItems(e, t, n, r, i) {
1590
+ let a = [];
1591
+ for (let o = 0; o < this.series.length; o++) {
1592
+ let s = this.series[o];
1593
+ if (!s.visible) continue;
1594
+ let c = s.nearestSampleByX(e, r);
1595
+ if (!c) continue;
1596
+ let [l, u] = this.camera.toClip(c.x, c.y), [d, f] = this.camera.toScreen(l, u, i.width, i.height), p = i.left + d, m = i.top + f, h = p - t, g = m - n;
1597
+ a.push({
1598
+ ...c,
1599
+ distancePx: Math.hypot(h, g),
1600
+ series: s,
1601
+ seriesIndex: o,
1602
+ id: s.config.id,
1603
+ name: s.config.name,
1604
+ mode: s.config.mode,
1605
+ plotX: d,
1606
+ plotY: f,
1607
+ clientX: p,
1608
+ clientY: m
1609
+ });
1610
+ }
1611
+ return a;
1612
+ }
1613
+ refreshHover() {
1614
+ this.pointerInPlot && this.emitHover(this.pick(this.lastPointerClientX, this.lastPointerClientY));
1615
+ }
1616
+ emitHover(e) {
1617
+ this.currentHover = e;
1618
+ for (let t of this.hoverSubscribers) t(e);
1619
+ }
1620
+ emitSeriesChange() {
1621
+ for (let e of this.seriesSubscribers) e();
1622
+ this.refreshHover();
1623
+ }
1624
+ drawDomTextForScreenshot(e, t, n) {
1625
+ let r = this.layout.root.querySelectorAll("div");
1626
+ for (let i of r) {
1627
+ let r = i.textContent;
1628
+ if (!r || i.children.length > 0) continue;
1629
+ let a = getComputedStyle(i);
1630
+ if (a.display === "none" || a.visibility === "hidden" || a.opacity === "0") continue;
1631
+ let o = i.getBoundingClientRect();
1632
+ o.width <= 0 || o.height <= 0 || (e.save(), e.scale(n, n), e.font = a.font, e.fillStyle = a.color, e.textBaseline = "top", e.textAlign = "left", e.fillText(r, o.left - t.left, o.top - t.top), e.restore());
1633
+ }
1634
+ }
1168
1635
  maxMinMaxSegments() {
1169
- return Math.min(this.canvas.width, w);
1636
+ return Math.min(this.canvas.width, I);
1637
+ }
1638
+ maxBarFallbackBars() {
1639
+ return Math.min(R, P);
1170
1640
  }
1171
1641
  writeGridVertices(e) {
1172
1642
  let t = Math.max(1, this.canvas.clientWidth), n = Math.max(1, this.canvas.clientHeight);
1173
1643
  this.axis.getXTickValues(t, 12, this.xTicks), this.axis.getYTickValues(n, 8, this.yTicks);
1174
1644
  let r = 0;
1175
1645
  for (let t of this.xTicks) {
1176
- if (r + 2 > E) return r;
1646
+ if (r + 2 > B) return r;
1177
1647
  this.gridData[r * 2] = t, this.gridData[r * 2 + 1] = e.yMin, r++, this.gridData[r * 2] = t, this.gridData[r * 2 + 1] = e.yMax, r++;
1178
1648
  }
1179
1649
  for (let t of this.yTicks) {
1180
- if (r + 2 > E) return r;
1650
+ if (r + 2 > B) return r;
1181
1651
  this.gridData[r * 2] = e.xMin, this.gridData[r * 2 + 1] = t, r++, this.gridData[r * 2] = e.xMax, this.gridData[r * 2 + 1] = t, r++;
1182
1652
  }
1183
1653
  return r;
@@ -1185,7 +1655,7 @@ var O = class {
1185
1655
  recordRenderMode(e) {
1186
1656
  this.stats.renderMode === "none" ? this.stats.renderMode = e : this.stats.renderMode !== e && (this.stats.renderMode = "mixed");
1187
1657
  }
1188
- }, k = class {
1658
+ }, U = class {
1189
1659
  xData;
1190
1660
  yData;
1191
1661
  constructor(e, t) {
@@ -1227,6 +1697,6 @@ var O = class {
1227
1697
  }
1228
1698
  };
1229
1699
  //#endregion
1230
- export { y as AxisController, v as Camera2D, O as Chart, n as MinMaxPyramid, i as RingBuffer, r as SeriesStore, k as StaticDataset };
1700
+ export { j as AxisController, A as Camera2D, H as Chart, n as MinMaxPyramid, a as RingBuffer, i as SeriesStore, U as StaticDataset };
1231
1701
 
1232
1702
  //# sourceMappingURL=index.js.map