@tradecanvas/chart 0.6.0 → 0.7.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
@@ -1,14 +1,169 @@
1
- import { a as e, i as t, n, r, t as i } from "./Chart-CrrTKx3r.js";
2
- import { DARK_TERMINAL as a, DARK_THEME as ee, DEFAULT_DRAWING_STYLE as te, DEFAULT_RECONNECT as o, DEFAULT_STREAM_CONFIG as s, DEFAULT_TIMEFRAME_FAVORITES as c, DEFAULT_TRADING_CONFIG as l, LIGHT_THEME as u, MARKET_CRYPTO as d, MARKET_HNX as f, MARKET_HOSE as p, MARKET_NYSE as m, MARKET_UPCOM as h, TIMEFRAMES_CRYPTO as g, TIMEFRAMES_FOREX as _, TIMEFRAMES_STOCK as v, VN_COLORS as y, computePriceLimits as b, createVNTheme as x, formatNumber as S, formatVND as C, formatVolumeLoc as w, getCurrentSession as T, getLocale as E, normalizeBar as D, normalizeBarTime as O, registerLocale as k, setLocale as A, t as j } from "@tradecanvas/commons";
3
- import { AlertManager as M, Animator as N, BarCountdown as P, BaseFinanceChart as F, BinanceAdapter as I, ChartLegend as L, ChartStateManager as R, CompareRenderer as z, CrosshairTooltip as B, CurrentPriceLine as V, DEFAULT_LEGEND_CONFIG as H, DataExporter as U, DrawingBase as W, Easing as G, FinanceCrosshair as K, IndicatorBase as q, KeyboardHandler as J, MockAdapter as Y, ReplayManager as X, Screenshot as Z, SessionBreaks as Q, StreamManager as ne, TickAggregator as re, UndoRedoManager as ie, VolumeRenderer as ae, Watermark as oe, layoutSquarifiedTreemap as se, layoutUniformGrid as ce, renderDepthChart as le, renderEquityCurve as ue, renderGauge as de, renderHeatmap as fe, renderSparkline as pe, renderWaterfall as me, toHeikinAshi as he, toKagi as ge, toLineBreak as _e, toPointAndFigure as ve, toRangeBars as ye, toRenko as be } from "@tradecanvas/core";
4
- //#region src/finance/SparklineChart.ts
5
- var $ = class extends F {
1
+ import { a as e, i as t, n, r, t as i } from "./Chart-Cy8K3wHS.js";
2
+ import { DARK_TERMINAL as a, DARK_THEME as o, DEFAULT_DRAWING_STYLE as ee, DEFAULT_RECONNECT as te, DEFAULT_SIGNAL_STYLE as ne, DEFAULT_STREAM_CONFIG as s, DEFAULT_TIMEFRAME_FAVORITES as c, DEFAULT_TRADE_ZONE_STYLE as l, DEFAULT_TRADING_CONFIG as u, LIGHT_THEME as d, MARKET_CRYPTO as f, MARKET_HNX as p, MARKET_HOSE as m, MARKET_NYSE as h, MARKET_UPCOM as g, TIMEFRAMES_CRYPTO as _, TIMEFRAMES_FOREX as v, TIMEFRAMES_STOCK as y, VN_COLORS as b, computePriceLimits as x, createVNTheme as S, formatNumber as C, formatVND as w, formatVolumeLoc as T, getCurrentSession as E, getLocale as D, normalizeBar as O, normalizeBarTime as k, registerLocale as A, setLocale as j, t as M } from "@tradecanvas/commons";
3
+ import { AlertManager as N, Animator as P, BarCountdown as F, BaseFinanceChart as I, BinanceAdapter as L, ChartLegend as R, ChartStateManager as z, CompareRenderer as B, CrosshairTooltip as V, CurrentPriceLine as H, DEFAULT_LEGEND_CONFIG as U, DataExporter as W, DrawingBase as G, Easing as K, FinanceCrosshair as q, IndicatorBase as J, KeyboardHandler as Y, MockAdapter as X, ReplayManager as Z, Screenshot as re, SessionBreaks as ie, SignalMarkerManager as ae, StreamManager as oe, TickAggregator as se, TradeZoneManager as ce, UndoRedoManager as le, VolumeRenderer as ue, Watermark as de, layoutSquarifiedTreemap as fe, layoutUniformGrid as pe, renderDepthChart as me, renderEquityCurve as he, renderGauge as ge, renderHeatmap as _e, renderSparkline as ve, renderWaterfall as ye, toHeikinAshi as be, toKagi as xe, toLineBreak as Se, toPointAndFigure as Ce, toRangeBars as we, toRenko as Te } from "@tradecanvas/core";
4
+ //#region src/grid/ChartGrid.ts
5
+ var Q = {
6
+ "1x1": {
7
+ cols: 1,
8
+ rows: 1
9
+ },
10
+ "1x2": {
11
+ cols: 2,
12
+ rows: 1
13
+ },
14
+ "2x1": {
15
+ cols: 1,
16
+ rows: 2
17
+ },
18
+ "2x2": {
19
+ cols: 2,
20
+ rows: 2
21
+ },
22
+ "1x3": {
23
+ cols: 3,
24
+ rows: 1
25
+ },
26
+ "3x1": {
27
+ cols: 1,
28
+ rows: 3
29
+ },
30
+ "2x3": {
31
+ cols: 3,
32
+ rows: 2
33
+ },
34
+ "3x2": {
35
+ cols: 2,
36
+ rows: 3
37
+ }
38
+ }, Ee = class {
39
+ root;
40
+ cells = [];
41
+ layout;
42
+ options;
43
+ destroyed = !1;
44
+ syncing = !1;
45
+ constructor(e, t = {}) {
46
+ 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();
47
+ }
48
+ applyLayout() {
49
+ let { cols: e, rows: t } = Q[this.layout], n = this.options.gap ?? 1;
50
+ this.root.style.gridTemplateColumns = `repeat(${e}, 1fr)`, this.root.style.gridTemplateRows = `repeat(${t}, 1fr)`, this.root.style.gap = `${n}px`;
51
+ }
52
+ createCells() {
53
+ let { cols: e, rows: t } = Q[this.layout], n = e * t;
54
+ for (let e = 0; e < n; e++) {
55
+ let t = this.options.cells?.[e] ?? {}, n = document.createElement("div");
56
+ n.style.cssText = "position:relative;overflow:hidden;min-width:0;min-height:0;", this.root.appendChild(n);
57
+ let r = new i(n, {
58
+ chartType: "candlestick",
59
+ autoScale: !0,
60
+ features: {
61
+ crosshair: !0,
62
+ keyboard: !0,
63
+ volume: !0,
64
+ legend: !0,
65
+ priceAxis: !0,
66
+ timeAxis: !0,
67
+ grid: !0
68
+ },
69
+ ...this.options.chartOptions,
70
+ ...t.chartOptions,
71
+ theme: this.options.theme
72
+ }), a = {
73
+ container: n,
74
+ chart: r,
75
+ symbol: t.symbol ?? `Chart ${e + 1}`,
76
+ timeframe: t.timeframe ?? "5m"
77
+ };
78
+ this.options.syncCrosshair !== !1 && r.on("crosshairMove", (e) => {
79
+ if (!this.syncing) {
80
+ this.syncing = !0;
81
+ for (let t of this.cells) t.chart !== r && t.chart.setCrosshairPosition(e.payload.point);
82
+ this.syncing = !1;
83
+ }
84
+ }), this.options.syncTimeAxis !== !1 && r.on("visibleRangeChange", (e) => {
85
+ if (this.syncing) return;
86
+ this.syncing = !0;
87
+ let { from: t, to: n } = e.payload, i = r.getData();
88
+ if (i.length > 0 && t >= 0 && n < i.length) {
89
+ let e = i[t]?.time, a = i[n]?.time;
90
+ if (e && a) for (let t of this.cells) t.chart !== r && t.chart.setVisibleRange(e, a);
91
+ }
92
+ this.syncing = !1;
93
+ }), this.cells.push(a);
94
+ }
95
+ }
96
+ setLayout(e) {
97
+ if (e === this.layout) return;
98
+ let t = this.cells.length, { cols: n, rows: r } = Q[e], a = n * r;
99
+ if (a < t) for (let e = t - 1; e >= a; e--) {
100
+ let t = this.cells[e];
101
+ t.chart.destroy(), t.container.remove(), this.cells.pop();
102
+ }
103
+ if (this.layout = e, this.applyLayout(), a > t) for (let e = t; e < a; e++) {
104
+ let t = this.options.cells?.[e] ?? {}, n = document.createElement("div");
105
+ n.style.cssText = "position:relative;overflow:hidden;min-width:0;min-height:0;", this.root.appendChild(n);
106
+ let r = new i(n, {
107
+ chartType: "candlestick",
108
+ autoScale: !0,
109
+ ...this.options.chartOptions,
110
+ ...t.chartOptions,
111
+ theme: this.options.theme
112
+ });
113
+ this.cells.push({
114
+ container: n,
115
+ chart: r,
116
+ symbol: t.symbol ?? `Chart ${e + 1}`,
117
+ timeframe: t.timeframe ?? "5m"
118
+ });
119
+ }
120
+ }
121
+ getChart(e) {
122
+ return this.cells[e]?.chart ?? null;
123
+ }
124
+ getCharts() {
125
+ return this.cells.map((e) => e.chart);
126
+ }
127
+ getCellCount() {
128
+ return this.cells.length;
129
+ }
130
+ setData(e, t) {
131
+ this.cells[e]?.chart.setData(t);
132
+ }
133
+ setAllData(e) {
134
+ for (let t of this.cells) t.chart.setData(e);
135
+ }
136
+ async connectCell(e, t) {
137
+ let n = this.cells[e];
138
+ n && (n.symbol = t.symbol, n.timeframe = t.timeframe, await n.chart.connect(t));
139
+ }
140
+ async connectAll(e, t, n, r = 500) {
141
+ let i = [];
142
+ for (let a = 0; a < this.cells.length && a < t.length; a++) i.push(this.connectCell(a, {
143
+ adapter: e,
144
+ symbol: t[a],
145
+ timeframe: n,
146
+ historyLimit: r
147
+ }));
148
+ await Promise.all(i);
149
+ }
150
+ setTheme(e) {
151
+ for (let t of this.cells) t.chart.setTheme(e);
152
+ }
153
+ destroy() {
154
+ if (!this.destroyed) {
155
+ this.destroyed = !0;
156
+ for (let e of this.cells) e.chart.destroy(), e.container.remove();
157
+ this.cells = [], this.root.remove();
158
+ }
159
+ }
160
+ }, De = class extends I {
6
161
  options;
7
162
  constructor(e, t) {
8
163
  super(e, t.theme), this.options = t, this.requestRender();
9
164
  }
10
165
  renderChart(e, t, n, r) {
11
- pe(e, t, n, this.options, r);
166
+ ve(e, t, n, this.options, r);
12
167
  }
13
168
  update(e) {
14
169
  this.options = {
@@ -22,15 +177,15 @@ var $ = class extends F {
22
177
  ...e
23
178
  }, this.requestRender();
24
179
  }
25
- }, xe = class extends F {
180
+ }, $ = class extends I {
26
181
  options;
27
182
  crosshair = null;
28
183
  constructor(e, t) {
29
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new K(this.canvas, () => this.requestRender())), this.requestRender();
184
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new q(this.canvas, () => this.requestRender())), this.requestRender();
30
185
  }
31
186
  renderChart(e, t, n, r) {
32
187
  let i = this.crosshair?.getPosition() ?? null;
33
- le(e, t, n, this.options, r, i);
188
+ me(e, t, n, this.options, r, i);
34
189
  }
35
190
  update(e) {
36
191
  this.options = {
@@ -47,15 +202,15 @@ var $ = class extends F {
47
202
  destroy() {
48
203
  this.crosshair?.destroy(), super.destroy();
49
204
  }
50
- }, Se = class extends F {
205
+ }, Oe = class extends I {
51
206
  options;
52
207
  crosshair = null;
53
208
  constructor(e, t) {
54
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new K(this.canvas, () => this.requestRender())), this.requestRender();
209
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new q(this.canvas, () => this.requestRender())), this.requestRender();
55
210
  }
56
211
  renderChart(e, t, n, r) {
57
212
  let i = this.crosshair?.getPosition() ?? null;
58
- ue(e, t, n, this.options, r, i);
213
+ he(e, t, n, this.options, r, i);
59
214
  }
60
215
  update(e, t) {
61
216
  this.options = {
@@ -75,7 +230,7 @@ var $ = class extends F {
75
230
  destroy() {
76
231
  this.crosshair?.destroy(), super.destroy();
77
232
  }
78
- }, Ce = class extends F {
233
+ }, ke = class extends I {
79
234
  options;
80
235
  crosshair = null;
81
236
  cachedRects = [];
@@ -84,7 +239,7 @@ var $ = class extends F {
84
239
  lastLayoutHeight = 0;
85
240
  handleClick = null;
86
241
  constructor(e, t) {
87
- super(e, t.theme), this.options = t, this.currentData = t.data ?? [], t.crosshair !== !1 && (this.crosshair = new K(this.canvas, () => this.requestRender())), t.onCellClick && (this.handleClick = (e) => {
242
+ super(e, t.theme), this.options = t, this.currentData = t.data ?? [], t.crosshair !== !1 && (this.crosshair = new q(this.canvas, () => this.requestRender())), t.onCellClick && (this.handleClick = (e) => {
88
243
  let t = this.canvas.getBoundingClientRect(), n = e.clientX - t.left, r = e.clientY - t.top;
89
244
  this.onCanvasClick(n, r);
90
245
  }, this.canvas.addEventListener("click", this.handleClick)), this.recomputeLayout(), this.requestRender();
@@ -101,8 +256,8 @@ var $ = class extends F {
101
256
  id: e.id,
102
257
  weight: e.weight ?? (Math.abs(e.value) || 1)
103
258
  }));
104
- this.cachedRects = se(n, e, t);
105
- } else this.cachedRects = ce(this.currentData.map((e) => ({ id: e.id })), e, t);
259
+ this.cachedRects = fe(n, e, t);
260
+ } else this.cachedRects = pe(this.currentData.map((e) => ({ id: e.id })), e, t);
106
261
  }
107
262
  onCanvasClick(e, t) {
108
263
  if (this.options.onCellClick) for (let n of this.cachedRects) {
@@ -117,7 +272,7 @@ var $ = class extends F {
117
272
  renderChart(e, t, n, r) {
118
273
  (t !== this.lastLayoutWidth || n !== this.lastLayoutHeight) && this.recomputeLayout();
119
274
  let i = this.crosshair?.getPosition() ?? null;
120
- fe(e, t, n, this.currentData, this.cachedRects, this.options, r, i);
275
+ _e(e, t, n, this.currentData, this.cachedRects, this.options, r, i);
121
276
  }
122
277
  update(e) {
123
278
  this.currentData = e, this.options = {
@@ -134,15 +289,15 @@ var $ = class extends F {
134
289
  destroy() {
135
290
  this.crosshair?.destroy(), this.handleClick && this.canvas.removeEventListener("click", this.handleClick), super.destroy();
136
291
  }
137
- }, we = class extends F {
292
+ }, Ae = class extends I {
138
293
  options;
139
294
  crosshair = null;
140
295
  constructor(e, t) {
141
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new K(this.canvas, () => this.requestRender())), this.requestRender();
296
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new q(this.canvas, () => this.requestRender())), this.requestRender();
142
297
  }
143
298
  renderChart(e, t, n, r) {
144
299
  let i = this.crosshair?.getPosition() ?? null;
145
- me(e, t, n, this.options, r, i);
300
+ ye(e, t, n, this.options, r, i);
146
301
  }
147
302
  update(e) {
148
303
  this.options = {
@@ -159,12 +314,12 @@ var $ = class extends F {
159
314
  destroy() {
160
315
  this.crosshair?.destroy(), super.destroy();
161
316
  }
162
- }, Te = 500;
163
- function Ee(e) {
317
+ }, je = 500;
318
+ function Me(e) {
164
319
  let t = 1 - e;
165
320
  return 1 - t * t * t;
166
321
  }
167
- var De = class extends F {
322
+ var Ne = class extends I {
168
323
  options;
169
324
  currentValue;
170
325
  targetValue;
@@ -175,7 +330,7 @@ var De = class extends F {
175
330
  super(e, t.theme), this.options = t, this.currentValue = t.value, this.targetValue = t.value, this.requestRender();
176
331
  }
177
332
  renderChart(e, t, n, r) {
178
- de(e, t, n, this.options, r, this.currentValue);
333
+ ge(e, t, n, this.options, r, this.currentValue);
179
334
  }
180
335
  setValue(e) {
181
336
  if (this.options.animate === !1) {
@@ -205,7 +360,7 @@ var De = class extends F {
205
360
  if (this.animationFrameId !== null) return;
206
361
  let e = () => {
207
362
  if (this.animationFrameId = null, this.animationStart === null) return;
208
- let t = this.options.animationDuration ?? Te, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = Ee(r);
363
+ let t = this.options.animationDuration ?? je, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = Me(r);
209
364
  this.currentValue = this.animationFrom + (this.targetValue - this.animationFrom) * i, this.requestRender(), r < 1 ? this.animationFrameId = requestAnimationFrame(e) : (this.currentValue = this.targetValue, this.animationStart = null);
210
365
  };
211
366
  this.animationFrameId = requestAnimationFrame(e);
@@ -218,6 +373,6 @@ var De = class extends F {
218
373
  }
219
374
  };
220
375
  //#endregion
221
- export { M as AlertManager, N as Animator, P as BarCountdown, I as BinanceAdapter, i as Chart, L as ChartLegend, R as ChartStateManager, z as CompareRenderer, B as CrosshairTooltip, V as CurrentPriceLine, a as DARK_TERMINAL, ee as DARK_THEME, te as DEFAULT_DRAWING_STYLE, H as DEFAULT_LEGEND_CONFIG, o as DEFAULT_RECONNECT, s as DEFAULT_STREAM_CONFIG, c as DEFAULT_TIMEFRAME_FAVORITES, l as DEFAULT_TRADING_CONFIG, U as DataExporter, e as DataManager, xe as DepthChart, W as DrawingBase, G as Easing, Se as EquityCurveChart, De as GaugeChart, Ce as HeatmapChart, q as IndicatorBase, J as KeyboardHandler, u as LIGHT_THEME, r as LayoutManager, d as MARKET_CRYPTO, f as MARKET_HNX, p as MARKET_HOSE, m as MARKET_NYSE, h as MARKET_UPCOM, Y as MockAdapter, n as PluginManager, X as ReplayManager, Z as Screenshot, Q as SessionBreaks, $ as SparklineChart, ne as StreamManager, g as TIMEFRAMES_CRYPTO, _ as TIMEFRAMES_FOREX, v as TIMEFRAMES_STOCK, t as ThemeManager, re as TickAggregator, ie as UndoRedoManager, y as VN_COLORS, ae as VolumeRenderer, we as WaterfallChart, oe as Watermark, b as computePriceLimits, x as createVNTheme, S as formatNumber, C as formatVND, w as formatVolumeLoc, T as getCurrentSession, E as getLocale, D as normalizeBar, O as normalizeBarTime, k as registerLocale, A as setLocale, j as t, he as toHeikinAshi, ge as toKagi, _e as toLineBreak, ve as toPointAndFigure, ye as toRangeBars, be as toRenko };
376
+ export { N as AlertManager, P as Animator, F as BarCountdown, L as BinanceAdapter, i as Chart, Ee as ChartGrid, R as ChartLegend, z as ChartStateManager, B as CompareRenderer, V as CrosshairTooltip, H as CurrentPriceLine, a as DARK_TERMINAL, o as DARK_THEME, ee as DEFAULT_DRAWING_STYLE, U as DEFAULT_LEGEND_CONFIG, te as DEFAULT_RECONNECT, ne as DEFAULT_SIGNAL_STYLE, s as DEFAULT_STREAM_CONFIG, c as DEFAULT_TIMEFRAME_FAVORITES, l as DEFAULT_TRADE_ZONE_STYLE, u as DEFAULT_TRADING_CONFIG, W as DataExporter, e as DataManager, $ as DepthChart, G as DrawingBase, K as Easing, Oe as EquityCurveChart, Ne as GaugeChart, ke as HeatmapChart, J as IndicatorBase, Y as KeyboardHandler, d as LIGHT_THEME, r as LayoutManager, f as MARKET_CRYPTO, p as MARKET_HNX, m as MARKET_HOSE, h as MARKET_NYSE, g as MARKET_UPCOM, X as MockAdapter, n as PluginManager, Z as ReplayManager, re as Screenshot, ie as SessionBreaks, ae as SignalMarkerManager, De as SparklineChart, oe as StreamManager, _ as TIMEFRAMES_CRYPTO, v as TIMEFRAMES_FOREX, y as TIMEFRAMES_STOCK, t as ThemeManager, se as TickAggregator, ce as TradeZoneManager, le as UndoRedoManager, b as VN_COLORS, ue as VolumeRenderer, Ae as WaterfallChart, de as Watermark, x as computePriceLimits, S as createVNTheme, C as formatNumber, w as formatVND, T as formatVolumeLoc, E as getCurrentSession, D as getLocale, O as normalizeBar, k as normalizeBarTime, A as registerLocale, j as setLocale, M as t, be as toHeikinAshi, xe as toKagi, Se as toLineBreak, Ce as toPointAndFigure, we as toRangeBars, Te as toRenko };
222
377
 
223
378
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/finance/SparklineChart.ts","../src/finance/DepthChart.ts","../src/finance/EquityCurveChart.ts","../src/finance/HeatmapChart.ts","../src/finance/WaterfallChart.ts","../src/finance/GaugeChart.ts"],"sourcesContent":["import type { SparklineOptions, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, renderSparkline } from '@tradecanvas/core';\n\nexport class SparklineChart extends BaseFinanceChart {\n private options: SparklineOptions;\n\n constructor(container: HTMLElement, options: SparklineOptions) {\n super(container, options.theme);\n this.options = options;\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n renderSparkline(ctx, width, height, this.options, theme);\n }\n\n update(data: number[]): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<SparklineOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n}\n","import type { DepthChartOptions, DepthData, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderDepthChart } from '@tradecanvas/core';\n\nexport class DepthChart extends BaseFinanceChart {\n private options: DepthChartOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: DepthChartOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderDepthChart(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: DepthData): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<DepthChartOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { EquityCurveOptions, EquityPoint, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderEquityCurve } from '@tradecanvas/core';\n\nexport class EquityCurveChart extends BaseFinanceChart {\n private options: EquityCurveOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: EquityCurveOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderEquityCurve(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: EquityPoint[], benchmark?: EquityPoint[]): void {\n this.options = { ...this.options, data };\n if (benchmark !== undefined) {\n this.options = { ...this.options, benchmark };\n }\n this.requestRender();\n }\n\n setOptions(opts: Partial<EquityCurveOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { HeatmapCell, HeatmapOptions, Theme } from '@tradecanvas/commons';\nimport {\n BaseFinanceChart,\n FinanceCrosshair,\n layoutUniformGrid,\n layoutSquarifiedTreemap,\n renderHeatmap,\n} from '@tradecanvas/core';\nimport type { LayoutRect } from '@tradecanvas/core';\n\nexport class HeatmapChart extends BaseFinanceChart {\n private options: HeatmapOptions;\n private crosshair: FinanceCrosshair | null = null;\n private cachedRects: LayoutRect[] = [];\n private currentData: HeatmapCell[] = [];\n private lastLayoutWidth = 0;\n private lastLayoutHeight = 0;\n private handleClick: ((e: MouseEvent) => void) | null = null;\n\n constructor(container: HTMLElement, options: HeatmapOptions) {\n super(container, options.theme);\n this.options = options;\n this.currentData = options.data ?? [];\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n if (options.onCellClick) {\n this.handleClick = (e: MouseEvent) => {\n const rect = this.canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n this.onCanvasClick(x, y);\n };\n this.canvas.addEventListener('click', this.handleClick);\n }\n\n this.recomputeLayout();\n this.requestRender();\n }\n\n private recomputeLayout(): void {\n const bounds = { x: 0, y: 0, width: this.width, height: this.height };\n const padding = this.options.cellPadding ?? 2;\n this.lastLayoutWidth = this.width;\n this.lastLayoutHeight = this.height;\n\n if (this.options.weighted) {\n const weighted = this.currentData.map(c => ({\n id: c.id,\n weight: c.weight ?? (Math.abs(c.value) || 1),\n }));\n this.cachedRects = layoutSquarifiedTreemap(weighted, bounds, padding);\n } else {\n this.cachedRects = layoutUniformGrid(\n this.currentData.map(c => ({ id: c.id })),\n bounds,\n padding,\n );\n }\n }\n\n private onCanvasClick(x: number, y: number): void {\n if (!this.options.onCellClick) return;\n\n for (const lr of this.cachedRects) {\n const r = lr.rect;\n if (x >= r.x && x <= r.x + r.width && y >= r.y && y <= r.y + r.height) {\n const cell = this.currentData.find(c => c.id === lr.id);\n if (cell) this.options.onCellClick(cell);\n return;\n }\n }\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n if (width !== this.lastLayoutWidth || height !== this.lastLayoutHeight) {\n this.recomputeLayout();\n }\n\n const pos = this.crosshair?.getPosition() ?? null;\n renderHeatmap(ctx, width, height, this.currentData, this.cachedRects, this.options, theme, pos);\n }\n\n update(data: HeatmapCell[]): void {\n this.currentData = data;\n this.options = { ...this.options, data };\n this.recomputeLayout();\n this.requestRender();\n }\n\n setOptions(opts: Partial<HeatmapOptions>): void {\n this.options = { ...this.options, ...opts };\n if (opts.data) {\n this.currentData = opts.data;\n }\n this.recomputeLayout();\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n if (this.handleClick) {\n this.canvas.removeEventListener('click', this.handleClick);\n }\n super.destroy();\n }\n}\n","import type { Theme, WaterfallBar, WaterfallOptions } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderWaterfall } from '@tradecanvas/core';\n\nexport class WaterfallChart extends BaseFinanceChart {\n private options: WaterfallOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: WaterfallOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderWaterfall(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: WaterfallBar[]): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<WaterfallOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { GaugeOptions, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, renderGauge } from '@tradecanvas/core';\n\nconst DEFAULT_ANIMATION_MS = 500;\n\nfunction easeOutCubic(t: number): number {\n const inv = 1 - t;\n return 1 - inv * inv * inv;\n}\n\nexport class GaugeChart extends BaseFinanceChart {\n private options: GaugeOptions;\n private currentValue: number;\n private targetValue: number;\n private animationStart: number | null = null;\n private animationFrom = 0;\n private animationFrameId: number | null = null;\n\n constructor(container: HTMLElement, options: GaugeOptions) {\n super(container, options.theme);\n this.options = options;\n this.currentValue = options.value;\n this.targetValue = options.value;\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n renderGauge(ctx, width, height, this.options, theme, this.currentValue);\n }\n\n setValue(value: number): void {\n const animate = this.options.animate !== false;\n if (!animate) {\n this.cancelAnimation();\n this.currentValue = value;\n this.targetValue = value;\n this.options = { ...this.options, value };\n this.requestRender();\n return;\n }\n\n this.targetValue = value;\n this.animationFrom = this.currentValue;\n this.animationStart = performance.now();\n this.options = { ...this.options, value };\n this.startAnimationLoop();\n }\n\n setOptions(opts: Partial<GaugeOptions>): void {\n const next = { ...this.options, ...opts };\n // If `value` is part of the partial, route through animation path\n if (opts.value !== undefined && opts.value !== this.targetValue) {\n this.options = next;\n this.setValue(opts.value);\n return;\n }\n this.options = next;\n this.requestRender();\n }\n\n private startAnimationLoop(): void {\n if (this.animationFrameId !== null) return;\n const step = (): void => {\n this.animationFrameId = null;\n if (this.animationStart === null) return;\n\n const duration = this.options.animationDuration ?? DEFAULT_ANIMATION_MS;\n const elapsed = performance.now() - this.animationStart;\n const t = Math.min(1, elapsed / Math.max(1, duration));\n const eased = easeOutCubic(t);\n this.currentValue = this.animationFrom + (this.targetValue - this.animationFrom) * eased;\n\n this.requestRender();\n\n if (t < 1) {\n this.animationFrameId = requestAnimationFrame(step);\n } else {\n this.currentValue = this.targetValue;\n this.animationStart = null;\n }\n };\n this.animationFrameId = requestAnimationFrame(step);\n }\n\n private cancelAnimation(): void {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n this.animationStart = null;\n }\n\n destroy(): void {\n this.cancelAnimation();\n super.destroy();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/grid/ChartGrid.ts","../src/finance/SparklineChart.ts","../src/finance/DepthChart.ts","../src/finance/EquityCurveChart.ts","../src/finance/HeatmapChart.ts","../src/finance/WaterfallChart.ts","../src/finance/GaugeChart.ts"],"sourcesContent":["import type { ChartOptions, Theme, TimeFrame, DataSeries, DataAdapter, StreamConfig } from '@tradecanvas/commons';\nimport { Chart } from '../Chart.js';\n\nexport type GridLayout = '1x1' | '1x2' | '2x1' | '2x2' | '1x3' | '3x1' | '2x3' | '3x2';\n\nexport interface GridCellConfig {\n symbol?: string;\n timeframe?: TimeFrame;\n chartOptions?: Partial<ChartOptions>;\n}\n\nexport interface ChartGridOptions {\n layout?: GridLayout;\n theme?: ChartOptions['theme'];\n syncCrosshair?: boolean;\n syncTimeAxis?: boolean;\n gap?: number;\n cells?: GridCellConfig[];\n chartOptions?: Partial<ChartOptions>;\n}\n\ninterface GridCell {\n container: HTMLDivElement;\n chart: Chart;\n symbol: string;\n timeframe: TimeFrame;\n}\n\nconst LAYOUT_MAP: Record<GridLayout, { cols: number; rows: number }> = {\n '1x1': { cols: 1, rows: 1 },\n '1x2': { cols: 2, rows: 1 },\n '2x1': { cols: 1, rows: 2 },\n '2x2': { cols: 2, rows: 2 },\n '1x3': { cols: 3, rows: 1 },\n '3x1': { cols: 1, rows: 3 },\n '2x3': { cols: 3, rows: 2 },\n '3x2': { cols: 2, rows: 3 },\n};\n\nexport class ChartGrid {\n private root: HTMLDivElement;\n private cells: GridCell[] = [];\n private layout: GridLayout;\n private options: ChartGridOptions;\n private destroyed = false;\n private syncing = false;\n\n constructor(container: HTMLElement, options: ChartGridOptions = {}) {\n this.options = options;\n this.layout = options.layout ?? '2x2';\n\n this.root = document.createElement('div');\n this.root.style.cssText = 'display:grid;width:100%;height:100%;overflow:hidden;';\n container.appendChild(this.root);\n\n this.applyLayout();\n this.createCells();\n }\n\n private applyLayout(): void {\n const { cols, rows } = LAYOUT_MAP[this.layout];\n const gap = this.options.gap ?? 1;\n this.root.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;\n this.root.style.gridTemplateRows = `repeat(${rows}, 1fr)`;\n this.root.style.gap = `${gap}px`;\n }\n\n private createCells(): void {\n const { cols, rows } = LAYOUT_MAP[this.layout];\n const count = cols * rows;\n\n for (let i = 0; i < count; i++) {\n const cellConfig = this.options.cells?.[i] ?? {};\n\n const cellEl = document.createElement('div');\n cellEl.style.cssText = 'position:relative;overflow:hidden;min-width:0;min-height:0;';\n this.root.appendChild(cellEl);\n\n const chartOpts: ChartOptions = {\n chartType: 'candlestick',\n autoScale: true,\n features: {\n crosshair: true,\n keyboard: true,\n volume: true,\n legend: true,\n priceAxis: true,\n timeAxis: true,\n grid: true,\n },\n ...this.options.chartOptions,\n ...cellConfig.chartOptions,\n theme: this.options.theme,\n };\n\n const chart = new Chart(cellEl, chartOpts);\n\n const cell: GridCell = {\n container: cellEl,\n chart,\n symbol: cellConfig.symbol ?? `Chart ${i + 1}`,\n timeframe: cellConfig.timeframe ?? '5m',\n };\n\n if (this.options.syncCrosshair !== false) {\n chart.on('crosshairMove', (e) => {\n if (this.syncing) return;\n this.syncing = true;\n for (const other of this.cells) {\n if (other.chart !== chart) {\n other.chart.setCrosshairPosition(e.payload.point);\n }\n }\n this.syncing = false;\n });\n }\n\n if (this.options.syncTimeAxis !== false) {\n chart.on('visibleRangeChange', (e) => {\n if (this.syncing) return;\n this.syncing = true;\n const { from, to } = e.payload;\n const srcData = chart.getData();\n if (srcData.length > 0 && from >= 0 && to < srcData.length) {\n const fromTime = srcData[from]?.time;\n const toTime = srcData[to]?.time;\n if (fromTime && toTime) {\n for (const other of this.cells) {\n if (other.chart !== chart) {\n other.chart.setVisibleRange(fromTime, toTime);\n }\n }\n }\n }\n this.syncing = false;\n });\n }\n\n this.cells.push(cell);\n }\n }\n\n setLayout(layout: GridLayout): void {\n if (layout === this.layout) return;\n const oldCount = this.cells.length;\n const { cols, rows } = LAYOUT_MAP[layout];\n const newCount = cols * rows;\n\n if (newCount < oldCount) {\n for (let i = oldCount - 1; i >= newCount; i--) {\n const cell = this.cells[i];\n cell.chart.destroy();\n cell.container.remove();\n this.cells.pop();\n }\n }\n\n this.layout = layout;\n this.applyLayout();\n\n if (newCount > oldCount) {\n for (let i = oldCount; i < newCount; i++) {\n const cellConfig = this.options.cells?.[i] ?? {};\n const cellEl = document.createElement('div');\n cellEl.style.cssText = 'position:relative;overflow:hidden;min-width:0;min-height:0;';\n this.root.appendChild(cellEl);\n\n const chart = new Chart(cellEl, {\n chartType: 'candlestick',\n autoScale: true,\n ...this.options.chartOptions,\n ...cellConfig.chartOptions,\n theme: this.options.theme,\n });\n\n this.cells.push({\n container: cellEl,\n chart,\n symbol: cellConfig.symbol ?? `Chart ${i + 1}`,\n timeframe: cellConfig.timeframe ?? '5m',\n });\n }\n }\n }\n\n getChart(index: number): Chart | null {\n return this.cells[index]?.chart ?? null;\n }\n\n getCharts(): Chart[] {\n return this.cells.map(c => c.chart);\n }\n\n getCellCount(): number {\n return this.cells.length;\n }\n\n setData(index: number, data: DataSeries): void {\n this.cells[index]?.chart.setData(data);\n }\n\n setAllData(data: DataSeries): void {\n for (const cell of this.cells) {\n cell.chart.setData(data);\n }\n }\n\n async connectCell(index: number, config: StreamConfig): Promise<void> {\n const cell = this.cells[index];\n if (!cell) return;\n cell.symbol = config.symbol;\n cell.timeframe = config.timeframe;\n await cell.chart.connect(config);\n }\n\n async connectAll(adapter: DataAdapter, symbols: string[], timeframe: TimeFrame, historyLimit = 500): Promise<void> {\n const promises: Promise<void>[] = [];\n for (let i = 0; i < this.cells.length && i < symbols.length; i++) {\n promises.push(this.connectCell(i, {\n adapter,\n symbol: symbols[i],\n timeframe,\n historyLimit,\n }));\n }\n await Promise.all(promises);\n }\n\n setTheme(theme: Theme): void {\n for (const cell of this.cells) {\n cell.chart.setTheme(theme);\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n for (const cell of this.cells) {\n cell.chart.destroy();\n cell.container.remove();\n }\n this.cells = [];\n this.root.remove();\n }\n}\n","import type { SparklineOptions, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, renderSparkline } from '@tradecanvas/core';\n\nexport class SparklineChart extends BaseFinanceChart {\n private options: SparklineOptions;\n\n constructor(container: HTMLElement, options: SparklineOptions) {\n super(container, options.theme);\n this.options = options;\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n renderSparkline(ctx, width, height, this.options, theme);\n }\n\n update(data: number[]): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<SparklineOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n}\n","import type { DepthChartOptions, DepthData, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderDepthChart } from '@tradecanvas/core';\n\nexport class DepthChart extends BaseFinanceChart {\n private options: DepthChartOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: DepthChartOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderDepthChart(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: DepthData): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<DepthChartOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { EquityCurveOptions, EquityPoint, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderEquityCurve } from '@tradecanvas/core';\n\nexport class EquityCurveChart extends BaseFinanceChart {\n private options: EquityCurveOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: EquityCurveOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderEquityCurve(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: EquityPoint[], benchmark?: EquityPoint[]): void {\n this.options = { ...this.options, data };\n if (benchmark !== undefined) {\n this.options = { ...this.options, benchmark };\n }\n this.requestRender();\n }\n\n setOptions(opts: Partial<EquityCurveOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { HeatmapCell, HeatmapOptions, Theme } from '@tradecanvas/commons';\nimport {\n BaseFinanceChart,\n FinanceCrosshair,\n layoutUniformGrid,\n layoutSquarifiedTreemap,\n renderHeatmap,\n} from '@tradecanvas/core';\nimport type { LayoutRect } from '@tradecanvas/core';\n\nexport class HeatmapChart extends BaseFinanceChart {\n private options: HeatmapOptions;\n private crosshair: FinanceCrosshair | null = null;\n private cachedRects: LayoutRect[] = [];\n private currentData: HeatmapCell[] = [];\n private lastLayoutWidth = 0;\n private lastLayoutHeight = 0;\n private handleClick: ((e: MouseEvent) => void) | null = null;\n\n constructor(container: HTMLElement, options: HeatmapOptions) {\n super(container, options.theme);\n this.options = options;\n this.currentData = options.data ?? [];\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n if (options.onCellClick) {\n this.handleClick = (e: MouseEvent) => {\n const rect = this.canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n this.onCanvasClick(x, y);\n };\n this.canvas.addEventListener('click', this.handleClick);\n }\n\n this.recomputeLayout();\n this.requestRender();\n }\n\n private recomputeLayout(): void {\n const bounds = { x: 0, y: 0, width: this.width, height: this.height };\n const padding = this.options.cellPadding ?? 2;\n this.lastLayoutWidth = this.width;\n this.lastLayoutHeight = this.height;\n\n if (this.options.weighted) {\n const weighted = this.currentData.map(c => ({\n id: c.id,\n weight: c.weight ?? (Math.abs(c.value) || 1),\n }));\n this.cachedRects = layoutSquarifiedTreemap(weighted, bounds, padding);\n } else {\n this.cachedRects = layoutUniformGrid(\n this.currentData.map(c => ({ id: c.id })),\n bounds,\n padding,\n );\n }\n }\n\n private onCanvasClick(x: number, y: number): void {\n if (!this.options.onCellClick) return;\n\n for (const lr of this.cachedRects) {\n const r = lr.rect;\n if (x >= r.x && x <= r.x + r.width && y >= r.y && y <= r.y + r.height) {\n const cell = this.currentData.find(c => c.id === lr.id);\n if (cell) this.options.onCellClick(cell);\n return;\n }\n }\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n if (width !== this.lastLayoutWidth || height !== this.lastLayoutHeight) {\n this.recomputeLayout();\n }\n\n const pos = this.crosshair?.getPosition() ?? null;\n renderHeatmap(ctx, width, height, this.currentData, this.cachedRects, this.options, theme, pos);\n }\n\n update(data: HeatmapCell[]): void {\n this.currentData = data;\n this.options = { ...this.options, data };\n this.recomputeLayout();\n this.requestRender();\n }\n\n setOptions(opts: Partial<HeatmapOptions>): void {\n this.options = { ...this.options, ...opts };\n if (opts.data) {\n this.currentData = opts.data;\n }\n this.recomputeLayout();\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n if (this.handleClick) {\n this.canvas.removeEventListener('click', this.handleClick);\n }\n super.destroy();\n }\n}\n","import type { Theme, WaterfallBar, WaterfallOptions } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderWaterfall } from '@tradecanvas/core';\n\nexport class WaterfallChart extends BaseFinanceChart {\n private options: WaterfallOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: WaterfallOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderWaterfall(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: WaterfallBar[]): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<WaterfallOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { GaugeOptions, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, renderGauge } from '@tradecanvas/core';\n\nconst DEFAULT_ANIMATION_MS = 500;\n\nfunction easeOutCubic(t: number): number {\n const inv = 1 - t;\n return 1 - inv * inv * inv;\n}\n\nexport class GaugeChart extends BaseFinanceChart {\n private options: GaugeOptions;\n private currentValue: number;\n private targetValue: number;\n private animationStart: number | null = null;\n private animationFrom = 0;\n private animationFrameId: number | null = null;\n\n constructor(container: HTMLElement, options: GaugeOptions) {\n super(container, options.theme);\n this.options = options;\n this.currentValue = options.value;\n this.targetValue = options.value;\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n renderGauge(ctx, width, height, this.options, theme, this.currentValue);\n }\n\n setValue(value: number): void {\n const animate = this.options.animate !== false;\n if (!animate) {\n this.cancelAnimation();\n this.currentValue = value;\n this.targetValue = value;\n this.options = { ...this.options, value };\n this.requestRender();\n return;\n }\n\n this.targetValue = value;\n this.animationFrom = this.currentValue;\n this.animationStart = performance.now();\n this.options = { ...this.options, value };\n this.startAnimationLoop();\n }\n\n setOptions(opts: Partial<GaugeOptions>): void {\n const next = { ...this.options, ...opts };\n // If `value` is part of the partial, route through animation path\n if (opts.value !== undefined && opts.value !== this.targetValue) {\n this.options = next;\n this.setValue(opts.value);\n return;\n }\n this.options = next;\n this.requestRender();\n }\n\n private startAnimationLoop(): void {\n if (this.animationFrameId !== null) return;\n const step = (): void => {\n this.animationFrameId = null;\n if (this.animationStart === null) return;\n\n const duration = this.options.animationDuration ?? DEFAULT_ANIMATION_MS;\n const elapsed = performance.now() - this.animationStart;\n const t = Math.min(1, elapsed / Math.max(1, duration));\n const eased = easeOutCubic(t);\n this.currentValue = this.animationFrom + (this.targetValue - this.animationFrom) * eased;\n\n this.requestRender();\n\n if (t < 1) {\n this.animationFrameId = requestAnimationFrame(step);\n } else {\n this.currentValue = this.targetValue;\n this.animationStart = null;\n }\n };\n this.animationFrameId = requestAnimationFrame(step);\n }\n\n private cancelAnimation(): void {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n this.animationStart = null;\n }\n\n destroy(): void {\n this.cancelAnimation();\n super.destroy();\n }\n}\n"],"mappings":"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"}
@@ -8,6 +8,7 @@ export declare class ChartWidget {
8
8
  private sidebar;
9
9
  private settings;
10
10
  private statusBar;
11
+ private commandPalette;
11
12
  private root;
12
13
  private chartContainer;
13
14
  private destroyed;
@@ -16,6 +17,7 @@ export declare class ChartWidget {
16
17
  private symbols;
17
18
  private settingsState;
18
19
  private adapter;
20
+ private boundGlobalKeydown;
19
21
  constructor(container: HTMLElement, options?: ChartWidgetOptions);
20
22
  setSymbol(symbol: string): Promise<void>;
21
23
  setTimeframe(tf: TimeFrame): Promise<void>;
@@ -27,6 +29,9 @@ export declare class ChartWidget {
27
29
  private handleChartType;
28
30
  private handleAddIndicator;
29
31
  private handleRemoveIndicator;
32
+ private toggleCommandPalette;
33
+ private buildCommandItems;
34
+ private handleAction;
30
35
  private handleDrawingTool;
31
36
  private handleCancelDrawing;
32
37
  private handleToggleMagnet;
@@ -1 +1 @@
1
- {"version":3,"file":"ChartWidget.d.ts","sourceRoot":"","sources":["../../src/widget/ChartWidget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8B,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAmC,MAAM,YAAY,CAAC;AAQtF,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,OAAO,CAA2D;gBAE9D,SAAS,EAAE,WAAW,EAAE,OAAO,GAAE,kBAAuB;IAkJ9D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxC,YAAY,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,QAAQ,CAAC,KAAK,EAAE,OAAO,sBAAsB,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI;IASvE,QAAQ,IAAI,KAAK;IAIjB,OAAO,IAAI,IAAI;IAef,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,kBAAkB;IAmB1B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,aAAa;YAKP,aAAa;IAwC3B,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;CAUpB"}
1
+ {"version":3,"file":"ChartWidget.d.ts","sourceRoot":"","sources":["../../src/widget/ChartWidget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8B,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAmC,MAAM,YAAY,CAAC;AAUtF,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,OAAO,CAA2D;IAC1E,OAAO,CAAC,kBAAkB,CAA6C;gBAE3D,SAAS,EAAE,WAAW,EAAE,OAAO,GAAE,kBAAuB;IAoK9D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxC,YAAY,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,QAAQ,CAAC,KAAK,EAAE,OAAO,sBAAsB,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI;IASvE,QAAQ,IAAI,KAAK;IAIjB,OAAO,IAAI,IAAI;IAmBf,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,kBAAkB;IAmB1B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,iBAAiB;IAmDzB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,aAAa;YAKP,aAAa;IAwC3B,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;CAUpB"}
@@ -0,0 +1,39 @@
1
+ import { ChartType, DrawingToolType, TimeFrame } from '@tradecanvas/commons';
2
+ export interface CommandItem {
3
+ id: string;
4
+ label: string;
5
+ category: 'indicator' | 'chartType' | 'drawing' | 'timeframe' | 'action';
6
+ shortcut?: string;
7
+ active?: boolean;
8
+ }
9
+ export interface CommandPaletteCallbacks {
10
+ onIndicator: (id: string) => void;
11
+ onChartType: (type: ChartType) => void;
12
+ onDrawingTool: (tool: DrawingToolType) => void;
13
+ onTimeframe: (tf: TimeFrame) => void;
14
+ onAction: (id: string) => void;
15
+ onClose: () => void;
16
+ }
17
+ export declare class WidgetCommandPalette {
18
+ private backdrop;
19
+ private modal;
20
+ private input;
21
+ private list;
22
+ private items;
23
+ private filtered;
24
+ private selectedIndex;
25
+ private callbacks;
26
+ private boundKeydown;
27
+ constructor(callbacks: CommandPaletteCallbacks);
28
+ open(items: CommandItem[]): void;
29
+ close(): void;
30
+ isOpen(): boolean;
31
+ private filter;
32
+ private renderList;
33
+ private updateSelection;
34
+ private select;
35
+ private handleKeydown;
36
+ private categoryLabel;
37
+ destroy(): void;
38
+ }
39
+ //# sourceMappingURL=WidgetCommandPalette.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetCommandPalette.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetCommandPalette.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAElF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,WAAW,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,YAAY,CAA6B;gBAErC,SAAS,EAAE,uBAAuB;IAK9C,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI;IAoDhC,KAAK,IAAI,IAAI;IAWb,MAAM,IAAI,OAAO;IAIjB,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,UAAU;IA2DlB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,MAAM;IAwBd,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,aAAa;IAWrB,OAAO,IAAI,IAAI;CAGhB"}