blazeplot 0.2.0 → 0.2.1

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
@@ -152,12 +152,22 @@ function r(e) {
152
152
  function i(e) {
153
153
  return "getOpen" in e && "getHigh" in e && "getLow" in e && "getClose" in e;
154
154
  }
155
- function a(e, t, n, r, i) {
155
+ function a(e) {
156
+ return "copySamplesRange" in e;
157
+ }
158
+ function o(e) {
159
+ return "copyMinMaxSegments" in e;
160
+ }
161
+ function s(e) {
162
+ return "copyVisibleSamples" in e;
163
+ }
164
+ var c = 64;
165
+ function l(e, t, n, r, i) {
156
166
  if (n === e) return t;
157
167
  let a = (i - e) / (n - e);
158
168
  return t + (r - t) * a;
159
169
  }
160
- var o = class {
170
+ var u = class {
161
171
  config;
162
172
  style;
163
173
  dataset;
@@ -237,19 +247,51 @@ var o = class {
237
247
  }
238
248
  return this.sampleAt(i);
239
249
  }
240
- nearestSampleByPoint(e, t, n, r, i) {
241
- let a = this.visibleIndexRange(n);
242
- if (a.start >= a.end || r <= 0 || i <= 0) return null;
243
- let o = r / (n.xMax - n.xMin), s = i / (n.yMax - n.yMin), c = -1, l = Infinity;
244
- for (let n = a.start; n < a.end; n++) {
245
- let r = (this.dataset.getX(n) - e) * o, i = (this.dataset.getY(n) - t) * s, a = r * r + i * i;
246
- a < l && (l = a, c = n);
247
- }
248
- if (c < 0) return null;
249
- let u = this.sampleAt(c);
250
- return u ? {
251
- ...u,
252
- distancePx: Math.sqrt(l)
250
+ nearestSampleByPoint(e, t, n, r, i, a = Infinity) {
251
+ let o = this.visibleIndexRange(n), s = n.xMax - n.xMin, l = n.yMax - n.yMin;
252
+ if (o.start >= o.end || r <= 0 || i <= 0 || s <= 0 || l <= 0) return null;
253
+ let u = r / s, d = i / l, f = -1, p = a < 0 ? -1 : Number.isFinite(a) ? a * a : Infinity, m = (n) => {
254
+ let r = (this.dataset.getX(n) - e) * u, i = (this.dataset.getY(n) - t) * d, a = r * r + i * i;
255
+ (a < p || f < 0 && a <= p) && (p = a, f = n);
256
+ }, h = this.dataset.lowerBoundX(e), g = Math.min(Math.max(h, o.start), o.end - 1);
257
+ if (m(g), g > o.start && m(g - 1), g + 1 < o.end && m(g + 1), this.hasPointIntervalBounds() && o.end - o.start > c) {
258
+ let n = this.pointIntervalDistanceSq(o.start, o.end, e, t, u, d), r = n <= p ? [{
259
+ start: o.start,
260
+ end: o.end,
261
+ lowerBoundSq: n
262
+ }] : [];
263
+ for (; r.length > 0;) {
264
+ let n = r.pop();
265
+ if (n.lowerBoundSq > p) continue;
266
+ let i = n.end - n.start;
267
+ if (i <= c) {
268
+ for (let e = n.start; e < n.end; e++) m(e);
269
+ continue;
270
+ }
271
+ let a = n.start + (i >> 1), o = this.pointIntervalDistanceSq(n.start, a, e, t, u, d), s = this.pointIntervalDistanceSq(a, n.end, e, t, u, d), l = {
272
+ start: n.start,
273
+ end: a,
274
+ lowerBoundSq: o
275
+ }, f = {
276
+ start: a,
277
+ end: n.end,
278
+ lowerBoundSq: s
279
+ };
280
+ o < s ? (s <= p && r.push(f), o <= p && r.push(l)) : (o <= p && r.push(l), s <= p && r.push(f));
281
+ }
282
+ } else {
283
+ let t = Math.min(h - 1, o.end - 1), n = Math.max(h, o.start);
284
+ for (; t >= o.start || n < o.end;) {
285
+ let r = t >= o.start ? this.pointXDistanceSq(t, e, u) : Infinity, i = n < o.end ? this.pointXDistanceSq(n, e, u) : Infinity;
286
+ if (r > p && i > p) break;
287
+ r <= i ? (r <= p && m(t), t--) : (i <= p && m(n), n++);
288
+ }
289
+ }
290
+ if (f < 0) return null;
291
+ let _ = this.sampleAt(f);
292
+ return _ ? {
293
+ ..._,
294
+ distancePx: Math.sqrt(p)
253
295
  } : null;
254
296
  }
255
297
  copyRawVisible(e, t, n, r = 0) {
@@ -285,6 +327,15 @@ var o = class {
285
327
  }
286
328
  return l;
287
329
  }
330
+ copyOhlcTuplesRange(e, t, n, r, a = 0) {
331
+ if (!i(this.dataset) || r <= 0 || n.length < r * 5) return 0;
332
+ let o = Math.max(0, Math.floor(e)), s = Math.min(this.dataset.length, Math.ceil(t)), c = Math.min(r, Math.max(0, s - o));
333
+ for (let e = 0; e < c; e++) {
334
+ let t = o + e, r = e * 5;
335
+ n[r] = this.dataset.getX(t) - a, n[r + 1] = this.dataset.getOpen(t), n[r + 2] = this.dataset.getHigh(t), n[r + 3] = this.dataset.getLow(t), n[r + 4] = this.dataset.getClose(t);
336
+ }
337
+ return c;
338
+ }
288
339
  visibleIndexRange(e, t = 0) {
289
340
  if (!e) return {
290
341
  start: 0,
@@ -296,78 +347,98 @@ var o = class {
296
347
  end: Math.min(this.dataset.length, this.dataset.upperBoundX(e.xMax) + n)
297
348
  };
298
349
  }
350
+ pointXDistanceSq(e, t, n) {
351
+ let r = (this.dataset.getX(e) - t) * n;
352
+ return r * r;
353
+ }
354
+ pointIntervalDistanceSq(e, t, n, r, i, a) {
355
+ if (t <= e) return Infinity;
356
+ let o = this.dataset.getX(e), s = this.dataset.getX(t - 1), c = n < o ? (o - n) * i : n > s ? (n - s) * i : 0, l = this.pointIntervalMinMaxY(e, t);
357
+ if (!l) return Infinity;
358
+ let u = r < l.minY ? (l.minY - r) * a : r > l.maxY ? (r - l.maxY) * a : 0;
359
+ return c * c + u * u;
360
+ }
361
+ hasPointIntervalBounds() {
362
+ return r(this.dataset) || this.pyramid !== null && !this._dirty && !this._useRawMinMaxScan;
363
+ }
364
+ pointIntervalMinMaxY(e, t) {
365
+ return r(this.dataset) ? this.dataset.rangeMinMaxY(e, t) : this.pyramid && !this._dirty && !this._useRawMinMaxScan ? this.pyramid.rangeMinMax(this.dataset, e, t) : null;
366
+ }
299
367
  copyClippedVisibleLine(e, t, n, r, i) {
300
368
  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;
369
+ let a = e.xMax - e.xMin, o = e.yMax - e.yMin;
370
+ if (i === "clip" && (a <= 0 || o <= 0)) return 0;
371
+ let s = Math.max(0, this.dataset.lowerBoundX(e.xMin) - 1), c = Math.min(this.dataset.length, this.dataset.upperBoundX(e.xMax) + 1);
372
+ if (c - s <= 0) return 0;
373
+ let u = 0, d = NaN, f = NaN, p = (s, c) => {
374
+ let l = i === "clip" ? (s - e.xMin) / a * 2 - 1 : s - r, p = i === "clip" ? (c - e.yMin) / o * 2 - 1 : c;
307
375
  if (u > 0 && l === d && p === f) return !0;
308
376
  if (u >= n) return !1;
309
377
  let m = u * 2;
310
378
  return t[m] = l, t[m + 1] = p, u++, d = l, f = p, !0;
311
379
  };
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;
380
+ if (c - s === 1) {
381
+ let t = this.dataset.getX(s);
382
+ return t < e.xMin || t > e.xMax ? 0 : p(t, this.dataset.getY(s)) ? u : 0;
315
383
  }
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);
384
+ for (let t = s; t + 1 < c; t++) {
385
+ let n = this.dataset.getX(t), r = this.dataset.getY(t), i = this.dataset.getX(t + 1), a = this.dataset.getY(t + 1);
318
386
  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;
387
+ let o = Math.max(n, e.xMin), s = Math.min(i, e.xMax);
388
+ if (s < o) continue;
389
+ let c = l(n, r, i, a, o), u = l(n, r, i, a, s);
390
+ if (!p(o, c) || !p(s, u)) break;
323
391
  }
324
392
  return u;
325
393
  }
326
394
  copyVisibleSamples(e, t, n, r, i, a) {
395
+ if (s(this.dataset)) return this.dataset.copyVisibleSamples(e, t, n, r, i, a);
327
396
  let o = r === "points" ? 2 : 4;
328
397
  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) {
398
+ let c = this.dataset.lowerBoundX(e.xMin), l = this.dataset.upperBoundX(e.xMax), u = l - c;
399
+ if (u <= 0) return 0;
400
+ let d = Math.max(1, Math.ceil(u / n)), f = 0;
401
+ for (let e = c; e < l && f < n; e += d) {
333
402
  let n = this.dataset.getX(e) - a, o = this.dataset.getY(e);
334
403
  if (r === "points") {
335
- let e = d * 2;
404
+ let e = f * 2;
336
405
  t[e] = n, t[e + 1] = o;
337
406
  } else {
338
- let e = d * 4;
407
+ let e = f * 4;
339
408
  t[e] = n, t[e + 1] = i, t[e + 2] = n, t[e + 3] = o;
340
409
  }
341
- d++;
410
+ f++;
342
411
  }
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);
412
+ return f;
413
+ }
414
+ copySampleRange(e, t, n, r, i, o, s) {
415
+ if (a(this.dataset)) return this.dataset.copySamplesRange(e, t, n, r, i, o, s);
416
+ let c = i === "points" ? 2 : 4;
417
+ if (r <= 0 || n.length < r * c) return 0;
418
+ let l = Math.max(0, Math.floor(e)), u = Math.min(this.dataset.length, Math.ceil(t)), d = Math.min(r, Math.max(0, u - l));
419
+ for (let e = 0; e < d; e++) {
420
+ let t = l + e, r = this.dataset.getX(t) - s, a = this.dataset.getY(t);
351
421
  if (i === "points") {
352
422
  let t = e * 2;
353
- n[t] = r, n[t + 1] = s;
423
+ n[t] = r, n[t + 1] = a;
354
424
  } else {
355
425
  let t = e * 4;
356
- n[t] = r, n[t + 1] = a, n[t + 2] = r, n[t + 3] = s;
426
+ n[t] = r, n[t + 1] = o, n[t + 2] = r, n[t + 3] = a;
357
427
  }
358
428
  }
359
- return u;
429
+ return d;
360
430
  }
361
431
  copyMinMaxSegments(e, t, n, r, i) {
432
+ if (o(this.dataset)) return this.dataset.copyMinMaxSegments(e, t, n, r, i);
362
433
  let a = r === "line-list" ? 4 : 3;
363
434
  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);
435
+ let s = this.dataset.lowerBoundX(e.xMin), c = this.dataset.upperBoundX(e.xMax), l = c - s;
436
+ if (l <= 0) return 0;
437
+ let u = Math.min(n, l);
438
+ for (let e = 0; e < u; e++) {
439
+ let n = s + Math.floor(e * l / u), a = s + Math.max(Math.floor((e + 1) * l / u), Math.floor(e * l / u) + 1), o = Math.min(c, a), d = this.minMaxForRange(n, o);
369
440
  if (!d) continue;
370
- let f = this.dataset.getX(n + (u - n >> 1)) - i, { minY: p, maxY: m } = d;
441
+ let f = this.dataset.getX(n + (o - n >> 1)) - i, { minY: p, maxY: m } = d;
371
442
  if (r === "line-list") {
372
443
  let n = e * 4;
373
444
  t[n] = f, t[n + 1] = p, t[n + 2] = f, t[n + 3] = m;
@@ -376,7 +447,7 @@ var o = class {
376
447
  t[n] = f, t[n + 1] = p, t[n + 2] = m;
377
448
  }
378
449
  }
379
- return l;
450
+ return u;
380
451
  }
381
452
  minMaxForRange(e, t) {
382
453
  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);
@@ -417,7 +488,7 @@ var o = class {
417
488
  };
418
489
  //#endregion
419
490
  //#region src/core/search.ts
420
- function s(e, t, n) {
491
+ function d(e, t, n) {
421
492
  let r = 0, i = e;
422
493
  for (; r < i;) {
423
494
  let e = r + (i - r >> 1);
@@ -425,7 +496,7 @@ function s(e, t, n) {
425
496
  }
426
497
  return r;
427
498
  }
428
- function c(e, t, n) {
499
+ function f(e, t, n) {
429
500
  let r = 0, i = e;
430
501
  for (; r < i;) {
431
502
  let e = r + (i - r >> 1);
@@ -435,7 +506,7 @@ function c(e, t, n) {
435
506
  }
436
507
  //#endregion
437
508
  //#region src/core/RingBuffer.ts
438
- var l = class e {
509
+ var p = class e {
439
510
  capacity;
440
511
  _length = 0;
441
512
  _head = 0;
@@ -497,10 +568,10 @@ var l = class e {
497
568
  return this.assertValidIndex(e), this.yData[this.logicalToPhysical(e)];
498
569
  }
499
570
  lowerBoundX(e) {
500
- return s(this._length, (e) => this.getX(e), e);
571
+ return d(this._length, (e) => this.getX(e), e);
501
572
  }
502
573
  upperBoundX(e) {
503
- return c(this._length, (e) => this.getX(e), e);
574
+ return f(this._length, (e) => this.getX(e), e);
504
575
  }
505
576
  rangeMinMaxY(e, t) {
506
577
  let n = Math.max(0, Math.floor(e)), r = Math.min(this._length, Math.ceil(t));
@@ -577,32 +648,32 @@ var l = class e {
577
648
  static nextPowerOfTwo(e) {
578
649
  return 2 ** Math.ceil(Math.log2(e));
579
650
  }
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 = {
651
+ }, m = "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", h = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", g = "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", _ = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", v = "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", y = "precision mediump float;\n\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n", ee = "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", te = "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", ne = "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", re = "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 = {
581
652
  line: {
582
- vert: u,
583
- frag: d
653
+ vert: m,
654
+ frag: h
584
655
  },
585
656
  segment: {
586
- vert: f,
587
- frag: p
657
+ vert: g,
658
+ frag: _
588
659
  },
589
660
  point: {
590
- vert: m,
591
- frag: h
661
+ vert: v,
662
+ frag: y
592
663
  },
593
664
  pointSprite: {
594
- vert: g,
595
- frag: _
665
+ vert: ee,
666
+ frag: te
596
667
  },
597
668
  bar: {
598
- vert: v,
669
+ vert: ne,
599
670
  frag: b
600
671
  },
601
672
  barRange: {
602
- vert: y,
673
+ vert: re,
603
674
  frag: b
604
675
  }
605
- }, S = 3, C = 2, w = 4, T = 4, E = .8, ee = 0, te = class {
676
+ }, S = 3, C = 2, w = 4, T = 4, E = .8, D = 0, O = class {
606
677
  backend;
607
678
  lineProgram;
608
679
  segmentProgram;
@@ -826,7 +897,7 @@ var l = class e {
826
897
  uScale: this.scaleUniform,
827
898
  uOffset: this.offsetUniform,
828
899
  uBarWidth: n.barWidth ?? E,
829
- uBaseline: n.baseline ?? ee,
900
+ uBaseline: n.baseline ?? D,
830
901
  uColor: n.color
831
902
  }
832
903
  });
@@ -923,13 +994,13 @@ var l = class e {
923
994
  dispose() {
924
995
  this.backend.destroy();
925
996
  }
926
- }, D = [
997
+ }, k = [
927
998
  1024,
928
999
  4096,
929
1000
  16384,
930
1001
  32768,
931
1002
  131072
932
- ], O = class {
1003
+ ], ie = class {
933
1004
  regl;
934
1005
  pool = [];
935
1006
  preAllocated = !1;
@@ -942,7 +1013,7 @@ var l = class e {
942
1013
  preAllocate() {
943
1014
  if (!this.preAllocated) {
944
1015
  this.preAllocated = !0;
945
- for (let e of D) this.pool.push(this.createEntry(e, "stream"));
1016
+ for (let e of k) this.pool.push(this.createEntry(e, "stream"));
946
1017
  }
947
1018
  }
948
1019
  acquire(e, t = "stream") {
@@ -982,17 +1053,17 @@ var l = class e {
982
1053
  return this.pool.find((t) => !t.inUse && t.floatCapacity >= e);
983
1054
  }
984
1055
  roundUp(e) {
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);
1056
+ for (let t of k) if (t >= e) return t;
1057
+ let t = k[k.length - 1], n = 1 << 32 - Math.clz32(e - 1);
987
1058
  return Math.max(t * 2, n);
988
1059
  }
989
1060
  };
990
1061
  //#endregion
991
1062
  //#region src/render/ReglBackend.ts
992
- function k(e) {
1063
+ function ae(e) {
993
1064
  return e;
994
1065
  }
995
- var A = class {
1066
+ var oe = class {
996
1067
  gl;
997
1068
  regl;
998
1069
  resources;
@@ -1012,10 +1083,10 @@ var A = class {
1012
1083
  });
1013
1084
  if (!n) throw Error("BlazePlot requires WebGL2, but this browser/context does not support it.");
1014
1085
  this.gl = n, this.regl = e({
1015
- gl: k(this.gl),
1086
+ gl: ae(this.gl),
1016
1087
  extensions: [],
1017
1088
  optionalExtensions: ["angle_instanced_arrays", "ext_disjoint_timer_query_webgl2"]
1018
- }), this.capabilities = { instancing: this.regl.hasExtension("angle_instanced_arrays") }, this.resources = new O(this.regl), this.resources.preAllocate();
1089
+ }), this.capabilities = { instancing: this.regl.hasExtension("angle_instanced_arrays") }, this.resources = new ie(this.regl), this.resources.preAllocate();
1019
1090
  }
1020
1091
  createBuffer(e) {
1021
1092
  let { buffer: t } = this.resources.acquire(e.length, e.usage);
@@ -1134,7 +1205,7 @@ var A = class {
1134
1205
  default: return e;
1135
1206
  }
1136
1207
  }
1137
- }, j = class e {
1208
+ }, A = class e {
1138
1209
  _xMin = 0;
1139
1210
  _xMax = 1;
1140
1211
  _yMin = 0;
@@ -1219,7 +1290,7 @@ var A = class {
1219
1290
  static assertFinite(e, t) {
1220
1291
  if (!Number.isFinite(t)) throw RangeError(`Camera2D ${e} must be finite.`);
1221
1292
  }
1222
- }, M = class {
1293
+ }, j = class {
1223
1294
  camera;
1224
1295
  constructor(e) {
1225
1296
  this.camera = e;
@@ -1251,33 +1322,39 @@ var A = class {
1251
1322
  let n = Math.max(0, -Math.floor(Math.log10(t)) + 2), r = Number(e.toFixed(n));
1252
1323
  return Object.is(r, -0) ? 0 : r;
1253
1324
  }
1254
- }, N = class {
1325
+ }, M = class {
1255
1326
  layout;
1256
1327
  config;
1257
1328
  options;
1258
1329
  xPool = [];
1259
1330
  yPool = [];
1331
+ y2Pool = [];
1260
1332
  xTicks = [];
1261
1333
  yTicks = [];
1334
+ y2Ticks = [];
1262
1335
  constructor(e, t, n = {}) {
1263
1336
  this.layout = e, this.config = t, this.options = n;
1264
1337
  }
1265
1338
  setOptions(e) {
1266
1339
  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";
1340
+ for (let e of [
1341
+ ...this.xPool,
1342
+ ...this.yPool,
1343
+ ...this.y2Pool
1344
+ ]) e.style.font = this.options.font ?? "11px ui-monospace, monospace, sans-serif", e.style.color = this.options.color ?? "#bfd6ff";
1269
1345
  }
1270
- update(e, t) {
1271
- let n = Math.max(1, this.layout.plot.clientWidth), r = Math.max(1, this.layout.plot.clientHeight);
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);
1346
+ update(e, t, n = e, r = t) {
1347
+ let i = Math.max(1, this.layout.plot.clientWidth), a = Math.max(1, this.layout.plot.clientHeight);
1348
+ this.config.x.visible ? t.getXTickValues(i, 12, this.xTicks) : this.xTicks.length = 0, this.config.y.visible ? t.getYTickValues(a, 8, this.yTicks) : this.yTicks.length = 0, this.config.y2.visible ? r.getYTickValues(a, 8, this.y2Ticks) : this.y2Ticks.length = 0, this.updateAxis(this.xPool, this.xTicks, "x", e, i, a, t), this.updateAxis(this.yPool, this.yTicks, "y", e, i, a, t), this.updateAxis(this.y2Pool, this.y2Ticks, "y2", n, i, a, r);
1273
1349
  }
1274
1350
  dispose() {
1275
1351
  for (let e of this.xPool) e.remove();
1276
1352
  for (let e of this.yPool) e.remove();
1277
- this.xPool = [], this.yPool = [];
1353
+ for (let e of this.y2Pool) e.remove();
1354
+ this.xPool = [], this.yPool = [], this.y2Pool = [];
1278
1355
  }
1279
1356
  parentForAxis(e) {
1280
- return e === "x" ? this.config.x.position === "outside" ? this.layout.xAxis : this.layout.plot : this.config.y.position === "outside" ? this.layout.yAxis : this.layout.plot;
1357
+ return e === "x" ? this.config.x.position === "outside" ? this.layout.xAxis : this.layout.plot : e === "y2" ? this.config.y2.position === "outside" ? this.layout.y2Axis : this.layout.plot : this.config.y.position === "outside" ? this.layout.yAxis : this.layout.plot;
1281
1358
  }
1282
1359
  updateAxis(e, t, n, r, i, a, o) {
1283
1360
  let s = this.parentForAxis(n);
@@ -1293,39 +1370,41 @@ var A = class {
1293
1370
  let [e] = r.toClip(l, r.yMin), t = (e + 1) * .5 * i;
1294
1371
  c.style.left = `${t}px`, c.style.right = "auto", c.style.transform = "translateX(-50%)", this.config.x.position === "outside" ? (c.style.top = "4px", c.style.bottom = "auto") : (c.style.top = "auto", c.style.bottom = "4px");
1295
1372
  } else {
1296
- let [, e] = r.toClip(r.xMin, l), t = (1 - e) * .5 * a;
1297
- c.style.top = `${t}px`, c.style.bottom = "auto", c.style.transform = "translateY(-50%)", this.config.y.position === "outside" ? (c.style.left = "auto", c.style.right = "4px") : (c.style.left = "4px", c.style.right = "auto");
1373
+ let e = n === "y2", t = e ? this.config.y2 : this.config.y, [, i] = r.toClip(r.xMin, l), o = (1 - i) * .5 * a;
1374
+ c.style.top = `${o}px`, c.style.bottom = "auto", c.style.transform = "translateY(-50%)", t.position === "outside" ? (c.style.left = e ? "4px" : "auto", c.style.right = e ? "auto" : "4px") : (c.style.left = e ? "auto" : "4px", c.style.right = e ? "4px" : "auto");
1298
1375
  }
1299
1376
  }
1300
1377
  }
1301
- }, ne = class {
1378
+ }, se = class {
1302
1379
  root;
1303
1380
  plot;
1304
1381
  canvas;
1305
1382
  xAxis;
1306
1383
  yAxis;
1384
+ y2Axis;
1307
1385
  corner;
1386
+ cornerRight;
1308
1387
  externalCanvas;
1309
1388
  originalCanvasCssText;
1310
1389
  originalCanvasParent;
1311
1390
  constructor(e, t) {
1312
1391
  let n = e instanceof HTMLCanvasElement ? e : null;
1313
- this.externalCanvas = n !== null, this.originalCanvasCssText = n?.style.cssText ?? "", this.originalCanvasParent = n?.parentElement ?? null, this.root = document.createElement("div"), this.plot = document.createElement("div"), this.canvas = n ?? document.createElement("canvas"), this.xAxis = document.createElement("div"), this.yAxis = document.createElement("div"), this.corner = document.createElement("div"), this.root.className = "blazeplot-root", this.plot.className = "blazeplot-plot", this.canvas.classList.add("blazeplot-canvas"), this.xAxis.className = "blazeplot-axis blazeplot-axis-x", this.yAxis.className = "blazeplot-axis blazeplot-axis-y", this.corner.className = "blazeplot-axis-corner", this.applyBaseStyles(), this.mount(e), this.update(t);
1392
+ this.externalCanvas = n !== null, this.originalCanvasCssText = n?.style.cssText ?? "", this.originalCanvasParent = n?.parentElement ?? null, this.root = document.createElement("div"), this.plot = document.createElement("div"), this.canvas = n ?? document.createElement("canvas"), this.xAxis = document.createElement("div"), this.yAxis = document.createElement("div"), this.y2Axis = document.createElement("div"), this.corner = document.createElement("div"), this.cornerRight = document.createElement("div"), this.root.className = "blazeplot-root", this.plot.className = "blazeplot-plot", this.canvas.classList.add("blazeplot-canvas"), this.xAxis.className = "blazeplot-axis blazeplot-axis-x", this.yAxis.className = "blazeplot-axis blazeplot-axis-y", this.y2Axis.className = "blazeplot-axis blazeplot-axis-y2", this.corner.className = "blazeplot-axis-corner", this.cornerRight.className = "blazeplot-axis-corner blazeplot-axis-corner-right", this.applyBaseStyles(), this.mount(e), this.update(t);
1314
1393
  }
1315
1394
  update(e) {
1316
- let t = e.y.visible && e.y.position === "outside", n = e.x.visible && e.x.position === "outside";
1317
- this.root.style.gridTemplateColumns = `${t ? 52 : 0}px minmax(0, 1fr)`, this.root.style.gridTemplateRows = `minmax(0, 1fr) ${n ? 28 : 0}px`, this.yAxis.style.display = t ? "block" : "none", this.xAxis.style.display = n ? "block" : "none", this.corner.style.display = n && t ? "block" : "none";
1395
+ let t = e.y.visible && e.y.position === "outside", n = e.y2.visible && e.y2.position === "outside", r = e.x.visible && e.x.position === "outside";
1396
+ this.root.style.gridTemplateColumns = `${t ? 52 : 0}px minmax(0, 1fr) ${n ? 52 : 0}px`, this.root.style.gridTemplateRows = `minmax(0, 1fr) ${r ? 28 : 0}px`, this.yAxis.style.display = t ? "block" : "none", this.y2Axis.style.display = n ? "block" : "none", this.xAxis.style.display = r ? "block" : "none", this.corner.style.display = r && t ? "block" : "none", this.cornerRight.style.display = r && n ? "block" : "none";
1318
1397
  }
1319
1398
  dispose() {
1320
1399
  this.externalCanvas && this.originalCanvasParent && (this.canvas.style.cssText = this.originalCanvasCssText, this.originalCanvasParent.insertBefore(this.canvas, this.root)), this.root.remove();
1321
1400
  }
1322
1401
  mount(e) {
1323
- this.externalCanvas ? this.originalCanvasParent?.insertBefore(this.root, e) : e.appendChild(this.root), this.root.appendChild(this.yAxis), this.root.appendChild(this.plot), this.root.appendChild(this.corner), this.root.appendChild(this.xAxis), this.plot.appendChild(this.canvas);
1402
+ this.externalCanvas ? this.originalCanvasParent?.insertBefore(this.root, e) : e.appendChild(this.root), this.root.appendChild(this.yAxis), this.root.appendChild(this.plot), this.root.appendChild(this.y2Axis), this.root.appendChild(this.corner), this.root.appendChild(this.xAxis), this.root.appendChild(this.cornerRight), this.plot.appendChild(this.canvas);
1324
1403
  }
1325
1404
  applyBaseStyles() {
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";
1405
+ 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.y2Axis.style.position = "relative", this.y2Axis.style.gridColumn = "3", this.y2Axis.style.gridRow = "1", this.y2Axis.style.minWidth = "0", this.y2Axis.style.minHeight = "0", this.y2Axis.style.overflow = "hidden", this.y2Axis.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", this.cornerRight.style.gridColumn = "3", this.cornerRight.style.gridRow = "2", this.cornerRight.style.minWidth = "0", this.cornerRight.style.minHeight = "0", this.cornerRight.style.pointerEvents = "none";
1327
1406
  }
1328
- }, P = {
1407
+ }, N = {
1329
1408
  backgroundColor: [
1330
1409
  .08,
1331
1410
  .1,
@@ -1388,39 +1467,39 @@ var A = class {
1388
1467
  legendMutedTextColor: "#789",
1389
1468
  legendFont: "11px/1.35 ui-monospace, monospace"
1390
1469
  };
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;
1470
+ function P(e, t) {
1471
+ if (!e) return N;
1472
+ let n = F(e.backgroundColor, N.backgroundColor, t), r = e.seriesColors?.length ? e.seriesColors.map((e, n) => F(e, N.seriesColors[n % N.seriesColors.length], t)) : N.seriesColors;
1394
1473
  return {
1395
1474
  backgroundColor: n,
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,
1475
+ backgroundCssColor: ce(e.backgroundColor, N.backgroundCssColor),
1476
+ gridColor: F(e.gridColor, N.gridColor, t),
1477
+ axisColor: e.axisColor ?? N.axisColor,
1478
+ axisFont: e.axisFont ?? N.axisFont,
1400
1479
  seriesColors: r,
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
1480
+ tooltipBackgroundColor: e.tooltipBackgroundColor ?? N.tooltipBackgroundColor,
1481
+ tooltipTextColor: e.tooltipTextColor ?? N.tooltipTextColor,
1482
+ tooltipFont: e.tooltipFont ?? N.tooltipFont,
1483
+ legendBackgroundColor: e.legendBackgroundColor ?? N.legendBackgroundColor,
1484
+ legendBorderColor: e.legendBorderColor ?? N.legendBorderColor,
1485
+ legendTextColor: e.legendTextColor ?? N.legendTextColor,
1486
+ legendMutedTextColor: e.legendMutedTextColor ?? N.legendMutedTextColor,
1487
+ legendFont: e.legendFont ?? N.legendFont
1409
1488
  };
1410
1489
  }
1411
- function I(e, t, n) {
1490
+ function F(e, t, n) {
1412
1491
  if (!e) return t;
1413
1492
  if (typeof e != "string") return e;
1414
- let r = re(e, n), i = B(r ?? e, n);
1415
- return z(r ?? e) ?? z(i ?? "") ?? t;
1493
+ let r = le(e, n), i = ue(r ?? e, n);
1494
+ return L(r ?? e) ?? L(i ?? "") ?? t;
1416
1495
  }
1417
- function L(e, t) {
1418
- return e ? typeof e == "string" ? e : R(e) : t;
1496
+ function ce(e, t) {
1497
+ return e ? typeof e == "string" ? e : I(e) : t;
1419
1498
  }
1420
- function R(e) {
1499
+ function I(e) {
1421
1500
  return `rgba(${Math.round(e[0] * 255)}, ${Math.round(e[1] * 255)}, ${Math.round(e[2] * 255)}, ${e[3]})`;
1422
1501
  }
1423
- function re(e, t) {
1502
+ function le(e, t) {
1424
1503
  let n = t?.ownerDocument ?? globalThis.document;
1425
1504
  if (!n?.documentElement || typeof getComputedStyle > "u") return null;
1426
1505
  let r = t instanceof HTMLElement ? t : n.documentElement, i = n.createElement("span");
@@ -1428,11 +1507,11 @@ function re(e, t) {
1428
1507
  let a = getComputedStyle(i).color;
1429
1508
  return i.remove(), a || null;
1430
1509
  }
1431
- function z(e) {
1510
+ function L(e) {
1432
1511
  let t = e.trim();
1433
- return ie(t) ?? ae(t) ?? oe(t);
1512
+ return de(t) ?? R(t) ?? z(t);
1434
1513
  }
1435
- function B(e, t) {
1514
+ function ue(e, t) {
1436
1515
  let n = t?.ownerDocument ?? globalThis.document;
1437
1516
  if (!n?.createElement) return null;
1438
1517
  let r = n.createElement("canvas").getContext("2d");
@@ -1442,12 +1521,12 @@ function B(e, t) {
1442
1521
  let a = String(r.fillStyle);
1443
1522
  return a === i ? null : a;
1444
1523
  }
1445
- function ie(e) {
1524
+ function de(e) {
1446
1525
  let t = e.match(/^rgba?\((.*)\)$/i);
1447
1526
  if (!t) return null;
1448
1527
  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);
1449
1528
  if (a.length < 3) return null;
1450
- let o = V(a[0]), s = V(a[1]), c = V(a[2]), l = U(i ?? (a.length > 3 ? a[3] : void 0));
1529
+ let o = B(a[0]), s = B(a[1]), c = B(a[2]), l = H(i ?? (a.length > 3 ? a[3] : void 0));
1451
1530
  return o === null || s === null || c === null || l === null ? null : [
1452
1531
  o,
1453
1532
  s,
@@ -1455,12 +1534,12 @@ function ie(e) {
1455
1534
  l
1456
1535
  ];
1457
1536
  }
1458
- function ae(e) {
1537
+ function R(e) {
1459
1538
  let t = e.match(/^color\(\s*srgb\s+(.+)\)$/i);
1460
1539
  if (!t) return null;
1461
1540
  let n = t[1].split("/").map((e) => e.trim()), r = n[0].split(/\s+/).filter(Boolean);
1462
1541
  if (r.length < 3) return null;
1463
- let i = H(r[0]), a = H(r[1]), o = H(r[2]), s = U(n[1]);
1542
+ let i = V(r[0]), a = V(r[1]), o = V(r[2]), s = H(n[1]);
1464
1543
  return i === null || a === null || o === null || s === null ? null : [
1465
1544
  i,
1466
1545
  a,
@@ -1468,7 +1547,7 @@ function ae(e) {
1468
1547
  s
1469
1548
  ];
1470
1549
  }
1471
- function oe(e) {
1550
+ function z(e) {
1472
1551
  let t = e.startsWith("#") ? e.slice(1) : "";
1473
1552
  if (![
1474
1553
  3,
@@ -1484,21 +1563,21 @@ function oe(e) {
1484
1563
  n.length === 8 ? (r & 255) / 255 : 1
1485
1564
  ] : null;
1486
1565
  }
1566
+ function B(e) {
1567
+ return e.endsWith("%") ? U(Number.parseFloat(e) / 100) : U(Number.parseFloat(e) / 255);
1568
+ }
1487
1569
  function V(e) {
1488
- return e.endsWith("%") ? W(Number.parseFloat(e) / 100) : W(Number.parseFloat(e) / 255);
1570
+ return e.endsWith("%") ? U(Number.parseFloat(e) / 100) : U(Number.parseFloat(e));
1489
1571
  }
1490
1572
  function H(e) {
1491
- return e.endsWith("%") ? W(Number.parseFloat(e) / 100) : W(Number.parseFloat(e));
1573
+ return e ? e.endsWith("%") ? U(Number.parseFloat(e) / 100) : U(Number.parseFloat(e)) : 1;
1492
1574
  }
1493
1575
  function U(e) {
1494
- return e ? e.endsWith("%") ? W(Number.parseFloat(e) / 100) : W(Number.parseFloat(e)) : 1;
1495
- }
1496
- function W(e) {
1497
1576
  return Number.isFinite(e) ? Math.min(1, Math.max(0, e)) : null;
1498
1577
  }
1499
1578
  //#endregion
1500
1579
  //#region src/ui/Chart.ts
1501
- var G = 16384, K = G >> 1, q = G >> 1, J = 3, Y = 4096, X = 12, se = 12, Z = 64;
1580
+ var W = 16384, G = W >> 1, K = W >> 1, q = 3, J = 4096, Y = 12, fe = 12, X = 5, Z = 64;
1502
1581
  function Q(e) {
1503
1582
  return e === !1 ? {
1504
1583
  visible: !1,
@@ -1520,6 +1599,10 @@ function $(e) {
1520
1599
  y: {
1521
1600
  visible: !1,
1522
1601
  position: "inside"
1602
+ },
1603
+ y2: {
1604
+ visible: !1,
1605
+ position: "inside"
1523
1606
  }
1524
1607
  } : e === !0 || e === void 0 ? {
1525
1608
  x: {
@@ -1529,17 +1612,24 @@ function $(e) {
1529
1612
  y: {
1530
1613
  visible: !0,
1531
1614
  position: "inside"
1615
+ },
1616
+ y2: {
1617
+ visible: !1,
1618
+ position: "inside"
1532
1619
  }
1533
1620
  } : {
1534
1621
  x: Q(e.x),
1535
- y: Q(e.y)
1622
+ y: Q(e.y),
1623
+ y2: Q(e.y2 ?? !1)
1536
1624
  };
1537
1625
  }
1538
- var ce = class {
1626
+ var pe = class {
1539
1627
  options;
1540
1628
  series = [];
1541
1629
  camera;
1630
+ rightCamera;
1542
1631
  axis;
1632
+ rightAxis;
1543
1633
  renderer;
1544
1634
  rawLineBuffer;
1545
1635
  rawLineData;
@@ -1584,10 +1674,10 @@ var ce = class {
1584
1674
  this.pointerInPlot = !1, this.emitHover(null);
1585
1675
  };
1586
1676
  constructor(e, t = {}) {
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 = {
1677
+ this.options = t, this.resolvedTheme = P(t.theme, e), this.normalizedAxes = $(t.axes), this._gridVisible = t.grid !== !1, this.layout = new se(e, this.normalizedAxes), this.layout.root.style.background = this.resolvedTheme.backgroundCssColor, this.applyCanvasSize(), this.camera = new A(), this.rightCamera = new A(), this.axis = new j(this.camera), this.rightAxis = new j(this.rightCamera), this.renderer = new O(new oe(this.layout.canvas)), this.rawLineData = new Float32Array(W * 2), this.rawLineBuffer = this.renderer.createFloatBuffer(this.rawLineData.length), this.minMaxInstanceData = new Float32Array(K * q), this.minMaxInstanceBuffer = this.renderer.createFloatBuffer(this.minMaxInstanceData.length), this.barTriangleData = new Float32Array(J * Y), this.barTriangleBuffer = this.renderer.createFloatBuffer(this.barTriangleData.length), this.gridData = new Float32Array(Z * 2), this.gridBuffer = this.renderer.createFloatBuffer(this.gridData.length), this.gridStyle = {
1588
1678
  color: t.gridStyle?.color ?? this.resolvedTheme.gridColor,
1589
1679
  lineWidth: t.gridStyle?.lineWidth ?? 1
1590
- }, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible) && (this.axisOverlay = new N(this.layout, this.normalizedAxes, {
1680
+ }, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible || this.normalizedAxes.y2.visible) && (this.axisOverlay = new M(this.layout, this.normalizedAxes, {
1591
1681
  color: this.resolvedTheme.axisColor,
1592
1682
  font: this.resolvedTheme.axisFont
1593
1683
  })), 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));
@@ -1611,36 +1701,39 @@ var ce = class {
1611
1701
  get yAxisElement() {
1612
1702
  return this.layout.yAxis;
1613
1703
  }
1704
+ get y2AxisElement() {
1705
+ return this.layout.y2Axis;
1706
+ }
1614
1707
  get theme() {
1615
1708
  return this.resolvedTheme;
1616
1709
  }
1617
- getCamera() {
1618
- return this.camera;
1710
+ getCamera(e = "left") {
1711
+ return e === "right" ? this.rightCamera : this.camera;
1619
1712
  }
1620
- dataToPlot(e, t) {
1621
- let [n, r] = this.camera.toClip(e, t);
1622
- return this.camera.toScreen(n, r, this.canvas.clientWidth, this.canvas.clientHeight);
1713
+ dataToPlot(e, t, n = "left") {
1714
+ let r = this.getCamera(n), [i, a] = r.toClip(e, t);
1715
+ return r.toScreen(i, a, this.canvas.clientWidth, this.canvas.clientHeight);
1623
1716
  }
1624
- clientToData(e, t) {
1625
- let n = this.canvas.getBoundingClientRect();
1626
- if (n.width <= 0 || n.height <= 0) return null;
1627
- let r = e - n.left, i = t - n.top;
1628
- if (r < 0 || i < 0 || r > n.width || i > n.height) return null;
1629
- let a = this.camera.viewport;
1630
- return [a.xMin + r / n.width * (a.xMax - a.xMin), a.yMax - i / n.height * (a.yMax - a.yMin)];
1717
+ clientToData(e, t, n = "left") {
1718
+ let r = this.canvas.getBoundingClientRect();
1719
+ if (r.width <= 0 || r.height <= 0) return null;
1720
+ let i = e - r.left, a = t - r.top;
1721
+ if (i < 0 || a < 0 || i > r.width || a > r.height) return null;
1722
+ let o = this.getCamera(n).viewport;
1723
+ return [o.xMin + i / r.width * (o.xMax - o.xMin), o.yMax - a / r.height * (o.yMax - o.yMin)];
1631
1724
  }
1632
- getViewport() {
1633
- return this.camera.viewport;
1725
+ getViewport(e = "left") {
1726
+ return this.getCamera(e).viewport;
1634
1727
  }
1635
1728
  pan(e) {
1636
- this.camera.pan(e), this.refreshHover();
1729
+ this.camera.pan(e), this.syncRightCameraX(), this.refreshHover();
1637
1730
  }
1638
1731
  zoom(e) {
1639
- this.camera.zoom(e), this.refreshHover();
1732
+ this.camera.zoom(e), this.syncRightCameraX(), this.refreshHover();
1640
1733
  }
1641
1734
  addSeries(e, t) {
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, {
1735
+ if ((e.mode === "ohlc" || e.mode === "candlestick") && !e.dataset) throw TypeError("OHLC and candlestick series require an OhlcDataset.");
1736
+ let n = e.dataset ?? new p(e.capacity, { overflow: e.overflow }), r = this.resolvedTheme.seriesColors, i = r[this.series.length % r.length] ?? this.resolvedTheme.seriesColors[0], a = t?.color ?? i, o = new u(n, e, {
1644
1737
  color: a,
1645
1738
  lineWidth: t?.lineWidth ?? 1,
1646
1739
  pointSize: t?.pointSize ?? 4,
@@ -1652,9 +1745,17 @@ var ce = class {
1652
1745
  a[2],
1653
1746
  a[3] * .25
1654
1747
  ],
1655
- tickWidth: t?.tickWidth ?? t?.barWidth ?? .8
1748
+ tickWidth: t?.tickWidth ?? t?.barWidth ?? .8,
1749
+ upColor: t?.upColor ?? a,
1750
+ downColor: t?.downColor ?? t?.fillColor ?? [
1751
+ a[0],
1752
+ a[1],
1753
+ a[2],
1754
+ a[3] * .45
1755
+ ],
1756
+ wickColor: t?.wickColor ?? a
1656
1757
  });
1657
- return this.series.push(s), this.emitSeriesChange(), s;
1758
+ return this.series.push(o), this.emitSeriesChange(), o;
1658
1759
  }
1659
1760
  addLine(e, t) {
1660
1761
  return this.addSeries({
@@ -1686,6 +1787,12 @@ var ce = class {
1686
1787
  mode: "ohlc"
1687
1788
  }, t);
1688
1789
  }
1790
+ addCandlestick(e, t) {
1791
+ return this.addSeries({
1792
+ ...e,
1793
+ mode: "candlestick"
1794
+ }, t);
1795
+ }
1689
1796
  removeSeries(e) {
1690
1797
  let t = this.series.indexOf(e);
1691
1798
  return t === -1 ? !1 : (this.series.splice(t, 1), this.emitSeriesChange(), !0);
@@ -1701,11 +1808,15 @@ var ce = class {
1701
1808
  name: e.config.name,
1702
1809
  mode: e.config.mode,
1703
1810
  visible: e.visible,
1704
- color: e.style.color
1811
+ color: e.style.color,
1812
+ yAxis: e.config.yAxis ?? "left"
1705
1813
  }));
1706
1814
  }
1707
1815
  setViewport(e) {
1708
- this.camera.setViewport(e), this.refreshHover();
1816
+ this.camera.setViewport(e), this.rightCamera.setViewport(e), this.refreshHover();
1817
+ }
1818
+ setYViewport(e, t) {
1819
+ this.getCamera(e).setViewport(t), this.refreshHover();
1709
1820
  }
1710
1821
  resize(e = globalThis.devicePixelRatio) {
1711
1822
  let t = this.applyCanvasSize(e);
@@ -1737,7 +1848,7 @@ var ce = class {
1737
1848
  return this.seriesSubscribers.add(n), () => this.seriesSubscribers.delete(n);
1738
1849
  }
1739
1850
  setTheme(e) {
1740
- this.resolvedTheme = F(e, this.layout.root), this.applyTheme(), this.emitThemeChange(), this.refreshHover();
1851
+ this.resolvedTheme = P(e, this.layout.root), this.applyTheme(), this.emitThemeChange(), this.refreshHover();
1741
1852
  }
1742
1853
  setGridVisible(e) {
1743
1854
  this._gridVisible = e;
@@ -1746,7 +1857,7 @@ var ce = class {
1746
1857
  return this._gridVisible;
1747
1858
  }
1748
1859
  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, {
1860
+ this.normalizedAxes = $(e), this.layout.update(this.normalizedAxes), this.axisOverlay?.dispose(), this.axisOverlay = null, (this.normalizedAxes.x.visible || this.normalizedAxes.y.visible || this.normalizedAxes.y2.visible) && (this.axisOverlay = new M(this.layout, this.normalizedAxes, {
1750
1861
  color: this.resolvedTheme.axisColor,
1751
1862
  font: this.resolvedTheme.axisFont
1752
1863
  })), this.resize(), this.refreshHover();
@@ -1756,17 +1867,21 @@ var ce = class {
1756
1867
  if (r.width <= 0 || r.height <= 0) return null;
1757
1868
  let i = e - r.left, a = t - r.top;
1758
1869
  if (i < 0 || a < 0 || i > r.width || a > r.height) return null;
1759
- let o = this.camera.viewport, s = o.xMin + i / r.width * (o.xMax - o.xMin), c = o.yMax - a / r.height * (o.yMax - o.yMin), l = n.mode ?? this.options.hover?.mode ?? "nearest-x", u = n.maxDistancePx ?? this.options.hover?.maxDistancePx ?? Infinity, d = l === "nearest-point" ? this.findNearestPointAnchor(s, c, o, r.width, r.height, u) : this.findNearestXAnchor(s, o, r.width, u);
1760
- return d === null ? null : {
1870
+ let o = this.camera.viewport, s = o.xMin + i / r.width * (o.xMax - o.xMin), c = o.yMax - a / r.height * (o.yMax - o.yMin), l = n.mode ?? this.options.hover?.mode ?? "nearest-x", u = n.group ?? this.options.hover?.group ?? "x", d = n.maxDistancePx ?? this.options.hover?.maxDistancePx ?? Infinity, f = l === "nearest-point" ? this.findNearestPointCandidate(s, a, r.width, r.height, d) : this.findNearestXCandidate(s, r.width, d);
1871
+ if (!f) return null;
1872
+ let p = f.sample.x;
1873
+ return {
1761
1874
  clientX: e,
1762
1875
  clientY: t,
1763
1876
  plotX: i,
1764
1877
  plotY: a,
1765
1878
  dataX: s,
1766
1879
  dataY: c,
1767
- anchorX: d,
1880
+ anchorX: p,
1768
1881
  mode: l,
1769
- items: this.collectPickItems(d, e, t, o, r)
1882
+ group: u,
1883
+ maxDistancePx: d,
1884
+ items: u === "none" ? [this.createPickItem(f.sample, f.series, f.seriesIndex, e, t, r)] : this.collectPickItems(p, e, t, r)
1770
1885
  };
1771
1886
  }
1772
1887
  async screenshot(e = {}) {
@@ -1775,7 +1890,7 @@ var ce = class {
1775
1890
  o.width = i, o.height = a;
1776
1891
  let s = o.getContext("2d");
1777
1892
  if (!s) throw Error("Unable to create a 2D canvas context for screenshot export.");
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) => {
1893
+ return s.fillStyle = e.background ?? I(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) => {
1779
1894
  o.toBlob((e) => e ? t(e) : n(/* @__PURE__ */ Error("Unable to encode chart screenshot.")), e.type ?? "image/png", e.quality);
1780
1895
  });
1781
1896
  }
@@ -1790,7 +1905,7 @@ var ce = class {
1790
1905
  }
1791
1906
  render() {
1792
1907
  let e = performance.now();
1793
- this.lastFrameAt > 0 && (this.stats.fps = 1e3 / (e - this.lastFrameAt)), this.lastFrameAt = e, this.stats.pointsRendered = 0, this.stats.drawCalls = 0, this.stats.uploadBytes = 0, this.stats.renderMode = "none", this.options.viewportPolicy?.beforeRender?.(this.camera);
1908
+ this.lastFrameAt > 0 && (this.stats.fps = 1e3 / (e - this.lastFrameAt)), this.lastFrameAt = e, this.stats.pointsRendered = 0, this.stats.drawCalls = 0, this.stats.uploadBytes = 0, this.stats.renderMode = "none", this.options.viewportPolicy?.beforeRender?.(this.camera), this.syncRightCameraX();
1794
1909
  let [t, n, r, i] = this.resolvedTheme.backgroundColor;
1795
1910
  this.renderer.viewport(0, 0, this.canvas.width, this.canvas.height), this.renderer.clear(t, n, r, i);
1796
1911
  let a = this.camera.viewport;
@@ -1798,8 +1913,8 @@ var ce = class {
1798
1913
  let e = this.writeGridVertices(a);
1799
1914
  e > 0 && (this.uploadGridData(e), this.renderer.drawClipLines(this.gridBuffer, e, this.gridStyle), this.stats.drawCalls++);
1800
1915
  }
1801
- for (let e of this.series) e.visible && (e.rebuildPyramid(), this.drawSeries(e, a));
1802
- this.axisOverlay?.update(this.camera, this.axis), this.stats.frameMs = performance.now() - e, this.refreshHover();
1916
+ for (let e of this.series) e.visible && (e.rebuildPyramid(), this.drawSeries(e));
1917
+ this.axisOverlay?.update(this.camera, this.axis, this.rightCamera, this.rightAxis), this.stats.frameMs = performance.now() - e, this.refreshHover();
1803
1918
  }
1804
1919
  dispose() {
1805
1920
  this.stop(), this.resizeObserver?.disconnect(), this.canvas.removeEventListener("pointermove", this.handlePointerMove), this.canvas.removeEventListener("pointerleave", this.handlePointerLeave);
@@ -1819,96 +1934,142 @@ var ce = class {
1819
1934
  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));
1820
1935
  return this.canvas.width === n && this.canvas.height === r ? !1 : (this.canvas.width = n, this.canvas.height = r, !0);
1821
1936
  }
1822
- drawSeries(e, t) {
1937
+ cameraForSeries(e) {
1938
+ return e.config.yAxis === "right" ? this.rightCamera : this.camera;
1939
+ }
1940
+ syncRightCameraX() {
1941
+ this.rightCamera.setViewport({
1942
+ xMin: this.camera.xMin,
1943
+ xMax: this.camera.xMax
1944
+ });
1945
+ }
1946
+ drawSeries(e) {
1947
+ let t = this.cameraForSeries(e), n = t.viewport;
1823
1948
  switch (e.config.mode) {
1824
1949
  case "area":
1825
- this.drawAreaSeries(e, t);
1950
+ this.drawAreaSeries(e, n, t);
1826
1951
  return;
1827
1952
  case "bar":
1828
- this.drawBarSeries(e, t);
1953
+ this.drawBarSeries(e, n, t);
1829
1954
  return;
1830
1955
  case "ohlc":
1831
- this.drawOhlcSeries(e, t);
1956
+ this.drawOhlcSeries(e, n, t);
1957
+ return;
1958
+ case "candlestick":
1959
+ this.drawCandlestickSeries(e, n, t);
1832
1960
  return;
1833
1961
  case "scatter":
1834
- this.drawScatterSeries(e, t);
1962
+ this.drawScatterSeries(e, n, t);
1835
1963
  return;
1836
- default: this.drawLineSeries(e, t);
1964
+ default: this.drawLineSeries(e, n, t);
1837
1965
  }
1838
1966
  }
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);
1967
+ drawLineSeries(e, t, n) {
1968
+ let r = e.visibleSampleCount(t), i = e.hasLOD && r > W - 2;
1969
+ if (i && this.renderer.supportsInstancedSegments) {
1970
+ let r = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxMinMaxSegments(), this.currentXOrigin);
1971
+ if (r <= 0) return;
1972
+ this.uploadMinMaxInstanceData(r), this.renderer.drawMinMaxSegmentsInstanced(this.minMaxInstanceBuffer, r, e.style, n), this.recordDraw("minmax", r * 2);
1845
1973
  return;
1846
1974
  }
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);
1975
+ if (i) {
1976
+ let r = e.copyMinMaxVisible(t, this.rawLineData, this.maxMinMaxSegments(), this.currentXOrigin);
1977
+ if (r < 2) return;
1978
+ this.uploadRawLineData(r), this.renderer.drawMinMaxSegments(this.rawLineBuffer, r, e.style, n), this.recordDraw("minmax", r);
1851
1979
  return;
1852
1980
  }
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));
1981
+ let a = e.copyRawVisibleClipSpace(t, this.rawLineData, W);
1982
+ a < 2 || (this.uploadRawLineData(a), this.renderer.drawClipLineStrip(this.rawLineBuffer, a, e.style), this.recordDraw("raw", a));
1983
+ }
1984
+ drawAreaSeries(e, t, n) {
1985
+ let r = e.visibleIndexRange(t, 1);
1986
+ if (r.end - r.start < 2) return;
1987
+ let i = e.style.baseline ?? 0;
1988
+ if (r.end - r.start > G) {
1989
+ let r = e.copyAreaVisible(t, this.rawLineData, G, i, this.currentXOrigin);
1990
+ r >= 4 && (this.uploadRawLineData(r), this.renderer.drawAreaStrip(this.rawLineBuffer, r, e.style, n), this.recordDraw("area", r));
1991
+ let a = e.copyRawVisible(t, this.rawLineData, G, this.currentXOrigin);
1992
+ a >= 2 && (this.uploadRawLineData(a), this.renderer.drawLineStrip(this.rawLineBuffer, a, e.style, n), this.recordDraw("area", a));
1993
+ return;
1994
+ }
1995
+ for (let t = r.start; t < r.end;) {
1996
+ let a = e.copyAreaRange(t, r.end, this.rawLineData, G, i, this.currentXOrigin);
1997
+ if (a < 4) break;
1998
+ this.uploadRawLineData(a), this.renderer.drawAreaStrip(this.rawLineBuffer, a, e.style, n), this.recordDraw("area", a), t += Math.max(1, (a >> 1) - 1);
1999
+ }
2000
+ for (let t = r.start; t < r.end;) {
2001
+ let i = e.copyRawRange(t, r.end, this.rawLineData, G, this.currentXOrigin);
2002
+ if (i < 2) break;
2003
+ this.uploadRawLineData(i), this.renderer.drawLineStrip(this.rawLineBuffer, i, e.style, n), this.recordDraw("area", i), t += Math.max(1, i - 1);
2004
+ }
1855
2005
  }
1856
- drawAreaSeries(e, t) {
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);
2006
+ drawOhlcSeries(e, t, n) {
2007
+ let r = e.visibleIndexRange(t), i = Math.floor(this.rawLineData.length / fe);
2008
+ for (let t = r.start; t < r.end;) {
2009
+ let a = e.copyOhlcRange(t, r.end, this.rawLineData, i, e.style.tickWidth ?? e.style.barWidth ?? .8, this.currentXOrigin);
2010
+ if (a <= 0) break;
2011
+ let o = a * 6;
2012
+ this.uploadRawLineData(o), this.renderer.drawLines(this.rawLineBuffer, o, e.style, n), this.recordDraw("raw", o), t += a;
1864
2013
  }
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);
2014
+ }
2015
+ drawCandlestickSeries(e, t, n) {
2016
+ let r = e.visibleIndexRange(t, 1), i = Math.min(Math.floor(this.rawLineData.length / X), this.maxBarTriangleBars()), a = {
2017
+ ...e.style,
2018
+ color: e.style.wickColor ?? e.style.color
2019
+ }, o = {
2020
+ ...e.style,
2021
+ color: e.style.upColor ?? e.style.color
2022
+ }, s = {
2023
+ ...e.style,
2024
+ color: e.style.downColor ?? e.style.fillColor ?? e.style.color
2025
+ };
2026
+ for (let t = r.start; t < r.end;) {
2027
+ let c = e.copyOhlcTuplesRange(t, r.end, this.rawLineData, i, this.currentXOrigin);
2028
+ if (c <= 0) break;
2029
+ let l = this.writeCandlestickWicks(c);
2030
+ l > 0 && (this.uploadBarTriangleData(l), this.renderer.drawLines(this.barTriangleBuffer, l, a, n), this.recordDraw("raw", l));
2031
+ let u = e.style.barWidth ?? e.style.tickWidth ?? .8;
2032
+ this.drawCandlestickBodies(c, u, "up", o, n), this.drawCandlestickBodies(c, u, "down", s, n), t += c;
1869
2033
  }
1870
2034
  }
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);
2035
+ drawScatterSeries(e, t, n) {
2036
+ if (e.visibleSampleCount(t) > W) {
2037
+ let r = e.copyRawVisible(t, this.rawLineData, W, this.currentXOrigin);
2038
+ if (r <= 0) return;
2039
+ this.uploadRawLineData(r), this.renderer.drawPoints(this.rawLineBuffer, r, e.style, n, this.canvas.width, this.canvas.height), this.recordDraw("points", r);
2040
+ return;
2041
+ }
2042
+ let r = e.visibleIndexRange(t);
2043
+ for (let t = r.start; t < r.end;) {
2044
+ let i = e.copyRawRange(t, r.end, this.rawLineData, W, this.currentXOrigin);
1875
2045
  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
- }
1879
- }
1880
- drawScatterSeries(e, t) {
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
- }
1887
- }
1888
- drawBarSeries(e, t) {
1889
- let n = e.visibleSampleCount(t), r = this.maxRawBarInstances();
1890
- if (e.hasLOD && n > r) {
1891
- let n = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxBarTriangleBars(), this.currentXOrigin);
1892
- if (n <= 0) return;
1893
- this.includeBaselineInBarRanges(n, e.style.baseline ?? 0);
1894
- let r = this.writeBarBucketTriangles(n, t);
1895
- this.drawBarTriangles(r, e.style);
2046
+ this.uploadRawLineData(i), this.renderer.drawPoints(this.rawLineBuffer, i, e.style, n, this.canvas.width, this.canvas.height), this.recordDraw("points", i), t += i;
2047
+ }
2048
+ }
2049
+ drawBarSeries(e, t, n) {
2050
+ let r = e.visibleSampleCount(t), i = this.maxRawBarInstances();
2051
+ if (e.hasLOD && r > i) {
2052
+ let r = e.copyMinMaxInstanced(t, this.minMaxInstanceData, this.maxBarTriangleBars(), this.currentXOrigin);
2053
+ if (r <= 0) return;
2054
+ this.includeBaselineInBarRanges(r, e.style.baseline ?? 0);
2055
+ let i = this.writeBarBucketTriangles(r, t);
2056
+ this.drawBarTriangles(i, e.style, n);
1896
2057
  return;
1897
2058
  }
1898
- let i = e.visibleIndexRange(t, 1), a = e.copyRawRange(i.start, i.end, this.rawLineData, r, this.currentXOrigin);
1899
- if (a <= 0) return;
2059
+ let a = e.visibleIndexRange(t, 1), o = e.copyRawRange(a.start, a.end, this.rawLineData, i, this.currentXOrigin);
2060
+ if (o <= 0) return;
1900
2061
  if (this.renderer.supportsInstancedBars) {
1901
- this.uploadRawLineData(a), this.renderer.drawBarsInstanced(this.rawLineBuffer, a, e.style, this.camera), this.recordDraw("bars", a);
2062
+ this.uploadRawLineData(o), this.renderer.drawBarsInstanced(this.rawLineBuffer, o, e.style, n), this.recordDraw("bars", o);
1902
2063
  return;
1903
2064
  }
1904
- let o = this.writeBarTriangles(a, e.style.baseline ?? 0, e.style.barWidth ?? .8);
1905
- this.drawBarTriangles(o, e.style);
2065
+ let s = this.writeBarTriangles(o, e.style.baseline ?? 0, e.style.barWidth ?? .8);
2066
+ this.drawBarTriangles(s, e.style, n);
1906
2067
  }
1907
2068
  uploadRawLineData(e) {
1908
2069
  this.uploadFloatData(this.rawLineBuffer, this.rawLineData, e * 2);
1909
2070
  }
1910
2071
  uploadMinMaxInstanceData(e) {
1911
- this.uploadFloatData(this.minMaxInstanceBuffer, this.minMaxInstanceData, e * J);
2072
+ this.uploadFloatData(this.minMaxInstanceBuffer, this.minMaxInstanceData, e * q);
1912
2073
  }
1913
2074
  uploadBarTriangleData(e) {
1914
2075
  this.uploadFloatData(this.barTriangleBuffer, this.barTriangleData, e * 2);
@@ -1922,7 +2083,7 @@ var ce = class {
1922
2083
  }
1923
2084
  includeBaselineInBarRanges(e, t) {
1924
2085
  for (let n = 0; n < e; n++) {
1925
- let e = n * J, r = this.minMaxInstanceData[e + 1], i = this.minMaxInstanceData[e + 2];
2086
+ let e = n * q, r = this.minMaxInstanceData[e + 1], i = this.minMaxInstanceData[e + 2];
1926
2087
  this.minMaxInstanceData[e + 1] = Math.min(t, r), this.minMaxInstanceData[e + 2] = Math.max(t, i);
1927
2088
  }
1928
2089
  }
@@ -1955,59 +2116,86 @@ var ce = class {
1955
2116
  }
1956
2117
  return [Math.max(i, l), Math.min(a, u)];
1957
2118
  }
2119
+ writeCandlestickWicks(e) {
2120
+ for (let t = 0; t < e; t++) {
2121
+ let e = t * X, n = t * 4, r = this.rawLineData[e], i = this.rawLineData[e + 2], a = this.rawLineData[e + 3];
2122
+ this.barTriangleData[n] = r, this.barTriangleData[n + 1] = a, this.barTriangleData[n + 2] = r, this.barTriangleData[n + 3] = i;
2123
+ }
2124
+ return e * 2;
2125
+ }
2126
+ drawCandlestickBodies(e, t, n, r, i) {
2127
+ let a = t * .5, o = 0;
2128
+ for (let t = 0; t < e && o < this.maxBarTriangleBars(); t++) {
2129
+ let e = t * X, r = this.rawLineData[e], i = this.rawLineData[e + 1], s = this.rawLineData[e + 4];
2130
+ n === "up" == s >= i && (this.writeBarTriangle(o, r - a, r + a, Math.min(i, s), Math.max(i, s)), o++);
2131
+ }
2132
+ this.drawBarTriangles(o * 6, r, i);
2133
+ }
1958
2134
  writeBarTriangle(e, t, n, r, i) {
1959
- let a = e * X;
2135
+ let a = e * Y;
1960
2136
  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;
1961
2137
  }
1962
- drawBarTriangles(e, t) {
1963
- e <= 0 || (this.uploadBarTriangleData(e), this.renderer.drawBarTriangles(this.barTriangleBuffer, e, t, this.camera), this.recordDraw("bars", e));
2138
+ drawBarTriangles(e, t, n, r = "bars") {
2139
+ e <= 0 || (this.uploadBarTriangleData(e), this.renderer.drawBarTriangles(this.barTriangleBuffer, e, t, n), this.recordDraw(r, e));
1964
2140
  }
1965
2141
  recordDraw(e, t, n = 1) {
1966
2142
  this.recordRenderMode(e), this.stats.pointsRendered += t, this.stats.drawCalls += n;
1967
2143
  }
1968
- findNearestXAnchor(e, t, n, r) {
1969
- let i = null, a = Infinity, o = n / (t.xMax - t.xMin);
1970
- for (let n of this.series) {
1971
- if (!n.visible) continue;
1972
- let r = n.nearestSampleByX(e, t);
1973
- if (!r) continue;
1974
- let s = Math.abs(r.x - e) * o;
1975
- s < a && (i = r, a = s);
1976
- }
1977
- return !i || a > r ? null : i.x;
1978
- }
1979
- findNearestPointAnchor(e, t, n, r, i, a) {
1980
- let o = null;
1981
- for (let a of this.series) {
2144
+ findNearestXCandidate(e, t, n) {
2145
+ let r = null, i = Infinity;
2146
+ for (let n = 0; n < this.series.length; n++) {
2147
+ let a = this.series[n];
1982
2148
  if (!a.visible) continue;
1983
- let s = a.nearestSampleByPoint(e, t, n, r, i);
1984
- s && (!o || (s.distancePx ?? Infinity) < (o.distancePx ?? Infinity)) && (o = s);
2149
+ let o = this.cameraForSeries(a).viewport, s = t / (o.xMax - o.xMin), c = a.nearestSampleByX(e, o);
2150
+ if (!c) continue;
2151
+ let l = Math.abs(c.x - e) * s;
2152
+ l < i && (r = {
2153
+ sample: c,
2154
+ series: a,
2155
+ seriesIndex: n
2156
+ }, i = l);
1985
2157
  }
1986
- return !o || (o.distancePx ?? Infinity) > a ? null : o.x;
2158
+ return r && i <= n ? r : null;
1987
2159
  }
1988
- collectPickItems(e, t, n, r, i) {
1989
- let a = [];
2160
+ findNearestPointCandidate(e, t, n, r, i) {
2161
+ let a = null;
1990
2162
  for (let o = 0; o < this.series.length; o++) {
1991
2163
  let s = this.series[o];
1992
2164
  if (!s.visible) continue;
1993
- let c = s.nearestSampleByX(e, r);
1994
- if (!c) continue;
1995
- let [l, u] = this.camera.toClip(c.x, c.y), [d, f] = this.camera.toScreen(l, u, i.width, i.height), p = i.left + d, m = i.top + f, h = p - t, g = m - n;
1996
- a.push({
1997
- ...c,
1998
- distancePx: Math.hypot(h, g),
2165
+ let c = this.cameraForSeries(s).viewport, l = c.yMax - t / r * (c.yMax - c.yMin), u = s.nearestSampleByPoint(e, l, c, n, r, i);
2166
+ u && (!a || (u.distancePx ?? Infinity) < (a.sample.distancePx ?? Infinity)) && (a = {
2167
+ sample: u,
1999
2168
  series: s,
2000
- seriesIndex: o,
2001
- id: s.config.id,
2002
- name: s.config.name,
2003
- mode: s.config.mode,
2004
- plotX: d,
2005
- plotY: f,
2006
- clientX: p,
2007
- clientY: m
2169
+ seriesIndex: o
2008
2170
  });
2009
2171
  }
2010
- return a;
2172
+ return a && (a.sample.distancePx ?? Infinity) <= i ? a : null;
2173
+ }
2174
+ collectPickItems(e, t, n, r) {
2175
+ let i = [];
2176
+ for (let a = 0; a < this.series.length; a++) {
2177
+ let o = this.series[a];
2178
+ if (!o.visible) continue;
2179
+ let s = o.nearestSampleByX(e, this.cameraForSeries(o).viewport);
2180
+ s && i.push(this.createPickItem(s, o, a, t, n, r));
2181
+ }
2182
+ return i;
2183
+ }
2184
+ createPickItem(e, t, n, r, i, a) {
2185
+ let o = this.cameraForSeries(t), [s, c] = o.toClip(e.x, e.y), [l, u] = o.toScreen(s, c, a.width, a.height), d = a.left + l, f = a.top + u, p = d - r, m = f - i;
2186
+ return {
2187
+ ...e,
2188
+ distancePx: Math.hypot(p, m),
2189
+ series: t,
2190
+ seriesIndex: n,
2191
+ id: t.config.id,
2192
+ name: t.config.name,
2193
+ mode: t.config.mode,
2194
+ plotX: l,
2195
+ plotY: u,
2196
+ clientX: d,
2197
+ clientY: f
2198
+ };
2011
2199
  }
2012
2200
  refreshHover() {
2013
2201
  this.pointerInPlot && this.emitHover(this.pick(this.lastPointerClientX, this.lastPointerClientY));
@@ -2035,13 +2223,13 @@ var ce = class {
2035
2223
  }
2036
2224
  }
2037
2225
  maxMinMaxSegments() {
2038
- return Math.min(this.canvas.width, q);
2226
+ return Math.min(this.canvas.width, K);
2039
2227
  }
2040
2228
  maxBarTriangleBars() {
2041
- return Math.min(Y, G);
2229
+ return Math.min(J, W);
2042
2230
  }
2043
2231
  maxRawBarInstances() {
2044
- return this.renderer.supportsInstancedBars ? G : this.maxBarTriangleBars();
2232
+ return this.renderer.supportsInstancedBars ? W : this.maxBarTriangleBars();
2045
2233
  }
2046
2234
  writeGridVertices(e) {
2047
2235
  let t = Math.max(1, this.canvas.clientWidth), n = Math.max(1, this.canvas.clientHeight);
@@ -2066,7 +2254,7 @@ var ce = class {
2066
2254
  recordRenderMode(e) {
2067
2255
  this.stats.renderMode === "none" ? this.stats.renderMode = e : this.stats.renderMode !== e && (this.stats.renderMode = "mixed");
2068
2256
  }
2069
- }, le = class {
2257
+ }, me = class {
2070
2258
  xData;
2071
2259
  yData;
2072
2260
  constructor(e, t) {
@@ -2088,15 +2276,15 @@ var ce = class {
2088
2276
  return this.assertValidIndex(e), this.yData[e];
2089
2277
  }
2090
2278
  lowerBoundX(e) {
2091
- return s(this.length, (e) => this.xData[e], e);
2279
+ return d(this.length, (e) => this.xData[e], e);
2092
2280
  }
2093
2281
  upperBoundX(e) {
2094
- return c(this.length, (e) => this.xData[e], e);
2282
+ return f(this.length, (e) => this.xData[e], e);
2095
2283
  }
2096
2284
  assertValidIndex(e) {
2097
2285
  if (!Number.isInteger(e) || e < 0 || e >= this.length) throw RangeError(`StaticDataset index out of range: ${e}`);
2098
2286
  }
2099
- }, ue = class {
2287
+ }, he = class {
2100
2288
  length;
2101
2289
  xs;
2102
2290
  opens;
@@ -2131,15 +2319,15 @@ var ce = class {
2131
2319
  return this.assertValidIndex(e), this.closes[e];
2132
2320
  }
2133
2321
  lowerBoundX(e) {
2134
- return s(this.length, (e) => this.xs[e], e);
2322
+ return d(this.length, (e) => this.xs[e], e);
2135
2323
  }
2136
2324
  upperBoundX(e) {
2137
- return c(this.length, (e) => this.xs[e], e);
2325
+ return f(this.length, (e) => this.xs[e], e);
2138
2326
  }
2139
2327
  assertValidIndex(e) {
2140
2328
  if (!Number.isInteger(e) || e < 0 || e >= this.length) throw RangeError(`StaticOhlcDataset index out of range: ${e}`);
2141
2329
  }
2142
- }, de = class {
2330
+ }, ge = class {
2143
2331
  capacity;
2144
2332
  overflow;
2145
2333
  xData;
@@ -2204,10 +2392,10 @@ var ce = class {
2204
2392
  return this.assertValidIndex(e), this.closeData[this.logicalToPhysical(e)];
2205
2393
  }
2206
2394
  lowerBoundX(e) {
2207
- return s(this._length, (e) => this.getX(e), e);
2395
+ return d(this._length, (e) => this.getX(e), e);
2208
2396
  }
2209
2397
  upperBoundX(e) {
2210
- return c(this._length, (e) => this.getX(e), e);
2398
+ return f(this._length, (e) => this.getX(e), e);
2211
2399
  }
2212
2400
  logicalToPhysical(e) {
2213
2401
  return (this._head - this._length + e + this.capacity) % this.capacity;
@@ -2217,6 +2405,6 @@ var ce = class {
2217
2405
  }
2218
2406
  };
2219
2407
  //#endregion
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 };
2408
+ export { j as AxisController, A as Camera2D, pe as Chart, N as DEFAULT_CHART_THEME, n as MinMaxPyramid, ge as OhlcRingBuffer, p as RingBuffer, u as SeriesStore, me as StaticDataset, he as StaticOhlcDataset };
2221
2409
 
2222
2410
  //# sourceMappingURL=index.js.map