blazeplot 0.1.12 → 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);
249
266
  }
250
- copyAreaVisible(e, t, n, r = 0) {
251
- return this.copyVisibleSamples(e, t, n, "area", r) * 2;
267
+ copyAreaVisible(e, t, n, r = 0, i = 0) {
268
+ return this.copyVisibleSamples(e, t, n, "area", r, i) * 2;
252
269
  }
253
- copyMinMaxVisible(e, t, n) {
254
- return this.copyMinMaxSegments(e, t, n, "line-list") * 2;
270
+ copyAreaRange(e, t, n, r, i = 0, a = 0) {
271
+ return this.copySampleRange(e, t, n, r, "area", i, a) * 2;
255
272
  }
256
- copyMinMaxInstanced(e, t, n) {
257
- return this.copyMinMaxSegments(e, t, n, "instanced");
273
+ copyMinMaxVisible(e, t, n, r = 0) {
274
+ return this.copyMinMaxSegments(e, t, n, "line-list", r) * 2;
258
275
  }
259
- visibleIndexRange(e) {
260
- return e ? {
261
- start: this.dataset.lowerBoundX(e.xMin),
262
- end: this.dataset.upperBoundX(e.xMax)
263
- } : {
276
+ copyMinMaxInstanced(e, t, n, r = 0) {
277
+ return this.copyMinMaxSegments(e, t, n, "instanced", r);
278
+ }
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, ee = 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
- }, w = [
926
+ }, D = [
797
927
  1024,
798
928
  4096,
799
929
  16384,
800
930
  32768,
801
931
  131072
802
- ], te = 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 w) 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 w) if (t >= e) return t;
856
- let t = w[w.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 ne(e) {
992
+ function k(e) {
863
993
  return e;
864
994
  }
865
- var T = class {
995
+ var A = class {
866
996
  gl;
867
997
  regl;
868
998
  resources;
@@ -882,10 +1012,10 @@ var T = 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: ne(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 te(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 T = class {
1004
1134
  default: return e;
1005
1135
  }
1006
1136
  }
1007
- }, E = class e {
1137
+ }, j = class e {
1008
1138
  _xMin = 0;
1009
1139
  _xMax = 1;
1010
1140
  _yMin = 0;
@@ -1089,7 +1219,7 @@ var T = class {
1089
1219
  static assertFinite(e, t) {
1090
1220
  if (!Number.isFinite(t)) throw RangeError(`Camera2D ${e} must be finite.`);
1091
1221
  }
1092
- }, D = class {
1222
+ }, M = class {
1093
1223
  camera;
1094
1224
  constructor(e) {
1095
1225
  this.camera = e;
@@ -1121,7 +1251,7 @@ var T = 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
- }, O = class {
1254
+ }, N = class {
1125
1255
  layout;
1126
1256
  config;
1127
1257
  options;
@@ -1168,7 +1298,7 @@ var T = class {
1168
1298
  }
1169
1299
  }
1170
1300
  }
1171
- }, k = class {
1301
+ }, ne = class {
1172
1302
  root;
1173
1303
  plot;
1174
1304
  canvas;
@@ -1195,7 +1325,7 @@ var T = class {
1195
1325
  applyBaseStyles() {
1196
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";
1197
1327
  }
1198
- }, A = {
1328
+ }, P = {
1199
1329
  backgroundColor: [
1200
1330
  .08,
1201
1331
  .1,
@@ -1258,39 +1388,39 @@ var T = class {
1258
1388
  legendMutedTextColor: "#789",
1259
1389
  legendFont: "11px/1.35 ui-monospace, monospace"
1260
1390
  };
1261
- function j(e, t) {
1262
- if (!e) return A;
1263
- let n = M(e.backgroundColor, A.backgroundColor, t), r = e.seriesColors?.length ? e.seriesColors.map((e, n) => M(e, A.seriesColors[n % A.seriesColors.length], t)) : A.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;
1264
1394
  return {
1265
1395
  backgroundColor: n,
1266
- backgroundCssColor: N(e.backgroundColor, A.backgroundCssColor),
1267
- gridColor: M(e.gridColor, A.gridColor, t),
1268
- axisColor: e.axisColor ?? A.axisColor,
1269
- axisFont: e.axisFont ?? A.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,
1270
1400
  seriesColors: r,
1271
- tooltipBackgroundColor: e.tooltipBackgroundColor ?? A.tooltipBackgroundColor,
1272
- tooltipTextColor: e.tooltipTextColor ?? A.tooltipTextColor,
1273
- tooltipFont: e.tooltipFont ?? A.tooltipFont,
1274
- legendBackgroundColor: e.legendBackgroundColor ?? A.legendBackgroundColor,
1275
- legendBorderColor: e.legendBorderColor ?? A.legendBorderColor,
1276
- legendTextColor: e.legendTextColor ?? A.legendTextColor,
1277
- legendMutedTextColor: e.legendMutedTextColor ?? A.legendMutedTextColor,
1278
- legendFont: e.legendFont ?? A.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
1279
1409
  };
1280
1410
  }
1281
- function M(e, t, n) {
1411
+ function I(e, t, n) {
1282
1412
  if (!e) return t;
1283
1413
  if (typeof e != "string") return e;
1284
- let r = F(e, n), i = L(r ?? e, n);
1285
- return I(r ?? e) ?? I(i ?? "") ?? t;
1414
+ let r = re(e, n), i = B(r ?? e, n);
1415
+ return z(r ?? e) ?? z(i ?? "") ?? t;
1286
1416
  }
1287
- function N(e, t) {
1288
- return e ? typeof e == "string" ? e : P(e) : t;
1417
+ function L(e, t) {
1418
+ return e ? typeof e == "string" ? e : R(e) : t;
1289
1419
  }
1290
- function P(e) {
1420
+ function R(e) {
1291
1421
  return `rgba(${Math.round(e[0] * 255)}, ${Math.round(e[1] * 255)}, ${Math.round(e[2] * 255)}, ${e[3]})`;
1292
1422
  }
1293
- function F(e, t) {
1423
+ function re(e, t) {
1294
1424
  let n = t?.ownerDocument ?? globalThis.document;
1295
1425
  if (!n?.documentElement || typeof getComputedStyle > "u") return null;
1296
1426
  let r = t instanceof HTMLElement ? t : n.documentElement, i = n.createElement("span");
@@ -1298,11 +1428,11 @@ function F(e, t) {
1298
1428
  let a = getComputedStyle(i).color;
1299
1429
  return i.remove(), a || null;
1300
1430
  }
1301
- function I(e) {
1431
+ function z(e) {
1302
1432
  let t = e.trim();
1303
- return R(t) ?? z(t) ?? B(t);
1433
+ return ie(t) ?? ae(t) ?? oe(t);
1304
1434
  }
1305
- function L(e, t) {
1435
+ function B(e, t) {
1306
1436
  let n = t?.ownerDocument ?? globalThis.document;
1307
1437
  if (!n?.createElement) return null;
1308
1438
  let r = n.createElement("canvas").getContext("2d");
@@ -1312,7 +1442,7 @@ function L(e, t) {
1312
1442
  let a = String(r.fillStyle);
1313
1443
  return a === i ? null : a;
1314
1444
  }
1315
- function R(e) {
1445
+ function ie(e) {
1316
1446
  let t = e.match(/^rgba?\((.*)\)$/i);
1317
1447
  if (!t) return null;
1318
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);
@@ -1325,7 +1455,7 @@ function R(e) {
1325
1455
  l
1326
1456
  ];
1327
1457
  }
1328
- function z(e) {
1458
+ function ae(e) {
1329
1459
  let t = e.match(/^color\(\s*srgb\s+(.+)\)$/i);
1330
1460
  if (!t) return null;
1331
1461
  let n = t[1].split("/").map((e) => e.trim()), r = n[0].split(/\s+/).filter(Boolean);
@@ -1338,7 +1468,7 @@ function z(e) {
1338
1468
  s
1339
1469
  ];
1340
1470
  }
1341
- function B(e) {
1471
+ function oe(e) {
1342
1472
  let t = e.startsWith("#") ? e.slice(1) : "";
1343
1473
  if (![
1344
1474
  3,
@@ -1368,7 +1498,7 @@ function W(e) {
1368
1498
  }
1369
1499
  //#endregion
1370
1500
  //#region src/ui/Chart.ts
1371
- var G = 16384, K = G >> 1, q = G >> 1, J = 3, Y = 4096, X = 12, Z = 64;
1501
+ var G = 16384, K = G >> 1, q = G >> 1, J = 3, Y = 4096, X = 12, se = 12, Z = 64;
1372
1502
  function Q(e) {
1373
1503
  return e === !1 ? {
1374
1504
  visible: !1,
@@ -1405,7 +1535,7 @@ function $(e) {
1405
1535
  y: Q(e.y)
1406
1536
  };
1407
1537
  }
1408
- var re = class {
1538
+ var ce = class {
1409
1539
  options;
1410
1540
  series = [];
1411
1541
  camera;
@@ -1445,6 +1575,7 @@ var re = class {
1445
1575
  lastPointerClientY = 0;
1446
1576
  pointerInPlot = !1;
1447
1577
  lastFrameAt = 0;
1578
+ currentXOrigin = 0;
1448
1579
  _rafId = 0;
1449
1580
  handlePointerMove = (e) => {
1450
1581
  this.pointerInPlot = !0, this.lastPointerClientX = e.clientX, this.lastPointerClientY = e.clientY, this.refreshHover();
@@ -1453,10 +1584,10 @@ var re = class {
1453
1584
  this.pointerInPlot = !1, this.emitHover(null);
1454
1585
  };
1455
1586
  constructor(e, t = {}) {
1456
- this.options = t, this.resolvedTheme = j(t.theme, e), this.normalizedAxes = $(t.axes), this._gridVisible = t.grid !== !1, this.layout = new k(e, this.normalizedAxes), this.layout.root.style.background = this.resolvedTheme.backgroundCssColor, this.applyCanvasSize(), this.camera = new E(), this.axis = new D(this.camera), this.renderer = new ee(new T(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 = {
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 = {
1457
1588
  color: t.gridStyle?.color ?? this.resolvedTheme.gridColor,
1458
1589
  lineWidth: t.gridStyle?.lineWidth ?? 1
1459
- }, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible) && (this.axisOverlay = new O(this.layout, this.normalizedAxes, {
1590
+ }, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible) && (this.axisOverlay = new N(this.layout, this.normalizedAxes, {
1460
1591
  color: this.resolvedTheme.axisColor,
1461
1592
  font: this.resolvedTheme.axisFont
1462
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));
@@ -1508,20 +1639,22 @@ var re = class {
1508
1639
  this.camera.zoom(e), this.refreshHover();
1509
1640
  }
1510
1641
  addSeries(e, t) {
1511
- 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, {
1512
- 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,
1513
1645
  lineWidth: t?.lineWidth ?? 1,
1514
1646
  pointSize: t?.pointSize ?? 4,
1515
1647
  barWidth: t?.barWidth ?? .8,
1516
1648
  baseline: t?.baseline ?? 0,
1517
1649
  fillColor: t?.fillColor ?? [
1518
- s[0],
1519
- s[1],
1520
- s[2],
1521
- s[3] * .25
1522
- ]
1650
+ a[0],
1651
+ a[1],
1652
+ a[2],
1653
+ a[3] * .25
1654
+ ],
1655
+ tickWidth: t?.tickWidth ?? t?.barWidth ?? .8
1523
1656
  });
1524
- return this.series.push(c), this.emitSeriesChange(), c;
1657
+ return this.series.push(s), this.emitSeriesChange(), s;
1525
1658
  }
1526
1659
  addLine(e, t) {
1527
1660
  return this.addSeries({
@@ -1547,6 +1680,12 @@ var re = class {
1547
1680
  mode: "bar"
1548
1681
  }, t);
1549
1682
  }
1683
+ addOhlc(e, t) {
1684
+ return this.addSeries({
1685
+ ...e,
1686
+ mode: "ohlc"
1687
+ }, t);
1688
+ }
1550
1689
  removeSeries(e) {
1551
1690
  let t = this.series.indexOf(e);
1552
1691
  return t === -1 ? !1 : (this.series.splice(t, 1), this.emitSeriesChange(), !0);
@@ -1598,7 +1737,7 @@ var re = class {
1598
1737
  return this.seriesSubscribers.add(n), () => this.seriesSubscribers.delete(n);
1599
1738
  }
1600
1739
  setTheme(e) {
1601
- this.resolvedTheme = j(e, this.layout.root), this.applyTheme(), this.emitThemeChange(), this.refreshHover();
1740
+ this.resolvedTheme = F(e, this.layout.root), this.applyTheme(), this.emitThemeChange(), this.refreshHover();
1602
1741
  }
1603
1742
  setGridVisible(e) {
1604
1743
  this._gridVisible = e;
@@ -1607,7 +1746,7 @@ var re = class {
1607
1746
  return this._gridVisible;
1608
1747
  }
1609
1748
  setAxes(e) {
1610
- 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 O(this.layout, this.normalizedAxes, {
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, {
1611
1750
  color: this.resolvedTheme.axisColor,
1612
1751
  font: this.resolvedTheme.axisFont
1613
1752
  })), this.resize(), this.refreshHover();
@@ -1636,7 +1775,7 @@ var re = class {
1636
1775
  o.width = i, o.height = a;
1637
1776
  let s = o.getContext("2d");
1638
1777
  if (!s) throw Error("Unable to create a 2D canvas context for screenshot export.");
1639
- return s.fillStyle = e.background ?? P(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) => {
1640
1779
  o.toBlob((e) => e ? t(e) : n(/* @__PURE__ */ Error("Unable to encode chart screenshot.")), e.type ?? "image/png", e.quality);
1641
1780
  });
1642
1781
  }
@@ -1655,34 +1794,11 @@ var re = class {
1655
1794
  let [t, n, r, i] = this.resolvedTheme.backgroundColor;
1656
1795
  this.renderer.viewport(0, 0, this.canvas.width, this.canvas.height), this.renderer.clear(t, n, r, i);
1657
1796
  let a = this.camera.viewport;
1658
- if (this._gridVisible) {
1797
+ if (this.currentXOrigin = a.xMin, this.renderer.setXOrigin(this.currentXOrigin), this._gridVisible) {
1659
1798
  let e = this.writeGridVertices(a);
1660
- 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);
1661
- }
1662
- for (let e of this.series) {
1663
- if (!e.visible) continue;
1664
- if (e.rebuildPyramid(), e.config.mode === "scatter") {
1665
- this.drawScatterSeries(e, a);
1666
- continue;
1667
- }
1668
- if (e.config.mode === "bar") {
1669
- this.drawBarSeries(e, a);
1670
- continue;
1671
- }
1672
- if (e.config.mode === "area") {
1673
- this.drawAreaSeries(e, a);
1674
- continue;
1675
- }
1676
- let t = e.visibleSampleCount(a), n = e.hasLOD && t > G;
1677
- if (n && this.renderer.supportsInstancedSegments) {
1678
- let t = e.copyMinMaxInstanced(a, this.minMaxInstanceData, this.maxMinMaxSegments());
1679
- if (t <= 0) continue;
1680
- 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;
1681
- continue;
1682
- }
1683
- let r = n ? e.copyMinMaxVisible(a, this.rawLineData, this.maxMinMaxSegments()) : e.copyRawVisible(a, this.rawLineData, G);
1684
- 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++);
1685
1800
  }
1801
+ for (let e of this.series) e.visible && (e.rebuildPyramid(), this.drawSeries(e, a));
1686
1802
  this.axisOverlay?.update(this.camera, this.axis), this.stats.frameMs = performance.now() - e, this.refreshHover();
1687
1803
  }
1688
1804
  dispose() {
@@ -1703,39 +1819,106 @@ var re = class {
1703
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));
1704
1820
  return this.canvas.width === n && this.canvas.height === r ? !1 : (this.canvas.width = n, this.canvas.height = r, !0);
1705
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
+ }
1706
1856
  drawAreaSeries(e, t) {
1707
- let n = e.style.baseline ?? 0, r = e.copyAreaVisible(t, this.rawLineData, K, n);
1708
- if (r < 4) return;
1709
- 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;
1710
- let i = this.uploadRawInstances(e, t, K);
1711
- 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
+ }
1712
1879
  }
1713
1880
  drawScatterSeries(e, t) {
1714
- let n = this.uploadRawInstances(e, t, G);
1715
- 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
+ }
1716
1887
  }
1717
1888
  drawBarSeries(e, t) {
1718
1889
  let n = e.visibleSampleCount(t), r = this.maxRawBarInstances();
1719
1890
  if (e.hasLOD && n > r) {
1720
- let n = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxBarFallbackBars());
1891
+ let n = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxBarTriangleBars(), this.currentXOrigin);
1721
1892
  if (n <= 0) return;
1722
1893
  this.includeBaselineInBarRanges(n, e.style.baseline ?? 0);
1723
1894
  let r = this.writeBarBucketTriangles(n, t);
1724
- this.drawBarTriangleFallback(r, e.style);
1895
+ this.drawBarTriangles(r, e.style);
1725
1896
  return;
1726
1897
  }
1727
- let i = this.uploadRawInstances(e, t, r);
1728
- 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;
1729
1900
  if (this.renderer.supportsInstancedBars) {
1730
- 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);
1731
1902
  return;
1732
1903
  }
1733
- let a = this.writeBarTriangles(i, e.style.baseline ?? 0, e.style.barWidth ?? .8);
1734
- 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);
1735
1912
  }
1736
- uploadRawInstances(e, t, n) {
1737
- let r = e.copyRawVisible(t, this.rawLineData, n);
1738
- 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;
1739
1922
  }
1740
1923
  includeBaselineInBarRanges(e, t) {
1741
1924
  for (let n = 0; n < e; n++) {
@@ -1744,7 +1927,7 @@ var re = class {
1744
1927
  }
1745
1928
  }
1746
1929
  writeBarTriangles(e, t, n) {
1747
- let r = Math.min(e, this.maxBarFallbackBars());
1930
+ let r = Math.min(e, this.maxBarTriangleBars());
1748
1931
  for (let e = 0; e < r; e++) {
1749
1932
  let r = this.rawLineData[e * 2], i = this.rawLineData[e * 2 + 1];
1750
1933
  this.writeBarTriangle(e, r - n * .5, r + n * .5, t, i);
@@ -1752,7 +1935,7 @@ var re = class {
1752
1935
  return r * 6;
1753
1936
  }
1754
1937
  writeBarBucketTriangles(e, t) {
1755
- let n = Math.min(e, this.maxBarFallbackBars());
1938
+ let n = Math.min(e, this.maxBarTriangleBars());
1756
1939
  for (let e = 0; e < n; e++) {
1757
1940
  let r = this.minMaxInstanceData[e * 3 + 1], i = this.minMaxInstanceData[e * 3 + 2], [a, o] = this.barBucketBounds(e, n, t);
1758
1941
  this.writeBarTriangle(e, a, o, r, i);
@@ -1760,27 +1943,27 @@ var re = class {
1760
1943
  return n * 6;
1761
1944
  }
1762
1945
  barBucketBounds(e, t, n) {
1763
- 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;
1764
1947
  if (t <= 1) {
1765
- let e = Math.max(0, i * .5);
1766
- 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)];
1767
1950
  }
1768
- 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;
1769
- if (!Number.isFinite(s) || !Number.isFinite(c) || c <= s) {
1770
- let r = i / Math.max(1, t);
1771
- 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;
1772
1955
  }
1773
- return [Math.max(n.xMin, s), Math.min(n.xMax, c)];
1956
+ return [Math.max(i, l), Math.min(a, u)];
1774
1957
  }
1775
1958
  writeBarTriangle(e, t, n, r, i) {
1776
1959
  let a = e * X;
1777
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;
1778
1961
  }
1779
- drawBarTriangleFallback(e, t) {
1780
- 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));
1781
1964
  }
1782
- recordInstancedDraw(e, t) {
1783
- 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;
1784
1967
  }
1785
1968
  findNearestXAnchor(e, t, n, r) {
1786
1969
  let i = null, a = Infinity, o = n / (t.xMax - t.xMin);
@@ -1854,11 +2037,11 @@ var re = class {
1854
2037
  maxMinMaxSegments() {
1855
2038
  return Math.min(this.canvas.width, q);
1856
2039
  }
1857
- maxBarFallbackBars() {
2040
+ maxBarTriangleBars() {
1858
2041
  return Math.min(Y, G);
1859
2042
  }
1860
2043
  maxRawBarInstances() {
1861
- return this.renderer.supportsInstancedBars ? G : this.maxBarFallbackBars();
2044
+ return this.renderer.supportsInstancedBars ? G : this.maxBarTriangleBars();
1862
2045
  }
1863
2046
  writeGridVertices(e) {
1864
2047
  let t = Math.max(1, this.canvas.clientWidth), n = Math.max(1, this.canvas.clientHeight);
@@ -1866,18 +2049,24 @@ var re = class {
1866
2049
  let r = 0;
1867
2050
  for (let t of this.xTicks) {
1868
2051
  if (r + 2 > Z) return r;
1869
- 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++;
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++;
1870
2053
  }
1871
2054
  for (let t of this.yTicks) {
1872
2055
  if (r + 2 > Z) return r;
1873
- 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++;
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++;
1874
2057
  }
1875
2058
  return r;
1876
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
+ }
1877
2066
  recordRenderMode(e) {
1878
2067
  this.stats.renderMode === "none" ? this.stats.renderMode = e : this.stats.renderMode !== e && (this.stats.renderMode = "mixed");
1879
2068
  }
1880
- }, ie = class {
2069
+ }, le = class {
1881
2070
  xData;
1882
2071
  yData;
1883
2072
  constructor(e, t) {
@@ -1899,26 +2088,135 @@ var re = class {
1899
2088
  return this.assertValidIndex(e), this.yData[e];
1900
2089
  }
1901
2090
  lowerBoundX(e) {
1902
- let t = 0, n = this.length;
1903
- for (; t < n;) {
1904
- let r = t + (n - t >> 1);
1905
- this.xData[r] < e ? t = r + 1 : n = r;
1906
- }
1907
- return t;
2091
+ return s(this.length, (e) => this.xData[e], e);
1908
2092
  }
1909
2093
  upperBoundX(e) {
1910
- let t = 0, n = this.length;
1911
- for (; t < n;) {
1912
- let r = t + (n - t >> 1);
1913
- this.xData[r] <= e ? t = r + 1 : n = r;
1914
- }
1915
- return t;
2094
+ return c(this.length, (e) => this.xData[e], e);
1916
2095
  }
1917
2096
  assertValidIndex(e) {
1918
2097
  if (!Number.isInteger(e) || e < 0 || e >= this.length) throw RangeError(`StaticDataset index out of range: ${e}`);
1919
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
+ }
1920
2218
  };
1921
2219
  //#endregion
1922
- export { D as AxisController, E as Camera2D, re as Chart, A as DEFAULT_CHART_THEME, n as MinMaxPyramid, a as RingBuffer, i as SeriesStore, ie 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 };
1923
2221
 
1924
2222
  //# sourceMappingURL=index.js.map