@tradecanvas/chart 1.20.0 → 1.21.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
@@ -1,8 +1,8 @@
1
- import { S as e, _ as t, a as n, b as r, c as i, d as a, f as o, g as s, h as c, i as l, l as u, m as ee, n as te, o as ne, p as re, r as ie, s as ae, t as oe, u as se, v as ce, x as le, y as ue } from "./LayoutSession-DepARyHT.js";
2
- import { CHART_STYLE_KEYS as de, DARK_TERMINAL as fe, DARK_THEME as pe, DARK_THEME as me, DEFAULT_DRAWING_STYLE as he, DEFAULT_RECONNECT as d, DEFAULT_SIGNAL_STYLE as f, DEFAULT_STREAM_CONFIG as p, DEFAULT_TIMEFRAME_FAVORITES as m, DEFAULT_TRADE_ZONE_STYLE as h, DEFAULT_TRADING_CONFIG as g, HNX_SESSIONS as _, HOSE_SESSIONS as v, LIGHT_THEME as y, LIGHT_THEME as b, MARKET_CRYPTO as x, MARKET_HNX as S, MARKET_HOSE as C, MARKET_HOSE_ETF as w, MARKET_NYSE as T, MARKET_UPCOM as E, MARKET_VN30F as D, PRICE_SOURCES as O, TC_PALETTE as k, TC_SERIES_COLORS as A, TIMEFRAMES_CRYPTO as j, TIMEFRAMES_FOREX as M, TIMEFRAMES_STOCK as N, UPCOM_SESSIONS as P, VN30F_SESSIONS as F, VN_COLORS as I, VOLUME_ALPHA as L, barsAreDaily as R, computePriceLimits as ge, createVNTheme as _e, formatFraction as ve, formatNumber as ye, formatVND as be, formatVolumeLoc as xe, fractionTick as Se, getCurrentSession as Ce, getLocale as we, indicatorSource as Te, isPriceSource as Ee, isTimeFrame as De, isValidTimeZone as Oe, marketStatus as ke, normalizeBar as Ae, normalizeBarTime as je, offsetAt as Me, parseIndicatorSource as Ne, parseTimeframe as Pe, pickBaseTimeframe as Fe, priceFormatterFor as Ie, priceStepAt as Le, rankSymbols as Re, readNews as ze, readQuote as Be, registerLocale as Ve, resampleBars as He, roundToPriceStep as Ue, scaleMarketPrices as We, setLocale as Ge, sourcePrice as Ke, stepDecimals as qe, t as Je, tickBarCount as Ye, timeframeBucketStart as Xe, timeframeToMs as Ze, vn30fContracts as Qe, vn30fLastTradingDay as $e, volumeColor as et, wallToUtc as tt, zoneOffsetMinutes as nt } from "@tradecanvas/commons";
3
- import { AlertManager as rt, Animator as it, BarCountdown as at, BaseFinanceChart as z, BinanceAdapter as ot, BybitAdapter as st, ChartLegend as ct, ChartStateManager as lt, CoinbaseAdapter as ut, CompareRenderer as dt, CrosshairTooltip as ft, CurrentPriceLine as pt, DEFAULT_LEGEND_CONFIG as B, DEFAULT_MAX_WEBGL_CHARTS as mt, DEFAULT_SESSION_HOURS as ht, DataExporter as gt, DrawingBase as _t, Easing as vt, FinanceCrosshair as V, IndicatorBase as yt, IndicatorValueMap as bt, KeyboardHandler as xt, KrakenAdapter as St, MAX_ALERT_BARS as Ct, MIN_ALERT_BARS as wt, MockAdapter as Tt, PaperExecutionAdapter as Et, PollingAdapter as Dt, RANGE_PRESETS as Ot, ReplayManager as kt, ResamplingAdapter as At, Screenshot as jt, SessionBreaks as Mt, SessionShading as Nt, SignalMarkerManager as Pt, StreamManager as Ft, TickAggregator as It, TickBarAdapter as Lt, TickBarBuilder as Rt, TradeZoneManager as zt, UndoRedoManager as Bt, VolumeRenderer as Vt, Watermark as Ht, WebSocketAdapter as Ut, barIndexToTime as Wt, barIndexToX as Gt, barIndexToX as H, formatTooltipTime as Kt, isPriceLevelAlert as qt, layoutSquarifiedTreemap as Jt, layoutUniformGrid as Yt, lttbDownsample as Xt, lttbVisibleIndices as Zt, priceToY as Qt, priceToYMapper as $t, priceToYMapper as en, rangePresetStart as tn, renderDepthChart as nn, renderEquityCurve as rn, renderGauge as an, renderHeatmap as on, renderSparkline as sn, renderWaterfall as cn, servesTimeframe as ln, setMaxWebGLCharts as un, timeToX as dn, timestampToBarIndex as fn, timestampToBarIndex as pn, toHeikinAshi as mn, toKagi as hn, toLineBreak as gn, toPointAndFigure as _n, toRangeBars as vn, toRenko as yn, withResampling as bn, withTickBars as xn, xToBarIndex as Sn, xToBarIndex as U, xToTime as Cn, yToPrice as wn, yToPrice as Tn } from "@tradecanvas/core";
1
+ import { S as e, _ as t, a as n, b as r, c as i, d as a, f as o, g as s, h as c, i as l, l as u, m as ee, n as te, o as ne, p as re, r as ie, s as ae, t as oe, u as se, v as ce, x as le, y as ue } from "./LayoutSession-CMgqwsEU.js";
2
+ import { CHART_STYLE_KEYS as de, DARK_TERMINAL as fe, DARK_THEME as pe, DARK_THEME as me, DEFAULT_DRAWING_STYLE as he, DEFAULT_RECONNECT as ge, DEFAULT_SIGNAL_STYLE as _e, DEFAULT_STREAM_CONFIG as ve, DEFAULT_TIMEFRAME_FAVORITES as ye, DEFAULT_TRADE_ZONE_STYLE as be, DEFAULT_TRADING_CONFIG as xe, HNX_SESSIONS as Se, HOSE_SESSIONS as d, LIGHT_THEME as f, LIGHT_THEME as p, MARKET_CRYPTO as m, MARKET_HNX as h, MARKET_HOSE as g, MARKET_HOSE_ETF as _, MARKET_NYSE as v, MARKET_UPCOM as y, MARKET_VN30F as b, PRICE_SOURCES as x, TC_PALETTE as S, TC_SERIES_COLORS as C, TIMEFRAMES_CRYPTO as w, TIMEFRAMES_FOREX as T, TIMEFRAMES_STOCK as E, UPCOM_SESSIONS as D, VN30F_SESSIONS as O, VN_COLORS as k, VOLUME_ALPHA as A, barsAreDaily as j, computePriceLimits as Ce, createVNTheme as we, formatFraction as Te, formatNumber as Ee, formatVND as De, formatVolumeLoc as Oe, fractionTick as ke, getCurrentSession as Ae, getLocale as je, indicatorSource as Me, isPriceSource as Ne, isTimeFrame as Pe, isValidTimeZone as Fe, marketStatus as Ie, normalizeBar as Le, normalizeBarTime as Re, offsetAt as ze, parseIndicatorSource as Be, parseTimeframe as Ve, pickBaseTimeframe as He, priceFormatterFor as Ue, priceStepAt as We, rankSymbols as Ge, readNews as Ke, readQuote as qe, registerLocale as Je, resampleBars as Ye, roundToPriceStep as Xe, scaleMarketPrices as Ze, setLocale as Qe, sourcePrice as $e, stepDecimals as et, t as tt, tickBarCount as nt, timeframeBucketStart as rt, timeframeToMs as it, vn30fContracts as at, vn30fLastTradingDay as ot, volumeColor as st, wallToUtc as ct, zoneOffsetMinutes as lt } from "@tradecanvas/commons";
3
+ import { AlertManager as ut, Animator as dt, BarCountdown as ft, BaseFinanceChart as M, BinanceAdapter as pt, BybitAdapter as mt, ChartLegend as ht, ChartStateManager as gt, CoinbaseAdapter as _t, CompareRenderer as vt, CrosshairTooltip as yt, CurrentPriceLine as bt, DEFAULT_LEGEND_CONFIG as xt, DEFAULT_MAX_WEBGL_CHARTS as St, DEFAULT_SESSION_HOURS as Ct, DataExporter as wt, DrawingBase as Tt, Easing as Et, FinanceCrosshair as N, GROUP_HEADER as Dt, IndicatorBase as Ot, IndicatorValueMap as kt, KeyboardHandler as At, KrakenAdapter as jt, MAX_ALERT_BARS as Mt, MIN_ALERT_BARS as Nt, MockAdapter as Pt, PaperExecutionAdapter as Ft, PollingAdapter as P, RANGE_PRESETS as It, ReplayManager as Lt, ResamplingAdapter as Rt, Screenshot as zt, SessionBreaks as Bt, SessionShading as Vt, SignalMarkerManager as Ht, StreamManager as Ut, TickAggregator as Wt, TickBarAdapter as Gt, TickBarBuilder as Kt, TradeZoneManager as qt, UndoRedoManager as Jt, VolumeRenderer as Yt, Watermark as Xt, WebSocketAdapter as Zt, barIndexToTime as Qt, barIndexToX as $t, barIndexToX as F, canvasMeasure as en, computeBarLayout as tn, computeCalendarLayout as nn, computeDonutLayout as rn, computeHistogramLayout as an, computeMatrixLayout as on, computeScatterLayout as sn, correlationMatrix as cn, formatTooltipTime as ln, histogramBins as un, hitBar as I, hitDay as L, hitMatrixCell as R, hitSlice as z, isPriceLevelAlert as dn, layoutGroupedTreemap as fn, layoutSquarifiedTreemap as pn, layoutUniformGrid as mn, lttbDownsample as hn, lttbVisibleIndices as gn, nearestPoint as B, niceScale as _n, priceToY as vn, priceToYMapper as yn, priceToYMapper as bn, rangePresetStart as xn, renderBarChart as Sn, renderCalendar as Cn, renderDepthChart as wn, renderDonut as Tn, renderEquityCurve as En, renderGauge as Dn, renderHeatmap as On, renderHistogram as kn, renderMatrix as An, renderScatter as jn, renderSparkline as Mn, renderWaterfall as Nn, servesTimeframe as Pn, setMaxWebGLCharts as Fn, timeToX as In, timestampToBarIndex as Ln, timestampToBarIndex as Rn, toHeikinAshi as zn, toKagi as Bn, toLineBreak as Vn, toPointAndFigure as Hn, toRangeBars as Un, toRenko as Wn, withResampling as Gn, withTickBars as Kn, xToBarIndex as qn, xToBarIndex as V, xToTime as Jn, yToPrice as Yn, yToPrice as Xn } from "@tradecanvas/core";
4
4
  //#region src/frameworks/syncIndicators.ts
5
- function En(e) {
5
+ function Zn(e) {
6
6
  let { id: t, params: n = {}, position: r = null } = typeof e == "string" ? { id: e } : e;
7
7
  return JSON.stringify([
8
8
  t,
@@ -10,9 +10,9 @@ function En(e) {
10
10
  r
11
11
  ]);
12
12
  }
13
- function Dn(e, t, n) {
13
+ function Qn(e, t, n) {
14
14
  let r = /* @__PURE__ */ new Map(), i = t.map((e) => {
15
- let t = En(e), n = r.get(t) ?? 0;
15
+ let t = Zn(e), n = r.get(t) ?? 0;
16
16
  return r.set(t, n + 1), {
17
17
  spec: e,
18
18
  key: `${t}#${n}`
@@ -27,18 +27,18 @@ function Dn(e, t, n) {
27
27
  }
28
28
  //#endregion
29
29
  //#region src/plugins/overlayScale.ts
30
- function On(e) {
31
- let { viewport: t, data: n } = e, r = en(t), i = n.length - 1, a = Math.max(0, Math.floor(t.visibleRange.from)), o = Math.min(i, Math.ceil(t.visibleRange.to)), s = (e) => n.length > 0 ? pn(e, n) : e;
30
+ function $n(e) {
31
+ let { viewport: t, data: n } = e, r = bn(t), i = n.length - 1, a = Math.max(0, Math.floor(t.visibleRange.from)), o = Math.min(i, Math.ceil(t.visibleRange.to)), s = (e) => n.length > 0 ? Rn(e, n) : e;
32
32
  return {
33
- timeToX: (e) => H(s(e), t),
33
+ timeToX: (e) => F(s(e), t),
34
34
  xToTime: (e) => {
35
- let r = U(e, t);
36
- return n.length > 0 ? Wt(r, n) : r;
35
+ let r = V(e, t);
36
+ return n.length > 0 ? Qt(r, n) : r;
37
37
  },
38
- indexToX: (e) => H(e, t),
39
- xToIndex: (e) => U(e, t),
38
+ indexToX: (e) => F(e, t),
39
+ xToIndex: (e) => V(e, t),
40
40
  priceToY: r,
41
- yToPrice: (e) => Tn(e, t),
41
+ yToPrice: (e) => Xn(e, t),
42
42
  barWidth: t.barWidth,
43
43
  visible: o < a ? {
44
44
  from: 0,
@@ -51,7 +51,7 @@ function On(e) {
51
51
  }
52
52
  //#endregion
53
53
  //#region src/grid/ChartGrid.ts
54
- var W = {
54
+ var H = {
55
55
  "1x1": {
56
56
  cols: 1,
57
57
  rows: 1
@@ -84,7 +84,7 @@ var W = {
84
84
  cols: 2,
85
85
  rows: 3
86
86
  }
87
- }, kn = class {
87
+ }, er = class {
88
88
  root;
89
89
  cells = [];
90
90
  layout;
@@ -95,11 +95,11 @@ var W = {
95
95
  this.options = t, this.layout = t.layout ?? "2x2", this.root = document.createElement("div"), this.root.style.cssText = "display:grid;width:100%;height:100%;overflow:hidden;", e.appendChild(this.root), this.applyLayout(), this.createCells();
96
96
  }
97
97
  applyLayout() {
98
- let { cols: e, rows: t } = W[this.layout], n = this.options.gap ?? 1;
98
+ let { cols: e, rows: t } = H[this.layout], n = this.options.gap ?? 1;
99
99
  this.root.style.gridTemplateColumns = `repeat(${e}, 1fr)`, this.root.style.gridTemplateRows = `repeat(${t}, 1fr)`, this.root.style.gap = `${n}px`;
100
100
  }
101
101
  createCells() {
102
- let { cols: e, rows: t } = W[this.layout], n = e * t;
102
+ let { cols: e, rows: t } = H[this.layout], n = e * t;
103
103
  for (let e = 0; e < n; e++) this.cells.push(this.createCell(e));
104
104
  }
105
105
  createCell(e) {
@@ -144,7 +144,7 @@ var W = {
144
144
  }
145
145
  setLayout(e) {
146
146
  if (e === this.layout) return;
147
- let t = this.cells.length, { cols: n, rows: r } = W[e], i = n * r;
147
+ let t = this.cells.length, { cols: n, rows: r } = H[e], i = n * r;
148
148
  if (i < t) for (let e = t - 1; e >= i; e--) {
149
149
  let t = this.cells[e];
150
150
  t.chart.destroy(), t.container.remove(), this.cells.pop();
@@ -191,13 +191,13 @@ var W = {
191
191
  this.cells = [], this.root.remove();
192
192
  }
193
193
  }
194
- }, An = class extends z {
194
+ }, tr = class extends M {
195
195
  options;
196
196
  constructor(e, t) {
197
197
  super(e, t.theme), this.options = t, this.requestRender();
198
198
  }
199
199
  renderChart(e, t, n, r) {
200
- sn(e, t, n, this.options, r);
200
+ Mn(e, t, n, this.options, r);
201
201
  }
202
202
  update(e) {
203
203
  this.options = {
@@ -211,15 +211,15 @@ var W = {
211
211
  ...e
212
212
  }, this.requestRender();
213
213
  }
214
- }, jn = class extends z {
214
+ }, nr = class extends M {
215
215
  options;
216
216
  crosshair = null;
217
217
  constructor(e, t) {
218
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new V(this.canvas, () => this.requestRender())), this.requestRender();
218
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new N(this.canvas, () => this.requestRender())), this.requestRender();
219
219
  }
220
220
  renderChart(e, t, n, r) {
221
221
  let i = this.crosshair?.getPosition() ?? null;
222
- nn(e, t, n, this.options, r, i);
222
+ wn(e, t, n, this.options, r, i);
223
223
  }
224
224
  update(e) {
225
225
  this.options = {
@@ -236,15 +236,15 @@ var W = {
236
236
  destroy() {
237
237
  this.crosshair?.destroy(), super.destroy();
238
238
  }
239
- }, G = class extends z {
239
+ }, U = class extends M {
240
240
  options;
241
241
  crosshair = null;
242
242
  constructor(e, t) {
243
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new V(this.canvas, () => this.requestRender())), this.requestRender();
243
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new N(this.canvas, () => this.requestRender())), this.requestRender();
244
244
  }
245
245
  renderChart(e, t, n, r) {
246
246
  let i = this.crosshair?.getPosition() ?? null;
247
- rn(e, t, n, this.options, r, i);
247
+ En(e, t, n, this.options, r, i);
248
248
  }
249
249
  update(e, t) {
250
250
  this.options = {
@@ -264,19 +264,24 @@ var W = {
264
264
  destroy() {
265
265
  this.crosshair?.destroy(), super.destroy();
266
266
  }
267
- }, K = class extends z {
267
+ }, W = class extends M {
268
268
  options;
269
269
  crosshair = null;
270
270
  cachedRects = [];
271
+ cachedGroups = [];
271
272
  currentData = [];
272
273
  lastLayoutWidth = 0;
273
274
  lastLayoutHeight = 0;
274
275
  handleClick = null;
275
276
  constructor(e, t) {
276
- super(e, t.theme), this.options = t, this.currentData = t.data ?? [], t.crosshair !== !1 && (this.crosshair = new V(this.canvas, () => this.requestRender())), t.onCellClick && (this.handleClick = (e) => {
277
+ super(e, t.theme), this.options = t, this.currentData = t.data ?? [], t.crosshair !== !1 && (this.crosshair = new N(this.canvas, () => this.requestRender())), t.onCellClick && (this.handleClick = (e) => {
277
278
  let t = this.canvas.getBoundingClientRect(), n = e.clientX - t.left, r = e.clientY - t.top;
278
279
  this.onCanvasClick(n, r);
279
- }, this.canvas.addEventListener("click", this.handleClick)), this.recomputeLayout(), this.requestRender();
280
+ }, this.canvas.addEventListener("click", this.handleClick)), this.applyLabel(), this.recomputeLayout(), this.requestRender();
281
+ }
282
+ applyLabel() {
283
+ let e = new Set(this.currentData.map((e) => e.group).filter(Boolean)).size, t = this.options.grouped && e > 0 ? `Market map of ${this.currentData.length} cells in ${e} groups` : `Heatmap of ${this.currentData.length} cells`;
284
+ this.setLabel(this.options.ariaLabel ?? t);
280
285
  }
281
286
  recomputeLayout() {
282
287
  let e = {
@@ -285,13 +290,21 @@ var W = {
285
290
  width: this.width,
286
291
  height: this.height
287
292
  }, t = this.options.cellPadding ?? 2;
288
- if (this.lastLayoutWidth = this.width, this.lastLayoutHeight = this.height, this.options.weighted) {
293
+ if (this.lastLayoutWidth = this.width, this.lastLayoutHeight = this.height, this.cachedGroups = [], this.options.grouped) {
294
+ let { groups: n, cells: r } = fn(this.currentData.map((e) => ({
295
+ id: e.id,
296
+ weight: e.weight ?? (Math.abs(e.value) || 1),
297
+ group: e.group,
298
+ value: e.value
299
+ })), e, t, Dt);
300
+ this.cachedRects = r, this.cachedGroups = n;
301
+ } else if (this.options.weighted) {
289
302
  let n = this.currentData.map((e) => ({
290
303
  id: e.id,
291
304
  weight: e.weight ?? (Math.abs(e.value) || 1)
292
305
  }));
293
- this.cachedRects = Jt(n, e, t);
294
- } else this.cachedRects = Yt(this.currentData.map((e) => ({ id: e.id })), e, t);
306
+ this.cachedRects = pn(n, e, t);
307
+ } else this.cachedRects = mn(this.currentData.map((e) => ({ id: e.id })), e, t);
295
308
  }
296
309
  onCanvasClick(e, t) {
297
310
  if (this.options.onCellClick) for (let n of this.cachedRects) {
@@ -306,32 +319,32 @@ var W = {
306
319
  renderChart(e, t, n, r) {
307
320
  (t !== this.lastLayoutWidth || n !== this.lastLayoutHeight) && this.recomputeLayout();
308
321
  let i = this.crosshair?.getPosition() ?? null;
309
- on(e, t, n, this.currentData, this.cachedRects, this.options, r, i);
322
+ On(e, t, n, this.currentData, this.cachedRects, this.options, r, i, this.cachedGroups);
310
323
  }
311
324
  update(e) {
312
325
  this.currentData = e, this.options = {
313
326
  ...this.options,
314
327
  data: e
315
- }, this.recomputeLayout(), this.requestRender();
328
+ }, this.applyLabel(), this.recomputeLayout(), this.requestRender();
316
329
  }
317
330
  setOptions(e) {
318
331
  this.options = {
319
332
  ...this.options,
320
333
  ...e
321
- }, e.data && (this.currentData = e.data), this.recomputeLayout(), this.requestRender();
334
+ }, e.data && (this.currentData = e.data), this.applyLabel(), this.recomputeLayout(), this.requestRender();
322
335
  }
323
336
  destroy() {
324
337
  this.crosshair?.destroy(), this.handleClick && this.canvas.removeEventListener("click", this.handleClick), super.destroy();
325
338
  }
326
- }, Mn = class extends z {
339
+ }, rr = class extends M {
327
340
  options;
328
341
  crosshair = null;
329
342
  constructor(e, t) {
330
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new V(this.canvas, () => this.requestRender())), this.requestRender();
343
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new N(this.canvas, () => this.requestRender())), this.requestRender();
331
344
  }
332
345
  renderChart(e, t, n, r) {
333
346
  let i = this.crosshair?.getPosition() ?? null;
334
- cn(e, t, n, this.options, r, i);
347
+ Nn(e, t, n, this.options, r, i);
335
348
  }
336
349
  update(e) {
337
350
  this.options = {
@@ -348,12 +361,12 @@ var W = {
348
361
  destroy() {
349
362
  this.crosshair?.destroy(), super.destroy();
350
363
  }
351
- }, Nn = 500;
352
- function Pn(e) {
364
+ }, ir = 500;
365
+ function ar(e) {
353
366
  let t = 1 - e;
354
367
  return 1 - t * t * t;
355
368
  }
356
- var Fn = class extends z {
369
+ var or = class extends M {
357
370
  options;
358
371
  currentValue;
359
372
  targetValue;
@@ -364,7 +377,7 @@ var Fn = class extends z {
364
377
  super(e, t.theme), this.options = t, this.currentValue = t.value, this.targetValue = t.value, this.requestRender();
365
378
  }
366
379
  renderChart(e, t, n, r) {
367
- an(e, t, n, this.options, r, this.currentValue);
380
+ Dn(e, t, n, this.options, r, this.currentValue);
368
381
  }
369
382
  setValue(e) {
370
383
  if (this.options.animate === !1) {
@@ -394,7 +407,7 @@ var Fn = class extends z {
394
407
  if (this.animationFrameId !== null) return;
395
408
  let e = () => {
396
409
  if (this.animationFrameId = null, this.animationStart === null) return;
397
- let t = this.options.animationDuration ?? Nn, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = Pn(r);
410
+ let t = this.options.animationDuration ?? ir, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = ar(r);
398
411
  this.currentValue = this.animationFrom + (this.targetValue - this.animationFrom) * i, this.requestRender(), r < 1 ? this.animationFrameId = requestAnimationFrame(e) : (this.currentValue = this.targetValue, this.animationStart = null);
399
412
  };
400
413
  this.animationFrameId = requestAnimationFrame(e);
@@ -405,7 +418,192 @@ var Fn = class extends z {
405
418
  destroy() {
406
419
  this.cancelAnimation(), super.destroy();
407
420
  }
408
- }, In = [
421
+ }, G = class extends M {
422
+ options;
423
+ layout = null;
424
+ layoutFor = null;
425
+ crosshair;
426
+ onClick = (e) => {
427
+ let t = this.canvas.getBoundingClientRect();
428
+ this.layout && this.clickAt(this.layout, e.clientX - t.left, e.clientY - t.top);
429
+ };
430
+ onMove = (e) => {
431
+ if (!this.layout || !this.clickable()) return;
432
+ let t = this.canvas.getBoundingClientRect();
433
+ this.canvas.style.cursor = this.hits(this.layout, e.clientX - t.left, e.clientY - t.top) ? "pointer" : "";
434
+ };
435
+ constructor(e, t) {
436
+ super(e, t.theme), this.options = t, this.crosshair = new N(this.canvas, () => this.requestRender()), this.canvas.addEventListener("click", this.onClick), this.canvas.addEventListener("pointermove", this.onMove), this.applyLabel(), this.requestRender();
437
+ }
438
+ renderChart(e, t, n, r) {
439
+ let i = this.options.crosshair === !1 ? null : this.crosshair.getPosition(), a = this.layoutFor;
440
+ (!this.layout || !a || a.options !== this.options || a.width !== t || a.height !== n || a.theme !== r) && (this.layout = this.compute(t, n, r, en(e, r)), this.layoutFor = {
441
+ options: this.options,
442
+ width: t,
443
+ height: n,
444
+ theme: r
445
+ }), this.draw(e, t, n, r, i, this.layout);
446
+ }
447
+ setOptions(e) {
448
+ this.options = {
449
+ ...this.options,
450
+ ...e
451
+ }, "theme" in e && this.setTheme(e.theme ?? "dark"), this.applyLabel(), this.requestRender();
452
+ }
453
+ applyLabel() {
454
+ this.setLabel(this.options.ariaLabel ?? this.describe());
455
+ }
456
+ destroy() {
457
+ this.crosshair.destroy(), this.canvas.removeEventListener("click", this.onClick), this.canvas.removeEventListener("pointermove", this.onMove), super.destroy();
458
+ }
459
+ }, sr = class extends G {
460
+ compute(e, t, n, r) {
461
+ return tn(this.options, e, t, n, r);
462
+ }
463
+ draw(e, t, n, r, i, a) {
464
+ Sn(e, t, n, this.options, r, i, a);
465
+ }
466
+ describe() {
467
+ return `Bar chart of ${this.options.series.map((e) => e.name).join(", ")}, ${this.options.categories.length} categories`;
468
+ }
469
+ clickable() {
470
+ return this.options.onBarClick !== void 0;
471
+ }
472
+ hits(e, t, n) {
473
+ return I(e, t, n) !== null;
474
+ }
475
+ clickAt(e, t, n) {
476
+ let r = I(e, t, n);
477
+ r && this.options.onBarClick?.({
478
+ category: r.category,
479
+ series: r.series,
480
+ value: r.value,
481
+ index: r.index
482
+ });
483
+ }
484
+ update(e, t) {
485
+ this.setOptions({
486
+ categories: e,
487
+ series: t
488
+ });
489
+ }
490
+ }, cr = class extends G {
491
+ compute(e, t, n, r) {
492
+ return rn(this.options, e, t, n, r);
493
+ }
494
+ draw(e, t, n, r, i, a) {
495
+ Tn(e, t, n, this.options, r, i, a);
496
+ }
497
+ describe() {
498
+ let e = this.options.data.filter((e) => Number.isFinite(e.value) && e.value > 0).map((e) => e.label).join(", ");
499
+ return `${(this.options.innerRadius ?? .6) > 0 ? "Donut" : "Pie"} chart of ${e}`;
500
+ }
501
+ clickable() {
502
+ return this.options.onSliceClick !== void 0;
503
+ }
504
+ hits(e, t, n) {
505
+ return z(e, t, n) !== null;
506
+ }
507
+ clickAt(e, t, n) {
508
+ let r = z(e, t, n);
509
+ r && this.options.onSliceClick?.(r.slice);
510
+ }
511
+ update(e) {
512
+ this.setOptions({ data: e });
513
+ }
514
+ }, lr = class extends G {
515
+ compute(e, t, n, r) {
516
+ return sn(this.options, e, t, n, r);
517
+ }
518
+ draw(e, t, n, r, i, a) {
519
+ jn(e, t, n, this.options, r, i, a);
520
+ }
521
+ describe() {
522
+ let e = this.options.series.reduce((e, t) => e + t.points.length, 0);
523
+ return `Scatter chart${this.options.xLabel && this.options.yLabel ? ` of ${this.options.yLabel} against ${this.options.xLabel}` : ""}, ${e} points`;
524
+ }
525
+ clickable() {
526
+ return this.options.onPointClick !== void 0;
527
+ }
528
+ hits(e, t, n) {
529
+ return B(e, t, n) !== null;
530
+ }
531
+ clickAt(e, t, n) {
532
+ let r = B(e, t, n);
533
+ r && this.options.onPointClick?.(r.point, r.series);
534
+ }
535
+ update(e) {
536
+ this.setOptions({ series: e });
537
+ }
538
+ }, ur = class extends G {
539
+ compute(e, t, n, r) {
540
+ return an(this.options, e, t, n, r);
541
+ }
542
+ draw(e, t, n, r, i, a) {
543
+ kn(e, t, n, this.options, r, i, a);
544
+ }
545
+ describe() {
546
+ return `Histogram of ${this.options.values.length} values`;
547
+ }
548
+ clickable() {
549
+ return !1;
550
+ }
551
+ hits() {
552
+ return !1;
553
+ }
554
+ clickAt() {}
555
+ update(e) {
556
+ this.setOptions({ values: e });
557
+ }
558
+ }, dr = class extends G {
559
+ compute(e, t, n, r) {
560
+ return nn(this.options, e, t, n, r);
561
+ }
562
+ draw(e, t, n, r, i, a) {
563
+ Cn(e, t, n, this.options, r, i, a);
564
+ }
565
+ describe() {
566
+ let e = this.options.data.map((e) => e.date).filter((e) => /^\d{4}-\d{2}-\d{2}$/.test(e)).sort(), t = this.options.from ?? e[0], n = this.options.to ?? e[e.length - 1];
567
+ return t && n ? `Calendar of daily values from ${t} to ${n}` : "Calendar of daily values";
568
+ }
569
+ clickable() {
570
+ return this.options.onDayClick !== void 0;
571
+ }
572
+ hits(e, t, n) {
573
+ return L(e, t, n)?.day !== void 0;
574
+ }
575
+ clickAt(e, t, n) {
576
+ let r = L(e, t, n)?.day;
577
+ r && this.options.onDayClick?.(r);
578
+ }
579
+ update(e) {
580
+ this.setOptions({ data: e });
581
+ }
582
+ }, K = 12, fr = class extends G {
583
+ compute(e, t, n, r) {
584
+ return on(this.options, e, t, n, r);
585
+ }
586
+ draw(e, t, n, r, i, a) {
587
+ An(e, t, n, this.options, r, i, a);
588
+ }
589
+ describe() {
590
+ let { rows: e, columns: t } = this.options;
591
+ return t ? e.length + t.length <= K ? `Matrix of ${e.join(", ")} by ${t.join(", ")}` : `Matrix of ${e.length} rows by ${t.length} columns` : e.length <= K ? `Matrix of ${e.join(", ")}` : `Matrix of ${e.length} rows`;
592
+ }
593
+ clickable() {
594
+ return this.options.onCellClick !== void 0;
595
+ }
596
+ hits(e, t, n) {
597
+ return R(e, t, n) !== null;
598
+ }
599
+ clickAt(e, t, n) {
600
+ let r = R(e, t, n);
601
+ r && this.options.onCellClick?.(r.cell);
602
+ }
603
+ update(e) {
604
+ this.setOptions({ values: e });
605
+ }
606
+ }, pr = [
409
607
  "Jan",
410
608
  "Feb",
411
609
  "Mar",
@@ -440,7 +638,7 @@ function Y(e) {
440
638
  if (e.length === 0) return [];
441
639
  let t = [];
442
640
  for (let n of e) {
443
- let e = Xe(n.time, "1M"), r = t[t.length - 1];
641
+ let e = rt(n.time, "1M"), r = t[t.length - 1];
444
642
  r && r.key === e ? r.close = n.equity : t.push({
445
643
  key: e,
446
644
  close: n.equity
@@ -453,7 +651,7 @@ function Y(e) {
453
651
  let a = new Date(e.key), o = a.getUTCFullYear(), s = a.getUTCMonth();
454
652
  r.push({
455
653
  id: `${o}-${String(s + 1).padStart(2, "0")}`,
456
- label: In[s],
654
+ label: pr[s],
457
655
  group: String(o),
458
656
  value: i
459
657
  });
@@ -513,9 +711,9 @@ function Q(e) {
513
711
  //#endregion
514
712
  //#region src/finance/PerformanceDashboard.ts
515
713
  function $(e) {
516
- return !e || e === "dark" ? me : e === "light" ? b : e;
714
+ return !e || e === "dark" ? me : e === "light" ? p : e;
517
715
  }
518
- var Ln = class {
716
+ var mr = class {
519
717
  options;
520
718
  theme;
521
719
  root;
@@ -558,7 +756,7 @@ var Ln = class {
558
756
  "gap:14px"
559
757
  ].join(";"), this.root.appendChild(o);
560
758
  let s = this.buildPanel("Equity Curve", i, a);
561
- s.wrap.style.gridColumn = "1 / -1", o.appendChild(s.wrap), this.equityChart = new G(s.body, {
759
+ s.wrap.style.gridColumn = "1 / -1", o.appendChild(s.wrap), this.equityChart = new U(s.body, {
562
760
  data: q(t.equityCurve),
563
761
  theme: e,
564
762
  lineColor: e.candleUp,
@@ -566,7 +764,7 @@ var Ln = class {
566
764
  crosshair: !0
567
765
  });
568
766
  let c = this.buildPanel("Drawdown", i, a);
569
- o.appendChild(c.wrap), this.drawdownChart = new G(c.body, {
767
+ o.appendChild(c.wrap), this.drawdownChart = new U(c.body, {
570
768
  data: J(t.equityCurve),
571
769
  theme: e,
572
770
  lineColor: e.candleDown,
@@ -575,7 +773,7 @@ var Ln = class {
575
773
  valueFormat: (e) => `${e.toFixed(1)}%`
576
774
  });
577
775
  let l = Y(t.equityCurve), u = this.buildPanel("Monthly Returns", i, a);
578
- o.appendChild(u.wrap), this.heatmap = new K(u.body, {
776
+ o.appendChild(u.wrap), this.heatmap = new W(u.body, {
579
777
  data: l,
580
778
  theme: e,
581
779
  showValues: !0,
@@ -664,6 +862,6 @@ var Ln = class {
664
862
  }
665
863
  };
666
864
  //#endregion
667
- export { rt as AlertManager, it as Animator, at as BarCountdown, ot as BinanceAdapter, st as BybitAdapter, de as CHART_STYLE_KEYS, i as Chart, kn as ChartGrid, ct as ChartLegend, lt as ChartStateManager, ut as CoinbaseAdapter, dt as CompareRenderer, ft as CrosshairTooltip, pt as CurrentPriceLine, fe as DARK_TERMINAL, pe as DARK_THEME, he as DEFAULT_DRAWING_STYLE, r as DEFAULT_HISTORY_PAGE_SIZE, B as DEFAULT_LEGEND_CONFIG, mt as DEFAULT_MAX_WEBGL_CHARTS, d as DEFAULT_RECONNECT, ht as DEFAULT_SESSION_HOURS, f as DEFAULT_SIGNAL_STYLE, p as DEFAULT_STREAM_CONFIG, m as DEFAULT_TIMEFRAME_FAVORITES, h as DEFAULT_TRADE_ZONE_STYLE, g as DEFAULT_TRADING_CONFIG, gt as DataExporter, e as DataManager, jn as DepthChart, ne as DragDropImporter, _t as DrawingBase, u as EXCHANGE_TIMEZONE, vt as Easing, G as EquityCurveChart, Fn as GaugeChart, le as HISTORY_RETRY_MS, _ as HNX_SESSIONS, v as HOSE_SESSIONS, K as HeatmapChart, yt as IndicatorBase, bt as IndicatorValueMap, xt as KeyboardHandler, St as KrakenAdapter, y as LIGHT_THEME, ce as LayoutManager, oe as LayoutSession, x as MARKET_CRYPTO, S as MARKET_HNX, C as MARKET_HOSE, w as MARKET_HOSE_ETF, T as MARKET_NYSE, E as MARKET_UPCOM, D as MARKET_VN30F, Ct as MAX_ALERT_BARS, te as MAX_LAYOUT_NAME, wt as MIN_ALERT_BARS, Tt as MockAdapter, c as PLUGIN_API_VERSION, O as PRICE_SOURCES, Et as PaperExecutionAdapter, Ln as PerformanceDashboard, se as PluginManager, Dt as PollingAdapter, Ot as RANGE_PRESETS, kt as ReplayManager, At as ResamplingAdapter, jt as Screenshot, Mt as SessionBreaks, Nt as SessionShading, Pt as SignalMarkerManager, An as SparklineChart, Ft as StreamManager, k as TC_PALETTE, A as TC_SERIES_COLORS, j as TIMEFRAMES_CRYPTO, M as TIMEFRAMES_FOREX, N as TIMEFRAMES_STOCK, ue as ThemeManager, It as TickAggregator, Lt as TickBarAdapter, Rt as TickBarBuilder, zt as TradeZoneManager, P as UPCOM_SESSIONS, Bt as UndoRedoManager, F as VN30F_SESSIONS, I as VN_COLORS, L as VOLUME_ALPHA, Vt as VolumeRenderer, Mn as WaterfallChart, Ht as Watermark, Ut as WebSocketAdapter, Gt as barIndexToX, R as barsAreDaily, ie as cleanLayoutName, a as clearGlobalPlugins, J as computeDrawdownCurve, Y as computeMonthlyReturns, ge as computePriceLimits, _e as createVNTheme, ve as formatFraction, ye as formatNumber, Kt as formatTooltipTime, be as formatVND, xe as formatVolumeLoc, Se as fractionTick, Ce as getCurrentSession, o as getGlobalPlugins, we as getLocale, Te as indicatorSource, qt as isPriceLevelAlert, Ee as isPriceSource, De as isTimeFrame, Oe as isValidTimeZone, l as localStorageLayouts, Xt as lttbDownsample, Zt as lttbVisibleIndices, ke as marketStatus, n as memoryLayouts, Ae as normalizeBar, je as normalizeBarTime, Me as offsetAt, On as overlayScale, s as overlaysForLayer, Ne as parseIndicatorSource, ae as parseOHLCV, Pe as parseTimeframe, Fe as pickBaseTimeframe, t as pluginKey, Ie as priceFormatterFor, Le as priceStepAt, Qt as priceToY, $t as priceToYMapper, tn as rangePresetStart, Re as rankSymbols, ze as readNews, Be as readQuote, Ve as registerLocale, re as registerPlugin, He as resampleBars, Ue as roundToPriceStep, We as scaleMarketPrices, Q as selectKeyStats, ln as servesTimeframe, Ge as setLocale, un as setMaxWebGLCharts, Ke as sourcePrice, qe as stepDecimals, Dn as syncIndicators, Je as t, Ye as tickBarCount, dn as timeToX, Ze as timeframeToMs, fn as timestampToBarIndex, q as toEquityPoints, mn as toHeikinAshi, hn as toKagi, gn as toLineBreak, _n as toPointAndFigure, vn as toRangeBars, yn as toRenko, ee as unregisterPlugin, Qe as vn30fContracts, $e as vn30fLastTradingDay, et as volumeColor, tt as wallToUtc, bn as withResampling, xn as withTickBars, Sn as xToBarIndex, Cn as xToTime, wn as yToPrice, nt as zoneOffsetMinutes };
865
+ export { ut as AlertManager, dt as Animator, sr as BarChart, ft as BarCountdown, pt as BinanceAdapter, mt as BybitAdapter, de as CHART_STYLE_KEYS, dr as CalendarChart, i as Chart, er as ChartGrid, ht as ChartLegend, gt as ChartStateManager, _t as CoinbaseAdapter, vt as CompareRenderer, yt as CrosshairTooltip, bt as CurrentPriceLine, fe as DARK_TERMINAL, pe as DARK_THEME, he as DEFAULT_DRAWING_STYLE, r as DEFAULT_HISTORY_PAGE_SIZE, xt as DEFAULT_LEGEND_CONFIG, St as DEFAULT_MAX_WEBGL_CHARTS, ge as DEFAULT_RECONNECT, Ct as DEFAULT_SESSION_HOURS, _e as DEFAULT_SIGNAL_STYLE, ve as DEFAULT_STREAM_CONFIG, ye as DEFAULT_TIMEFRAME_FAVORITES, be as DEFAULT_TRADE_ZONE_STYLE, xe as DEFAULT_TRADING_CONFIG, wt as DataExporter, e as DataManager, nr as DepthChart, cr as DonutChart, ne as DragDropImporter, Tt as DrawingBase, u as EXCHANGE_TIMEZONE, Et as Easing, U as EquityCurveChart, or as GaugeChart, le as HISTORY_RETRY_MS, Se as HNX_SESSIONS, d as HOSE_SESSIONS, W as HeatmapChart, ur as HistogramChart, Ot as IndicatorBase, kt as IndicatorValueMap, At as KeyboardHandler, jt as KrakenAdapter, f as LIGHT_THEME, ce as LayoutManager, oe as LayoutSession, m as MARKET_CRYPTO, h as MARKET_HNX, g as MARKET_HOSE, _ as MARKET_HOSE_ETF, v as MARKET_NYSE, y as MARKET_UPCOM, b as MARKET_VN30F, Mt as MAX_ALERT_BARS, te as MAX_LAYOUT_NAME, Nt as MIN_ALERT_BARS, fr as MatrixChart, Pt as MockAdapter, c as PLUGIN_API_VERSION, x as PRICE_SOURCES, Ft as PaperExecutionAdapter, mr as PerformanceDashboard, se as PluginManager, P as PollingAdapter, It as RANGE_PRESETS, Lt as ReplayManager, Rt as ResamplingAdapter, lr as ScatterChart, zt as Screenshot, Bt as SessionBreaks, Vt as SessionShading, Ht as SignalMarkerManager, tr as SparklineChart, Ut as StreamManager, S as TC_PALETTE, C as TC_SERIES_COLORS, w as TIMEFRAMES_CRYPTO, T as TIMEFRAMES_FOREX, E as TIMEFRAMES_STOCK, ue as ThemeManager, Wt as TickAggregator, Gt as TickBarAdapter, Kt as TickBarBuilder, qt as TradeZoneManager, D as UPCOM_SESSIONS, Jt as UndoRedoManager, O as VN30F_SESSIONS, k as VN_COLORS, A as VOLUME_ALPHA, Yt as VolumeRenderer, rr as WaterfallChart, Xt as Watermark, Zt as WebSocketAdapter, $t as barIndexToX, j as barsAreDaily, ie as cleanLayoutName, a as clearGlobalPlugins, J as computeDrawdownCurve, Y as computeMonthlyReturns, Ce as computePriceLimits, cn as correlationMatrix, we as createVNTheme, Te as formatFraction, Ee as formatNumber, ln as formatTooltipTime, De as formatVND, Oe as formatVolumeLoc, ke as fractionTick, Ae as getCurrentSession, o as getGlobalPlugins, je as getLocale, un as histogramBins, Me as indicatorSource, dn as isPriceLevelAlert, Ne as isPriceSource, Pe as isTimeFrame, Fe as isValidTimeZone, l as localStorageLayouts, hn as lttbDownsample, gn as lttbVisibleIndices, Ie as marketStatus, n as memoryLayouts, _n as niceScale, Le as normalizeBar, Re as normalizeBarTime, ze as offsetAt, $n as overlayScale, s as overlaysForLayer, Be as parseIndicatorSource, ae as parseOHLCV, Ve as parseTimeframe, He as pickBaseTimeframe, t as pluginKey, Ue as priceFormatterFor, We as priceStepAt, vn as priceToY, yn as priceToYMapper, xn as rangePresetStart, Ge as rankSymbols, Ke as readNews, qe as readQuote, Je as registerLocale, re as registerPlugin, Ye as resampleBars, Xe as roundToPriceStep, Ze as scaleMarketPrices, Q as selectKeyStats, Pn as servesTimeframe, Qe as setLocale, Fn as setMaxWebGLCharts, $e as sourcePrice, et as stepDecimals, Qn as syncIndicators, tt as t, nt as tickBarCount, In as timeToX, it as timeframeToMs, Ln as timestampToBarIndex, q as toEquityPoints, zn as toHeikinAshi, Bn as toKagi, Vn as toLineBreak, Hn as toPointAndFigure, Un as toRangeBars, Wn as toRenko, ee as unregisterPlugin, at as vn30fContracts, ot as vn30fLastTradingDay, st as volumeColor, ct as wallToUtc, Gn as withResampling, Kn as withTickBars, qn as xToBarIndex, Jn as xToTime, Yn as yToPrice, lt as zoneOffsetMinutes };
668
866
 
669
867
  //# sourceMappingURL=index.js.map