blazeplot 0.1.11 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -149,7 +149,15 @@ var t = 16, n = class {
149
149
  function r(e) {
150
150
  return "rangeMinMaxY" in e;
151
151
  }
152
- var i = class {
152
+ function i(e) {
153
+ return "getOpen" in e && "getHigh" in e && "getLow" in e && "getClose" in e;
154
+ }
155
+ function a(e, t, n, r, i) {
156
+ if (n === e) return t;
157
+ let a = (i - e) / (n - e);
158
+ return t + (r - t) * a;
159
+ }
160
+ var o = class {
153
161
  config;
154
162
  style;
155
163
  dataset;
@@ -244,65 +252,131 @@ var i = class {
244
252
  distancePx: Math.sqrt(l)
245
253
  } : null;
246
254
  }
247
- copyRawVisible(e, t, n) {
248
- return this.copyVisibleSamples(e, t, n, "points", 0);
255
+ copyRawVisible(e, t, n, r = 0) {
256
+ return this.copyVisibleSamples(e, t, n, "points", 0, r);
257
+ }
258
+ copyRawVisibleClipped(e, t, n, r = 0) {
259
+ return this.copyClippedVisibleLine(e, t, n, r, "data");
260
+ }
261
+ copyRawVisibleClipSpace(e, t, n) {
262
+ return this.copyClippedVisibleLine(e, t, n, 0, "clip");
263
+ }
264
+ copyRawRange(e, t, n, r, i = 0) {
265
+ return this.copySampleRange(e, t, n, r, "points", 0, i);
266
+ }
267
+ copyAreaVisible(e, t, n, r = 0, i = 0) {
268
+ return this.copyVisibleSamples(e, t, n, "area", r, i) * 2;
249
269
  }
250
- copyAreaVisible(e, t, n, r = 0) {
251
- return this.copyVisibleSamples(e, t, n, "area", r) * 2;
270
+ copyAreaRange(e, t, n, r, i = 0, a = 0) {
271
+ return this.copySampleRange(e, t, n, r, "area", i, a) * 2;
252
272
  }
253
- copyMinMaxVisible(e, t, n) {
254
- return this.copyMinMaxSegments(e, t, n, "line-list") * 2;
273
+ copyMinMaxVisible(e, t, n, r = 0) {
274
+ return this.copyMinMaxSegments(e, t, n, "line-list", r) * 2;
255
275
  }
256
- copyMinMaxInstanced(e, t, n) {
257
- return this.copyMinMaxSegments(e, t, n, "instanced");
276
+ copyMinMaxInstanced(e, t, n, r = 0) {
277
+ return this.copyMinMaxSegments(e, t, n, "instanced", r);
258
278
  }
259
- visibleIndexRange(e) {
260
- return e ? {
261
- start: this.dataset.lowerBoundX(e.xMin),
262
- end: this.dataset.upperBoundX(e.xMax)
263
- } : {
279
+ copyOhlcRange(e, t, n, r, a, o = 0) {
280
+ if (!i(this.dataset) || r <= 0 || n.length < r * 12) return 0;
281
+ let s = Math.max(0, Math.floor(e)), c = Math.min(this.dataset.length, Math.ceil(t)), l = Math.min(r, Math.max(0, c - s)), u = a * .5;
282
+ for (let e = 0; e < l; e++) {
283
+ let t = s + e, r = this.dataset.getX(t) - o, i = this.dataset.getOpen(t), a = this.dataset.getHigh(t), c = this.dataset.getLow(t), l = this.dataset.getClose(t), d = e * 12;
284
+ n[d] = r, n[d + 1] = c, n[d + 2] = r, n[d + 3] = a, n[d + 4] = r - u, n[d + 5] = i, n[d + 6] = r, n[d + 7] = i, n[d + 8] = r, n[d + 9] = l, n[d + 10] = r + u, n[d + 11] = l;
285
+ }
286
+ return l;
287
+ }
288
+ visibleIndexRange(e, t = 0) {
289
+ if (!e) return {
264
290
  start: 0,
265
291
  end: this.dataset.length
266
292
  };
293
+ let n = Math.max(0, Math.floor(t));
294
+ return {
295
+ start: Math.max(0, this.dataset.lowerBoundX(e.xMin) - n),
296
+ end: Math.min(this.dataset.length, this.dataset.upperBoundX(e.xMax) + n)
297
+ };
267
298
  }
268
- copyVisibleSamples(e, t, n, r, i) {
269
- let a = r === "points" ? 2 : 4;
270
- if (n <= 0 || t.length < n * a) return 0;
271
- let o = this.dataset.lowerBoundX(e.xMin), s = this.dataset.upperBoundX(e.xMax), c = s - o;
272
- if (c <= 0) return 0;
273
- let l = Math.max(1, Math.ceil(c / n)), u = 0;
274
- for (let e = o; e < s && u < n; e += l) {
275
- let n = this.dataset.getX(e), a = this.dataset.getY(e);
299
+ copyClippedVisibleLine(e, t, n, r, i) {
300
+ if (n <= 0 || t.length < n * 2) return 0;
301
+ let o = e.xMax - e.xMin, s = e.yMax - e.yMin;
302
+ if (i === "clip" && (o <= 0 || s <= 0)) return 0;
303
+ let c = Math.max(0, this.dataset.lowerBoundX(e.xMin) - 1), l = Math.min(this.dataset.length, this.dataset.upperBoundX(e.xMax) + 1);
304
+ if (l - c <= 0) return 0;
305
+ let u = 0, d = NaN, f = NaN, p = (a, c) => {
306
+ let l = i === "clip" ? (a - e.xMin) / o * 2 - 1 : a - r, p = i === "clip" ? (c - e.yMin) / s * 2 - 1 : c;
307
+ if (u > 0 && l === d && p === f) return !0;
308
+ if (u >= n) return !1;
309
+ let m = u * 2;
310
+ return t[m] = l, t[m + 1] = p, u++, d = l, f = p, !0;
311
+ };
312
+ if (l - c === 1) {
313
+ let t = this.dataset.getX(c);
314
+ return t < e.xMin || t > e.xMax ? 0 : p(t, this.dataset.getY(c)) ? u : 0;
315
+ }
316
+ for (let t = c; t + 1 < l; t++) {
317
+ let n = this.dataset.getX(t), r = this.dataset.getY(t), i = this.dataset.getX(t + 1), o = this.dataset.getY(t + 1);
318
+ if (i < e.xMin || n > e.xMax) continue;
319
+ let s = Math.max(n, e.xMin), c = Math.min(i, e.xMax);
320
+ if (c < s) continue;
321
+ let l = a(n, r, i, o, s), u = a(n, r, i, o, c);
322
+ if (!p(s, l) || !p(c, u)) break;
323
+ }
324
+ return u;
325
+ }
326
+ copyVisibleSamples(e, t, n, r, i, a) {
327
+ let o = r === "points" ? 2 : 4;
328
+ if (n <= 0 || t.length < n * o) return 0;
329
+ let s = this.dataset.lowerBoundX(e.xMin), c = this.dataset.upperBoundX(e.xMax), l = c - s;
330
+ if (l <= 0) return 0;
331
+ let u = Math.max(1, Math.ceil(l / n)), d = 0;
332
+ for (let e = s; e < c && d < n; e += u) {
333
+ let n = this.dataset.getX(e) - a, o = this.dataset.getY(e);
276
334
  if (r === "points") {
277
- let e = u * 2;
278
- t[e] = n, t[e + 1] = a;
335
+ let e = d * 2;
336
+ t[e] = n, t[e + 1] = o;
337
+ } else {
338
+ let e = d * 4;
339
+ t[e] = n, t[e + 1] = i, t[e + 2] = n, t[e + 3] = o;
340
+ }
341
+ d++;
342
+ }
343
+ return d;
344
+ }
345
+ copySampleRange(e, t, n, r, i, a, o) {
346
+ let s = i === "points" ? 2 : 4;
347
+ if (r <= 0 || n.length < r * s) return 0;
348
+ let c = Math.max(0, Math.floor(e)), l = Math.min(this.dataset.length, Math.ceil(t)), u = Math.min(r, Math.max(0, l - c));
349
+ for (let e = 0; e < u; e++) {
350
+ let t = c + e, r = this.dataset.getX(t) - o, s = this.dataset.getY(t);
351
+ if (i === "points") {
352
+ let t = e * 2;
353
+ n[t] = r, n[t + 1] = s;
279
354
  } else {
280
- let e = u * 4;
281
- t[e] = n, t[e + 1] = i, t[e + 2] = n, t[e + 3] = a;
355
+ let t = e * 4;
356
+ n[t] = r, n[t + 1] = a, n[t + 2] = r, n[t + 3] = s;
282
357
  }
283
- u++;
284
358
  }
285
359
  return u;
286
360
  }
287
- copyMinMaxSegments(e, t, n, r) {
288
- let i = r === "line-list" ? 4 : 3;
289
- if (!this.pyramid || n <= 0 || t.length < n * i) return 0;
290
- let a = this.dataset.lowerBoundX(e.xMin), o = this.dataset.upperBoundX(e.xMax), s = o - a;
291
- if (s <= 0) return 0;
292
- let c = Math.min(n, s);
293
- for (let e = 0; e < c; e++) {
294
- 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);
295
- if (!u) continue;
296
- let d = this.dataset.getX(n + (l - n >> 1)), { minY: f, maxY: p } = u;
361
+ copyMinMaxSegments(e, t, n, r, i) {
362
+ let a = r === "line-list" ? 4 : 3;
363
+ if (!this.pyramid || n <= 0 || t.length < n * a) return 0;
364
+ let o = this.dataset.lowerBoundX(e.xMin), s = this.dataset.upperBoundX(e.xMax), c = s - o;
365
+ if (c <= 0) return 0;
366
+ let l = Math.min(n, c);
367
+ for (let e = 0; e < l; e++) {
368
+ let n = o + Math.floor(e * c / l), a = o + Math.max(Math.floor((e + 1) * c / l), Math.floor(e * c / l) + 1), u = Math.min(s, a), d = this.minMaxForRange(n, u);
369
+ if (!d) continue;
370
+ let f = this.dataset.getX(n + (u - n >> 1)) - i, { minY: p, maxY: m } = d;
297
371
  if (r === "line-list") {
298
372
  let n = e * 4;
299
- t[n] = d, t[n + 1] = f, t[n + 2] = d, t[n + 3] = p;
373
+ t[n] = f, t[n + 1] = p, t[n + 2] = f, t[n + 3] = m;
300
374
  } else {
301
375
  let n = e * 3;
302
- t[n] = d, t[n + 1] = f, t[n + 2] = p;
376
+ t[n] = f, t[n + 1] = p, t[n + 2] = m;
303
377
  }
304
378
  }
305
- return c;
379
+ return l;
306
380
  }
307
381
  minMaxForRange(e, t) {
308
382
  return this._useDatasetRangeMinMax && r(this.dataset) ? this.dataset.rangeMinMaxY(e, t) : !this.pyramid || this._useRawMinMaxScan ? this.rawMinMaxForRange(e, t) : this.pyramid.rangeMinMax(this.dataset, e, t);
@@ -340,7 +414,28 @@ var i = class {
340
414
  maxY: o
341
415
  };
342
416
  }
343
- }, a = class e {
417
+ };
418
+ //#endregion
419
+ //#region src/core/search.ts
420
+ function s(e, t, n) {
421
+ let r = 0, i = e;
422
+ for (; r < i;) {
423
+ let e = r + (i - r >> 1);
424
+ t(e) < n ? r = e + 1 : i = e;
425
+ }
426
+ return r;
427
+ }
428
+ function c(e, t, n) {
429
+ let r = 0, i = e;
430
+ for (; r < i;) {
431
+ let e = r + (i - r >> 1);
432
+ t(e) <= n ? r = e + 1 : i = e;
433
+ }
434
+ return r;
435
+ }
436
+ //#endregion
437
+ //#region src/core/RingBuffer.ts
438
+ var l = class e {
344
439
  capacity;
345
440
  _length = 0;
346
441
  _head = 0;
@@ -349,9 +444,10 @@ var i = class {
349
444
  treeBase;
350
445
  minTree;
351
446
  maxTree;
352
- constructor(t) {
447
+ overflow;
448
+ constructor(t, n = {}) {
353
449
  if (!Number.isInteger(t) || t <= 0) throw RangeError("RingBuffer capacity must be a positive integer.");
354
- 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);
450
+ this.capacity = t, this.overflow = n.overflow ?? "wrap", 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);
355
451
  }
356
452
  get length() {
357
453
  return this._length;
@@ -363,20 +459,29 @@ var i = class {
363
459
  };
364
460
  }
365
461
  push(e, t) {
462
+ if (this._length >= this.capacity) {
463
+ if (this.overflow === "drop-new") return;
464
+ if (this.overflow === "error") throw RangeError("RingBuffer capacity exceeded.");
465
+ }
366
466
  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++;
367
467
  }
368
468
  append(e, t) {
369
469
  let n = Math.min(e.length, t.length);
370
- if (n <= 0) return;
371
- if (n >= this.capacity) {
372
- let r = n - this.capacity;
373
- this._head = 0, this._length = this.capacity, this.copyIntoPhysical(0, e, t, r, this.capacity);
374
- return;
375
- }
376
- let r = 0, i = n;
377
- for (; i > 0;) {
378
- let n = Math.min(i, this.capacity - this._head);
379
- 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;
470
+ if (!(n <= 0)) {
471
+ if (this.overflow !== "wrap") {
472
+ let r = this.capacity - this._length;
473
+ if (n > r && this.overflow === "error") throw RangeError("RingBuffer capacity exceeded.");
474
+ let i = Math.min(n, r);
475
+ if (i <= 0) return;
476
+ this.appendNoWrap(e, t, 0, i);
477
+ return;
478
+ }
479
+ if (n >= this.capacity) {
480
+ let r = n - this.capacity;
481
+ this._head = 0, this._length = this.capacity, this.copyIntoPhysical(0, e, t, r, this.capacity);
482
+ return;
483
+ }
484
+ this.appendNoWrap(e, t, 0, n);
380
485
  }
381
486
  }
382
487
  get(e) {
@@ -392,20 +497,10 @@ var i = class {
392
497
  return this.assertValidIndex(e), this.yData[this.logicalToPhysical(e)];
393
498
  }
394
499
  lowerBoundX(e) {
395
- let t = 0, n = this._length;
396
- for (; t < n;) {
397
- let r = t + (n - t >> 1);
398
- this.getX(r) < e ? t = r + 1 : n = r;
399
- }
400
- return t;
500
+ return s(this._length, (e) => this.getX(e), e);
401
501
  }
402
502
  upperBoundX(e) {
403
- let t = 0, n = this._length;
404
- for (; t < n;) {
405
- let r = t + (n - t >> 1);
406
- this.getX(r) <= e ? t = r + 1 : n = r;
407
- }
408
- return t;
503
+ return c(this._length, (e) => this.getX(e), e);
409
504
  }
410
505
  rangeMinMaxY(e, t) {
411
506
  let n = Math.max(0, Math.floor(e)), r = Math.min(this._length, Math.ceil(t));
@@ -421,6 +516,13 @@ var i = class {
421
516
  clear() {
422
517
  this._length = 0, this._head = 0, this.minTree.fill(Infinity), this.maxTree.fill(-Infinity);
423
518
  }
519
+ appendNoWrap(e, t, n, r) {
520
+ let i = n, a = r;
521
+ for (; a > 0;) {
522
+ let n = Math.min(a, this.capacity - this._head);
523
+ this.copyIntoPhysical(this._head, e, t, i, n), this._head = (this._head + n) % this.capacity, this._length = Math.min(this.capacity, this._length + n), i += n, a -= n;
524
+ }
525
+ }
424
526
  copyIntoPhysical(e, t, n, r, i) {
425
527
  for (let a = 0; a < i; a++) {
426
528
  let i = e + a, o = n[r + a];
@@ -475,32 +577,32 @@ var i = class {
475
577
  static nextPowerOfTwo(e) {
476
578
  return 2 ** Math.ceil(Math.log2(e));
477
579
  }
478
- }, 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", _ = {
580
+ }, u = "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", d = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", f = "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", p = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", m = "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", h = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", g = "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", _ = "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", v = "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", y = "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", b = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", x = {
479
581
  line: {
480
- vert: o,
481
- frag: s
582
+ vert: u,
583
+ frag: d
482
584
  },
483
585
  segment: {
484
- vert: c,
485
- frag: l
586
+ vert: f,
587
+ frag: p
486
588
  },
487
589
  point: {
488
- vert: u,
489
- frag: d
590
+ vert: m,
591
+ frag: h
490
592
  },
491
593
  pointSprite: {
492
- vert: f,
493
- frag: p
594
+ vert: g,
595
+ frag: _
494
596
  },
495
597
  bar: {
496
- vert: m,
497
- frag: g
598
+ vert: v,
599
+ frag: b
498
600
  },
499
601
  barRange: {
500
- vert: h,
501
- frag: g
602
+ vert: y,
603
+ frag: b
502
604
  }
503
- }, v = 3, y = 2, b = 4, x = 4, S = .8, C = 0, w = class {
605
+ }, S = 3, C = 2, w = 4, T = 4, E = .8, ee = 0, te = class {
504
606
  backend;
505
607
  lineProgram;
506
608
  segmentProgram;
@@ -514,8 +616,9 @@ var i = class {
514
616
  scaleUniform = new Float32Array(2);
515
617
  offsetUniform = new Float32Array(2);
516
618
  canvasSizeUniform = new Float32Array(2);
619
+ xOrigin = 0;
517
620
  constructor(e) {
518
- 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({
621
+ this.backend = e, this.lineProgram = this.backend.createProgram(x.line.vert, x.line.frag), this.segmentProgram = this.backend.createProgram(x.segment.vert, x.segment.frag), this.pointProgram = this.backend.createProgram(x.point.vert, x.point.frag), this.pointSpriteProgram = this.backend.createProgram(x.pointSprite.vert, x.pointSprite.frag), this.barProgram = this.backend.createProgram(x.bar.vert, x.bar.frag), this.barRangeProgram = this.backend.createProgram(x.barRange.vert, x.barRange.frag), this.segmentSelectBuffer = this.backend.createBuffer({
519
622
  usage: "static",
520
623
  type: "float",
521
624
  length: 2
@@ -566,24 +669,34 @@ var i = class {
566
669
  length: e
567
670
  });
568
671
  }
569
- updateFloatBuffer(e, t) {
570
- this.backend.updateBuffer(e, t);
672
+ updateFloatBuffer(e, t, n = t.length) {
673
+ let r = Math.max(0, Math.min(n, t.length));
674
+ this.backend.updateBuffer(e, r === t.length ? t : t.subarray(0, r));
571
675
  }
572
676
  viewport(e, t, n, r) {
573
677
  this.backend.viewport(e, t, n, r);
574
678
  }
679
+ setXOrigin(e) {
680
+ this.xOrigin = Number.isFinite(e) ? e : 0;
681
+ }
575
682
  drawLines(e, t, n, r) {
576
683
  this.drawLinePrimitive("lines", e, t, n, r);
577
684
  }
578
685
  drawLineStrip(e, t, n, r) {
579
686
  this.drawLinePrimitive("line_strip", e, t, n, r);
580
687
  }
688
+ drawClipLineStrip(e, t, n) {
689
+ this.drawClipPrimitive("line_strip", e, t, n);
690
+ }
691
+ drawClipLines(e, t, n) {
692
+ this.drawClipPrimitive("lines", e, t, n);
693
+ }
581
694
  drawMinMaxSegments(e, t, n, r) {
582
695
  this.drawLines(e, t, n, r);
583
696
  }
584
697
  drawMinMaxSegmentsInstanced(e, t, n, r) {
585
698
  this.writeCameraUniforms(r);
586
- let i = v * b, a = {
699
+ let i = S * w, a = {
587
700
  buffer: e,
588
701
  divisor: 1,
589
702
  stride: i,
@@ -592,16 +705,16 @@ var i = class {
592
705
  buffer: e,
593
706
  divisor: 1,
594
707
  stride: i,
595
- offset: b
708
+ offset: w
596
709
  }, s = {
597
710
  buffer: e,
598
711
  divisor: 1,
599
712
  stride: i,
600
- offset: b * 2
713
+ offset: w * 2
601
714
  }, c = {
602
715
  buffer: this.segmentSelectBuffer,
603
716
  divisor: 0,
604
- stride: b,
717
+ stride: w,
605
718
  offset: 0
606
719
  };
607
720
  this.backend.draw({
@@ -622,18 +735,21 @@ var i = class {
622
735
  }
623
736
  });
624
737
  }
738
+ drawPoints(e, t, n, r, i, a) {
739
+ this.supportsInstancedPoints ? this.drawPointsInstanced(e, t, n, r, i, a) : this.drawPointSprites(e, t, n, r);
740
+ }
625
741
  drawPointsInstanced(e, t, n, r, i, a) {
626
742
  this.writeCameraUniforms(r), this.canvasSizeUniform[0] = Math.max(1, i), this.canvasSizeUniform[1] = Math.max(1, a);
627
743
  let o = {
628
744
  buffer: e,
629
745
  divisor: 1,
630
- stride: y * b,
746
+ stride: C * w,
631
747
  offset: 0,
632
748
  size: 2
633
749
  }, s = {
634
750
  buffer: this.pointCornerBuffer,
635
751
  divisor: 0,
636
- stride: y * b,
752
+ stride: C * w,
637
753
  offset: 0,
638
754
  size: 2
639
755
  };
@@ -650,7 +766,7 @@ var i = class {
650
766
  uScale: this.scaleUniform,
651
767
  uOffset: this.offsetUniform,
652
768
  uCanvasSize: this.canvasSizeUniform,
653
- uPointSize: n.pointSize ?? x,
769
+ uPointSize: n.pointSize ?? T,
654
770
  uColor: n.color
655
771
  }
656
772
  });
@@ -664,7 +780,7 @@ var i = class {
664
780
  uniforms: {
665
781
  uScale: this.scaleUniform,
666
782
  uOffset: this.offsetUniform,
667
- uPointSize: n.pointSize ?? x,
783
+ uPointSize: n.pointSize ?? T,
668
784
  uColor: n.color
669
785
  }
670
786
  });
@@ -687,13 +803,13 @@ var i = class {
687
803
  let i = {
688
804
  buffer: e,
689
805
  divisor: 1,
690
- stride: y * b,
806
+ stride: C * w,
691
807
  offset: 0,
692
808
  size: 2
693
809
  }, a = {
694
810
  buffer: this.barCornerBuffer,
695
811
  divisor: 0,
696
- stride: y * b,
812
+ stride: C * w,
697
813
  offset: 0,
698
814
  size: 2
699
815
  };
@@ -709,15 +825,15 @@ var i = class {
709
825
  uniforms: {
710
826
  uScale: this.scaleUniform,
711
827
  uOffset: this.offsetUniform,
712
- uBarWidth: n.barWidth ?? S,
713
- uBaseline: n.baseline ?? C,
828
+ uBarWidth: n.barWidth ?? E,
829
+ uBaseline: n.baseline ?? ee,
714
830
  uColor: n.color
715
831
  }
716
832
  });
717
833
  }
718
834
  drawBarRangesInstanced(e, t, n, r) {
719
835
  this.writeCameraUniforms(r);
720
- let i = v * b, a = {
836
+ let i = S * w, a = {
721
837
  buffer: e,
722
838
  divisor: 1,
723
839
  stride: i,
@@ -726,16 +842,16 @@ var i = class {
726
842
  buffer: e,
727
843
  divisor: 1,
728
844
  stride: i,
729
- offset: b
845
+ offset: w
730
846
  }, s = {
731
847
  buffer: e,
732
848
  divisor: 1,
733
849
  stride: i,
734
- offset: b * 2
850
+ offset: w * 2
735
851
  }, c = {
736
852
  buffer: this.barCornerBuffer,
737
853
  divisor: 0,
738
- stride: y * b,
854
+ stride: C * w,
739
855
  offset: 0,
740
856
  size: 2
741
857
  };
@@ -753,7 +869,7 @@ var i = class {
753
869
  uniforms: {
754
870
  uScale: this.scaleUniform,
755
871
  uOffset: this.offsetUniform,
756
- uBarWidth: n.barWidth ?? S,
872
+ uBarWidth: n.barWidth ?? E,
757
873
  uColor: n.color
758
874
  }
759
875
  });
@@ -787,19 +903,33 @@ var i = class {
787
903
  }
788
904
  });
789
905
  }
906
+ drawClipPrimitive(e, t, n, r) {
907
+ this.scaleUniform[0] = 1, this.scaleUniform[1] = 1, this.offsetUniform[0] = 0, this.offsetUniform[1] = 0, this.backend.draw({
908
+ program: this.lineProgram,
909
+ primitive: e,
910
+ count: n,
911
+ attributes: { position: t },
912
+ uniforms: {
913
+ uScale: this.scaleUniform,
914
+ uOffset: this.offsetUniform,
915
+ uColor: r.color
916
+ }
917
+ });
918
+ }
790
919
  writeCameraUniforms(e) {
791
- this.scaleUniform[0] = e.xScale, this.scaleUniform[1] = e.yScale, this.offsetUniform[0] = e.xOffset, this.offsetUniform[1] = e.yOffset;
920
+ let t = e.xMin - this.xOrigin, n = e.xMax - this.xOrigin;
921
+ this.scaleUniform[0] = e.xScale, this.scaleUniform[1] = e.yScale, this.offsetUniform[0] = -(t + n) / (n - t), this.offsetUniform[1] = e.yOffset;
792
922
  }
793
923
  dispose() {
794
924
  this.backend.destroy();
795
925
  }
796
- }, T = [
926
+ }, D = [
797
927
  1024,
798
928
  4096,
799
929
  16384,
800
930
  32768,
801
931
  131072
802
- ], ee = class {
932
+ ], O = class {
803
933
  regl;
804
934
  pool = [];
805
935
  preAllocated = !1;
@@ -812,7 +942,7 @@ var i = class {
812
942
  preAllocate() {
813
943
  if (!this.preAllocated) {
814
944
  this.preAllocated = !0;
815
- for (let e of T) this.pool.push(this.createEntry(e, "stream"));
945
+ for (let e of D) this.pool.push(this.createEntry(e, "stream"));
816
946
  }
817
947
  }
818
948
  acquire(e, t = "stream") {
@@ -852,17 +982,17 @@ var i = class {
852
982
  return this.pool.find((t) => !t.inUse && t.floatCapacity >= e);
853
983
  }
854
984
  roundUp(e) {
855
- for (let t of T) if (t >= e) return t;
856
- let t = T[T.length - 1], n = 1 << 32 - Math.clz32(e - 1);
985
+ for (let t of D) if (t >= e) return t;
986
+ let t = D[D.length - 1], n = 1 << 32 - Math.clz32(e - 1);
857
987
  return Math.max(t * 2, n);
858
988
  }
859
989
  };
860
990
  //#endregion
861
991
  //#region src/render/ReglBackend.ts
862
- function te(e) {
992
+ function k(e) {
863
993
  return e;
864
994
  }
865
- var E = class {
995
+ var A = class {
866
996
  gl;
867
997
  regl;
868
998
  resources;
@@ -882,10 +1012,10 @@ var E = class {
882
1012
  });
883
1013
  if (!n) throw Error("BlazePlot requires WebGL2, but this browser/context does not support it.");
884
1014
  this.gl = n, this.regl = e({
885
- gl: te(this.gl),
1015
+ gl: k(this.gl),
886
1016
  extensions: [],
887
1017
  optionalExtensions: ["angle_instanced_arrays", "ext_disjoint_timer_query_webgl2"]
888
- }), this.capabilities = { instancing: this.regl.hasExtension("angle_instanced_arrays") }, this.resources = new ee(this.regl), this.resources.preAllocate();
1018
+ }), this.capabilities = { instancing: this.regl.hasExtension("angle_instanced_arrays") }, this.resources = new O(this.regl), this.resources.preAllocate();
889
1019
  }
890
1020
  createBuffer(e) {
891
1021
  let { buffer: t } = this.resources.acquire(e.length, e.usage);
@@ -1004,7 +1134,7 @@ var E = class {
1004
1134
  default: return e;
1005
1135
  }
1006
1136
  }
1007
- }, D = class e {
1137
+ }, j = class e {
1008
1138
  _xMin = 0;
1009
1139
  _xMax = 1;
1010
1140
  _yMin = 0;
@@ -1089,7 +1219,7 @@ var E = class {
1089
1219
  static assertFinite(e, t) {
1090
1220
  if (!Number.isFinite(t)) throw RangeError(`Camera2D ${e} must be finite.`);
1091
1221
  }
1092
- }, O = class {
1222
+ }, M = class {
1093
1223
  camera;
1094
1224
  constructor(e) {
1095
1225
  this.camera = e;
@@ -1121,7 +1251,7 @@ var E = class {
1121
1251
  let n = Math.max(0, -Math.floor(Math.log10(t)) + 2), r = Number(e.toFixed(n));
1122
1252
  return Object.is(r, -0) ? 0 : r;
1123
1253
  }
1124
- }, k = class {
1254
+ }, N = class {
1125
1255
  layout;
1126
1256
  config;
1127
1257
  options;
@@ -1132,6 +1262,11 @@ var E = class {
1132
1262
  constructor(e, t, n = {}) {
1133
1263
  this.layout = e, this.config = t, this.options = n;
1134
1264
  }
1265
+ setOptions(e) {
1266
+ this.options = e;
1267
+ for (let e of this.xPool) e.style.font = this.options.font ?? "11px ui-monospace, monospace, sans-serif", e.style.color = this.options.color ?? "#bfd6ff";
1268
+ for (let e of this.yPool) e.style.font = this.options.font ?? "11px ui-monospace, monospace, sans-serif", e.style.color = this.options.color ?? "#bfd6ff";
1269
+ }
1135
1270
  update(e, t) {
1136
1271
  let n = Math.max(1, this.layout.plot.clientWidth), r = Math.max(1, this.layout.plot.clientHeight);
1137
1272
  this.config.x.visible ? t.getXTickValues(n, 12, this.xTicks) : this.xTicks.length = 0, this.config.y.visible ? t.getYTickValues(r, 8, this.yTicks) : this.yTicks.length = 0, this.updateAxis(this.xPool, this.xTicks, "x", e, n, r, t), this.updateAxis(this.yPool, this.yTicks, "y", e, n, r, t);
@@ -1163,7 +1298,7 @@ var E = class {
1163
1298
  }
1164
1299
  }
1165
1300
  }
1166
- }, A = class {
1301
+ }, ne = class {
1167
1302
  root;
1168
1303
  plot;
1169
1304
  canvas;
@@ -1190,7 +1325,7 @@ var E = class {
1190
1325
  applyBaseStyles() {
1191
1326
  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";
1192
1327
  }
1193
- }, j = {
1328
+ }, P = {
1194
1329
  backgroundColor: [
1195
1330
  .08,
1196
1331
  .1,
@@ -1253,39 +1388,39 @@ var E = class {
1253
1388
  legendMutedTextColor: "#789",
1254
1389
  legendFont: "11px/1.35 ui-monospace, monospace"
1255
1390
  };
1256
- function M(e, t) {
1257
- if (!e) return j;
1258
- let n = N(e.backgroundColor, j.backgroundColor, t), r = e.seriesColors?.length ? e.seriesColors.map((e, n) => N(e, j.seriesColors[n % j.seriesColors.length], t)) : j.seriesColors;
1391
+ function F(e, t) {
1392
+ if (!e) return P;
1393
+ let n = I(e.backgroundColor, P.backgroundColor, t), r = e.seriesColors?.length ? e.seriesColors.map((e, n) => I(e, P.seriesColors[n % P.seriesColors.length], t)) : P.seriesColors;
1259
1394
  return {
1260
1395
  backgroundColor: n,
1261
- backgroundCssColor: P(e.backgroundColor, j.backgroundCssColor),
1262
- gridColor: N(e.gridColor, j.gridColor, t),
1263
- axisColor: e.axisColor ?? j.axisColor,
1264
- axisFont: e.axisFont ?? j.axisFont,
1396
+ backgroundCssColor: L(e.backgroundColor, P.backgroundCssColor),
1397
+ gridColor: I(e.gridColor, P.gridColor, t),
1398
+ axisColor: e.axisColor ?? P.axisColor,
1399
+ axisFont: e.axisFont ?? P.axisFont,
1265
1400
  seriesColors: r,
1266
- tooltipBackgroundColor: e.tooltipBackgroundColor ?? j.tooltipBackgroundColor,
1267
- tooltipTextColor: e.tooltipTextColor ?? j.tooltipTextColor,
1268
- tooltipFont: e.tooltipFont ?? j.tooltipFont,
1269
- legendBackgroundColor: e.legendBackgroundColor ?? j.legendBackgroundColor,
1270
- legendBorderColor: e.legendBorderColor ?? j.legendBorderColor,
1271
- legendTextColor: e.legendTextColor ?? j.legendTextColor,
1272
- legendMutedTextColor: e.legendMutedTextColor ?? j.legendMutedTextColor,
1273
- legendFont: e.legendFont ?? j.legendFont
1401
+ tooltipBackgroundColor: e.tooltipBackgroundColor ?? P.tooltipBackgroundColor,
1402
+ tooltipTextColor: e.tooltipTextColor ?? P.tooltipTextColor,
1403
+ tooltipFont: e.tooltipFont ?? P.tooltipFont,
1404
+ legendBackgroundColor: e.legendBackgroundColor ?? P.legendBackgroundColor,
1405
+ legendBorderColor: e.legendBorderColor ?? P.legendBorderColor,
1406
+ legendTextColor: e.legendTextColor ?? P.legendTextColor,
1407
+ legendMutedTextColor: e.legendMutedTextColor ?? P.legendMutedTextColor,
1408
+ legendFont: e.legendFont ?? P.legendFont
1274
1409
  };
1275
1410
  }
1276
- function N(e, t, n) {
1411
+ function I(e, t, n) {
1277
1412
  if (!e) return t;
1278
1413
  if (typeof e != "string") return e;
1279
- let r = I(e, n), i = R(r ?? e, n);
1280
- return L(r ?? e) ?? L(i ?? "") ?? t;
1414
+ let r = re(e, n), i = B(r ?? e, n);
1415
+ return z(r ?? e) ?? z(i ?? "") ?? t;
1281
1416
  }
1282
- function P(e, t) {
1283
- return e ? typeof e == "string" ? e : F(e) : t;
1417
+ function L(e, t) {
1418
+ return e ? typeof e == "string" ? e : R(e) : t;
1284
1419
  }
1285
- function F(e) {
1420
+ function R(e) {
1286
1421
  return `rgba(${Math.round(e[0] * 255)}, ${Math.round(e[1] * 255)}, ${Math.round(e[2] * 255)}, ${e[3]})`;
1287
1422
  }
1288
- function I(e, t) {
1423
+ function re(e, t) {
1289
1424
  let n = t?.ownerDocument ?? globalThis.document;
1290
1425
  if (!n?.documentElement || typeof getComputedStyle > "u") return null;
1291
1426
  let r = t instanceof HTMLElement ? t : n.documentElement, i = n.createElement("span");
@@ -1293,11 +1428,11 @@ function I(e, t) {
1293
1428
  let a = getComputedStyle(i).color;
1294
1429
  return i.remove(), a || null;
1295
1430
  }
1296
- function L(e) {
1431
+ function z(e) {
1297
1432
  let t = e.trim();
1298
- return z(t) ?? B(t) ?? V(t);
1433
+ return ie(t) ?? ae(t) ?? oe(t);
1299
1434
  }
1300
- function R(e, t) {
1435
+ function B(e, t) {
1301
1436
  let n = t?.ownerDocument ?? globalThis.document;
1302
1437
  if (!n?.createElement) return null;
1303
1438
  let r = n.createElement("canvas").getContext("2d");
@@ -1307,12 +1442,12 @@ function R(e, t) {
1307
1442
  let a = String(r.fillStyle);
1308
1443
  return a === i ? null : a;
1309
1444
  }
1310
- function z(e) {
1445
+ function ie(e) {
1311
1446
  let t = e.match(/^rgba?\((.*)\)$/i);
1312
1447
  if (!t) return null;
1313
1448
  let n = t[1].trim().split("/").map((e) => e.trim()), r = n[0], i = n[1], a = r.includes(",") ? r.split(",").map((e) => e.trim()).filter(Boolean) : r.split(/\s+/).filter(Boolean);
1314
1449
  if (a.length < 3) return null;
1315
- let o = H(a[0]), s = H(a[1]), c = H(a[2]), l = W(i ?? (a.length > 3 ? a[3] : void 0));
1450
+ let o = V(a[0]), s = V(a[1]), c = V(a[2]), l = U(i ?? (a.length > 3 ? a[3] : void 0));
1316
1451
  return o === null || s === null || c === null || l === null ? null : [
1317
1452
  o,
1318
1453
  s,
@@ -1320,12 +1455,12 @@ function z(e) {
1320
1455
  l
1321
1456
  ];
1322
1457
  }
1323
- function B(e) {
1458
+ function ae(e) {
1324
1459
  let t = e.match(/^color\(\s*srgb\s+(.+)\)$/i);
1325
1460
  if (!t) return null;
1326
1461
  let n = t[1].split("/").map((e) => e.trim()), r = n[0].split(/\s+/).filter(Boolean);
1327
1462
  if (r.length < 3) return null;
1328
- let i = U(r[0]), a = U(r[1]), o = U(r[2]), s = W(n[1]);
1463
+ let i = H(r[0]), a = H(r[1]), o = H(r[2]), s = U(n[1]);
1329
1464
  return i === null || a === null || o === null || s === null ? null : [
1330
1465
  i,
1331
1466
  a,
@@ -1333,7 +1468,7 @@ function B(e) {
1333
1468
  s
1334
1469
  ];
1335
1470
  }
1336
- function V(e) {
1471
+ function oe(e) {
1337
1472
  let t = e.startsWith("#") ? e.slice(1) : "";
1338
1473
  if (![
1339
1474
  3,
@@ -1349,22 +1484,22 @@ function V(e) {
1349
1484
  n.length === 8 ? (r & 255) / 255 : 1
1350
1485
  ] : null;
1351
1486
  }
1487
+ function V(e) {
1488
+ return e.endsWith("%") ? W(Number.parseFloat(e) / 100) : W(Number.parseFloat(e) / 255);
1489
+ }
1352
1490
  function H(e) {
1353
- return e.endsWith("%") ? G(Number.parseFloat(e) / 100) : G(Number.parseFloat(e) / 255);
1491
+ return e.endsWith("%") ? W(Number.parseFloat(e) / 100) : W(Number.parseFloat(e));
1354
1492
  }
1355
1493
  function U(e) {
1356
- return e.endsWith("%") ? G(Number.parseFloat(e) / 100) : G(Number.parseFloat(e));
1494
+ return e ? e.endsWith("%") ? W(Number.parseFloat(e) / 100) : W(Number.parseFloat(e)) : 1;
1357
1495
  }
1358
1496
  function W(e) {
1359
- return e ? e.endsWith("%") ? G(Number.parseFloat(e) / 100) : G(Number.parseFloat(e)) : 1;
1360
- }
1361
- function G(e) {
1362
1497
  return Number.isFinite(e) ? Math.min(1, Math.max(0, e)) : null;
1363
1498
  }
1364
1499
  //#endregion
1365
1500
  //#region src/ui/Chart.ts
1366
- var K = 16384, q = K >> 1, J = K >> 1, Y = 3, X = 4096, Z = 12, Q = 64;
1367
- function $(e) {
1501
+ var G = 16384, K = G >> 1, q = G >> 1, J = 3, Y = 4096, X = 12, se = 12, Z = 64;
1502
+ function Q(e) {
1368
1503
  return e === !1 ? {
1369
1504
  visible: !1,
1370
1505
  position: "inside"
@@ -1376,7 +1511,31 @@ function $(e) {
1376
1511
  position: e.position ?? "inside"
1377
1512
  };
1378
1513
  }
1379
- var ne = class {
1514
+ function $(e) {
1515
+ return e === !1 ? {
1516
+ x: {
1517
+ visible: !1,
1518
+ position: "inside"
1519
+ },
1520
+ y: {
1521
+ visible: !1,
1522
+ position: "inside"
1523
+ }
1524
+ } : e === !0 || e === void 0 ? {
1525
+ x: {
1526
+ visible: !0,
1527
+ position: "inside"
1528
+ },
1529
+ y: {
1530
+ visible: !0,
1531
+ position: "inside"
1532
+ }
1533
+ } : {
1534
+ x: Q(e.x),
1535
+ y: Q(e.y)
1536
+ };
1537
+ }
1538
+ var ce = class {
1380
1539
  options;
1381
1540
  series = [];
1382
1541
  camera;
@@ -1396,6 +1555,7 @@ var ne = class {
1396
1555
  axisOverlay = null;
1397
1556
  normalizedAxes;
1398
1557
  resolvedTheme;
1558
+ _gridVisible;
1399
1559
  layout;
1400
1560
  stats = {
1401
1561
  fps: 0,
@@ -1409,11 +1569,13 @@ var ne = class {
1409
1569
  pluginDisposers = [];
1410
1570
  hoverSubscribers = /* @__PURE__ */ new Set();
1411
1571
  seriesSubscribers = /* @__PURE__ */ new Set();
1572
+ themeSubscribers = /* @__PURE__ */ new Set();
1412
1573
  currentHover = null;
1413
1574
  lastPointerClientX = 0;
1414
1575
  lastPointerClientY = 0;
1415
1576
  pointerInPlot = !1;
1416
1577
  lastFrameAt = 0;
1578
+ currentXOrigin = 0;
1417
1579
  _rafId = 0;
1418
1580
  handlePointerMove = (e) => {
1419
1581
  this.pointerInPlot = !0, this.lastPointerClientX = e.clientX, this.lastPointerClientY = e.clientY, this.refreshHover();
@@ -1422,33 +1584,10 @@ var ne = class {
1422
1584
  this.pointerInPlot = !1, this.emitHover(null);
1423
1585
  };
1424
1586
  constructor(e, t = {}) {
1425
- this.options = t, this.resolvedTheme = M(t.theme, e);
1426
- let n = t.axes;
1427
- n === !1 ? this.normalizedAxes = {
1428
- x: {
1429
- visible: !1,
1430
- position: "inside"
1431
- },
1432
- y: {
1433
- visible: !1,
1434
- position: "inside"
1435
- }
1436
- } : n === !0 || n === void 0 ? this.normalizedAxes = {
1437
- x: {
1438
- visible: !0,
1439
- position: "inside"
1440
- },
1441
- y: {
1442
- visible: !0,
1443
- position: "inside"
1444
- }
1445
- } : this.normalizedAxes = {
1446
- x: $(n.x),
1447
- y: $(n.y)
1448
- }, this.layout = new A(e, this.normalizedAxes), this.layout.root.style.background = this.resolvedTheme.backgroundCssColor, this.applyCanvasSize(), this.camera = new D(), this.axis = new O(this.camera), this.renderer = new w(new E(this.layout.canvas)), this.rawLineData = new Float32Array(K * 2), this.rawLineBuffer = this.renderer.createFloatBuffer(this.rawLineData.length), this.minMaxInstanceData = new Float32Array(J * Y), this.minMaxInstanceBuffer = this.renderer.createFloatBuffer(this.minMaxInstanceData.length), this.barTriangleData = new Float32Array(X * Z), this.barTriangleBuffer = this.renderer.createFloatBuffer(this.barTriangleData.length), this.gridData = new Float32Array(Q * 2), this.gridBuffer = this.renderer.createFloatBuffer(this.gridData.length), this.gridStyle = {
1587
+ this.options = t, this.resolvedTheme = F(t.theme, e), this.normalizedAxes = $(t.axes), this._gridVisible = t.grid !== !1, this.layout = new ne(e, this.normalizedAxes), this.layout.root.style.background = this.resolvedTheme.backgroundCssColor, this.applyCanvasSize(), this.camera = new j(), this.axis = new M(this.camera), this.renderer = new te(new A(this.layout.canvas)), this.rawLineData = new Float32Array(G * 2), this.rawLineBuffer = this.renderer.createFloatBuffer(this.rawLineData.length), this.minMaxInstanceData = new Float32Array(q * J), this.minMaxInstanceBuffer = this.renderer.createFloatBuffer(this.minMaxInstanceData.length), this.barTriangleData = new Float32Array(Y * X), this.barTriangleBuffer = this.renderer.createFloatBuffer(this.barTriangleData.length), this.gridData = new Float32Array(Z * 2), this.gridBuffer = this.renderer.createFloatBuffer(this.gridData.length), this.gridStyle = {
1449
1588
  color: t.gridStyle?.color ?? this.resolvedTheme.gridColor,
1450
1589
  lineWidth: t.gridStyle?.lineWidth ?? 1
1451
- }, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible) && (this.axisOverlay = new k(this.layout, this.normalizedAxes, {
1590
+ }, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible) && (this.axisOverlay = new N(this.layout, this.normalizedAxes, {
1452
1591
  color: this.resolvedTheme.axisColor,
1453
1592
  font: this.resolvedTheme.axisFont
1454
1593
  })), 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));
@@ -1500,20 +1639,22 @@ var ne = class {
1500
1639
  this.camera.zoom(e), this.refreshHover();
1501
1640
  }
1502
1641
  addSeries(e, t) {
1503
- let n = e.dataset ?? new a(e.capacity), r = this.resolvedTheme.seriesColors, o = r[this.series.length % r.length] ?? this.resolvedTheme.seriesColors[0], s = t?.color ?? o, c = new i(n, e, {
1504
- color: s,
1642
+ if (e.mode === "ohlc" && !e.dataset) throw TypeError("OHLC series require an OhlcDataset.");
1643
+ let n = e.dataset ?? new l(e.capacity, { overflow: e.overflow }), r = this.resolvedTheme.seriesColors, i = r[this.series.length % r.length] ?? this.resolvedTheme.seriesColors[0], a = t?.color ?? i, s = new o(n, e, {
1644
+ color: a,
1505
1645
  lineWidth: t?.lineWidth ?? 1,
1506
1646
  pointSize: t?.pointSize ?? 4,
1507
1647
  barWidth: t?.barWidth ?? .8,
1508
1648
  baseline: t?.baseline ?? 0,
1509
1649
  fillColor: t?.fillColor ?? [
1510
- s[0],
1511
- s[1],
1512
- s[2],
1513
- s[3] * .25
1514
- ]
1650
+ a[0],
1651
+ a[1],
1652
+ a[2],
1653
+ a[3] * .25
1654
+ ],
1655
+ tickWidth: t?.tickWidth ?? t?.barWidth ?? .8
1515
1656
  });
1516
- return this.series.push(c), this.emitSeriesChange(), c;
1657
+ return this.series.push(s), this.emitSeriesChange(), s;
1517
1658
  }
1518
1659
  addLine(e, t) {
1519
1660
  return this.addSeries({
@@ -1539,6 +1680,12 @@ var ne = class {
1539
1680
  mode: "bar"
1540
1681
  }, t);
1541
1682
  }
1683
+ addOhlc(e, t) {
1684
+ return this.addSeries({
1685
+ ...e,
1686
+ mode: "ohlc"
1687
+ }, t);
1688
+ }
1542
1689
  removeSeries(e) {
1543
1690
  let t = this.series.indexOf(e);
1544
1691
  return t === -1 ? !1 : (this.series.splice(t, 1), this.emitSeriesChange(), !0);
@@ -1582,9 +1729,28 @@ var ne = class {
1582
1729
  let e = t;
1583
1730
  return this.hoverSubscribers.add(e), () => this.hoverSubscribers.delete(e);
1584
1731
  }
1732
+ if (e === "themechange") {
1733
+ let e = t;
1734
+ return this.themeSubscribers.add(e), () => this.themeSubscribers.delete(e);
1735
+ }
1585
1736
  let n = t;
1586
1737
  return this.seriesSubscribers.add(n), () => this.seriesSubscribers.delete(n);
1587
1738
  }
1739
+ setTheme(e) {
1740
+ this.resolvedTheme = F(e, this.layout.root), this.applyTheme(), this.emitThemeChange(), this.refreshHover();
1741
+ }
1742
+ setGridVisible(e) {
1743
+ this._gridVisible = e;
1744
+ }
1745
+ getGridVisible() {
1746
+ return this._gridVisible;
1747
+ }
1748
+ setAxes(e) {
1749
+ this.normalizedAxes = $(e), this.layout.update(this.normalizedAxes), this.axisOverlay?.dispose(), this.axisOverlay = null, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible) && (this.axisOverlay = new N(this.layout, this.normalizedAxes, {
1750
+ color: this.resolvedTheme.axisColor,
1751
+ font: this.resolvedTheme.axisFont
1752
+ })), this.resize(), this.refreshHover();
1753
+ }
1588
1754
  pick(e, t, n = {}) {
1589
1755
  let r = this.canvas.getBoundingClientRect();
1590
1756
  if (r.width <= 0 || r.height <= 0) return null;
@@ -1609,7 +1775,7 @@ var ne = class {
1609
1775
  o.width = i, o.height = a;
1610
1776
  let s = o.getContext("2d");
1611
1777
  if (!s) throw Error("Unable to create a 2D canvas context for screenshot export.");
1612
- return s.fillStyle = e.background ?? F(this.resolvedTheme.backgroundColor), s.fillRect(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) => {
1778
+ return s.fillStyle = e.background ?? R(this.resolvedTheme.backgroundColor), s.fillRect(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) => {
1613
1779
  o.toBlob((e) => e ? t(e) : n(/* @__PURE__ */ Error("Unable to encode chart screenshot.")), e.type ?? "image/png", e.quality);
1614
1780
  });
1615
1781
  }
@@ -1628,34 +1794,11 @@ var ne = class {
1628
1794
  let [t, n, r, i] = this.resolvedTheme.backgroundColor;
1629
1795
  this.renderer.viewport(0, 0, this.canvas.width, this.canvas.height), this.renderer.clear(t, n, r, i);
1630
1796
  let a = this.camera.viewport;
1631
- if (this.options.grid !== !1) {
1797
+ if (this.currentXOrigin = a.xMin, this.renderer.setXOrigin(this.currentXOrigin), this._gridVisible) {
1632
1798
  let e = this.writeGridVertices(a);
1633
- e > 0 && (this.renderer.updateFloatBuffer(this.gridBuffer, this.gridData), this.renderer.drawLines(this.gridBuffer, e, this.gridStyle, this.camera), this.stats.drawCalls++, this.stats.uploadBytes += this.gridData.byteLength);
1634
- }
1635
- for (let e of this.series) {
1636
- if (!e.visible) continue;
1637
- if (e.rebuildPyramid(), e.config.mode === "scatter") {
1638
- this.drawScatterSeries(e, a);
1639
- continue;
1640
- }
1641
- if (e.config.mode === "bar") {
1642
- this.drawBarSeries(e, a);
1643
- continue;
1644
- }
1645
- if (e.config.mode === "area") {
1646
- this.drawAreaSeries(e, a);
1647
- continue;
1648
- }
1649
- let t = e.visibleSampleCount(a), n = e.hasLOD && t > K;
1650
- if (n && this.renderer.supportsInstancedSegments) {
1651
- let t = e.copyMinMaxInstanced(a, this.minMaxInstanceData, this.maxMinMaxSegments());
1652
- if (t <= 0) continue;
1653
- this.renderer.updateFloatBuffer(this.minMaxInstanceBuffer, this.minMaxInstanceData), this.renderer.drawMinMaxSegmentsInstanced(this.minMaxInstanceBuffer, t, e.style, this.camera), this.recordRenderMode("minmax"), this.stats.pointsRendered += t * 2, this.stats.drawCalls++, this.stats.uploadBytes += this.minMaxInstanceData.byteLength;
1654
- continue;
1655
- }
1656
- let r = n ? e.copyMinMaxVisible(a, this.rawLineData, this.maxMinMaxSegments()) : e.copyRawVisible(a, this.rawLineData, K);
1657
- r < 2 || (this.renderer.updateFloatBuffer(this.rawLineBuffer, this.rawLineData), n ? (this.renderer.drawMinMaxSegments(this.rawLineBuffer, r, e.style, this.camera), this.recordRenderMode("minmax")) : (this.renderer.drawLineStrip(this.rawLineBuffer, r, e.style, this.camera), this.recordRenderMode("raw")), this.stats.pointsRendered += r, this.stats.drawCalls++, this.stats.uploadBytes += this.rawLineData.byteLength);
1799
+ e > 0 && (this.uploadGridData(e), this.renderer.drawClipLines(this.gridBuffer, e, this.gridStyle), this.stats.drawCalls++);
1658
1800
  }
1801
+ for (let e of this.series) e.visible && (e.rebuildPyramid(), this.drawSeries(e, a));
1659
1802
  this.axisOverlay?.update(this.camera, this.axis), this.stats.frameMs = performance.now() - e, this.refreshHover();
1660
1803
  }
1661
1804
  dispose() {
@@ -1663,52 +1806,128 @@ var ne = class {
1663
1806
  for (let e of this.pluginDisposers.splice(0)) e();
1664
1807
  this.axisOverlay?.dispose(), this.renderer.dispose(), this.layout.dispose();
1665
1808
  }
1809
+ applyTheme() {
1810
+ this.layout.root.style.background = this.resolvedTheme.backgroundCssColor, this.options.gridStyle?.color === void 0 && (this.gridStyle = {
1811
+ ...this.gridStyle,
1812
+ color: this.resolvedTheme.gridColor
1813
+ }), this.axisOverlay?.setOptions({
1814
+ color: this.resolvedTheme.axisColor,
1815
+ font: this.resolvedTheme.axisFont
1816
+ });
1817
+ }
1666
1818
  applyCanvasSize(e = globalThis.devicePixelRatio) {
1667
1819
  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));
1668
1820
  return this.canvas.width === n && this.canvas.height === r ? !1 : (this.canvas.width = n, this.canvas.height = r, !0);
1669
1821
  }
1822
+ drawSeries(e, t) {
1823
+ switch (e.config.mode) {
1824
+ case "area":
1825
+ this.drawAreaSeries(e, t);
1826
+ return;
1827
+ case "bar":
1828
+ this.drawBarSeries(e, t);
1829
+ return;
1830
+ case "ohlc":
1831
+ this.drawOhlcSeries(e, t);
1832
+ return;
1833
+ case "scatter":
1834
+ this.drawScatterSeries(e, t);
1835
+ return;
1836
+ default: this.drawLineSeries(e, t);
1837
+ }
1838
+ }
1839
+ drawLineSeries(e, t) {
1840
+ let n = e.visibleSampleCount(t), r = e.hasLOD && n > G - 2;
1841
+ if (r && this.renderer.supportsInstancedSegments) {
1842
+ let n = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxMinMaxSegments(), this.currentXOrigin);
1843
+ if (n <= 0) return;
1844
+ this.uploadMinMaxInstanceData(n), this.renderer.drawMinMaxSegmentsInstanced(this.minMaxInstanceBuffer, n, e.style, this.camera), this.recordDraw("minmax", n * 2);
1845
+ return;
1846
+ }
1847
+ if (r) {
1848
+ let n = e.copyMinMaxVisible(t, this.rawLineData, this.maxMinMaxSegments(), this.currentXOrigin);
1849
+ if (n < 2) return;
1850
+ this.uploadRawLineData(n), this.renderer.drawMinMaxSegments(this.rawLineBuffer, n, e.style, this.camera), this.recordDraw("minmax", n);
1851
+ return;
1852
+ }
1853
+ let i = e.copyRawVisibleClipSpace(t, this.rawLineData, G);
1854
+ i < 2 || (this.uploadRawLineData(i), this.renderer.drawClipLineStrip(this.rawLineBuffer, i, e.style), this.recordDraw("raw", i));
1855
+ }
1670
1856
  drawAreaSeries(e, t) {
1671
- let n = e.style.baseline ?? 0, r = e.copyAreaVisible(t, this.rawLineData, q, n);
1672
- if (r < 4) return;
1673
- 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;
1674
- let i = this.uploadRawInstances(e, t, q);
1675
- i >= 2 && (this.renderer.drawLineStrip(this.rawLineBuffer, i, e.style, this.camera), this.stats.pointsRendered += i, this.stats.drawCalls++), this.recordRenderMode("area");
1857
+ let n = e.visibleIndexRange(t, 1);
1858
+ if (n.end - n.start < 2) return;
1859
+ let r = e.style.baseline ?? 0;
1860
+ for (let t = n.start; t < n.end;) {
1861
+ let i = e.copyAreaRange(t, n.end, this.rawLineData, K, r, this.currentXOrigin);
1862
+ if (i < 4) break;
1863
+ this.uploadRawLineData(i), this.renderer.drawAreaStrip(this.rawLineBuffer, i, e.style, this.camera), this.recordDraw("area", i), t += Math.max(1, (i >> 1) - 1);
1864
+ }
1865
+ for (let t = n.start; t < n.end;) {
1866
+ let r = e.copyRawRange(t, n.end, this.rawLineData, K, this.currentXOrigin);
1867
+ if (r < 2) break;
1868
+ this.uploadRawLineData(r), this.renderer.drawLineStrip(this.rawLineBuffer, r, e.style, this.camera), this.recordDraw("area", r), t += Math.max(1, r - 1);
1869
+ }
1870
+ }
1871
+ drawOhlcSeries(e, t) {
1872
+ let n = e.visibleIndexRange(t), r = Math.floor(this.rawLineData.length / se);
1873
+ for (let t = n.start; t < n.end;) {
1874
+ let i = e.copyOhlcRange(t, n.end, this.rawLineData, r, e.style.tickWidth ?? e.style.barWidth ?? .8, this.currentXOrigin);
1875
+ if (i <= 0) break;
1876
+ let a = i * 6;
1877
+ this.uploadRawLineData(a), this.renderer.drawLines(this.rawLineBuffer, a, e.style, this.camera), this.recordDraw("raw", a), t += i;
1878
+ }
1676
1879
  }
1677
1880
  drawScatterSeries(e, t) {
1678
- let n = this.uploadRawInstances(e, t, K);
1679
- 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));
1881
+ let n = e.visibleIndexRange(t);
1882
+ for (let t = n.start; t < n.end;) {
1883
+ let r = e.copyRawRange(t, n.end, this.rawLineData, G, this.currentXOrigin);
1884
+ if (r <= 0) break;
1885
+ this.uploadRawLineData(r), this.renderer.drawPoints(this.rawLineBuffer, r, e.style, this.camera, this.canvas.width, this.canvas.height), this.recordDraw("points", r), t += r;
1886
+ }
1680
1887
  }
1681
1888
  drawBarSeries(e, t) {
1682
1889
  let n = e.visibleSampleCount(t), r = this.maxRawBarInstances();
1683
1890
  if (e.hasLOD && n > r) {
1684
- let n = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxBarFallbackBars());
1891
+ let n = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxBarTriangleBars(), this.currentXOrigin);
1685
1892
  if (n <= 0) return;
1686
1893
  this.includeBaselineInBarRanges(n, e.style.baseline ?? 0);
1687
1894
  let r = this.writeBarBucketTriangles(n, t);
1688
- this.drawBarTriangleFallback(r, e.style);
1895
+ this.drawBarTriangles(r, e.style);
1689
1896
  return;
1690
1897
  }
1691
- let i = this.uploadRawInstances(e, t, r);
1692
- if (i <= 0) return;
1898
+ let i = e.visibleIndexRange(t, 1), a = e.copyRawRange(i.start, i.end, this.rawLineData, r, this.currentXOrigin);
1899
+ if (a <= 0) return;
1693
1900
  if (this.renderer.supportsInstancedBars) {
1694
- this.renderer.drawBarsInstanced(this.rawLineBuffer, i, e.style, this.camera), this.recordInstancedDraw("bars", i);
1901
+ this.uploadRawLineData(a), this.renderer.drawBarsInstanced(this.rawLineBuffer, a, e.style, this.camera), this.recordDraw("bars", a);
1695
1902
  return;
1696
1903
  }
1697
- let a = this.writeBarTriangles(i, e.style.baseline ?? 0, e.style.barWidth ?? .8);
1698
- this.drawBarTriangleFallback(a, e.style);
1904
+ let o = this.writeBarTriangles(a, e.style.baseline ?? 0, e.style.barWidth ?? .8);
1905
+ this.drawBarTriangles(o, e.style);
1906
+ }
1907
+ uploadRawLineData(e) {
1908
+ this.uploadFloatData(this.rawLineBuffer, this.rawLineData, e * 2);
1909
+ }
1910
+ uploadMinMaxInstanceData(e) {
1911
+ this.uploadFloatData(this.minMaxInstanceBuffer, this.minMaxInstanceData, e * J);
1699
1912
  }
1700
- uploadRawInstances(e, t, n) {
1701
- let r = e.copyRawVisible(t, this.rawLineData, n);
1702
- return r <= 0 ? 0 : (this.renderer.updateFloatBuffer(this.rawLineBuffer, this.rawLineData), this.stats.uploadBytes += this.rawLineData.byteLength, r);
1913
+ uploadBarTriangleData(e) {
1914
+ this.uploadFloatData(this.barTriangleBuffer, this.barTriangleData, e * 2);
1915
+ }
1916
+ uploadGridData(e) {
1917
+ this.uploadFloatData(this.gridBuffer, this.gridData, e * 2);
1918
+ }
1919
+ uploadFloatData(e, t, n) {
1920
+ let r = Math.max(0, Math.min(n, t.length));
1921
+ this.renderer.updateFloatBuffer(e, t, r), this.stats.uploadBytes += r * Float32Array.BYTES_PER_ELEMENT;
1703
1922
  }
1704
1923
  includeBaselineInBarRanges(e, t) {
1705
1924
  for (let n = 0; n < e; n++) {
1706
- let e = n * Y, r = this.minMaxInstanceData[e + 1], i = this.minMaxInstanceData[e + 2];
1925
+ let e = n * J, r = this.minMaxInstanceData[e + 1], i = this.minMaxInstanceData[e + 2];
1707
1926
  this.minMaxInstanceData[e + 1] = Math.min(t, r), this.minMaxInstanceData[e + 2] = Math.max(t, i);
1708
1927
  }
1709
1928
  }
1710
1929
  writeBarTriangles(e, t, n) {
1711
- let r = Math.min(e, this.maxBarFallbackBars());
1930
+ let r = Math.min(e, this.maxBarTriangleBars());
1712
1931
  for (let e = 0; e < r; e++) {
1713
1932
  let r = this.rawLineData[e * 2], i = this.rawLineData[e * 2 + 1];
1714
1933
  this.writeBarTriangle(e, r - n * .5, r + n * .5, t, i);
@@ -1716,7 +1935,7 @@ var ne = class {
1716
1935
  return r * 6;
1717
1936
  }
1718
1937
  writeBarBucketTriangles(e, t) {
1719
- let n = Math.min(e, this.maxBarFallbackBars());
1938
+ let n = Math.min(e, this.maxBarTriangleBars());
1720
1939
  for (let e = 0; e < n; e++) {
1721
1940
  let r = this.minMaxInstanceData[e * 3 + 1], i = this.minMaxInstanceData[e * 3 + 2], [a, o] = this.barBucketBounds(e, n, t);
1722
1941
  this.writeBarTriangle(e, a, o, r, i);
@@ -1724,27 +1943,27 @@ var ne = class {
1724
1943
  return n * 6;
1725
1944
  }
1726
1945
  barBucketBounds(e, t, n) {
1727
- let r = this.minMaxInstanceData[e * 3], i = n.xMax - n.xMin;
1946
+ let r = this.minMaxInstanceData[e * 3], i = n.xMin - this.currentXOrigin, a = n.xMax - this.currentXOrigin, o = a - i;
1728
1947
  if (t <= 1) {
1729
- let e = Math.max(0, i * .5);
1730
- return [Math.max(n.xMin, r - e), Math.min(n.xMax, r + e)];
1948
+ let e = Math.max(0, o * .5);
1949
+ return [Math.max(i, r - e), Math.min(a, r + e)];
1731
1950
  }
1732
- let a = e > 0 ? this.minMaxInstanceData[(e - 1) * 3] : NaN, o = e + 1 < t ? this.minMaxInstanceData[(e + 1) * 3] : NaN, s = e === 0 ? r - (o - r) * .5 : (a + r) * .5, c = e + 1 === t ? r + (r - a) * .5 : (r + o) * .5;
1733
- if (!Number.isFinite(s) || !Number.isFinite(c) || c <= s) {
1734
- let r = i / Math.max(1, t);
1735
- s = n.xMin + e * r, c = e + 1 === t ? n.xMax : s + r;
1951
+ let s = e > 0 ? this.minMaxInstanceData[(e - 1) * 3] : NaN, c = e + 1 < t ? this.minMaxInstanceData[(e + 1) * 3] : NaN, l = e === 0 ? r - (c - r) * .5 : (s + r) * .5, u = e + 1 === t ? r + (r - s) * .5 : (r + c) * .5;
1952
+ if (!Number.isFinite(l) || !Number.isFinite(u) || u <= l) {
1953
+ let n = o / Math.max(1, t);
1954
+ l = i + e * n, u = e + 1 === t ? a : l + n;
1736
1955
  }
1737
- return [Math.max(n.xMin, s), Math.min(n.xMax, c)];
1956
+ return [Math.max(i, l), Math.min(a, u)];
1738
1957
  }
1739
1958
  writeBarTriangle(e, t, n, r, i) {
1740
- let a = e * Z;
1959
+ let a = e * X;
1741
1960
  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;
1742
1961
  }
1743
- drawBarTriangleFallback(e, t) {
1744
- 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));
1962
+ drawBarTriangles(e, t) {
1963
+ e <= 0 || (this.uploadBarTriangleData(e), this.renderer.drawBarTriangles(this.barTriangleBuffer, e, t, this.camera), this.recordDraw("bars", e));
1745
1964
  }
1746
- recordInstancedDraw(e, t) {
1747
- this.recordRenderMode(e), this.stats.pointsRendered += t, this.stats.drawCalls++;
1965
+ recordDraw(e, t, n = 1) {
1966
+ this.recordRenderMode(e), this.stats.pointsRendered += t, this.stats.drawCalls += n;
1748
1967
  }
1749
1968
  findNearestXAnchor(e, t, n, r) {
1750
1969
  let i = null, a = Infinity, o = n / (t.xMax - t.xMin);
@@ -1801,6 +2020,9 @@ var ne = class {
1801
2020
  for (let e of this.seriesSubscribers) e();
1802
2021
  this.refreshHover();
1803
2022
  }
2023
+ emitThemeChange() {
2024
+ for (let e of this.themeSubscribers) e();
2025
+ }
1804
2026
  drawDomTextForScreenshot(e, t, n) {
1805
2027
  let r = this.layout.root.querySelectorAll("div");
1806
2028
  for (let i of r) {
@@ -1813,32 +2035,38 @@ var ne = class {
1813
2035
  }
1814
2036
  }
1815
2037
  maxMinMaxSegments() {
1816
- return Math.min(this.canvas.width, J);
2038
+ return Math.min(this.canvas.width, q);
1817
2039
  }
1818
- maxBarFallbackBars() {
1819
- return Math.min(X, K);
2040
+ maxBarTriangleBars() {
2041
+ return Math.min(Y, G);
1820
2042
  }
1821
2043
  maxRawBarInstances() {
1822
- return this.renderer.supportsInstancedBars ? K : this.maxBarFallbackBars();
2044
+ return this.renderer.supportsInstancedBars ? G : this.maxBarTriangleBars();
1823
2045
  }
1824
2046
  writeGridVertices(e) {
1825
2047
  let t = Math.max(1, this.canvas.clientWidth), n = Math.max(1, this.canvas.clientHeight);
1826
2048
  this.axis.getXTickValues(t, 12, this.xTicks), this.axis.getYTickValues(n, 8, this.yTicks);
1827
2049
  let r = 0;
1828
2050
  for (let t of this.xTicks) {
1829
- if (r + 2 > Q) return r;
1830
- 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++;
2051
+ if (r + 2 > Z) return r;
2052
+ this.gridData[r * 2] = this.xToClip(t, e), this.gridData[r * 2 + 1] = -1, r++, this.gridData[r * 2] = this.xToClip(t, e), this.gridData[r * 2 + 1] = 1, r++;
1831
2053
  }
1832
2054
  for (let t of this.yTicks) {
1833
- if (r + 2 > Q) return r;
1834
- 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++;
2055
+ if (r + 2 > Z) return r;
2056
+ this.gridData[r * 2] = -1, this.gridData[r * 2 + 1] = this.yToClip(t, e), r++, this.gridData[r * 2] = 1, this.gridData[r * 2 + 1] = this.yToClip(t, e), r++;
1835
2057
  }
1836
2058
  return r;
1837
2059
  }
2060
+ xToClip(e, t) {
2061
+ return (e - t.xMin) / (t.xMax - t.xMin) * 2 - 1;
2062
+ }
2063
+ yToClip(e, t) {
2064
+ return (e - t.yMin) / (t.yMax - t.yMin) * 2 - 1;
2065
+ }
1838
2066
  recordRenderMode(e) {
1839
2067
  this.stats.renderMode === "none" ? this.stats.renderMode = e : this.stats.renderMode !== e && (this.stats.renderMode = "mixed");
1840
2068
  }
1841
- }, re = class {
2069
+ }, le = class {
1842
2070
  xData;
1843
2071
  yData;
1844
2072
  constructor(e, t) {
@@ -1860,26 +2088,135 @@ var ne = class {
1860
2088
  return this.assertValidIndex(e), this.yData[e];
1861
2089
  }
1862
2090
  lowerBoundX(e) {
1863
- let t = 0, n = this.length;
1864
- for (; t < n;) {
1865
- let r = t + (n - t >> 1);
1866
- this.xData[r] < e ? t = r + 1 : n = r;
1867
- }
1868
- return t;
2091
+ return s(this.length, (e) => this.xData[e], e);
1869
2092
  }
1870
2093
  upperBoundX(e) {
1871
- let t = 0, n = this.length;
1872
- for (; t < n;) {
1873
- let r = t + (n - t >> 1);
1874
- this.xData[r] <= e ? t = r + 1 : n = r;
1875
- }
1876
- return t;
2094
+ return c(this.length, (e) => this.xData[e], e);
1877
2095
  }
1878
2096
  assertValidIndex(e) {
1879
2097
  if (!Number.isInteger(e) || e < 0 || e >= this.length) throw RangeError(`StaticDataset index out of range: ${e}`);
1880
2098
  }
2099
+ }, ue = class {
2100
+ length;
2101
+ xs;
2102
+ opens;
2103
+ highs;
2104
+ lows;
2105
+ closes;
2106
+ constructor(e, t, n, r, i) {
2107
+ this.length = Math.min(e.length, t.length, n.length, r.length, i.length), this.xs = e, this.opens = t, this.highs = n, this.lows = r, this.closes = i;
2108
+ }
2109
+ get range() {
2110
+ return this.length === 0 ? null : {
2111
+ start: this.getX(0),
2112
+ end: this.getX(this.length - 1)
2113
+ };
2114
+ }
2115
+ getX(e) {
2116
+ return this.assertValidIndex(e), this.xs[e];
2117
+ }
2118
+ getY(e) {
2119
+ return this.getClose(e);
2120
+ }
2121
+ getOpen(e) {
2122
+ return this.assertValidIndex(e), this.opens[e];
2123
+ }
2124
+ getHigh(e) {
2125
+ return this.assertValidIndex(e), this.highs[e];
2126
+ }
2127
+ getLow(e) {
2128
+ return this.assertValidIndex(e), this.lows[e];
2129
+ }
2130
+ getClose(e) {
2131
+ return this.assertValidIndex(e), this.closes[e];
2132
+ }
2133
+ lowerBoundX(e) {
2134
+ return s(this.length, (e) => this.xs[e], e);
2135
+ }
2136
+ upperBoundX(e) {
2137
+ return c(this.length, (e) => this.xs[e], e);
2138
+ }
2139
+ assertValidIndex(e) {
2140
+ if (!Number.isInteger(e) || e < 0 || e >= this.length) throw RangeError(`StaticOhlcDataset index out of range: ${e}`);
2141
+ }
2142
+ }, de = class {
2143
+ capacity;
2144
+ overflow;
2145
+ xData;
2146
+ openData;
2147
+ highData;
2148
+ lowData;
2149
+ closeData;
2150
+ _length = 0;
2151
+ _head = 0;
2152
+ constructor(e, t = {}) {
2153
+ if (!Number.isInteger(e) || e <= 0) throw RangeError("OhlcRingBuffer capacity must be a positive integer.");
2154
+ this.capacity = e, this.overflow = t.overflow ?? "wrap", this.xData = new Float64Array(e), this.openData = new Float32Array(e), this.highData = new Float32Array(e), this.lowData = new Float32Array(e), this.closeData = new Float32Array(e);
2155
+ }
2156
+ get length() {
2157
+ return this._length;
2158
+ }
2159
+ get range() {
2160
+ return this._length === 0 ? null : {
2161
+ start: this.getX(0),
2162
+ end: this.getX(this._length - 1)
2163
+ };
2164
+ }
2165
+ push(e, t, n, r, i) {
2166
+ if (this._length >= this.capacity) {
2167
+ if (this.overflow === "drop-new") return;
2168
+ if (this.overflow === "error") throw RangeError("OhlcRingBuffer capacity exceeded.");
2169
+ }
2170
+ this.xData[this._head] = e, this.openData[this._head] = t, this.highData[this._head] = n, this.lowData[this._head] = r, this.closeData[this._head] = i, this._head = (this._head + 1) % this.capacity, this._length < this.capacity && this._length++;
2171
+ }
2172
+ append(e, t, n, r, i) {
2173
+ let a = Math.min(e.length, t.length, n.length, r.length, i.length);
2174
+ if (a <= 0) return;
2175
+ if (this.overflow !== "wrap") {
2176
+ let o = this.capacity - this._length;
2177
+ if (a > o && this.overflow === "error") throw RangeError("OhlcRingBuffer capacity exceeded.");
2178
+ let s = Math.min(a, o);
2179
+ for (let a = 0; a < s; a++) this.push(e[a], t[a], n[a], r[a], i[a]);
2180
+ return;
2181
+ }
2182
+ let o = Math.max(0, a - this.capacity);
2183
+ for (let s = o; s < a; s++) this.push(e[s], t[s], n[s], r[s], i[s]);
2184
+ }
2185
+ clear() {
2186
+ this._length = 0, this._head = 0;
2187
+ }
2188
+ getX(e) {
2189
+ return this.assertValidIndex(e), this.xData[this.logicalToPhysical(e)];
2190
+ }
2191
+ getY(e) {
2192
+ return this.getClose(e);
2193
+ }
2194
+ getOpen(e) {
2195
+ return this.assertValidIndex(e), this.openData[this.logicalToPhysical(e)];
2196
+ }
2197
+ getHigh(e) {
2198
+ return this.assertValidIndex(e), this.highData[this.logicalToPhysical(e)];
2199
+ }
2200
+ getLow(e) {
2201
+ return this.assertValidIndex(e), this.lowData[this.logicalToPhysical(e)];
2202
+ }
2203
+ getClose(e) {
2204
+ return this.assertValidIndex(e), this.closeData[this.logicalToPhysical(e)];
2205
+ }
2206
+ lowerBoundX(e) {
2207
+ return s(this._length, (e) => this.getX(e), e);
2208
+ }
2209
+ upperBoundX(e) {
2210
+ return c(this._length, (e) => this.getX(e), e);
2211
+ }
2212
+ logicalToPhysical(e) {
2213
+ return (this._head - this._length + e + this.capacity) % this.capacity;
2214
+ }
2215
+ assertValidIndex(e) {
2216
+ if (!Number.isInteger(e) || e < 0 || e >= this._length) throw RangeError(`OhlcRingBuffer index out of range: ${e}`);
2217
+ }
1881
2218
  };
1882
2219
  //#endregion
1883
- export { O as AxisController, D as Camera2D, ne as Chart, j as DEFAULT_CHART_THEME, n as MinMaxPyramid, a as RingBuffer, i as SeriesStore, re as StaticDataset };
2220
+ export { M as AxisController, j as Camera2D, ce as Chart, P as DEFAULT_CHART_THEME, n as MinMaxPyramid, de as OhlcRingBuffer, l as RingBuffer, o as SeriesStore, le as StaticDataset, ue as StaticOhlcDataset };
1884
2221
 
1885
2222
  //# sourceMappingURL=index.js.map