@tradecanvas/chart
Advanced tools
| import { DARK_THEME as e, DEFAULT_PANEL_HEIGHT as t, LIGHT_THEME as n, LayerType as r, MIN_PANEL_HEIGHT as i, PRICE_AXIS_WIDTH as a, TIME_AXIS_HEIGHT as o, computePriceLimits as s, mergeBar as c, setLocale as l, timeframeToMs as u } from "@tradecanvas/commons"; | ||
| import { AlertDragHandler as d, AlertManager as f, Animator as p, AreaRenderer as m, AxisDragHandler as ee, BarCountdown as te, BarRenderer as h, BaselineRenderer as ne, CandlestickRenderer as g, ChartLegend as re, ChartStateManager as _, CompareRenderer as ie, CrosshairHandler as ae, CrosshairTooltip as oe, CurrentPriceLine as se, DataExporter as v, DepthHeatmapRenderer as ce, DrawingManager as le, DrawingRenderer as ue, EquivolumeRenderer as de, EventBus as fe, GridRenderer as pe, HLCAreaRenderer as me, HollowCandleRenderer as he, IndicatorEngine as y, InteractionManager as ge, KagiRenderer as _e, KeyboardHandler as ve, LineRenderer as ye, LineWithMarkersRenderer as be, MarketProfileRenderer as xe, MeasureOverlay as Se, PanHandler as Ce, PeriodLevelsRenderer as we, PinnedTooltip as Te, PivotMarkersRenderer as b, PointAndFigureRenderer as x, PriceAxis as S, RenderEngine as C, RenkoRenderer as w, ReplayManager as T, Screenshot as E, SessionBreaks as D, SessionShading as O, SignalMarkerManager as Ee, StepLineRenderer as De, StreamManager as Oe, TimeAxis as ke, TradeZoneManager as Ae, TradingManager as je, TradingRenderer as Me, UndoRedoManager as Ne, Viewport as Pe, VolumeCandleRenderer as Fe, VolumeProfileRenderer as Ie, VolumeRenderer as Le, Watermark as Re, ZoomHandler as ze, findDominantSwing as Be, registerBuiltInDrawingTools as Ve, registerBuiltInIndicators as k, toHeikinAshi as A, toKagi as He, toLineBreak as Ue, toPointAndFigure as We, toRangeBars as Ge, toRenko as Ke, xToBarIndex as qe } from "@tradecanvas/core"; | ||
| //#region src/charts/ChartTypeStrategy.ts | ||
| function Je(e) { | ||
| switch (e) { | ||
| case "candlestick": | ||
| case "heikinAshi": | ||
| case "lineBreak": | ||
| case "rangeBars": return new g(); | ||
| case "line": return new ye(); | ||
| case "area": return new m(); | ||
| case "bar": return new h(); | ||
| case "hollowCandle": return new he(); | ||
| case "baseline": return new ne(); | ||
| case "renko": return new w(); | ||
| case "kagi": return new _e(); | ||
| case "pointAndFigure": return new x(); | ||
| case "volumeCandles": return new Fe(); | ||
| case "equivolume": return new de(); | ||
| case "hlcArea": return new me(); | ||
| case "stepLine": return new De(); | ||
| case "lineWithMarkers": return new be(); | ||
| default: return new g(); | ||
| } | ||
| } | ||
| function Ye(e, t) { | ||
| if (t.length === 0) return t; | ||
| switch (e) { | ||
| case "heikinAshi": return A(t); | ||
| case "renko": return Ke(t, { | ||
| brickSize: 0, | ||
| useATR: !0, | ||
| atrPeriod: 14 | ||
| }); | ||
| case "lineBreak": return Ue(t, 3); | ||
| case "kagi": return He(t, 4); | ||
| case "pointAndFigure": return We(t, j(t) * .01, 3); | ||
| case "rangeBars": return Ge(t, { rangeSize: j(t) * .005 }); | ||
| default: return t; | ||
| } | ||
| } | ||
| function j(e) { | ||
| let t = 0; | ||
| for (let n of e) t += n.close; | ||
| return t / e.length; | ||
| } | ||
| //#endregion | ||
| //#region src/charts/IndicatorPriceRange.ts | ||
| var M = { | ||
| min: 0, | ||
| max: 100 | ||
| }, N = .1; | ||
| function Xe(e, t, n) { | ||
| if (!e) return { ...M }; | ||
| let r = Infinity, i = -Infinity, a = 0; | ||
| for (let [, o] of e.values) { | ||
| if (a >= t && a <= n) for (let e in o) { | ||
| let t = o[e]; | ||
| t !== void 0 && Number.isFinite(t) && (t < r && (r = t), t > i && (i = t)); | ||
| } | ||
| a++; | ||
| } | ||
| if (r === Infinity) return { ...M }; | ||
| let o = i - r || 1; | ||
| return { | ||
| min: r - o * N, | ||
| max: i + o * N | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/state/AutoSaveScheduler.ts | ||
| var Ze = class { | ||
| timer = null; | ||
| delayMs = 0; | ||
| key = null; | ||
| constructor(e) { | ||
| this.save = e; | ||
| } | ||
| enable(e, t) { | ||
| this.key = e, this.delayMs = t; | ||
| } | ||
| disable() { | ||
| this.key = null, this.delayMs = 0, this.cancel(); | ||
| } | ||
| schedule() { | ||
| this.delayMs <= 0 || !this.key || (this.timer && clearTimeout(this.timer), this.timer = setTimeout(() => { | ||
| this.timer = null, this.key && this.save(this.key); | ||
| }, this.delayMs)); | ||
| } | ||
| cancel() { | ||
| this.timer &&= (clearTimeout(this.timer), null); | ||
| } | ||
| isEnabled() { | ||
| return this.delayMs > 0 && this.key !== null; | ||
| } | ||
| hasPending() { | ||
| return this.timer !== null; | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/DataManager.ts | ||
| function P(e) { | ||
| if (!e || typeof e.time != "number") return !1; | ||
| let { open: t, high: n, low: r, close: i } = e; | ||
| return !(!isFinite(t) || !isFinite(n) || !isFinite(r) || !isFinite(i) || t < 0 || n < 0 || r < 0 || i < 0 || n < r || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0)); | ||
| } | ||
| function F(e) { | ||
| return { | ||
| ...e, | ||
| high: Math.max(e.open, e.high, e.low, e.close), | ||
| low: Math.min(e.open, e.high, e.low, e.close), | ||
| volume: e.volume === void 0 ? 0 : Math.max(0, e.volume) | ||
| }; | ||
| } | ||
| var I = class { | ||
| data = []; | ||
| getData() { | ||
| return this.data; | ||
| } | ||
| setData(e) { | ||
| this.data = e.filter(P).map(F); | ||
| } | ||
| appendBar(e) { | ||
| P(e) && this.data.push(F(e)); | ||
| } | ||
| updateLastBar(e) { | ||
| if (!P(e)) return; | ||
| let t = F(e); | ||
| if (this.data.length === 0) { | ||
| this.data.push(t); | ||
| return; | ||
| } | ||
| this.data[this.data.length - 1] = t; | ||
| } | ||
| updateLastBarFromTick(e) { | ||
| this.data.length !== 0 && (!isFinite(e.price) || e.price < 0 || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0) || (this.data[this.data.length - 1] = c(this.data[this.data.length - 1], e))); | ||
| } | ||
| getLength() { | ||
| return this.data.length; | ||
| } | ||
| clear() { | ||
| this.data = []; | ||
| } | ||
| }, L = class { | ||
| theme; | ||
| constructor(t) { | ||
| !t || t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t }; | ||
| } | ||
| getTheme() { | ||
| return this.theme; | ||
| } | ||
| setTheme(t) { | ||
| t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t }; | ||
| } | ||
| }, R = 200, z = 80, B = class { | ||
| panels = []; | ||
| containerWidth = 0; | ||
| containerHeight = 0; | ||
| resize(e, t) { | ||
| this.containerWidth = e, this.containerHeight = t; | ||
| } | ||
| addPanel(e, n = "bottom", r) { | ||
| let a = n === "left" || n === "right"; | ||
| this.panels.push({ | ||
| id: e, | ||
| position: n, | ||
| size: r ?? (a ? R : t), | ||
| minSize: a ? z : i, | ||
| content: { | ||
| type: "indicator", | ||
| indicatorInstanceId: e | ||
| } | ||
| }); | ||
| } | ||
| removePanel(e) { | ||
| this.panels = this.panels.filter((t) => t.id !== e); | ||
| } | ||
| setPanelPosition(e, n) { | ||
| let r = this.panels.find((t) => t.id === e); | ||
| if (r) { | ||
| let e = r.position === "left" || r.position === "right", a = n === "left" || n === "right"; | ||
| r.position = n, e !== a && (r.size = a ? R : t, r.minSize = a ? z : i); | ||
| } | ||
| } | ||
| setPanelSize(e, t) { | ||
| let n = this.panels.find((t) => t.id === e); | ||
| n && (n.size = Math.max(n.minSize, t)); | ||
| } | ||
| getPanels() { | ||
| return this.panels; | ||
| } | ||
| resolve() { | ||
| let e = this.panels.filter((e) => e.position === "left"), t = this.panels.filter((e) => e.position === "right"), n = this.panels.filter((e) => e.position === "top"), r = this.panels.filter((e) => e.position === "bottom"), i = e.reduce((e, t) => e + t.size, 0), s = t.reduce((e, t) => e + t.size, 0), c = n.reduce((e, t) => e + t.size, 0), l = r.reduce((e, t) => e + t.size, 0), u = { | ||
| x: i, | ||
| y: c, | ||
| width: Math.max(0, this.containerWidth - i - s - a), | ||
| height: Math.max(0, this.containerHeight - c - l - o) | ||
| }, d = [], f = [], p = 0; | ||
| for (let t of e) d.push({ | ||
| config: t, | ||
| rect: { | ||
| x: p, | ||
| y: 0, | ||
| width: t.size, | ||
| height: this.containerHeight - o | ||
| } | ||
| }), f.push({ | ||
| panelId: t.id, | ||
| rect: { | ||
| x: p + t.size - 2, | ||
| y: 0, | ||
| width: 4, | ||
| height: this.containerHeight | ||
| }, | ||
| orientation: "vertical" | ||
| }), p += t.size; | ||
| let m = 0; | ||
| for (let e of n) d.push({ | ||
| config: e, | ||
| rect: { | ||
| x: i, | ||
| y: m, | ||
| width: u.width, | ||
| height: e.size | ||
| } | ||
| }), f.push({ | ||
| panelId: e.id, | ||
| rect: { | ||
| x: i, | ||
| y: m + e.size - 2, | ||
| width: u.width, | ||
| height: 4 | ||
| }, | ||
| orientation: "horizontal" | ||
| }), m += e.size; | ||
| m = u.y + u.height; | ||
| for (let e of r) d.push({ | ||
| config: e, | ||
| rect: { | ||
| x: i, | ||
| y: m, | ||
| width: u.width, | ||
| height: e.size | ||
| } | ||
| }), f.push({ | ||
| panelId: e.id, | ||
| rect: { | ||
| x: i, | ||
| y: m - 2, | ||
| width: u.width, | ||
| height: 4 | ||
| }, | ||
| orientation: "horizontal" | ||
| }), m += e.size; | ||
| p = i + u.width + a; | ||
| for (let e of t) d.push({ | ||
| config: e, | ||
| rect: { | ||
| x: p, | ||
| y: 0, | ||
| width: e.size, | ||
| height: this.containerHeight - o | ||
| } | ||
| }), f.push({ | ||
| panelId: e.id, | ||
| rect: { | ||
| x: p - 2, | ||
| y: 0, | ||
| width: 4, | ||
| height: this.containerHeight | ||
| }, | ||
| orientation: "vertical" | ||
| }), p += e.size; | ||
| return { | ||
| mainChartRect: u, | ||
| panels: d, | ||
| dividers: f | ||
| }; | ||
| } | ||
| getMainChartRect() { | ||
| return this.resolve().mainChartRect; | ||
| } | ||
| }, V = class { | ||
| constructor(e) { | ||
| this.indicatorEngine = e; | ||
| } | ||
| registerIndicator(e) { | ||
| this.indicatorEngine.register(e); | ||
| } | ||
| }, Qe = class { | ||
| static version = "0.7.0"; | ||
| engine; | ||
| viewport; | ||
| dataManager; | ||
| themeManager; | ||
| layoutManager; | ||
| pluginManager; | ||
| indicatorEngine; | ||
| drawingManager; | ||
| drawingRenderer; | ||
| tradingManager; | ||
| tradingRenderer; | ||
| eventBus; | ||
| streamManager = null; | ||
| autoScrollOnNewBar = !0; | ||
| displayDataCache = null; | ||
| resolvedLayoutCache = null; | ||
| panelInfoCache = null; | ||
| renderScheduled = !1; | ||
| containerSizeCache = null; | ||
| containerSizeCacheTime = 0; | ||
| chartLegend; | ||
| watermark; | ||
| barCountdown; | ||
| sessionBreaks; | ||
| sessionShading; | ||
| compareRenderer; | ||
| countdownInterval = null; | ||
| volumeRenderer; | ||
| volumeProfile; | ||
| marketProfile; | ||
| depthHeatmap; | ||
| periodLevels; | ||
| pivotMarkers; | ||
| alertManager; | ||
| signalMarkerManager; | ||
| tradeZoneManager; | ||
| measureOverlay; | ||
| replayManager; | ||
| undoRedoManager; | ||
| autoSaveScheduler = new Ze((e) => this.saveState(e)); | ||
| animator; | ||
| crosshairTooltip; | ||
| pinnedTooltip; | ||
| interactionManager; | ||
| crosshairHandler; | ||
| chartRenderer; | ||
| gridRenderer; | ||
| priceAxis; | ||
| timeAxis; | ||
| options; | ||
| features; | ||
| marketConfig = null; | ||
| container; | ||
| currentPriceLine; | ||
| numberLocale; | ||
| keyboardHandler = null; | ||
| onWindowKeyDown = null; | ||
| currentSymbol = ""; | ||
| constructor(e, t) { | ||
| this.container = e, this.options = t, this.numberLocale = t.numberLocale ?? "en-US"; | ||
| let n = t.features ?? {}; | ||
| this.features = { | ||
| drawings: n.drawings ?? !0, | ||
| drawingTools: n.drawingTools ?? [], | ||
| drawingMagnet: n.drawingMagnet ?? !0, | ||
| drawingUndoRedo: n.drawingUndoRedo ?? !0, | ||
| trading: n.trading ?? !0, | ||
| tradingContextMenu: n.tradingContextMenu ?? !0, | ||
| indicators: n.indicators ?? !0, | ||
| indicatorIds: n.indicatorIds ?? [], | ||
| panning: n.panning ?? !0, | ||
| zooming: n.zooming ?? !0, | ||
| crosshair: n.crosshair ?? !0, | ||
| keyboard: n.keyboard ?? !0, | ||
| priceAxis: n.priceAxis ?? !0, | ||
| timeAxis: n.timeAxis ?? !0, | ||
| grid: n.grid ?? t.grid?.visible ?? !0, | ||
| legend: n.legend ?? !0, | ||
| volume: n.volume ?? !0, | ||
| watermark: n.watermark ?? !0, | ||
| saveLoad: n.saveLoad ?? !0, | ||
| screenshot: n.screenshot ?? !0, | ||
| alerts: n.alerts ?? !0, | ||
| replay: n.replay ?? !0, | ||
| sessionBreaks: n.sessionBreaks ?? !0, | ||
| barCountdown: n.barCountdown ?? !0, | ||
| compareSymbols: n.compareSymbols ?? !0, | ||
| dataExport: n.dataExport ?? !0, | ||
| logScale: n.logScale ?? !0, | ||
| timeframes: n.timeframes ?? [], | ||
| defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? [] | ||
| }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new I(), this.themeManager = new L(t.theme), this.layoutManager = new B(), this.indicatorEngine = new y(), this.pluginManager = new V(this.indicatorEngine), this.eventBus = new fe(), k(this.indicatorEngine), this.drawingManager = new le(), Ve(this.drawingManager), this.drawingRenderer = new ue(this.drawingManager), this.drawingManager.setRequestRender(() => { | ||
| this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave(); | ||
| }), this.drawingManager.setEventCallback((e, t) => { | ||
| this.eventBus.emit(e, t); | ||
| }), this.undoRedoManager = new Ne(), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setDataGetter(() => this.dataManager.getData()), this.drawingManager.setDisplayDataGetter(() => this.getDisplayData()), t.crosshair?.mode === "magnet" && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new je({ | ||
| enabled: this.features.trading, | ||
| contextMenu: { enabled: this.features.tradingContextMenu } | ||
| }), this.tradingRenderer = new Me(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => { | ||
| this.eventBus.emit(e, t); | ||
| }), this.engine = new C(e); | ||
| let i = this.engine.dprManager.getContainerSize(); | ||
| if (this.viewport = new Pe(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => { | ||
| if (e.width <= 0 || e.height <= 0) return; | ||
| let t = this.viewport.isAtEnd(); | ||
| this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t); | ||
| }, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new pe(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new S(), this.priceAxis.setLocale(this.numberLocale), this.timeAxis = new ke(), this.crosshairHandler = new ae(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => { | ||
| if (e !== null && t) { | ||
| let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0; | ||
| this.chartLegend.setHoverBar(r ?? null), r && this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize()), this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", { | ||
| point: t, | ||
| bar: r, | ||
| barIndex: e | ||
| }); | ||
| } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null); | ||
| }), this.chartLegend = new re(), this.chartLegend.setChartType(t.chartType), this.watermark = new Re(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new Le(), this.volumeProfile = new Ie(), this.marketProfile = new xe(), this.depthHeatmap = new ce(), this.periodLevels = new we(), this.pivotMarkers = new b(), this.barCountdown = new te(), this.sessionBreaks = new D(), this.sessionShading = new O(), this.compareRenderer = new ie(), t.sessionBreaks ? this.sessionBreaks.setConfig({ | ||
| visible: t.sessionBreaks.visible ?? !0, | ||
| color: t.sessionBreaks.color, | ||
| lineStyle: t.sessionBreaks.lineStyle, | ||
| lineWidth: t.sessionBreaks.lineWidth | ||
| }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.viewport.setLogScale(!0), this.animator = new p(), this.crosshairTooltip = new oe(), this.crosshairTooltip.create(e), this.pinnedTooltip = new Te(), this.pinnedTooltip.create(e), this.keyboardHandler = new ve({ | ||
| scrollBars: (e) => { | ||
| let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing; | ||
| this.viewport.scrollBy(e * t), this.updateViewportAndRender(); | ||
| }, | ||
| zoom: (e) => { | ||
| let t = this.viewport.getState().chartRect.width; | ||
| this.viewport.zoom(e, t / 2), this.updateViewportAndRender(); | ||
| }, | ||
| goToStart: () => { | ||
| this.viewport.scrollBy(-Infinity), this.updateViewportAndRender(); | ||
| }, | ||
| goToEnd: () => { | ||
| this.viewport.scrollToEnd(), this.updateViewportAndRender(); | ||
| }, | ||
| fitContent: () => this.fitContent() | ||
| }), this.keyboardHandler.setEnabled(this.features.keyboard), this.onWindowKeyDown = (e) => { | ||
| if (!this.keyboardHandler) return; | ||
| let t = document.activeElement; | ||
| t && t !== this.container && !this.container.contains(t) || t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable) || this.keyboardHandler.handleKey(e) && e.preventDefault(); | ||
| }, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new se(), this.alertManager = new f(), this.alertManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.alertManager.on("triggered", (e) => { | ||
| let t = { | ||
| id: e.id, | ||
| price: e.price, | ||
| condition: e.condition, | ||
| message: e.message, | ||
| triggered: e.triggered | ||
| }; | ||
| this.eventBus.emit("alertTriggered", t), this.eventBus.emit("dataUpdate", { | ||
| alert: "triggered", | ||
| alertId: e.id, | ||
| price: e.price, | ||
| message: e.message | ||
| }); | ||
| }), this.alertManager.on("added", (e) => { | ||
| this.eventBus.emit("alertAdd", { | ||
| id: e.id, | ||
| price: e.price, | ||
| condition: e.condition, | ||
| message: e.message, | ||
| triggered: e.triggered | ||
| }); | ||
| }), this.alertManager.on("removed", (e) => { | ||
| this.eventBus.emit("alertRemove", { id: e }); | ||
| }), this.alertManager.on("updated", (e) => { | ||
| this.eventBus.emit("alertUpdate", { | ||
| id: e.id, | ||
| price: e.price, | ||
| condition: e.condition, | ||
| message: e.message, | ||
| triggered: e.triggered | ||
| }); | ||
| }), this.signalMarkerManager = new Ee(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => { | ||
| this.eventBus.emit("signalMarkerAdd", { | ||
| id: e.id, | ||
| source: e.source, | ||
| direction: e.direction | ||
| }); | ||
| }), this.signalMarkerManager.on("removed", (e) => { | ||
| this.eventBus.emit("signalMarkerRemove", { id: e }); | ||
| }), this.tradeZoneManager = new Ae(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => { | ||
| this.eventBus.emit("tradeZoneAdd", { | ||
| id: e.id, | ||
| direction: e.direction | ||
| }); | ||
| }), this.tradeZoneManager.on("removed", (e) => { | ||
| this.eventBus.emit("tradeZoneRemove", { id: e }); | ||
| }), this.replayManager = new T(), this.measureOverlay = new Se(), this.interactionManager = new ge(e), this.features.panning && this.interactionManager.setPanHandler(new Ce((e) => { | ||
| this.viewport.scrollBy(e), this.updateViewportAndRender(); | ||
| })), this.features.zooming) { | ||
| this.interactionManager.setZoomHandler(new ze((e, t) => { | ||
| this.viewport.zoom(e, t), this.updateViewportAndRender(); | ||
| })); | ||
| let e = new ee((e) => { | ||
| this.options.autoScale = !1, this.viewport.scalePriceRange(e), this.syncRenderContext(), this.engine.requestRender(); | ||
| }, (e) => { | ||
| let t = this.viewport.getState().chartRect.width; | ||
| this.viewport.zoom(1 / e - 1, t / 2), this.updateViewportAndRender(); | ||
| }); | ||
| this.interactionManager.setAxisDragHandler(e, () => this.viewport.getState(), (e) => { | ||
| e === "price" ? (this.options.autoScale = !0, this.updateViewportAndRender()) : this.fitContent(); | ||
| }); | ||
| } | ||
| if (this.features.crosshair && this.interactionManager.setCrosshairHandler(this.crosshairHandler), this.features.drawings && this.interactionManager.setDrawingManager(this.drawingManager, () => ({ | ||
| ...this.viewport.getState(), | ||
| data: this.getDisplayData() | ||
| })), this.features.trading && this.interactionManager.setTradingManager(this.tradingManager, () => ({ | ||
| ...this.viewport.getState(), | ||
| data: this.getDisplayData() | ||
| })), this.features.alerts) { | ||
| let e = new d(this.alertManager, () => this.viewport.getState()); | ||
| this.interactionManager.setAlertDragHandler(e); | ||
| } | ||
| this.interactionManager.setAltClickHandler((e) => { | ||
| let t = this.getDisplayData(); | ||
| if (t.length === 0) return; | ||
| let n = this.viewport.getState(), i = n.barWidth + n.barSpacing, a = Math.round((n.offset + e.x) / i); | ||
| a < 0 || a >= t.length || (this.pinnedTooltip.isPinned() && this.pinnedTooltip.getPinnedIndex() === a ? this.pinnedTooltip.unpin() : this.pinnedTooltip.pin(t[a], a, this.themeManager.getTheme()), this.pinnedTooltip.reposition(this.viewport.getState(), this.dataManager.getData()[a] ?? null, a, this.themeManager.getTheme()), this.engine.requestRender(r.Overlay)); | ||
| }), this.interactionManager.setClickHandler((e) => { | ||
| let t = this.getDisplayData(); | ||
| if (this.eventBus.emit("click", { | ||
| x: e.x, | ||
| y: e.y | ||
| }), t.length === 0) return; | ||
| let n = qe(e.x, this.viewport.getState()); | ||
| n < 0 || n >= t.length || this.eventBus.emit("barClick", { | ||
| bar: t[n], | ||
| barIndex: n, | ||
| point: e | ||
| }); | ||
| }), this.interactionManager.setEscapeHandler(() => { | ||
| if (this.features.trading && this.tradingManager.isBracketActive()) { | ||
| this.tradingManager.cancelBracket(), this.eventBus.emit("dataUpdate", { bracket: "cancelled" }); | ||
| return; | ||
| } | ||
| this.pinnedTooltip.isPinned() && (this.pinnedTooltip.unpin(), this.engine.requestRender(r.Overlay)); | ||
| }), this.interactionManager.setConfirmHandler(() => this.features.trading && this.tradingManager.isBracketActive() ? (this.tradingManager.confirmBracket(), !0) : !1), this.interactionManager.setMeasureHandlers({ | ||
| begin: (e) => { | ||
| this.measureOverlay.begin(e, this.viewport.getState(), this.getDisplayData()); | ||
| }, | ||
| move: (e) => { | ||
| this.measureOverlay.update(e, this.viewport.getState(), this.getDisplayData()); | ||
| }, | ||
| end: () => { | ||
| this.measureOverlay.end(); | ||
| } | ||
| }), this.interactionManager.setOverlayDirtyCallback(() => { | ||
| this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI); | ||
| }), this.interactionManager.attach(), this.syncRenderContext(), this.engine.start(); | ||
| } | ||
| setData(e) { | ||
| this.dataManager.setData(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.alertManager.clearLastValues(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), e.length > 0 && this.currentPriceLine.setPrice(e[e.length - 1].close), this.updateViewportAndRender(!0), this.eventBus.emit("dataUpdate", { length: e.length }); | ||
| } | ||
| appendBar(e) { | ||
| this.dataManager.appendBar(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.autoScrollOnNewBar && this.viewport.scrollToEnd(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.updateViewportAndRender(); | ||
| } | ||
| appendBars(e) { | ||
| if (e.length !== 0) { | ||
| for (let t of e) this.dataManager.appendBar(t); | ||
| this.displayDataCache = null, this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(this.viewport.isAtEnd()); | ||
| } | ||
| } | ||
| updateLastBar(e) { | ||
| this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender(); | ||
| } | ||
| updateLastBarFromTick(e) { | ||
| this.dataManager.updateLastBarFromTick(e), this.currentPriceLine.setPrice(e.price), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender(); | ||
| } | ||
| setChartType(e) { | ||
| this.options.chartType = e, this.chartRenderer = this.createChartRenderer(e), this.chartLegend.setChartType(e), this.displayDataCache = null, this.updateViewportAndRender(!0); | ||
| } | ||
| addIndicator(e, t = {}, n = "bottom") { | ||
| if (!this.features.indicators || this.features.indicatorIds.length > 0 && !this.features.indicatorIds.includes(e)) return null; | ||
| let r = this.indicatorEngine.addIndicator(e, t, this.dataManager.getData()); | ||
| return this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e)?.placement === "panel" ? (this.layoutManager.addPanel(r, n), this.updateViewportAndRender()) : this.engine.requestRender(), this.eventBus.emit("indicatorAdd", { | ||
| instanceId: r, | ||
| id: e | ||
| }), r; | ||
| } | ||
| updateIndicator(e, t) { | ||
| this.indicatorEngine.updateIndicator(e, t, this.dataManager.getData()), this.engine.requestRender(); | ||
| } | ||
| removeIndicator(e) { | ||
| let t = this.layoutManager.getPanels().some((t) => t.id === e); | ||
| this.indicatorEngine.removeIndicator(e), this.layoutManager.removePanel(e), this.eventBus.emit("indicatorRemove", { instanceId: e }), t ? this.updateViewportAndRender() : this.engine.requestRender(); | ||
| } | ||
| getIndicatorOutput(e) { | ||
| return this.indicatorEngine.getOutput(e); | ||
| } | ||
| registerIndicator(e) { | ||
| this.pluginManager.registerIndicator(e); | ||
| } | ||
| static indicators() { | ||
| let e = new y(); | ||
| return k(e), e.getAvailableIndicators(); | ||
| } | ||
| setPanelPosition(e, t) { | ||
| this.layoutManager.setPanelPosition(e, t), this.engine.requestRender(); | ||
| } | ||
| setPanelSize(e, t) { | ||
| this.layoutManager.setPanelSize(e, t), this.engine.requestRender(); | ||
| } | ||
| setDrawingTool(e) { | ||
| this.features.drawings && (e && this.features.drawingTools.length > 0 && !this.features.drawingTools.includes(e) || this.drawingManager.setActiveTool(e)); | ||
| } | ||
| getDrawingTool() { | ||
| return this.drawingManager.getActiveTool(); | ||
| } | ||
| setDrawingStyle(e) { | ||
| this.drawingManager.setStyle(e); | ||
| } | ||
| getDrawingStyle() { | ||
| return this.drawingManager.getActiveStyle(); | ||
| } | ||
| getSelectedDrawingId() { | ||
| return this.drawingManager.getSelectedDrawingId(); | ||
| } | ||
| setSelectedDrawingStyle(e, t) { | ||
| return this.drawingManager.setSelectedDrawingStyle(e, t); | ||
| } | ||
| getDrawings() { | ||
| return this.drawingManager.getDrawings(); | ||
| } | ||
| setDrawings(e) { | ||
| this.drawingManager.setDrawings(e); | ||
| } | ||
| addDrawing(e) { | ||
| if (!this.features.drawings) return null; | ||
| let t = this.drawingManager.addDrawing(e); | ||
| return this.scheduleAutoSave(), t; | ||
| } | ||
| autoFib() { | ||
| if (!this.features.drawings) return null; | ||
| let e = this.getDisplayData(), t = this.viewport.getState(), n = Be(e, t.visibleRange.from, t.visibleRange.to); | ||
| return n ? this.addDrawing({ | ||
| type: "fibRetracement", | ||
| anchors: [n[0], n[1]] | ||
| }) : null; | ||
| } | ||
| removeDrawing(e) { | ||
| this.drawingManager.removeDrawing(e); | ||
| } | ||
| setDrawingVisible(e, t) { | ||
| this.drawingManager.setDrawingVisible(e, t); | ||
| } | ||
| setDrawingLocked(e, t) { | ||
| this.drawingManager.setDrawingLocked(e, t); | ||
| } | ||
| clearDrawings() { | ||
| this.drawingManager.clearDrawings(); | ||
| } | ||
| registerDrawingTool(e) { | ||
| this.drawingManager.register(e); | ||
| } | ||
| undo() { | ||
| return this.features.drawingUndoRedo ? this.drawingManager.undo() : !1; | ||
| } | ||
| redo() { | ||
| return this.features.drawingUndoRedo ? this.drawingManager.redo() : !1; | ||
| } | ||
| getUndoRedoState() { | ||
| return this.undoRedoManager.getState(); | ||
| } | ||
| setDrawingMagnet(e) { | ||
| this.drawingManager.setMagnetMode(e ? "magnet" : "none"); | ||
| } | ||
| getDrawingMagnet() { | ||
| return this.drawingManager.getMagnetMode() === "magnet"; | ||
| } | ||
| lockAllDrawings() { | ||
| this.drawingManager.lockAllDrawings(); | ||
| } | ||
| unlockAllDrawings() { | ||
| this.drawingManager.unlockAllDrawings(); | ||
| } | ||
| hideAllDrawings() { | ||
| this.drawingManager.hideAllDrawings(); | ||
| } | ||
| showAllDrawings() { | ||
| this.drawingManager.showAllDrawings(); | ||
| } | ||
| duplicateDrawing(e) { | ||
| let t = e ?? this.drawingManager.getSelectedDrawingId(); | ||
| return t ? this.drawingManager.duplicateDrawing(t) : null; | ||
| } | ||
| exportVisibleData(e = "csv", t) { | ||
| let n = this.viewport.getState(), r = this.dataManager.getData(), i = Math.max(0, n.visibleRange.from), a = Math.min(r.length - 1, n.visibleRange.to), o = r.slice(i, a + 1); | ||
| if (e === "json") { | ||
| let e = v.toJSON(o); | ||
| v.download(e, t ?? "chart-data.json", "application/json"); | ||
| } else { | ||
| let e = v.toCSV(o); | ||
| v.download(e, t ?? "chart-data.csv", "text/csv"); | ||
| } | ||
| } | ||
| exportAllData(e = "csv", t) { | ||
| let n = this.dataManager.getData(); | ||
| if (e === "json") { | ||
| let e = v.toJSON(n); | ||
| v.download(e, t ?? "chart-data.json", "application/json"); | ||
| } else { | ||
| let e = v.toCSV(n); | ||
| v.download(e, t ?? "chart-data.csv", "text/csv"); | ||
| } | ||
| } | ||
| setAutoSave(e, t = 5e3) { | ||
| this.autoSaveScheduler.enable(e, t); | ||
| } | ||
| disableAutoSave() { | ||
| this.autoSaveScheduler.disable(); | ||
| } | ||
| scheduleAutoSave() { | ||
| this.autoSaveScheduler.schedule(); | ||
| } | ||
| getAvailableIndicators() { | ||
| return this.indicatorEngine.getAvailableIndicators(); | ||
| } | ||
| getIndicatorInputs(e) { | ||
| let t = this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e); | ||
| return t ? { | ||
| id: t.id, | ||
| params: t.defaultConfig | ||
| } : null; | ||
| } | ||
| getActiveIndicators() { | ||
| return this.indicatorEngine.getActiveIndicators(); | ||
| } | ||
| setIndicatorVisible(e, t) { | ||
| this.indicatorEngine.setVisible(e, t) !== null && this.updateViewportAndRender(); | ||
| } | ||
| getIndicatorConfig(e) { | ||
| let t = this.indicatorEngine.getIndicatorConfig(e); | ||
| return t ? { | ||
| id: t.id, | ||
| params: { ...t.params } | ||
| } : null; | ||
| } | ||
| updateIndicatorStyle(e, t) { | ||
| this.indicatorEngine.updateIndicatorStyle(e, t), this.engine.requestRender(); | ||
| } | ||
| setOrders(e) { | ||
| this.features.trading && this.tradingManager.setOrders(e); | ||
| } | ||
| startBracket(e, t) { | ||
| if (!this.features.trading) return !1; | ||
| let n = this.dataManager.getData(), r = t ?? (n.length > 0 ? n[n.length - 1].close : null); | ||
| return r === null ? !1 : (this.tradingManager.startBracket(e, r), !0); | ||
| } | ||
| cancelBracket() { | ||
| this.features.trading && this.tradingManager.cancelBracket(); | ||
| } | ||
| confirmBracket() { | ||
| return this.features.trading ? this.tradingManager.confirmBracket() : !1; | ||
| } | ||
| isBracketActive() { | ||
| return this.features.trading && this.tradingManager.isBracketActive(); | ||
| } | ||
| placeOrderIntent(e) { | ||
| this.features.trading && this.eventBus.emit("orderPlace", e); | ||
| } | ||
| setPositions(e) { | ||
| this.features.trading && this.tradingManager.setPositions(e); | ||
| } | ||
| setDepthData(e) { | ||
| this.features.trading && this.tradingManager.setDepthData(e); | ||
| } | ||
| setCurrentPrice(e, t) { | ||
| this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e), this.scheduleRender(), this.features.alerts && (this.alertManager.checkPrice(e), this.feedIndicatorAlerts()); | ||
| } | ||
| feedIndicatorAlerts() { | ||
| let e = this.alertManager.getAlerts(), t = this.dataManager.getData(); | ||
| if (t.length === 0) return; | ||
| let n = t.length - 1, r = /* @__PURE__ */ new Set(); | ||
| for (let t of e) { | ||
| if (t.channel === "price" || r.has(t.channel)) continue; | ||
| r.add(t.channel); | ||
| let e = t.channel.indexOf(":"); | ||
| if (e < 0) continue; | ||
| let i = t.channel.slice(0, e), a = t.channel.slice(e + 1), o = this.indicatorEngine.getOutput(i)?.series?.[n]?.[a]; | ||
| typeof o == "number" && Number.isFinite(o) && this.alertManager.checkChannel(t.channel, o); | ||
| } | ||
| } | ||
| setTradingConfig(e) { | ||
| this.features.trading && this.tradingManager.setConfig(e); | ||
| } | ||
| async connect(e) { | ||
| this.disconnectStream(), this.streamManager = new Oe(), this.streamManager.on("snapshot", (e) => { | ||
| this.setData(e); | ||
| }), this.streamManager.on("barClose", (e) => { | ||
| this.dataManager.appendBar(e), this.crosshairHandler.setData(this.dataManager.getData()), this.autoScrollOnNewBar && this.viewport.scrollToEnd(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.updateViewportAndRender(); | ||
| }), this.streamManager.on("barUpdate", (e) => { | ||
| this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender(); | ||
| }), this.streamManager.on("priceChange", ({ price: e }) => { | ||
| this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e), this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI); | ||
| }), this.streamManager.on("connectionChange", (e) => { | ||
| this.eventBus.emit("dataUpdate", { connection: e }); | ||
| }), this.streamManager.on("error", (e) => { | ||
| this.eventBus.emit("dataUpdate", { error: e.message }); | ||
| }), this.autoScrollOnNewBar = e.autoScroll !== !1, this.currentSymbol = e.symbol, await this.streamManager.connect(e); | ||
| let t = u(e.timeframe); | ||
| this.barCountdown.setTimeframeMs(t), this.countdownInterval && clearInterval(this.countdownInterval), this.countdownInterval = setInterval(() => { | ||
| this.barCountdown.isVisible() && this.engine.requestRender(r.UI); | ||
| }, 1e3); | ||
| } | ||
| async switchStream(e, t) { | ||
| this.streamManager && (this.currentSymbol = e, await this.streamManager.switchTo(e, t)); | ||
| } | ||
| async setTimeframe(e) { | ||
| if (!this.streamManager) throw Error("No active stream. Call connect() first."); | ||
| await this.switchStream(this.currentSymbol, e); | ||
| } | ||
| disconnectStream() { | ||
| this.streamManager &&= (this.streamManager.dispose(), null); | ||
| } | ||
| setBarCountdownVisible(e) { | ||
| this.barCountdown.setVisible(e), this.engine.requestRender(r.UI); | ||
| } | ||
| setSessionBreaksVisible(e) { | ||
| this.sessionBreaks.setVisible(e), this.engine.requestRender(r.Background); | ||
| } | ||
| addCompareSymbol(e, t, n, i) { | ||
| this.compareRenderer.addSymbol({ | ||
| id: e, | ||
| label: t, | ||
| data: n, | ||
| color: i, | ||
| visible: !0 | ||
| }), this.engine.requestRender(r.Main); | ||
| } | ||
| removeCompareSymbol(e) { | ||
| this.compareRenderer.removeSymbol(e), this.engine.requestRender(r.Main); | ||
| } | ||
| updateCompareData(e, t) { | ||
| this.compareRenderer.setSymbolData(e, t), this.engine.requestRender(r.Main); | ||
| } | ||
| setCompareMode(e) { | ||
| this.compareRenderer.setMode(e), this.engine.requestRender(r.Main); | ||
| } | ||
| clearCompareSymbols() { | ||
| this.compareRenderer.clear(), this.engine.requestRender(r.Main); | ||
| } | ||
| setLogScale(e) { | ||
| this.viewport.setLogScale(e), this.updateViewportAndRender(); | ||
| } | ||
| isLogScale() { | ||
| return this.viewport.isLogScale(); | ||
| } | ||
| setScaleMode(e) { | ||
| this.viewport.setScaleMode(e), this.updateViewportAndRender(); | ||
| } | ||
| getScaleMode() { | ||
| return this.viewport.getScaleMode(); | ||
| } | ||
| setSessionBreaksConfig(e) { | ||
| this.sessionBreaks.setConfig(e), this.engine.requestRender(r.Background); | ||
| } | ||
| getConnectionState() { | ||
| return this.streamManager?.getConnectionState() ?? "disconnected"; | ||
| } | ||
| getConnectionInfo() { | ||
| return this.streamManager?.getConnectionInfo() ?? { state: "disconnected" }; | ||
| } | ||
| setAutoScroll(e) { | ||
| this.autoScrollOnNewBar = e; | ||
| } | ||
| scrollTo(e) { | ||
| let t = this.dataManager.getData(); | ||
| for (let n = 0; n < t.length; n++) if (t[n].time >= e) { | ||
| let e = this.viewport.getState().barWidth + this.viewport.getState().barSpacing; | ||
| this.viewport.scrollBy(n * e - this.viewport.getState().offset), this.updateViewportAndRender(); | ||
| return; | ||
| } | ||
| } | ||
| scrollToEnd() { | ||
| this.viewport.scrollToEnd(), this.updateViewportAndRender(); | ||
| } | ||
| setVisibleRange(e, t) { | ||
| let n = this.dataManager.getData(), r = 0, i = n.length - 1; | ||
| for (let t = 0; t < n.length; t++) if (n[t].time >= e) { | ||
| r = t; | ||
| break; | ||
| } | ||
| for (let e = n.length - 1; e >= 0; e--) if (n[e].time <= t) { | ||
| i = e; | ||
| break; | ||
| } | ||
| let a = i - r + 1; | ||
| if (a > 0) { | ||
| let e = this.viewport.getState().chartRect.width, t = e / a, n = Math.max(2, t - this.viewport.getState().barSpacing); | ||
| this.viewport.zoom((n - this.viewport.getState().barWidth) / this.viewport.getState().barWidth, e / 2); | ||
| } | ||
| this.updateViewportAndRender(); | ||
| } | ||
| zoomIn() { | ||
| let e = this.viewport.getState().chartRect.width; | ||
| this.viewport.zoom(.2, e / 2), this.updateViewportAndRender(); | ||
| } | ||
| zoomOut() { | ||
| let e = this.viewport.getState().chartRect.width; | ||
| this.viewport.zoom(-.2, e / 2), this.updateViewportAndRender(); | ||
| } | ||
| fitContent() { | ||
| let e = this.dataManager.getData(); | ||
| e.length !== 0 && this.setVisibleRange(e[0].time, e[e.length - 1].time); | ||
| } | ||
| on(e, t) { | ||
| this.eventBus.on(e, t); | ||
| } | ||
| off(e, t) { | ||
| this.eventBus.off(e, t); | ||
| } | ||
| enableTauriBridge(e) { | ||
| this.eventBus.enableTauriBridge({ | ||
| enabled: !0, | ||
| ...e | ||
| }); | ||
| } | ||
| disableTauriBridge() { | ||
| this.eventBus.disableTauriBridge(); | ||
| } | ||
| setTheme(e) { | ||
| this.themeManager.setTheme(e), this.syncRenderContext(), this.container.style.backgroundColor = this.themeManager.getTheme().background, this.engine.requestRender(), this.eventBus.emit("themeChange", { theme: e }); | ||
| } | ||
| getTheme() { | ||
| return this.themeManager.getTheme(); | ||
| } | ||
| setWatermark(e, t) { | ||
| this.watermark.setConfig({ | ||
| text: e, | ||
| ...t | ||
| }), this.engine.requestRender(r.Background); | ||
| } | ||
| setAutoScale(e) { | ||
| this.options.autoScale = e, this.updateViewportAndRender(); | ||
| } | ||
| isAutoScale() { | ||
| return this.options.autoScale !== !1; | ||
| } | ||
| setCrosshairMode(e) { | ||
| this.crosshairHandler.setMode(e), this.engine.requestRender(r.Overlay); | ||
| } | ||
| getCrosshairMode() { | ||
| return this.crosshairHandler.getMode(); | ||
| } | ||
| setCrosshairPosition(e) { | ||
| e && this.crosshairHandler.onPointerMove(e), this.engine.requestRender(r.Overlay); | ||
| } | ||
| getData() { | ||
| return this.dataManager.getData(); | ||
| } | ||
| setGridVisible(e) { | ||
| this.gridRenderer.setVisible(e), this.engine.requestRender(r.Background); | ||
| } | ||
| isGridVisible() { | ||
| return this.gridRenderer.isVisible(); | ||
| } | ||
| setVolumeVisible(e) { | ||
| this.volumeRenderer.setVisible(e), this.engine.requestRender(r.Main); | ||
| } | ||
| setVolumeProfileVisible(e) { | ||
| this.volumeProfile.setVisible(e), this.engine.requestRender(r.Main); | ||
| } | ||
| isVolumeProfileVisible() { | ||
| return this.volumeProfile.isVisible(); | ||
| } | ||
| setVolumeProfileConfig(e) { | ||
| e.buckets !== void 0 && this.volumeProfile.setBuckets(e.buckets), e.widthRatio !== void 0 && this.volumeProfile.setWidthRatio(e.widthRatio), e.opacity !== void 0 && this.volumeProfile.setOpacity(e.opacity), e.highlightPoC !== void 0 && this.volumeProfile.setHighlightPoC(e.highlightPoC), this.engine.requestRender(r.Main); | ||
| } | ||
| setMarketProfileVisible(e) { | ||
| this.marketProfile.setVisible(e), this.engine.requestRender(r.Main); | ||
| } | ||
| isMarketProfileVisible() { | ||
| return this.marketProfile.isVisible(); | ||
| } | ||
| setMarketProfileConfig(e) { | ||
| e.buckets !== void 0 && this.marketProfile.setBuckets(e.buckets), e.widthRatio !== void 0 && this.marketProfile.setWidthRatio(e.widthRatio), e.opacity !== void 0 && this.marketProfile.setOpacity(e.opacity), e.valueAreaPct !== void 0 && this.marketProfile.setValueAreaPct(e.valueAreaPct), e.highlightPoC !== void 0 && this.marketProfile.setHighlightPoC(e.highlightPoC), e.showStats !== void 0 && this.marketProfile.setShowStats(e.showStats), e.splitBySession !== void 0 && this.marketProfile.setSplitBySession(e.splitBySession), e.letters !== void 0 && this.marketProfile.setLetters(e.letters), this.engine.requestRender(r.Main); | ||
| } | ||
| getMarketProfileStats() { | ||
| return this.marketProfile.getStats(); | ||
| } | ||
| setDepthHeatmapVisible(e) { | ||
| this.depthHeatmap.setVisible(e), this.engine.requestRender(r.Main); | ||
| } | ||
| isDepthHeatmapVisible() { | ||
| return this.depthHeatmap.isVisible(); | ||
| } | ||
| setDepthHeatmapConfig(e) { | ||
| e.opacity !== void 0 && this.depthHeatmap.setOpacity(e.opacity), e.capacity !== void 0 && this.depthHeatmap.setCapacity(e.capacity), this.engine.requestRender(r.Main); | ||
| } | ||
| pushDepthSnapshot(e) { | ||
| let t = this.dataManager.getData(); | ||
| t.length !== 0 && (this.depthHeatmap.push(t[t.length - 1].time, e), this.depthHeatmap.isVisible() && this.engine.requestRender(r.Main)); | ||
| } | ||
| clearDepthHeatmap() { | ||
| this.depthHeatmap.clear(), this.engine.requestRender(r.Main); | ||
| } | ||
| setPeriodLevelsVisible(e) { | ||
| this.periodLevels.setVisible(e), this.engine.requestRender(r.Main); | ||
| } | ||
| isPeriodLevelsVisible() { | ||
| return this.periodLevels.isVisible(); | ||
| } | ||
| setPeriodLevelsPeriod(e) { | ||
| this.periodLevels.setPeriod(e), this.engine.requestRender(r.Main); | ||
| } | ||
| setTimezoneOffset(e) { | ||
| this.timeAxis.setTimezoneOffset(e), this.crosshairHandler.setTimezoneOffset(e), this.engine.requestRender(r.UI), this.engine.requestRender(r.Overlay); | ||
| } | ||
| setPivotMarkersVisible(e) { | ||
| this.pivotMarkers.setVisible(e), this.engine.requestRender(r.Overlay); | ||
| } | ||
| isPivotMarkersVisible() { | ||
| return this.pivotMarkers.isVisible(); | ||
| } | ||
| setPivotMarkersConfig(e) { | ||
| (e.left !== void 0 || e.right !== void 0) && this.pivotMarkers.setStrength(e.left ?? 5, e.right ?? e.left ?? 5), e.showLabels !== void 0 && this.pivotMarkers.setShowLabels(e.showLabels), e.structureLabels !== void 0 && this.pivotMarkers.setStructureLabels(e.structureLabels), this.engine.requestRender(r.Overlay); | ||
| } | ||
| setSessionShadingVisible(e) { | ||
| this.sessionShading.setVisible(e), this.engine.requestRender(r.Background); | ||
| } | ||
| isSessionShadingVisible() { | ||
| return this.sessionShading.isVisible(); | ||
| } | ||
| setSessionShadingConfig(e) { | ||
| this.sessionShading.setConfig(e), this.engine.requestRender(r.Background); | ||
| } | ||
| setTooltipVisible(e) { | ||
| e || this.crosshairTooltip.hide(); | ||
| } | ||
| setLegend(e) { | ||
| this.chartLegend.setConfig(e), this.engine.requestRender(r.UI); | ||
| } | ||
| setSymbolName(e) { | ||
| this.chartLegend.setSymbol(e), this.engine.requestRender(r.UI); | ||
| } | ||
| setStatusText(e) { | ||
| this.chartLegend.setStatusText(e), this.engine.requestRender(r.UI); | ||
| } | ||
| screenshot(e) { | ||
| this.features.screenshot && E.download(this.container, e, this.themeManager.getTheme().background); | ||
| } | ||
| async copyScreenshot() { | ||
| if (!this.features.screenshot) return !1; | ||
| try { | ||
| let e = await E.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem; | ||
| return !e || !navigator.clipboard?.write || !t ? !1 : (await navigator.clipboard.write([new t({ "image/png": e })]), !0); | ||
| } catch { | ||
| return !1; | ||
| } | ||
| } | ||
| screenshotDataURL() { | ||
| return this.features.screenshot ? E.toDataURL(this.container, this.themeManager.getTheme().background) : null; | ||
| } | ||
| async screenshotBlob() { | ||
| return this.features.screenshot ? E.toBlob(this.container, this.themeManager.getTheme().background) : null; | ||
| } | ||
| addAlert(e, t = "crossing", n, r = "price", i) { | ||
| if (!this.features.alerts) return null; | ||
| let a = this.alertManager.addAlert(e, t, n, !1, r, i); | ||
| return this.scheduleAutoSave(), a; | ||
| } | ||
| removeAlert(e) { | ||
| this.alertManager.removeAlert(e), this.scheduleAutoSave(); | ||
| } | ||
| getAlerts() { | ||
| return this.alertManager.getAlerts(); | ||
| } | ||
| clearAlerts() { | ||
| this.alertManager.clearAlerts(), this.scheduleAutoSave(); | ||
| } | ||
| saveAlerts(e) { | ||
| this.alertManager.saveToStorage(e); | ||
| } | ||
| loadAlerts(e) { | ||
| this.alertManager.loadFromStorage(e), this.engine.requestRender(r.Overlay); | ||
| } | ||
| addSignalMarker(e) { | ||
| return this.signalMarkerManager.addMarker(e); | ||
| } | ||
| removeSignalMarker(e) { | ||
| this.signalMarkerManager.removeMarker(e); | ||
| } | ||
| getSignalMarkers() { | ||
| return this.signalMarkerManager.getMarkers(); | ||
| } | ||
| setSignalMarkers(e) { | ||
| this.signalMarkerManager.setMarkers(e); | ||
| } | ||
| clearSignalMarkers() { | ||
| this.signalMarkerManager.clearMarkers(); | ||
| } | ||
| setSignalMarkerStyle(e) { | ||
| this.signalMarkerManager.setStyle(e); | ||
| } | ||
| addTradeZone(e) { | ||
| return this.tradeZoneManager.addZone(e); | ||
| } | ||
| updateTradeZone(e, t) { | ||
| this.tradeZoneManager.updateZone(e, t); | ||
| } | ||
| removeTradeZone(e) { | ||
| this.tradeZoneManager.removeZone(e); | ||
| } | ||
| getTradeZones() { | ||
| return this.tradeZoneManager.getZones(); | ||
| } | ||
| setTradeZones(e) { | ||
| this.tradeZoneManager.setZones(e); | ||
| } | ||
| clearTradeZones() { | ||
| this.tradeZoneManager.clearZones(); | ||
| } | ||
| setTradeZoneStyle(e) { | ||
| this.tradeZoneManager.setStyle(e); | ||
| } | ||
| replay(e) { | ||
| if (!this.features.replay) return; | ||
| let t = this.dataManager.getData(); | ||
| this.replayManager.load(t), this.replayManager.on("bar", ({ bar: e, index: n }) => { | ||
| let r = t.slice(0, n + 1); | ||
| this.dataManager.setData(r), this.crosshairHandler.setData(r), this.indicatorEngine.recalculateAll(r), this.updateViewportAndRender(); | ||
| }), this.replayManager.play(e); | ||
| } | ||
| replayPause() { | ||
| this.replayManager.pause(); | ||
| } | ||
| replayResume() { | ||
| this.replayManager.resume(); | ||
| } | ||
| replayStop() { | ||
| this.replayManager.stop(); | ||
| } | ||
| replaySeek(e) { | ||
| this.replayManager.seekTo(e); | ||
| } | ||
| setReplaySpeed(e) { | ||
| this.replayManager.setSpeed(e); | ||
| } | ||
| getReplayState() { | ||
| return this.replayManager.getState(); | ||
| } | ||
| getReplayProgress() { | ||
| return this.replayManager.getProgress(); | ||
| } | ||
| saveState(e) { | ||
| if (!this.features.saveLoad) return null; | ||
| let t = _.capture({ | ||
| getDrawings: () => this.getDrawings(), | ||
| getTheme: () => this.getTheme(), | ||
| getAlerts: () => this.getAlerts() | ||
| }, { chartType: this.options.chartType }), n = _.serialize(t); | ||
| return e && _.saveToStorage(e, t), n; | ||
| } | ||
| loadState(e) { | ||
| if (!this.features.saveLoad) return; | ||
| let t = _.deserialize(e); | ||
| if (t.chartType && this.setChartType(t.chartType), t.drawings && this.setDrawings(t.drawings), t.theme && this.setTheme(t.theme), t.alerts) { | ||
| this.clearAlerts(); | ||
| for (let e of t.alerts) this.addAlert(e.price, e.condition, e.message); | ||
| } | ||
| } | ||
| loadStateFromStorage(e) { | ||
| if (!this.features.saveLoad) return !1; | ||
| let t = _.loadFromStorage(e); | ||
| return t ? (this.loadState(_.serialize(t)), !0) : !1; | ||
| } | ||
| downloadState(e) { | ||
| if (!this.features.saveLoad) return; | ||
| let t = _.capture({ | ||
| getDrawings: () => this.getDrawings(), | ||
| getTheme: () => this.getTheme(), | ||
| getAlerts: () => this.getAlerts() | ||
| }, { chartType: this.options.chartType }); | ||
| _.downloadFile(t, e); | ||
| } | ||
| async loadStateFromFile() { | ||
| if (!this.features.saveLoad) return; | ||
| let e = await _.loadFromFile(); | ||
| this.loadState(_.serialize(e)); | ||
| } | ||
| setLocale(e) { | ||
| l(e), this.engine.requestRender(); | ||
| } | ||
| setNumberLocale(e) { | ||
| this.numberLocale = e, this.priceAxis.setLocale(e), this.crosshairHandler.setLocale(e), this.syncRenderContext(), this.engine.requestRender(); | ||
| } | ||
| getNumberLocale() { | ||
| return this.numberLocale; | ||
| } | ||
| setMarket(e) { | ||
| if (this.marketConfig = e, e.colorScheme) { | ||
| let t = { | ||
| ...this.themeManager.getTheme(), | ||
| candleUp: e.colorScheme.up, | ||
| candleDown: e.colorScheme.down, | ||
| candleUpWick: e.colorScheme.up, | ||
| candleDownWick: e.colorScheme.down, | ||
| volumeUp: e.colorScheme.up.replace(")", ", 0.3)").replace("rgb(", "rgba(") || `${e.colorScheme.up}4D`, | ||
| volumeDown: e.colorScheme.down.replace(")", ", 0.3)").replace("rgb(", "rgba(") || `${e.colorScheme.down}4D` | ||
| }; | ||
| this.themeManager.setTheme(t); | ||
| } | ||
| e.pricePrecision !== void 0 && (this.tradingManager.setConfig({ pricePrecision: e.pricePrecision }), this.alertManager.setPricePrecision(e.pricePrecision), this.streamManager?.priceLine.setPricePrecision(e.pricePrecision), this.crosshairHandler.setPricePrecision(e.pricePrecision)), this.syncRenderContext(), this.engine.requestRender(); | ||
| } | ||
| getMarket() { | ||
| return this.marketConfig; | ||
| } | ||
| setPriceLimits(e) { | ||
| this.marketConfig && (s(e, this.marketConfig) && (this.marketConfig.priceLimits = { | ||
| ...this.marketConfig.priceLimits, | ||
| referencePrice: e | ||
| }), this.engine.requestRender()); | ||
| } | ||
| getFeatures() { | ||
| return this.features; | ||
| } | ||
| setFeatures(e) { | ||
| Object.assign(this.features, e), e.crosshair === !1 && this.crosshairTooltip.hide(), e.grid !== void 0 && this.engine.requestRender(r.Background), e.volume !== void 0 && (this.volumeRenderer.setVisible(e.volume), this.engine.requestRender(r.Main)), e.drawings === !1 && this.drawingManager.setActiveTool(null), e.trading === !1 && (this.tradingManager.setOrders([]), this.tradingManager.setPositions([])), e.keyboard !== void 0 && this.keyboardHandler?.setEnabled(e.keyboard), this.engine.requestRender(); | ||
| } | ||
| resize() { | ||
| let e = this.engine.dprManager.readContainerSize(); | ||
| if (e.width <= 0 || e.height <= 0) return; | ||
| this.containerSizeCache = e, this.containerSizeCacheTime = Date.now(); | ||
| let t = this.engine.dprManager.getDpr(); | ||
| this.engine.layerManager.resize(e, t); | ||
| let n = this.viewport.isAtEnd(); | ||
| this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(n), this.eventBus.emit("resize", e); | ||
| } | ||
| destroy() { | ||
| this.countdownInterval && clearInterval(this.countdownInterval), this.disableAutoSave(), this.disconnectStream(), this.onWindowKeyDown &&= (window.removeEventListener("keydown", this.onWindowKeyDown), null), this.keyboardHandler = null, this.interactionManager.detach(), this.tradingManager.destroy(), this.animator.dispose(), this.crosshairTooltip.destroy(), this.pinnedTooltip.destroy(), this.replayManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = ""; | ||
| } | ||
| createChartRenderer(e) { | ||
| return Je(e); | ||
| } | ||
| getDisplayData() { | ||
| if (this.displayDataCache) return this.displayDataCache; | ||
| let e = this.dataManager.getData(); | ||
| if (e.length === 0) return e; | ||
| let t = Ye(this.options.chartType, e); | ||
| return this.displayDataCache = t, t; | ||
| } | ||
| scheduleRender() { | ||
| this.renderScheduled || (this.renderScheduled = !0, requestAnimationFrame(() => { | ||
| this.renderScheduled = !1; | ||
| let e = this.getDisplayData(); | ||
| this.viewport.updateData(e, this.options.autoScale !== !1), this.syncRenderContext(), this.engine.requestRender(); | ||
| })); | ||
| } | ||
| updateViewportAndRender(e = !1) { | ||
| this.resolvedLayoutCache = null, this.panelInfoCache = null; | ||
| let t = this.getResolvedLayout(); | ||
| this.viewport.setChartRect(t.mainChartRect); | ||
| let n = this.getDisplayData(); | ||
| if (this.viewport.updateData(n, this.options.autoScale !== !1), n.length > 0) { | ||
| let e = this.viewport.getState(), t = Math.max(0, Math.min(e.visibleRange.from, n.length - 1)); | ||
| this.viewport.setScaleBaseline(n[t]?.close); | ||
| } | ||
| if (this.options.autoScale !== !1) { | ||
| let e = this.viewport.getState(), t = this.indicatorEngine.getOverlayPriceRange(e.visibleRange.from, Math.min(e.visibleRange.to, n.length - 1)); | ||
| if (t) { | ||
| let n = e.priceRange, r = Math.min(n.min, t.min), i = Math.max(n.max, t.max); | ||
| if (r < n.min || i > n.max) { | ||
| let e = i - r || 1; | ||
| this.viewport.setPriceRange(r - e * .02, i + e * .02); | ||
| } | ||
| } | ||
| } | ||
| e && this.viewport.scrollToEnd(), this.syncRenderContext(), this.engine.requestRender(); | ||
| } | ||
| getResolvedLayout() { | ||
| return this.resolvedLayoutCache ||= this.layoutManager.resolve(), this.resolvedLayoutCache; | ||
| } | ||
| cachedContainerSize() { | ||
| let e = Date.now(); | ||
| return (!this.containerSizeCache || e - this.containerSizeCacheTime > 500) && (this.containerSizeCache = this.engine.dprManager.getContainerSize(), this.containerSizeCacheTime = e), this.containerSizeCache; | ||
| } | ||
| buildPanelRenderInfos() { | ||
| if (this.panelInfoCache) return this.panelInfoCache; | ||
| let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => { | ||
| let i = Xe(this.indicatorEngine.getOutput(e.config.id), n, r), a = { | ||
| x: e.rect.x, | ||
| y: e.rect.y + 20, | ||
| width: e.rect.width, | ||
| height: Math.max(0, e.rect.height - 20) | ||
| }; | ||
| return { | ||
| instanceId: e.config.id, | ||
| rect: e.rect, | ||
| viewport: { | ||
| ...t, | ||
| chartRect: a, | ||
| priceRange: i | ||
| } | ||
| }; | ||
| }); | ||
| return this.panelInfoCache = i, i; | ||
| } | ||
| syncRenderContext() { | ||
| this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), null, null, this.themeManager.getTheme()); | ||
| let e = this.getResolvedLayout(), t = this.features.indicators ? this.buildPanelRenderInfos() : [], n = e.panels.filter((e) => e.config.position === "bottom").reduce((e, t) => e + t.rect.height, 0), r = e.mainChartRect.y + e.mainChartRect.height + n, i = this.getDisplayData(); | ||
| this.engine.setRenderContext({ | ||
| chartRenderer: this.chartRenderer, | ||
| gridRenderer: this.features.grid ? this.gridRenderer : null, | ||
| priceAxis: this.features.priceAxis ? this.priceAxis : null, | ||
| timeAxis: this.features.timeAxis ? this.timeAxis : null, | ||
| crosshairHandler: this.features.crosshair ? this.crosshairHandler : null, | ||
| indicatorEngine: this.features.indicators ? this.indicatorEngine : null, | ||
| drawingRenderer: this.features.drawings ? this.drawingRenderer : null, | ||
| tradingRenderer: this.features.trading ? this.tradingRenderer : null, | ||
| currentPriceLine: this.streamManager?.priceLine ?? this.currentPriceLine, | ||
| chartLegend: this.features.legend ? this.chartLegend : null, | ||
| volumeRenderer: this.features.volume ? this.volumeRenderer : null, | ||
| volumeProfile: this.volumeProfile, | ||
| marketProfile: this.marketProfile, | ||
| depthHeatmap: this.depthHeatmap, | ||
| periodLevels: this.periodLevels, | ||
| pivotMarkers: this.pivotMarkers, | ||
| watermark: this.features.watermark ? this.watermark : null, | ||
| barCountdown: this.barCountdown, | ||
| sessionBreaks: this.sessionBreaks, | ||
| sessionShading: this.sessionShading, | ||
| compareRenderer: this.compareRenderer, | ||
| alertManager: this.features.alerts ? this.alertManager : null, | ||
| measureOverlay: this.measureOverlay, | ||
| signalMarkerManager: this.signalMarkerManager, | ||
| tradeZoneManager: this.tradeZoneManager, | ||
| panels: t, | ||
| priceLimits: this.buildPriceLimits(), | ||
| timeAxisY: r, | ||
| viewport: { | ||
| ...this.viewport.getState(), | ||
| data: i | ||
| }, | ||
| theme: this.themeManager.getTheme(), | ||
| data: i, | ||
| numberLocale: this.numberLocale | ||
| }); | ||
| } | ||
| buildPriceLimits() { | ||
| if (!this.marketConfig?.priceLimits?.enabled || !this.marketConfig.priceLimits.referencePrice) return null; | ||
| let e = s(this.marketConfig.priceLimits.referencePrice, this.marketConfig); | ||
| return e ? { | ||
| ...e, | ||
| colors: this.marketConfig.colorScheme ? { | ||
| ceiling: this.marketConfig.colorScheme.ceiling, | ||
| floor: this.marketConfig.colorScheme.floor, | ||
| reference: this.marketConfig.colorScheme.reference | ||
| } : void 0 | ||
| } : null; | ||
| } | ||
| }, H = [ | ||
| "time", | ||
| "timestamp", | ||
| "date", | ||
| "datetime", | ||
| "t" | ||
| ], U = ["open", "o"], W = ["high", "h"], G = ["low", "l"], K = ["close", "c"], q = [ | ||
| "volume", | ||
| "vol", | ||
| "v" | ||
| ]; | ||
| function J(e) { | ||
| let t = e.trim(); | ||
| return t ? t[0] === "[" || t[0] === "{" ? $e(t) : et(t) : { | ||
| data: [], | ||
| rowCount: 0, | ||
| skipped: 0 | ||
| }; | ||
| } | ||
| function $e(e) { | ||
| let t; | ||
| try { | ||
| t = JSON.parse(e); | ||
| } catch (e) { | ||
| throw Error(`Invalid JSON: ${e.message}`); | ||
| } | ||
| if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows"); | ||
| let n = [], r = 0; | ||
| for (let e of t) { | ||
| let t = Array.isArray(e) ? it(e) : rt(e); | ||
| t ? n.push(t) : r++; | ||
| } | ||
| return Q(n, t.length, r); | ||
| } | ||
| function et(e) { | ||
| let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0); | ||
| if (t.length === 0) return { | ||
| data: [], | ||
| rowCount: 0, | ||
| skipped: 0 | ||
| }; | ||
| let n = tt(t[0]), r = Y(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? nt(r) : { | ||
| time: 0, | ||
| open: 1, | ||
| high: 2, | ||
| low: 3, | ||
| close: 4, | ||
| volume: 5 | ||
| }; | ||
| if (a.time < 0 || a.open < 0 || a.high < 0 || a.low < 0 || a.close < 0) throw Error("CSV is missing required column(s): time, open, high, low, close"); | ||
| let o = [], s = 0; | ||
| for (let e = +!!i; e < t.length; e++) { | ||
| let r = Y(t[e], n), i = Z(r[a.time]), c = X(r[a.open]), l = X(r[a.high]), u = X(r[a.low]), d = X(r[a.close]), f = a.volume >= 0 ? Number(r[a.volume]) : 0; | ||
| if (i === null || ![ | ||
| c, | ||
| l, | ||
| u, | ||
| d | ||
| ].every(Number.isFinite)) { | ||
| s++; | ||
| continue; | ||
| } | ||
| o.push({ | ||
| time: i, | ||
| open: c, | ||
| high: l, | ||
| low: u, | ||
| close: d, | ||
| volume: Number.isFinite(f) ? f : 0 | ||
| }); | ||
| } | ||
| return Q(o, t.length - +!!i, s); | ||
| } | ||
| function tt(e) { | ||
| let t = { | ||
| ",": 0, | ||
| ";": 0, | ||
| " ": 0, | ||
| "|": 0 | ||
| }; | ||
| for (let n of e) n in t && t[n]++; | ||
| let n = ",", r = 0; | ||
| for (let [e, i] of Object.entries(t)) i > r && (n = e, r = i); | ||
| return n; | ||
| } | ||
| function Y(e, t) { | ||
| let n = [], r = "", i = !1; | ||
| for (let a = 0; a < e.length; a++) { | ||
| let o = e[a]; | ||
| o === "\"" ? i && e[a + 1] === "\"" ? (r += "\"", a++) : i = !i : o === t && !i ? (n.push(r), r = "") : r += o; | ||
| } | ||
| return n.push(r), n; | ||
| } | ||
| function nt(e) { | ||
| let t = (t) => e.findIndex((e) => t.includes(e)); | ||
| return { | ||
| time: t(H), | ||
| open: t(U), | ||
| high: t(W), | ||
| low: t(G), | ||
| close: t(K), | ||
| volume: t(q) | ||
| }; | ||
| } | ||
| function rt(e) { | ||
| let t = (t) => { | ||
| for (let n of t) { | ||
| if (e[n] !== void 0) return e[n]; | ||
| let t = n.toUpperCase(); | ||
| if (e[t] !== void 0) return e[t]; | ||
| } | ||
| }, n = Z(String(t(H) ?? "")), r = Number(t(U)), i = Number(t(W)), a = Number(t(G)), o = Number(t(K)), s = Number(t(q) ?? 0); | ||
| return n === null || ![ | ||
| r, | ||
| i, | ||
| a, | ||
| o | ||
| ].every(Number.isFinite) ? null : { | ||
| time: n, | ||
| open: r, | ||
| high: i, | ||
| low: a, | ||
| close: o, | ||
| volume: Number.isFinite(s) ? s : 0 | ||
| }; | ||
| } | ||
| function it(e) { | ||
| if (e.length < 5) return null; | ||
| let t = Z(String(e[0])), n = Number(e[1]), r = Number(e[2]), i = Number(e[3]), a = Number(e[4]), o = e.length >= 6 ? Number(e[5]) : 0; | ||
| return t === null || ![ | ||
| n, | ||
| r, | ||
| i, | ||
| a | ||
| ].every(Number.isFinite) ? null : { | ||
| time: t, | ||
| open: n, | ||
| high: r, | ||
| low: i, | ||
| close: a, | ||
| volume: Number.isFinite(o) ? o : 0 | ||
| }; | ||
| } | ||
| function X(e) { | ||
| return e === void 0 || e.trim() === "" ? NaN : Number(e); | ||
| } | ||
| function Z(e) { | ||
| let t = e.trim(); | ||
| if (!t) return null; | ||
| let n = Number(t); | ||
| if (Number.isFinite(n) && n > 0) return n < 0xe8d4a51000 ? n * 1e3 : n; | ||
| let r = Date.parse(t); | ||
| return Number.isFinite(r) ? r : null; | ||
| } | ||
| function Q(e, t, n) { | ||
| e.sort((e, t) => e.time - t.time); | ||
| let r = []; | ||
| for (let t of e) r.length > 0 && r[r.length - 1].time === t.time ? r[r.length - 1] = t : r.push(t); | ||
| return { | ||
| data: r, | ||
| rowCount: t, | ||
| skipped: n | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/io/DragDropImporter.ts | ||
| var at = class { | ||
| host; | ||
| overlay = null; | ||
| callbacks; | ||
| bound; | ||
| depth = 0; | ||
| constructor(e, t) { | ||
| this.host = e, this.callbacks = t, this.bound = { | ||
| dragenter: (e) => this.onDragEnter(e), | ||
| dragover: (e) => this.onDragOver(e), | ||
| dragleave: (e) => this.onDragLeave(e), | ||
| drop: (e) => this.onDrop(e) | ||
| }; | ||
| } | ||
| attach() { | ||
| this.host.addEventListener("dragenter", this.bound.dragenter), this.host.addEventListener("dragover", this.bound.dragover), this.host.addEventListener("dragleave", this.bound.dragleave), this.host.addEventListener("drop", this.bound.drop); | ||
| } | ||
| detach() { | ||
| this.host.removeEventListener("dragenter", this.bound.dragenter), this.host.removeEventListener("dragover", this.bound.dragover), this.host.removeEventListener("dragleave", this.bound.dragleave), this.host.removeEventListener("drop", this.bound.drop), this.hideOverlay(); | ||
| } | ||
| onDragEnter(e) { | ||
| $(e) && (e.preventDefault(), this.depth++, this.showOverlay()); | ||
| } | ||
| onDragOver(e) { | ||
| $(e) && (e.preventDefault(), e.dataTransfer && (e.dataTransfer.dropEffect = "copy")); | ||
| } | ||
| onDragLeave(e) { | ||
| $(e) && (this.depth = Math.max(0, this.depth - 1), this.depth === 0 && this.hideOverlay()); | ||
| } | ||
| async onDrop(e) { | ||
| e.preventDefault(), this.depth = 0, this.hideOverlay(); | ||
| let t = e.dataTransfer?.files?.[0]; | ||
| if (t) try { | ||
| let e = J(await t.text()); | ||
| if (e.data.length === 0) throw Error(`No valid OHLCV rows found in "${t.name}"`); | ||
| this.callbacks.onData(e.data, e, t); | ||
| } catch (e) { | ||
| this.callbacks.onError?.(e, t); | ||
| } | ||
| } | ||
| showOverlay() { | ||
| this.overlay || (this.overlay = document.createElement("div"), Object.assign(this.overlay.style, { | ||
| position: "absolute", | ||
| inset: "8px", | ||
| zIndex: "90", | ||
| pointerEvents: "none", | ||
| borderRadius: "10px", | ||
| border: "2px dashed var(--tcw-accent, #4f88ff)", | ||
| background: "rgba(79, 136, 255, 0.06)", | ||
| display: "flex", | ||
| alignItems: "center", | ||
| justifyContent: "center", | ||
| color: "var(--tcw-accent, #4f88ff)", | ||
| fontSize: "14px", | ||
| fontWeight: "600", | ||
| letterSpacing: "-0.005em", | ||
| fontFamily: "inherit", | ||
| backdropFilter: "blur(2px)" | ||
| }), this.overlay.textContent = "Drop CSV or JSON to load chart data", getComputedStyle(this.host).position === "static" && (this.host.style.position = "relative"), this.host.appendChild(this.overlay)); | ||
| } | ||
| hideOverlay() { | ||
| this.overlay?.remove(), this.overlay = null; | ||
| } | ||
| }; | ||
| function $(e) { | ||
| return e.dataTransfer?.types?.includes("Files") ?? !1; | ||
| } | ||
| //#endregion | ||
| export { B as a, V as i, J as n, L as o, Qe as r, I as s, at as t }; | ||
| //# sourceMappingURL=DragDropImporter-Br2ez5Gz.js.map |
Sorry, the diff of this file is too big to display
| let e=require(`@tradecanvas/commons`),t=require(`@tradecanvas/core`);function n(e){switch(e){case`candlestick`:case`heikinAshi`:case`lineBreak`:case`rangeBars`:return new t.CandlestickRenderer;case`line`:return new t.LineRenderer;case`area`:return new t.AreaRenderer;case`bar`:return new t.BarRenderer;case`hollowCandle`:return new t.HollowCandleRenderer;case`baseline`:return new t.BaselineRenderer;case`renko`:return new t.RenkoRenderer;case`kagi`:return new t.KagiRenderer;case`pointAndFigure`:return new t.PointAndFigureRenderer;case`volumeCandles`:return new t.VolumeCandleRenderer;case`equivolume`:return new t.EquivolumeRenderer;case`hlcArea`:return new t.HLCAreaRenderer;case`stepLine`:return new t.StepLineRenderer;case`lineWithMarkers`:return new t.LineWithMarkersRenderer;default:return new t.CandlestickRenderer}}function r(e,n){if(n.length===0)return n;switch(e){case`heikinAshi`:return(0,t.toHeikinAshi)(n);case`renko`:return(0,t.toRenko)(n,{brickSize:0,useATR:!0,atrPeriod:14});case`lineBreak`:return(0,t.toLineBreak)(n,3);case`kagi`:return(0,t.toKagi)(n,4);case`pointAndFigure`:return(0,t.toPointAndFigure)(n,i(n)*.01,3);case`rangeBars`:return(0,t.toRangeBars)(n,{rangeSize:i(n)*.005});default:return n}}function i(e){let t=0;for(let n of e)t+=n.close;return t/e.length}var a={min:0,max:100},o=.1;function s(e,t,n){if(!e)return{...a};let r=1/0,i=-1/0,s=0;for(let[,a]of e.values){if(s>=t&&s<=n)for(let e in a){let t=a[e];t!==void 0&&Number.isFinite(t)&&(t<r&&(r=t),t>i&&(i=t))}s++}if(r===1/0)return{...a};let c=i-r||1;return{min:r-c*o,max:i+c*o}}var c=class{timer=null;delayMs=0;key=null;constructor(e){this.save=e}enable(e,t){this.key=e,this.delayMs=t}disable(){this.key=null,this.delayMs=0,this.cancel()}schedule(){this.delayMs<=0||!this.key||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.timer=null,this.key&&this.save(this.key)},this.delayMs))}cancel(){this.timer&&=(clearTimeout(this.timer),null)}isEnabled(){return this.delayMs>0&&this.key!==null}hasPending(){return this.timer!==null}};function l(e){if(!e||typeof e.time!=`number`)return!1;let{open:t,high:n,low:r,close:i}=e;return!(!isFinite(t)||!isFinite(n)||!isFinite(r)||!isFinite(i)||t<0||n<0||r<0||i<0||n<r||e.volume!==void 0&&(!isFinite(e.volume)||e.volume<0))}function u(e){return{...e,high:Math.max(e.open,e.high,e.low,e.close),low:Math.min(e.open,e.high,e.low,e.close),volume:e.volume===void 0?0:Math.max(0,e.volume)}}var d=class{data=[];getData(){return this.data}setData(e){this.data=e.filter(l).map(u)}appendBar(e){l(e)&&this.data.push(u(e))}updateLastBar(e){if(!l(e))return;let t=u(e);if(this.data.length===0){this.data.push(t);return}this.data[this.data.length-1]=t}updateLastBarFromTick(t){this.data.length!==0&&(!isFinite(t.price)||t.price<0||t.volume!==void 0&&(!isFinite(t.volume)||t.volume<0)||(this.data[this.data.length-1]=(0,e.mergeBar)(this.data[this.data.length-1],t)))}getLength(){return this.data.length}clear(){this.data=[]}},f=class{theme;constructor(t){!t||t===`dark`?this.theme={...e.DARK_THEME}:t===`light`?this.theme={...e.LIGHT_THEME}:this.theme={...t}}getTheme(){return this.theme}setTheme(t){t===`dark`?this.theme={...e.DARK_THEME}:t===`light`?this.theme={...e.LIGHT_THEME}:this.theme={...t}}},p=200,m=80,h=class{panels=[];containerWidth=0;containerHeight=0;resize(e,t){this.containerWidth=e,this.containerHeight=t}addPanel(t,n=`bottom`,r){let i=n===`left`||n===`right`;this.panels.push({id:t,position:n,size:r??(i?p:e.DEFAULT_PANEL_HEIGHT),minSize:i?m:e.MIN_PANEL_HEIGHT,content:{type:`indicator`,indicatorInstanceId:t}})}removePanel(e){this.panels=this.panels.filter(t=>t.id!==e)}setPanelPosition(t,n){let r=this.panels.find(e=>e.id===t);if(r){let t=r.position===`left`||r.position===`right`,i=n===`left`||n===`right`;r.position=n,t!==i&&(r.size=i?p:e.DEFAULT_PANEL_HEIGHT,r.minSize=i?m:e.MIN_PANEL_HEIGHT)}}setPanelSize(e,t){let n=this.panels.find(t=>t.id===e);n&&(n.size=Math.max(n.minSize,t))}getPanels(){return this.panels}resolve(){let t=this.panels.filter(e=>e.position===`left`),n=this.panels.filter(e=>e.position===`right`),r=this.panels.filter(e=>e.position===`top`),i=this.panels.filter(e=>e.position===`bottom`),a=t.reduce((e,t)=>e+t.size,0),o=n.reduce((e,t)=>e+t.size,0),s=r.reduce((e,t)=>e+t.size,0),c=i.reduce((e,t)=>e+t.size,0),l={x:a,y:s,width:Math.max(0,this.containerWidth-a-o-e.PRICE_AXIS_WIDTH),height:Math.max(0,this.containerHeight-s-c-e.TIME_AXIS_HEIGHT)},u=[],d=[],f=0;for(let n of t)u.push({config:n,rect:{x:f,y:0,width:n.size,height:this.containerHeight-e.TIME_AXIS_HEIGHT}}),d.push({panelId:n.id,rect:{x:f+n.size-2,y:0,width:4,height:this.containerHeight},orientation:`vertical`}),f+=n.size;let p=0;for(let e of r)u.push({config:e,rect:{x:a,y:p,width:l.width,height:e.size}}),d.push({panelId:e.id,rect:{x:a,y:p+e.size-2,width:l.width,height:4},orientation:`horizontal`}),p+=e.size;p=l.y+l.height;for(let e of i)u.push({config:e,rect:{x:a,y:p,width:l.width,height:e.size}}),d.push({panelId:e.id,rect:{x:a,y:p-2,width:l.width,height:4},orientation:`horizontal`}),p+=e.size;f=a+l.width+e.PRICE_AXIS_WIDTH;for(let t of n)u.push({config:t,rect:{x:f,y:0,width:t.size,height:this.containerHeight-e.TIME_AXIS_HEIGHT}}),d.push({panelId:t.id,rect:{x:f-2,y:0,width:4,height:this.containerHeight},orientation:`vertical`}),f+=t.size;return{mainChartRect:l,panels:u,dividers:d}}getMainChartRect(){return this.resolve().mainChartRect}},g=class{constructor(e){this.indicatorEngine=e}registerIndicator(e){this.indicatorEngine.register(e)}},_=class{static version=`0.7.0`;engine;viewport;dataManager;themeManager;layoutManager;pluginManager;indicatorEngine;drawingManager;drawingRenderer;tradingManager;tradingRenderer;eventBus;streamManager=null;autoScrollOnNewBar=!0;displayDataCache=null;resolvedLayoutCache=null;panelInfoCache=null;renderScheduled=!1;containerSizeCache=null;containerSizeCacheTime=0;chartLegend;watermark;barCountdown;sessionBreaks;sessionShading;compareRenderer;countdownInterval=null;volumeRenderer;volumeProfile;marketProfile;depthHeatmap;periodLevels;pivotMarkers;alertManager;signalMarkerManager;tradeZoneManager;measureOverlay;replayManager;undoRedoManager;autoSaveScheduler=new c(e=>this.saveState(e));animator;crosshairTooltip;pinnedTooltip;interactionManager;crosshairHandler;chartRenderer;gridRenderer;priceAxis;timeAxis;options;features;marketConfig=null;container;currentPriceLine;numberLocale;keyboardHandler=null;onWindowKeyDown=null;currentSymbol=``;constructor(n,r){this.container=n,this.options=r,this.numberLocale=r.numberLocale??`en-US`;let i=r.features??{};this.features={drawings:i.drawings??!0,drawingTools:i.drawingTools??[],drawingMagnet:i.drawingMagnet??!0,drawingUndoRedo:i.drawingUndoRedo??!0,trading:i.trading??!0,tradingContextMenu:i.tradingContextMenu??!0,indicators:i.indicators??!0,indicatorIds:i.indicatorIds??[],panning:i.panning??!0,zooming:i.zooming??!0,crosshair:i.crosshair??!0,keyboard:i.keyboard??!0,priceAxis:i.priceAxis??!0,timeAxis:i.timeAxis??!0,grid:i.grid??r.grid?.visible??!0,legend:i.legend??!0,volume:i.volume??!0,watermark:i.watermark??!0,saveLoad:i.saveLoad??!0,screenshot:i.screenshot??!0,alerts:i.alerts??!0,replay:i.replay??!0,sessionBreaks:i.sessionBreaks??!0,barCountdown:i.barCountdown??!0,compareSymbols:i.compareSymbols??!0,dataExport:i.dataExport??!0,logScale:i.logScale??!0,timeframes:i.timeframes??[],defaultTimeframeFavorites:i.defaultTimeframeFavorites??[]},n.style.position=`relative`,n.style.overflow=`hidden`,n.tabIndex=0,n.style.outline=`none`,this.dataManager=new d,this.themeManager=new f(r.theme),this.layoutManager=new h,this.indicatorEngine=new t.IndicatorEngine,this.pluginManager=new g(this.indicatorEngine),this.eventBus=new t.EventBus,(0,t.registerBuiltInIndicators)(this.indicatorEngine),this.drawingManager=new t.DrawingManager,(0,t.registerBuiltInDrawingTools)(this.drawingManager),this.drawingRenderer=new t.DrawingRenderer(this.drawingManager),this.drawingManager.setRequestRender(()=>{this.syncRenderContext(),this.engine.requestRender(e.LayerType.Overlay),this.scheduleAutoSave()}),this.drawingManager.setEventCallback((e,t)=>{this.eventBus.emit(e,t)}),this.undoRedoManager=new t.UndoRedoManager,this.drawingManager.setUndoRedoManager(this.undoRedoManager),this.drawingManager.setDataGetter(()=>this.dataManager.getData()),this.drawingManager.setDisplayDataGetter(()=>this.getDisplayData()),r.crosshair?.mode===`magnet`&&this.drawingManager.setMagnetMode(`magnet`),this.tradingManager=new t.TradingManager({enabled:this.features.trading,contextMenu:{enabled:this.features.tradingContextMenu}}),this.tradingRenderer=new t.TradingRenderer(this.tradingManager),this.tradingManager.setContainer(n),this.tradingManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.tradingManager.setEventCallback((e,t)=>{this.eventBus.emit(e,t)}),this.engine=new t.RenderEngine(n);let a=this.engine.dprManager.getContainerSize();if(this.viewport=new t.Viewport(a.width,a.height,r.minBarSpacing??2,r.maxBarSpacing??30,r.rightMargin??5),this.layoutManager.resize(a.width,a.height),this.engine.onContainerResize=e=>{if(e.width<=0||e.height<=0)return;let t=this.viewport.isAtEnd();this.viewport.resize(e.width,e.height),this.layoutManager.resize(e.width,e.height),this.updateViewportAndRender(t)},this.chartRenderer=this.createChartRenderer(r.chartType),this.gridRenderer=new t.GridRenderer,r.grid?.visible===!1&&this.gridRenderer.setVisible(!1),this.priceAxis=new t.PriceAxis,this.priceAxis.setLocale(this.numberLocale),this.timeAxis=new t.TimeAxis,this.crosshairHandler=new t.CrosshairHandler,this.crosshairHandler.setLocale(this.numberLocale),r.crosshair?.mode&&this.crosshairHandler.setMode(r.crosshair.mode),this.crosshairHandler.setCallback((e,t)=>{if(e!==null&&t){let n=this.dataManager.getData(),r=e<n.length?n[e]:void 0;this.chartLegend.setHoverBar(r??null),r&&this.crosshairTooltip.show(t,r,this.themeManager.getTheme(),this.cachedContainerSize()),this.pinnedTooltip.isPinned()&&this.pinnedTooltip.reposition(this.viewport.getState(),r??null,e,this.themeManager.getTheme()),this.eventBus.emit(`crosshairMove`,{point:t,bar:r,barIndex:e})}else this.crosshairTooltip.hide(),this.chartLegend.setHoverBar(null)}),this.chartLegend=new t.ChartLegend,this.chartLegend.setChartType(r.chartType),this.watermark=new t.Watermark,r.watermark&&this.watermark.setConfig(r.watermark),this.volumeRenderer=new t.VolumeRenderer,this.volumeProfile=new t.VolumeProfileRenderer,this.marketProfile=new t.MarketProfileRenderer,this.depthHeatmap=new t.DepthHeatmapRenderer,this.periodLevels=new t.PeriodLevelsRenderer,this.pivotMarkers=new t.PivotMarkersRenderer,this.barCountdown=new t.BarCountdown,this.sessionBreaks=new t.SessionBreaks,this.sessionShading=new t.SessionShading,this.compareRenderer=new t.CompareRenderer,r.sessionBreaks?this.sessionBreaks.setConfig({visible:r.sessionBreaks.visible??!0,color:r.sessionBreaks.color,lineStyle:r.sessionBreaks.lineStyle,lineWidth:r.sessionBreaks.lineWidth}):r.features?.sessionBreaks!==!1&&this.sessionBreaks.setVisible(!0),r.logScale&&this.viewport.setLogScale(!0),this.animator=new t.Animator,this.crosshairTooltip=new t.CrosshairTooltip,this.crosshairTooltip.create(n),this.pinnedTooltip=new t.PinnedTooltip,this.pinnedTooltip.create(n),this.keyboardHandler=new t.KeyboardHandler({scrollBars:e=>{let t=this.viewport.getState().barWidth+this.viewport.getState().barSpacing;this.viewport.scrollBy(e*t),this.updateViewportAndRender()},zoom:e=>{let t=this.viewport.getState().chartRect.width;this.viewport.zoom(e,t/2),this.updateViewportAndRender()},goToStart:()=>{this.viewport.scrollBy(-1/0),this.updateViewportAndRender()},goToEnd:()=>{this.viewport.scrollToEnd(),this.updateViewportAndRender()},fitContent:()=>this.fitContent()}),this.keyboardHandler.setEnabled(this.features.keyboard),this.onWindowKeyDown=e=>{if(!this.keyboardHandler)return;let t=document.activeElement;t&&t!==this.container&&!this.container.contains(t)||t&&(t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.isContentEditable)||this.keyboardHandler.handleKey(e)&&e.preventDefault()},window.addEventListener(`keydown`,this.onWindowKeyDown),this.currentPriceLine=new t.CurrentPriceLine,this.alertManager=new t.AlertManager,this.alertManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.alertManager.on(`triggered`,e=>{let t={id:e.id,price:e.price,condition:e.condition,message:e.message,triggered:e.triggered};this.eventBus.emit(`alertTriggered`,t),this.eventBus.emit(`dataUpdate`,{alert:`triggered`,alertId:e.id,price:e.price,message:e.message})}),this.alertManager.on(`added`,e=>{this.eventBus.emit(`alertAdd`,{id:e.id,price:e.price,condition:e.condition,message:e.message,triggered:e.triggered})}),this.alertManager.on(`removed`,e=>{this.eventBus.emit(`alertRemove`,{id:e})}),this.alertManager.on(`updated`,e=>{this.eventBus.emit(`alertUpdate`,{id:e.id,price:e.price,condition:e.condition,message:e.message,triggered:e.triggered})}),this.signalMarkerManager=new t.SignalMarkerManager,this.signalMarkerManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.signalMarkerManager.setDataGetter(()=>this.dataManager.getData()),this.signalMarkerManager.on(`added`,e=>{this.eventBus.emit(`signalMarkerAdd`,{id:e.id,source:e.source,direction:e.direction})}),this.signalMarkerManager.on(`removed`,e=>{this.eventBus.emit(`signalMarkerRemove`,{id:e})}),this.tradeZoneManager=new t.TradeZoneManager,this.tradeZoneManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.tradeZoneManager.setDataGetter(()=>this.dataManager.getData()),this.tradeZoneManager.on(`added`,e=>{this.eventBus.emit(`tradeZoneAdd`,{id:e.id,direction:e.direction})}),this.tradeZoneManager.on(`removed`,e=>{this.eventBus.emit(`tradeZoneRemove`,{id:e})}),this.replayManager=new t.ReplayManager,this.measureOverlay=new t.MeasureOverlay,this.interactionManager=new t.InteractionManager(n),this.features.panning&&this.interactionManager.setPanHandler(new t.PanHandler(e=>{this.viewport.scrollBy(e),this.updateViewportAndRender()})),this.features.zooming){this.interactionManager.setZoomHandler(new t.ZoomHandler((e,t)=>{this.viewport.zoom(e,t),this.updateViewportAndRender()}));let e=new t.AxisDragHandler(e=>{this.options.autoScale=!1,this.viewport.scalePriceRange(e),this.syncRenderContext(),this.engine.requestRender()},e=>{let t=this.viewport.getState().chartRect.width;this.viewport.zoom(1/e-1,t/2),this.updateViewportAndRender()});this.interactionManager.setAxisDragHandler(e,()=>this.viewport.getState(),e=>{e===`price`?(this.options.autoScale=!0,this.updateViewportAndRender()):this.fitContent()})}if(this.features.crosshair&&this.interactionManager.setCrosshairHandler(this.crosshairHandler),this.features.drawings&&this.interactionManager.setDrawingManager(this.drawingManager,()=>({...this.viewport.getState(),data:this.getDisplayData()})),this.features.trading&&this.interactionManager.setTradingManager(this.tradingManager,()=>({...this.viewport.getState(),data:this.getDisplayData()})),this.features.alerts){let e=new t.AlertDragHandler(this.alertManager,()=>this.viewport.getState());this.interactionManager.setAlertDragHandler(e)}this.interactionManager.setAltClickHandler(t=>{let n=this.getDisplayData();if(n.length===0)return;let r=this.viewport.getState(),i=r.barWidth+r.barSpacing,a=Math.round((r.offset+t.x)/i);a<0||a>=n.length||(this.pinnedTooltip.isPinned()&&this.pinnedTooltip.getPinnedIndex()===a?this.pinnedTooltip.unpin():this.pinnedTooltip.pin(n[a],a,this.themeManager.getTheme()),this.pinnedTooltip.reposition(this.viewport.getState(),this.dataManager.getData()[a]??null,a,this.themeManager.getTheme()),this.engine.requestRender(e.LayerType.Overlay))}),this.interactionManager.setClickHandler(e=>{let n=this.getDisplayData();if(this.eventBus.emit(`click`,{x:e.x,y:e.y}),n.length===0)return;let r=(0,t.xToBarIndex)(e.x,this.viewport.getState());r<0||r>=n.length||this.eventBus.emit(`barClick`,{bar:n[r],barIndex:r,point:e})}),this.interactionManager.setEscapeHandler(()=>{if(this.features.trading&&this.tradingManager.isBracketActive()){this.tradingManager.cancelBracket(),this.eventBus.emit(`dataUpdate`,{bracket:`cancelled`});return}this.pinnedTooltip.isPinned()&&(this.pinnedTooltip.unpin(),this.engine.requestRender(e.LayerType.Overlay))}),this.interactionManager.setConfirmHandler(()=>this.features.trading&&this.tradingManager.isBracketActive()?(this.tradingManager.confirmBracket(),!0):!1),this.interactionManager.setMeasureHandlers({begin:e=>{this.measureOverlay.begin(e,this.viewport.getState(),this.getDisplayData())},move:e=>{this.measureOverlay.update(e,this.viewport.getState(),this.getDisplayData())},end:()=>{this.measureOverlay.end()}}),this.interactionManager.setOverlayDirtyCallback(()=>{this.engine.requestRender(e.LayerType.Overlay),this.engine.requestRender(e.LayerType.UI)}),this.interactionManager.attach(),this.syncRenderContext(),this.engine.start()}setData(e){this.dataManager.setData(e),this.crosshairHandler.setData(this.dataManager.getData()),this.displayDataCache=null,this.sessionBreaks.invalidateCache(),this.alertManager.clearLastValues(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),e.length>0&&this.currentPriceLine.setPrice(e[e.length-1].close),this.updateViewportAndRender(!0),this.eventBus.emit(`dataUpdate`,{length:e.length})}appendBar(e){this.dataManager.appendBar(e),this.crosshairHandler.setData(this.dataManager.getData()),this.displayDataCache=null,this.autoScrollOnNewBar&&this.viewport.scrollToEnd(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.updateViewportAndRender()}appendBars(e){if(e.length!==0){for(let t of e)this.dataManager.appendBar(t);this.displayDataCache=null,this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.crosshairHandler.setData(this.dataManager.getData()),this.updateViewportAndRender(this.viewport.isAtEnd())}}updateLastBar(e){this.dataManager.updateLastBar(e),this.currentPriceLine.setPrice(e.close),this.options.chartType!==`candlestick`&&this.options.chartType!==`line`&&this.options.chartType!==`area`&&this.options.chartType!==`bar`&&this.options.chartType!==`hollowCandle`&&(this.displayDataCache=null),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.scheduleRender()}updateLastBarFromTick(e){this.dataManager.updateLastBarFromTick(e),this.currentPriceLine.setPrice(e.price),this.options.chartType!==`candlestick`&&this.options.chartType!==`line`&&this.options.chartType!==`area`&&this.options.chartType!==`bar`&&this.options.chartType!==`hollowCandle`&&(this.displayDataCache=null),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.scheduleRender()}setChartType(e){this.options.chartType=e,this.chartRenderer=this.createChartRenderer(e),this.chartLegend.setChartType(e),this.displayDataCache=null,this.updateViewportAndRender(!0)}addIndicator(e,t={},n=`bottom`){if(!this.features.indicators||this.features.indicatorIds.length>0&&!this.features.indicatorIds.includes(e))return null;let r=this.indicatorEngine.addIndicator(e,t,this.dataManager.getData());return this.indicatorEngine.getAvailableIndicators().find(t=>t.id===e)?.placement===`panel`?(this.layoutManager.addPanel(r,n),this.updateViewportAndRender()):this.engine.requestRender(),this.eventBus.emit(`indicatorAdd`,{instanceId:r,id:e}),r}updateIndicator(e,t){this.indicatorEngine.updateIndicator(e,t,this.dataManager.getData()),this.engine.requestRender()}removeIndicator(e){let t=this.layoutManager.getPanels().some(t=>t.id===e);this.indicatorEngine.removeIndicator(e),this.layoutManager.removePanel(e),this.eventBus.emit(`indicatorRemove`,{instanceId:e}),t?this.updateViewportAndRender():this.engine.requestRender()}getIndicatorOutput(e){return this.indicatorEngine.getOutput(e)}registerIndicator(e){this.pluginManager.registerIndicator(e)}static indicators(){let e=new t.IndicatorEngine;return(0,t.registerBuiltInIndicators)(e),e.getAvailableIndicators()}setPanelPosition(e,t){this.layoutManager.setPanelPosition(e,t),this.engine.requestRender()}setPanelSize(e,t){this.layoutManager.setPanelSize(e,t),this.engine.requestRender()}setDrawingTool(e){this.features.drawings&&(e&&this.features.drawingTools.length>0&&!this.features.drawingTools.includes(e)||this.drawingManager.setActiveTool(e))}getDrawingTool(){return this.drawingManager.getActiveTool()}setDrawingStyle(e){this.drawingManager.setStyle(e)}getDrawingStyle(){return this.drawingManager.getActiveStyle()}getSelectedDrawingId(){return this.drawingManager.getSelectedDrawingId()}setSelectedDrawingStyle(e,t){return this.drawingManager.setSelectedDrawingStyle(e,t)}getDrawings(){return this.drawingManager.getDrawings()}setDrawings(e){this.drawingManager.setDrawings(e)}addDrawing(e){if(!this.features.drawings)return null;let t=this.drawingManager.addDrawing(e);return this.scheduleAutoSave(),t}autoFib(){if(!this.features.drawings)return null;let e=this.getDisplayData(),n=this.viewport.getState(),r=(0,t.findDominantSwing)(e,n.visibleRange.from,n.visibleRange.to);return r?this.addDrawing({type:`fibRetracement`,anchors:[r[0],r[1]]}):null}removeDrawing(e){this.drawingManager.removeDrawing(e)}setDrawingVisible(e,t){this.drawingManager.setDrawingVisible(e,t)}setDrawingLocked(e,t){this.drawingManager.setDrawingLocked(e,t)}clearDrawings(){this.drawingManager.clearDrawings()}registerDrawingTool(e){this.drawingManager.register(e)}undo(){return this.features.drawingUndoRedo?this.drawingManager.undo():!1}redo(){return this.features.drawingUndoRedo?this.drawingManager.redo():!1}getUndoRedoState(){return this.undoRedoManager.getState()}setDrawingMagnet(e){this.drawingManager.setMagnetMode(e?`magnet`:`none`)}getDrawingMagnet(){return this.drawingManager.getMagnetMode()===`magnet`}lockAllDrawings(){this.drawingManager.lockAllDrawings()}unlockAllDrawings(){this.drawingManager.unlockAllDrawings()}hideAllDrawings(){this.drawingManager.hideAllDrawings()}showAllDrawings(){this.drawingManager.showAllDrawings()}duplicateDrawing(e){let t=e??this.drawingManager.getSelectedDrawingId();return t?this.drawingManager.duplicateDrawing(t):null}exportVisibleData(e=`csv`,n){let r=this.viewport.getState(),i=this.dataManager.getData(),a=Math.max(0,r.visibleRange.from),o=Math.min(i.length-1,r.visibleRange.to),s=i.slice(a,o+1);if(e===`json`){let e=t.DataExporter.toJSON(s);t.DataExporter.download(e,n??`chart-data.json`,`application/json`)}else{let e=t.DataExporter.toCSV(s);t.DataExporter.download(e,n??`chart-data.csv`,`text/csv`)}}exportAllData(e=`csv`,n){let r=this.dataManager.getData();if(e===`json`){let e=t.DataExporter.toJSON(r);t.DataExporter.download(e,n??`chart-data.json`,`application/json`)}else{let e=t.DataExporter.toCSV(r);t.DataExporter.download(e,n??`chart-data.csv`,`text/csv`)}}setAutoSave(e,t=5e3){this.autoSaveScheduler.enable(e,t)}disableAutoSave(){this.autoSaveScheduler.disable()}scheduleAutoSave(){this.autoSaveScheduler.schedule()}getAvailableIndicators(){return this.indicatorEngine.getAvailableIndicators()}getIndicatorInputs(e){let t=this.indicatorEngine.getAvailableIndicators().find(t=>t.id===e);return t?{id:t.id,params:t.defaultConfig}:null}getActiveIndicators(){return this.indicatorEngine.getActiveIndicators()}setIndicatorVisible(e,t){this.indicatorEngine.setVisible(e,t)!==null&&this.updateViewportAndRender()}getIndicatorConfig(e){let t=this.indicatorEngine.getIndicatorConfig(e);return t?{id:t.id,params:{...t.params}}:null}updateIndicatorStyle(e,t){this.indicatorEngine.updateIndicatorStyle(e,t),this.engine.requestRender()}setOrders(e){this.features.trading&&this.tradingManager.setOrders(e)}startBracket(e,t){if(!this.features.trading)return!1;let n=this.dataManager.getData(),r=t??(n.length>0?n[n.length-1].close:null);return r===null?!1:(this.tradingManager.startBracket(e,r),!0)}cancelBracket(){this.features.trading&&this.tradingManager.cancelBracket()}confirmBracket(){return this.features.trading?this.tradingManager.confirmBracket():!1}isBracketActive(){return this.features.trading&&this.tradingManager.isBracketActive()}placeOrderIntent(e){this.features.trading&&this.eventBus.emit(`orderPlace`,e)}setPositions(e){this.features.trading&&this.tradingManager.setPositions(e)}setDepthData(e){this.features.trading&&this.tradingManager.setDepthData(e)}setCurrentPrice(e,t){this.tradingManager.setCurrentPrice(e),this.currentPriceLine.setPrice(e),this.scheduleRender(),this.features.alerts&&(this.alertManager.checkPrice(e),this.feedIndicatorAlerts())}feedIndicatorAlerts(){let e=this.alertManager.getAlerts(),t=this.dataManager.getData();if(t.length===0)return;let n=t.length-1,r=new Set;for(let t of e){if(t.channel===`price`||r.has(t.channel))continue;r.add(t.channel);let e=t.channel.indexOf(`:`);if(e<0)continue;let i=t.channel.slice(0,e),a=t.channel.slice(e+1),o=this.indicatorEngine.getOutput(i)?.series?.[n]?.[a];typeof o==`number`&&Number.isFinite(o)&&this.alertManager.checkChannel(t.channel,o)}}setTradingConfig(e){this.features.trading&&this.tradingManager.setConfig(e)}async connect(n){this.disconnectStream(),this.streamManager=new t.StreamManager,this.streamManager.on(`snapshot`,e=>{this.setData(e)}),this.streamManager.on(`barClose`,e=>{this.dataManager.appendBar(e),this.crosshairHandler.setData(this.dataManager.getData()),this.autoScrollOnNewBar&&this.viewport.scrollToEnd(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.updateViewportAndRender()}),this.streamManager.on(`barUpdate`,e=>{this.dataManager.updateLastBar(e),this.currentPriceLine.setPrice(e.close),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.scheduleRender()}),this.streamManager.on(`priceChange`,({price:t})=>{this.tradingManager.setCurrentPrice(t),this.currentPriceLine.setPrice(t),this.engine.requestRender(e.LayerType.Overlay),this.engine.requestRender(e.LayerType.UI)}),this.streamManager.on(`connectionChange`,e=>{this.eventBus.emit(`dataUpdate`,{connection:e})}),this.streamManager.on(`error`,e=>{this.eventBus.emit(`dataUpdate`,{error:e.message})}),this.autoScrollOnNewBar=n.autoScroll!==!1,this.currentSymbol=n.symbol,await this.streamManager.connect(n);let r=(0,e.timeframeToMs)(n.timeframe);this.barCountdown.setTimeframeMs(r),this.countdownInterval&&clearInterval(this.countdownInterval),this.countdownInterval=setInterval(()=>{this.barCountdown.isVisible()&&this.engine.requestRender(e.LayerType.UI)},1e3)}async switchStream(e,t){this.streamManager&&(this.currentSymbol=e,await this.streamManager.switchTo(e,t))}async setTimeframe(e){if(!this.streamManager)throw Error(`No active stream. Call connect() first.`);await this.switchStream(this.currentSymbol,e)}disconnectStream(){this.streamManager&&=(this.streamManager.dispose(),null)}setBarCountdownVisible(t){this.barCountdown.setVisible(t),this.engine.requestRender(e.LayerType.UI)}setSessionBreaksVisible(t){this.sessionBreaks.setVisible(t),this.engine.requestRender(e.LayerType.Background)}addCompareSymbol(t,n,r,i){this.compareRenderer.addSymbol({id:t,label:n,data:r,color:i,visible:!0}),this.engine.requestRender(e.LayerType.Main)}removeCompareSymbol(t){this.compareRenderer.removeSymbol(t),this.engine.requestRender(e.LayerType.Main)}updateCompareData(t,n){this.compareRenderer.setSymbolData(t,n),this.engine.requestRender(e.LayerType.Main)}setCompareMode(t){this.compareRenderer.setMode(t),this.engine.requestRender(e.LayerType.Main)}clearCompareSymbols(){this.compareRenderer.clear(),this.engine.requestRender(e.LayerType.Main)}setLogScale(e){this.viewport.setLogScale(e),this.updateViewportAndRender()}isLogScale(){return this.viewport.isLogScale()}setScaleMode(e){this.viewport.setScaleMode(e),this.updateViewportAndRender()}getScaleMode(){return this.viewport.getScaleMode()}setSessionBreaksConfig(t){this.sessionBreaks.setConfig(t),this.engine.requestRender(e.LayerType.Background)}getConnectionState(){return this.streamManager?.getConnectionState()??`disconnected`}getConnectionInfo(){return this.streamManager?.getConnectionInfo()??{state:`disconnected`}}setAutoScroll(e){this.autoScrollOnNewBar=e}scrollTo(e){let t=this.dataManager.getData();for(let n=0;n<t.length;n++)if(t[n].time>=e){let e=this.viewport.getState().barWidth+this.viewport.getState().barSpacing;this.viewport.scrollBy(n*e-this.viewport.getState().offset),this.updateViewportAndRender();return}}scrollToEnd(){this.viewport.scrollToEnd(),this.updateViewportAndRender()}setVisibleRange(e,t){let n=this.dataManager.getData(),r=0,i=n.length-1;for(let t=0;t<n.length;t++)if(n[t].time>=e){r=t;break}for(let e=n.length-1;e>=0;e--)if(n[e].time<=t){i=e;break}let a=i-r+1;if(a>0){let e=this.viewport.getState().chartRect.width,t=e/a,n=Math.max(2,t-this.viewport.getState().barSpacing);this.viewport.zoom((n-this.viewport.getState().barWidth)/this.viewport.getState().barWidth,e/2)}this.updateViewportAndRender()}zoomIn(){let e=this.viewport.getState().chartRect.width;this.viewport.zoom(.2,e/2),this.updateViewportAndRender()}zoomOut(){let e=this.viewport.getState().chartRect.width;this.viewport.zoom(-.2,e/2),this.updateViewportAndRender()}fitContent(){let e=this.dataManager.getData();e.length!==0&&this.setVisibleRange(e[0].time,e[e.length-1].time)}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}enableTauriBridge(e){this.eventBus.enableTauriBridge({enabled:!0,...e})}disableTauriBridge(){this.eventBus.disableTauriBridge()}setTheme(e){this.themeManager.setTheme(e),this.syncRenderContext(),this.container.style.backgroundColor=this.themeManager.getTheme().background,this.engine.requestRender(),this.eventBus.emit(`themeChange`,{theme:e})}getTheme(){return this.themeManager.getTheme()}setWatermark(t,n){this.watermark.setConfig({text:t,...n}),this.engine.requestRender(e.LayerType.Background)}setAutoScale(e){this.options.autoScale=e,this.updateViewportAndRender()}isAutoScale(){return this.options.autoScale!==!1}setCrosshairMode(t){this.crosshairHandler.setMode(t),this.engine.requestRender(e.LayerType.Overlay)}getCrosshairMode(){return this.crosshairHandler.getMode()}setCrosshairPosition(t){t&&this.crosshairHandler.onPointerMove(t),this.engine.requestRender(e.LayerType.Overlay)}getData(){return this.dataManager.getData()}setGridVisible(t){this.gridRenderer.setVisible(t),this.engine.requestRender(e.LayerType.Background)}isGridVisible(){return this.gridRenderer.isVisible()}setVolumeVisible(t){this.volumeRenderer.setVisible(t),this.engine.requestRender(e.LayerType.Main)}setVolumeProfileVisible(t){this.volumeProfile.setVisible(t),this.engine.requestRender(e.LayerType.Main)}isVolumeProfileVisible(){return this.volumeProfile.isVisible()}setVolumeProfileConfig(t){t.buckets!==void 0&&this.volumeProfile.setBuckets(t.buckets),t.widthRatio!==void 0&&this.volumeProfile.setWidthRatio(t.widthRatio),t.opacity!==void 0&&this.volumeProfile.setOpacity(t.opacity),t.highlightPoC!==void 0&&this.volumeProfile.setHighlightPoC(t.highlightPoC),this.engine.requestRender(e.LayerType.Main)}setMarketProfileVisible(t){this.marketProfile.setVisible(t),this.engine.requestRender(e.LayerType.Main)}isMarketProfileVisible(){return this.marketProfile.isVisible()}setMarketProfileConfig(t){t.buckets!==void 0&&this.marketProfile.setBuckets(t.buckets),t.widthRatio!==void 0&&this.marketProfile.setWidthRatio(t.widthRatio),t.opacity!==void 0&&this.marketProfile.setOpacity(t.opacity),t.valueAreaPct!==void 0&&this.marketProfile.setValueAreaPct(t.valueAreaPct),t.highlightPoC!==void 0&&this.marketProfile.setHighlightPoC(t.highlightPoC),t.showStats!==void 0&&this.marketProfile.setShowStats(t.showStats),t.splitBySession!==void 0&&this.marketProfile.setSplitBySession(t.splitBySession),t.letters!==void 0&&this.marketProfile.setLetters(t.letters),this.engine.requestRender(e.LayerType.Main)}getMarketProfileStats(){return this.marketProfile.getStats()}setDepthHeatmapVisible(t){this.depthHeatmap.setVisible(t),this.engine.requestRender(e.LayerType.Main)}isDepthHeatmapVisible(){return this.depthHeatmap.isVisible()}setDepthHeatmapConfig(t){t.opacity!==void 0&&this.depthHeatmap.setOpacity(t.opacity),t.capacity!==void 0&&this.depthHeatmap.setCapacity(t.capacity),this.engine.requestRender(e.LayerType.Main)}pushDepthSnapshot(t){let n=this.dataManager.getData();n.length!==0&&(this.depthHeatmap.push(n[n.length-1].time,t),this.depthHeatmap.isVisible()&&this.engine.requestRender(e.LayerType.Main))}clearDepthHeatmap(){this.depthHeatmap.clear(),this.engine.requestRender(e.LayerType.Main)}setPeriodLevelsVisible(t){this.periodLevels.setVisible(t),this.engine.requestRender(e.LayerType.Main)}isPeriodLevelsVisible(){return this.periodLevels.isVisible()}setPeriodLevelsPeriod(t){this.periodLevels.setPeriod(t),this.engine.requestRender(e.LayerType.Main)}setTimezoneOffset(t){this.timeAxis.setTimezoneOffset(t),this.crosshairHandler.setTimezoneOffset(t),this.engine.requestRender(e.LayerType.UI),this.engine.requestRender(e.LayerType.Overlay)}setPivotMarkersVisible(t){this.pivotMarkers.setVisible(t),this.engine.requestRender(e.LayerType.Overlay)}isPivotMarkersVisible(){return this.pivotMarkers.isVisible()}setPivotMarkersConfig(t){(t.left!==void 0||t.right!==void 0)&&this.pivotMarkers.setStrength(t.left??5,t.right??t.left??5),t.showLabels!==void 0&&this.pivotMarkers.setShowLabels(t.showLabels),t.structureLabels!==void 0&&this.pivotMarkers.setStructureLabels(t.structureLabels),this.engine.requestRender(e.LayerType.Overlay)}setSessionShadingVisible(t){this.sessionShading.setVisible(t),this.engine.requestRender(e.LayerType.Background)}isSessionShadingVisible(){return this.sessionShading.isVisible()}setSessionShadingConfig(t){this.sessionShading.setConfig(t),this.engine.requestRender(e.LayerType.Background)}setTooltipVisible(e){e||this.crosshairTooltip.hide()}setLegend(t){this.chartLegend.setConfig(t),this.engine.requestRender(e.LayerType.UI)}setSymbolName(t){this.chartLegend.setSymbol(t),this.engine.requestRender(e.LayerType.UI)}setStatusText(t){this.chartLegend.setStatusText(t),this.engine.requestRender(e.LayerType.UI)}screenshot(e){this.features.screenshot&&t.Screenshot.download(this.container,e,this.themeManager.getTheme().background)}async copyScreenshot(){if(!this.features.screenshot)return!1;try{let e=await t.Screenshot.toBlob(this.container,this.themeManager.getTheme().background),n=globalThis.ClipboardItem;return!e||!navigator.clipboard?.write||!n?!1:(await navigator.clipboard.write([new n({"image/png":e})]),!0)}catch{return!1}}screenshotDataURL(){return this.features.screenshot?t.Screenshot.toDataURL(this.container,this.themeManager.getTheme().background):null}async screenshotBlob(){return this.features.screenshot?t.Screenshot.toBlob(this.container,this.themeManager.getTheme().background):null}addAlert(e,t=`crossing`,n,r=`price`,i){if(!this.features.alerts)return null;let a=this.alertManager.addAlert(e,t,n,!1,r,i);return this.scheduleAutoSave(),a}removeAlert(e){this.alertManager.removeAlert(e),this.scheduleAutoSave()}getAlerts(){return this.alertManager.getAlerts()}clearAlerts(){this.alertManager.clearAlerts(),this.scheduleAutoSave()}saveAlerts(e){this.alertManager.saveToStorage(e)}loadAlerts(t){this.alertManager.loadFromStorage(t),this.engine.requestRender(e.LayerType.Overlay)}addSignalMarker(e){return this.signalMarkerManager.addMarker(e)}removeSignalMarker(e){this.signalMarkerManager.removeMarker(e)}getSignalMarkers(){return this.signalMarkerManager.getMarkers()}setSignalMarkers(e){this.signalMarkerManager.setMarkers(e)}clearSignalMarkers(){this.signalMarkerManager.clearMarkers()}setSignalMarkerStyle(e){this.signalMarkerManager.setStyle(e)}addTradeZone(e){return this.tradeZoneManager.addZone(e)}updateTradeZone(e,t){this.tradeZoneManager.updateZone(e,t)}removeTradeZone(e){this.tradeZoneManager.removeZone(e)}getTradeZones(){return this.tradeZoneManager.getZones()}setTradeZones(e){this.tradeZoneManager.setZones(e)}clearTradeZones(){this.tradeZoneManager.clearZones()}setTradeZoneStyle(e){this.tradeZoneManager.setStyle(e)}replay(e){if(!this.features.replay)return;let t=this.dataManager.getData();this.replayManager.load(t),this.replayManager.on(`bar`,({bar:e,index:n})=>{let r=t.slice(0,n+1);this.dataManager.setData(r),this.crosshairHandler.setData(r),this.indicatorEngine.recalculateAll(r),this.updateViewportAndRender()}),this.replayManager.play(e)}replayPause(){this.replayManager.pause()}replayResume(){this.replayManager.resume()}replayStop(){this.replayManager.stop()}replaySeek(e){this.replayManager.seekTo(e)}setReplaySpeed(e){this.replayManager.setSpeed(e)}getReplayState(){return this.replayManager.getState()}getReplayProgress(){return this.replayManager.getProgress()}saveState(e){if(!this.features.saveLoad)return null;let n=t.ChartStateManager.capture({getDrawings:()=>this.getDrawings(),getTheme:()=>this.getTheme(),getAlerts:()=>this.getAlerts()},{chartType:this.options.chartType}),r=t.ChartStateManager.serialize(n);return e&&t.ChartStateManager.saveToStorage(e,n),r}loadState(e){if(!this.features.saveLoad)return;let n=t.ChartStateManager.deserialize(e);if(n.chartType&&this.setChartType(n.chartType),n.drawings&&this.setDrawings(n.drawings),n.theme&&this.setTheme(n.theme),n.alerts){this.clearAlerts();for(let e of n.alerts)this.addAlert(e.price,e.condition,e.message)}}loadStateFromStorage(e){if(!this.features.saveLoad)return!1;let n=t.ChartStateManager.loadFromStorage(e);return n?(this.loadState(t.ChartStateManager.serialize(n)),!0):!1}downloadState(e){if(!this.features.saveLoad)return;let n=t.ChartStateManager.capture({getDrawings:()=>this.getDrawings(),getTheme:()=>this.getTheme(),getAlerts:()=>this.getAlerts()},{chartType:this.options.chartType});t.ChartStateManager.downloadFile(n,e)}async loadStateFromFile(){if(!this.features.saveLoad)return;let e=await t.ChartStateManager.loadFromFile();this.loadState(t.ChartStateManager.serialize(e))}setLocale(t){(0,e.setLocale)(t),this.engine.requestRender()}setNumberLocale(e){this.numberLocale=e,this.priceAxis.setLocale(e),this.crosshairHandler.setLocale(e),this.syncRenderContext(),this.engine.requestRender()}getNumberLocale(){return this.numberLocale}setMarket(e){if(this.marketConfig=e,e.colorScheme){let t={...this.themeManager.getTheme(),candleUp:e.colorScheme.up,candleDown:e.colorScheme.down,candleUpWick:e.colorScheme.up,candleDownWick:e.colorScheme.down,volumeUp:e.colorScheme.up.replace(`)`,`, 0.3)`).replace(`rgb(`,`rgba(`)||`${e.colorScheme.up}4D`,volumeDown:e.colorScheme.down.replace(`)`,`, 0.3)`).replace(`rgb(`,`rgba(`)||`${e.colorScheme.down}4D`};this.themeManager.setTheme(t)}e.pricePrecision!==void 0&&(this.tradingManager.setConfig({pricePrecision:e.pricePrecision}),this.alertManager.setPricePrecision(e.pricePrecision),this.streamManager?.priceLine.setPricePrecision(e.pricePrecision),this.crosshairHandler.setPricePrecision(e.pricePrecision)),this.syncRenderContext(),this.engine.requestRender()}getMarket(){return this.marketConfig}setPriceLimits(t){this.marketConfig&&((0,e.computePriceLimits)(t,this.marketConfig)&&(this.marketConfig.priceLimits={...this.marketConfig.priceLimits,referencePrice:t}),this.engine.requestRender())}getFeatures(){return this.features}setFeatures(t){Object.assign(this.features,t),t.crosshair===!1&&this.crosshairTooltip.hide(),t.grid!==void 0&&this.engine.requestRender(e.LayerType.Background),t.volume!==void 0&&(this.volumeRenderer.setVisible(t.volume),this.engine.requestRender(e.LayerType.Main)),t.drawings===!1&&this.drawingManager.setActiveTool(null),t.trading===!1&&(this.tradingManager.setOrders([]),this.tradingManager.setPositions([])),t.keyboard!==void 0&&this.keyboardHandler?.setEnabled(t.keyboard),this.engine.requestRender()}resize(){let e=this.engine.dprManager.readContainerSize();if(e.width<=0||e.height<=0)return;this.containerSizeCache=e,this.containerSizeCacheTime=Date.now();let t=this.engine.dprManager.getDpr();this.engine.layerManager.resize(e,t);let n=this.viewport.isAtEnd();this.viewport.resize(e.width,e.height),this.layoutManager.resize(e.width,e.height),this.updateViewportAndRender(n),this.eventBus.emit(`resize`,e)}destroy(){this.countdownInterval&&clearInterval(this.countdownInterval),this.disableAutoSave(),this.disconnectStream(),this.onWindowKeyDown&&=(window.removeEventListener(`keydown`,this.onWindowKeyDown),null),this.keyboardHandler=null,this.interactionManager.detach(),this.tradingManager.destroy(),this.animator.dispose(),this.crosshairTooltip.destroy(),this.pinnedTooltip.destroy(),this.replayManager.dispose(),this.undoRedoManager.clear(),this.engine.destroy(),this.eventBus.destroy(),this.container.innerHTML=``}createChartRenderer(e){return n(e)}getDisplayData(){if(this.displayDataCache)return this.displayDataCache;let e=this.dataManager.getData();if(e.length===0)return e;let t=r(this.options.chartType,e);return this.displayDataCache=t,t}scheduleRender(){this.renderScheduled||(this.renderScheduled=!0,requestAnimationFrame(()=>{this.renderScheduled=!1;let e=this.getDisplayData();this.viewport.updateData(e,this.options.autoScale!==!1),this.syncRenderContext(),this.engine.requestRender()}))}updateViewportAndRender(e=!1){this.resolvedLayoutCache=null,this.panelInfoCache=null;let t=this.getResolvedLayout();this.viewport.setChartRect(t.mainChartRect);let n=this.getDisplayData();if(this.viewport.updateData(n,this.options.autoScale!==!1),n.length>0){let e=this.viewport.getState(),t=Math.max(0,Math.min(e.visibleRange.from,n.length-1));this.viewport.setScaleBaseline(n[t]?.close)}if(this.options.autoScale!==!1){let e=this.viewport.getState(),t=this.indicatorEngine.getOverlayPriceRange(e.visibleRange.from,Math.min(e.visibleRange.to,n.length-1));if(t){let n=e.priceRange,r=Math.min(n.min,t.min),i=Math.max(n.max,t.max);if(r<n.min||i>n.max){let e=i-r||1;this.viewport.setPriceRange(r-e*.02,i+e*.02)}}}e&&this.viewport.scrollToEnd(),this.syncRenderContext(),this.engine.requestRender()}getResolvedLayout(){return this.resolvedLayoutCache||=this.layoutManager.resolve(),this.resolvedLayoutCache}cachedContainerSize(){let e=Date.now();return(!this.containerSizeCache||e-this.containerSizeCacheTime>500)&&(this.containerSizeCache=this.engine.dprManager.getContainerSize(),this.containerSizeCacheTime=e),this.containerSizeCache}buildPanelRenderInfos(){if(this.panelInfoCache)return this.panelInfoCache;let e=this.getResolvedLayout(),t=this.viewport.getState(),{from:n,to:r}=t.visibleRange,i=e.panels.map(e=>{let i=s(this.indicatorEngine.getOutput(e.config.id),n,r),a={x:e.rect.x,y:e.rect.y+20,width:e.rect.width,height:Math.max(0,e.rect.height-20)};return{instanceId:e.config.id,rect:e.rect,viewport:{...t,chartRect:a,priceRange:i}}});return this.panelInfoCache=i,i}syncRenderContext(){this.pinnedTooltip.isPinned()&&this.pinnedTooltip.reposition(this.viewport.getState(),null,null,this.themeManager.getTheme());let e=this.getResolvedLayout(),t=this.features.indicators?this.buildPanelRenderInfos():[],n=e.panels.filter(e=>e.config.position===`bottom`).reduce((e,t)=>e+t.rect.height,0),r=e.mainChartRect.y+e.mainChartRect.height+n,i=this.getDisplayData();this.engine.setRenderContext({chartRenderer:this.chartRenderer,gridRenderer:this.features.grid?this.gridRenderer:null,priceAxis:this.features.priceAxis?this.priceAxis:null,timeAxis:this.features.timeAxis?this.timeAxis:null,crosshairHandler:this.features.crosshair?this.crosshairHandler:null,indicatorEngine:this.features.indicators?this.indicatorEngine:null,drawingRenderer:this.features.drawings?this.drawingRenderer:null,tradingRenderer:this.features.trading?this.tradingRenderer:null,currentPriceLine:this.streamManager?.priceLine??this.currentPriceLine,chartLegend:this.features.legend?this.chartLegend:null,volumeRenderer:this.features.volume?this.volumeRenderer:null,volumeProfile:this.volumeProfile,marketProfile:this.marketProfile,depthHeatmap:this.depthHeatmap,periodLevels:this.periodLevels,pivotMarkers:this.pivotMarkers,watermark:this.features.watermark?this.watermark:null,barCountdown:this.barCountdown,sessionBreaks:this.sessionBreaks,sessionShading:this.sessionShading,compareRenderer:this.compareRenderer,alertManager:this.features.alerts?this.alertManager:null,measureOverlay:this.measureOverlay,signalMarkerManager:this.signalMarkerManager,tradeZoneManager:this.tradeZoneManager,panels:t,priceLimits:this.buildPriceLimits(),timeAxisY:r,viewport:{...this.viewport.getState(),data:i},theme:this.themeManager.getTheme(),data:i,numberLocale:this.numberLocale})}buildPriceLimits(){if(!this.marketConfig?.priceLimits?.enabled||!this.marketConfig.priceLimits.referencePrice)return null;let t=(0,e.computePriceLimits)(this.marketConfig.priceLimits.referencePrice,this.marketConfig);return t?{...t,colors:this.marketConfig.colorScheme?{ceiling:this.marketConfig.colorScheme.ceiling,floor:this.marketConfig.colorScheme.floor,reference:this.marketConfig.colorScheme.reference}:void 0}:null}},v=[`time`,`timestamp`,`date`,`datetime`,`t`],y=[`open`,`o`],b=[`high`,`h`],x=[`low`,`l`],S=[`close`,`c`],C=[`volume`,`vol`,`v`];function w(e){let t=e.trim();return t?t[0]===`[`||t[0]===`{`?T(t):E(t):{data:[],rowCount:0,skipped:0}}function T(e){let t;try{t=JSON.parse(e)}catch(e){throw Error(`Invalid JSON: ${e.message}`)}if(!Array.isArray(t))throw Error(`Expected a JSON array of OHLCV rows`);let n=[],r=0;for(let e of t){let t=Array.isArray(e)?j(e):A(e);t?n.push(t):r++}return P(n,t.length,r)}function E(e){let t=e.split(/\r?\n/).filter(e=>e.trim().length>0);if(t.length===0)return{data:[],rowCount:0,skipped:0};let n=D(t[0]),r=O(t[0],n).map(e=>e.trim().toLowerCase()),i=r.some(e=>isNaN(Number(e))&&e.length>0),a=i?k(r):{time:0,open:1,high:2,low:3,close:4,volume:5};if(a.time<0||a.open<0||a.high<0||a.low<0||a.close<0)throw Error(`CSV is missing required column(s): time, open, high, low, close`);let o=[],s=0;for(let e=+!!i;e<t.length;e++){let r=O(t[e],n),i=N(r[a.time]),c=M(r[a.open]),l=M(r[a.high]),u=M(r[a.low]),d=M(r[a.close]),f=a.volume>=0?Number(r[a.volume]):0;if(i===null||![c,l,u,d].every(Number.isFinite)){s++;continue}o.push({time:i,open:c,high:l,low:u,close:d,volume:Number.isFinite(f)?f:0})}return P(o,t.length-+!!i,s)}function D(e){let t={",":0,";":0," ":0,"|":0};for(let n of e)n in t&&t[n]++;let n=`,`,r=0;for(let[e,i]of Object.entries(t))i>r&&(n=e,r=i);return n}function O(e,t){let n=[],r=``,i=!1;for(let a=0;a<e.length;a++){let o=e[a];o===`"`?i&&e[a+1]===`"`?(r+=`"`,a++):i=!i:o===t&&!i?(n.push(r),r=``):r+=o}return n.push(r),n}function k(e){let t=t=>e.findIndex(e=>t.includes(e));return{time:t(v),open:t(y),high:t(b),low:t(x),close:t(S),volume:t(C)}}function A(e){let t=t=>{for(let n of t){if(e[n]!==void 0)return e[n];let t=n.toUpperCase();if(e[t]!==void 0)return e[t]}},n=N(String(t(v)??``)),r=Number(t(y)),i=Number(t(b)),a=Number(t(x)),o=Number(t(S)),s=Number(t(C)??0);return n===null||![r,i,a,o].every(Number.isFinite)?null:{time:n,open:r,high:i,low:a,close:o,volume:Number.isFinite(s)?s:0}}function j(e){if(e.length<5)return null;let t=N(String(e[0])),n=Number(e[1]),r=Number(e[2]),i=Number(e[3]),a=Number(e[4]),o=e.length>=6?Number(e[5]):0;return t===null||![n,r,i,a].every(Number.isFinite)?null:{time:t,open:n,high:r,low:i,close:a,volume:Number.isFinite(o)?o:0}}function M(e){return e===void 0||e.trim()===``?NaN:Number(e)}function N(e){let t=e.trim();if(!t)return null;let n=Number(t);if(Number.isFinite(n)&&n>0)return n<0xe8d4a51000?n*1e3:n;let r=Date.parse(t);return Number.isFinite(r)?r:null}function P(e,t,n){e.sort((e,t)=>e.time-t.time);let r=[];for(let t of e)r.length>0&&r[r.length-1].time===t.time?r[r.length-1]=t:r.push(t);return{data:r,rowCount:t,skipped:n}}var F=class{host;overlay=null;callbacks;bound;depth=0;constructor(e,t){this.host=e,this.callbacks=t,this.bound={dragenter:e=>this.onDragEnter(e),dragover:e=>this.onDragOver(e),dragleave:e=>this.onDragLeave(e),drop:e=>this.onDrop(e)}}attach(){this.host.addEventListener(`dragenter`,this.bound.dragenter),this.host.addEventListener(`dragover`,this.bound.dragover),this.host.addEventListener(`dragleave`,this.bound.dragleave),this.host.addEventListener(`drop`,this.bound.drop)}detach(){this.host.removeEventListener(`dragenter`,this.bound.dragenter),this.host.removeEventListener(`dragover`,this.bound.dragover),this.host.removeEventListener(`dragleave`,this.bound.dragleave),this.host.removeEventListener(`drop`,this.bound.drop),this.hideOverlay()}onDragEnter(e){I(e)&&(e.preventDefault(),this.depth++,this.showOverlay())}onDragOver(e){I(e)&&(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect=`copy`))}onDragLeave(e){I(e)&&(this.depth=Math.max(0,this.depth-1),this.depth===0&&this.hideOverlay())}async onDrop(e){e.preventDefault(),this.depth=0,this.hideOverlay();let t=e.dataTransfer?.files?.[0];if(t)try{let e=w(await t.text());if(e.data.length===0)throw Error(`No valid OHLCV rows found in "${t.name}"`);this.callbacks.onData(e.data,e,t)}catch(e){this.callbacks.onError?.(e,t)}}showOverlay(){this.overlay||(this.overlay=document.createElement(`div`),Object.assign(this.overlay.style,{position:`absolute`,inset:`8px`,zIndex:`90`,pointerEvents:`none`,borderRadius:`10px`,border:`2px dashed var(--tcw-accent, #4f88ff)`,background:`rgba(79, 136, 255, 0.06)`,display:`flex`,alignItems:`center`,justifyContent:`center`,color:`var(--tcw-accent, #4f88ff)`,fontSize:`14px`,fontWeight:`600`,letterSpacing:`-0.005em`,fontFamily:`inherit`,backdropFilter:`blur(2px)`}),this.overlay.textContent=`Drop CSV or JSON to load chart data`,getComputedStyle(this.host).position===`static`&&(this.host.style.position=`relative`),this.host.appendChild(this.overlay))}hideOverlay(){this.overlay?.remove(),this.overlay=null}};function I(e){return e.dataTransfer?.types?.includes(`Files`)??!1}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return F}}); | ||
| //# sourceMappingURL=DragDropImporter-ycI_Tcs6.cjs.map |
Sorry, the diff of this file is too big to display
| import { Theme, ThemeName } from '@tradecanvas/commons'; | ||
| import { EquitySample, RiskMetricsLike } from './performanceData.js'; | ||
| /** Structurally satisfied by analytics' `BacktestResult`. */ | ||
| export interface PerformanceResult { | ||
| equityCurve: ReadonlyArray<EquitySample>; | ||
| metrics: RiskMetricsLike; | ||
| } | ||
| export interface PerformanceDashboardOptions { | ||
| result: PerformanceResult; | ||
| theme?: ThemeName | Theme; | ||
| title?: string; | ||
| subtitle?: string; | ||
| } | ||
| /** | ||
| * A composed strategy-performance dashboard: a headline stats strip, an equity | ||
| * curve, an underwater drawdown panel, and a monthly-returns heatmap. Built | ||
| * entirely from a backtest `result`, reusing the finance chart renderers. | ||
| * | ||
| * ```ts | ||
| * const result = new Backtester(opts).run(bars, strategy); | ||
| * const dash = new PerformanceDashboard(el, { result, theme: 'dark' }); | ||
| * ``` | ||
| */ | ||
| export declare class PerformanceDashboard { | ||
| private options; | ||
| private theme; | ||
| private root; | ||
| private equityChart; | ||
| private drawdownChart; | ||
| private heatmap; | ||
| constructor(container: HTMLElement, options: PerformanceDashboardOptions); | ||
| private build; | ||
| private buildStatsStrip; | ||
| private buildPanel; | ||
| /** A subtle surface tint distinct from the page background, per theme. */ | ||
| private panelBackground; | ||
| /** Replace the displayed result and re-render all panels. */ | ||
| update(result: PerformanceResult): void; | ||
| setTheme(theme: ThemeName | Theme): void; | ||
| private destroyCharts; | ||
| destroy(): void; | ||
| } | ||
| //# sourceMappingURL=PerformanceDashboard.d.ts.map |
| {"version":3,"file":"PerformanceDashboard.d.ts","sourceRoot":"","sources":["../../src/finance/PerformanceDashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAI7D,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,eAAe,EAErB,MAAM,sBAAsB,CAAC;AAE9B,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACzC,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD;;;;;;;;;GASG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,OAAO,CAA6B;gBAEhC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,2BAA2B;IAQxE,OAAO,CAAC,KAAK;IAkFb,OAAO,CAAC,eAAe;IAqCvB,OAAO,CAAC,UAAU;IAgClB,0EAA0E;IAC1E,OAAO,CAAC,eAAe;IAIvB,6DAA6D;IAC7D,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAOvC,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI;IAQxC,OAAO,CAAC,aAAa;IASrB,OAAO,IAAI,IAAI;CAIhB"} |
| import { EquityPoint, HeatmapCell } from '@tradecanvas/commons'; | ||
| /** Minimal equity sample shape — structurally satisfied by analytics' EquityPoint. */ | ||
| export interface EquitySample { | ||
| time: number; | ||
| equity: number; | ||
| } | ||
| /** Subset of analytics RiskMetrics needed to render the stats strip. */ | ||
| export interface RiskMetricsLike { | ||
| totalReturnPct: number; | ||
| cagr: number; | ||
| sharpe: number; | ||
| sortino: number; | ||
| maxDrawdownPct: number; | ||
| winRate: number; | ||
| profitFactor: number; | ||
| trades: number; | ||
| } | ||
| export interface DashboardStat { | ||
| label: string; | ||
| value: string; | ||
| tone: 'positive' | 'negative' | 'neutral'; | ||
| } | ||
| /** Map an analytics equity curve to the finance EquityCurveChart point shape. */ | ||
| export declare function toEquityPoints(curve: ReadonlyArray<EquitySample>): EquityPoint[]; | ||
| /** | ||
| * Underwater drawdown curve as a percentage (<= 0). Each point is the equity's | ||
| * shortfall from the running peak: `equity / peak - 1`, expressed in percent. | ||
| */ | ||
| export declare function computeDrawdownCurve(curve: ReadonlyArray<EquitySample>): EquityPoint[]; | ||
| /** | ||
| * Calendar-month returns as heatmap cells. Each month's return is chained off | ||
| * the prior month's closing equity (the first month chains off its own opening | ||
| * equity), so the series reads as sequential monthly performance. `group` is | ||
| * the year and `value` is the return in percent. | ||
| */ | ||
| export declare function computeMonthlyReturns(curve: ReadonlyArray<EquitySample>): HeatmapCell[]; | ||
| /** The headline stats rendered as cards above the charts. */ | ||
| export declare function selectKeyStats(metrics: RiskMetricsLike): DashboardStat[]; | ||
| //# sourceMappingURL=performanceData.d.ts.map |
| {"version":3,"file":"performanceData.d.ts","sourceRoot":"","sources":["../../src/finance/performanceData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGrE,sFAAsF;AACtF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;CAC3C;AAID,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,WAAW,EAAE,CAEhF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,WAAW,EAAE,CAOtF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,WAAW,EAAE,CAgCvF;AAaD,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,aAAa,EAAE,CAWxE"} |
| import { DataSeries, TimeFrame } from '@tradecanvas/commons'; | ||
| export interface ResampleOptions { | ||
| /** 0 = Sunday, 1 = Monday (default) — anchor for weekly buckets. */ | ||
| weekStartsOn?: 0 | 1; | ||
| } | ||
| /** | ||
| * Aggregate a finer OHLCV series into a coarser timeframe. | ||
| * | ||
| * Bars are grouped by calendar-aware bucket (see `timeframeBucketStart`): | ||
| * open = first bar's open, high/low = extremes, close = last bar's close, | ||
| * volume = sum. Input bars are assumed sorted ascending by `time` and are | ||
| * never mutated. | ||
| * | ||
| * Upsampling (target finer than source) cannot synthesize data — pass a target | ||
| * coarser than the source. Use `inferTimeframeMs` to detect the source spacing. | ||
| */ | ||
| export declare function resampleOHLCV(bars: DataSeries, target: TimeFrame, opts?: ResampleOptions): DataSeries; | ||
| /** | ||
| * Estimate the source bar spacing in milliseconds from the median gap between | ||
| * consecutive bars. Robust to occasional gaps (weekends, halts). Returns 0 for | ||
| * series with fewer than two bars. | ||
| */ | ||
| export declare function inferTimeframeMs(bars: DataSeries): number; | ||
| /** | ||
| * Whether `target` is coarser than (or equal to) the source spacing, i.e. a | ||
| * valid downsample. A non-positive `sourceMs` (unknown) is treated as valid. | ||
| */ | ||
| export declare function canResample(sourceMs: number, target: TimeFrame): boolean; | ||
| //# sourceMappingURL=resampleOHLCV.d.ts.map |
| {"version":3,"file":"resampleOHLCV.d.ts","sourceRoot":"","sources":["../../src/io/resampleOHLCV.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAW,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAG3E,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE,eAAoB,GACzB,UAAU,CAkCZ;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAUzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAGxE"} |
| export interface AlertNotifyOptions { | ||
| /** Play a sound on trigger. `true` = built-in beep, string = audio URL. Default `false`. */ | ||
| sound?: boolean | string; | ||
| /** Show a desktop notification (requests permission on first use). Default `false`. */ | ||
| desktop?: boolean; | ||
| /** Title for desktop notifications. Default `'Price alert'`. */ | ||
| title?: string; | ||
| } | ||
| /** True when the Notification API is present and not denied. */ | ||
| export declare function canRequestNotifications(): boolean; | ||
| /** | ||
| * Plays a sound and/or raises a desktop notification when a price alert fires. | ||
| * Browser-API heavy by nature — every entry point is guarded so it degrades to | ||
| * a no-op in SSR, unsupported browsers, or when permission is denied. | ||
| */ | ||
| export declare class AlertNotifier { | ||
| private options; | ||
| private audioCtx; | ||
| private audioEl; | ||
| private permissionAsked; | ||
| constructor(options?: AlertNotifyOptions); | ||
| setOptions(options: AlertNotifyOptions): void; | ||
| /** Fire the configured notifications for a triggered alert. */ | ||
| notify(message: string): void; | ||
| private playSound; | ||
| /** A short two-tone beep via Web Audio — no asset required. */ | ||
| private beep; | ||
| private ensurePermission; | ||
| private showDesktop; | ||
| destroy(): void; | ||
| } | ||
| //# sourceMappingURL=AlertNotifier.d.ts.map |
| {"version":3,"file":"AlertNotifier.d.ts","sourceRoot":"","sources":["../../src/widget/AlertNotifier.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,4FAA4F;IAC5F,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,GAAE,kBAAuB;IAc5C,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAI7C,+DAA+D;IAC/D,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK7B,OAAO,CAAC,SAAS;IASjB,+DAA+D;IAC/D,OAAO,CAAC,IAAI;IAwBZ,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,WAAW;IAanB,OAAO,IAAI,IAAI;CAShB"} |
| import { KeyValueStorage } from './DrawingTemplateStore.js'; | ||
| /** | ||
| * An ordered, de-duplicated set of pinned drawing-tool ids, persisted to a | ||
| * key-value store. Order is insertion order (most-recently-pinned last). | ||
| */ | ||
| export declare class DrawingFavoritesStore { | ||
| private storageKey; | ||
| private storage; | ||
| private favorites; | ||
| constructor(storageKey?: string, storage?: KeyValueStorage | null); | ||
| list(): string[]; | ||
| has(tool: string): boolean; | ||
| add(tool: string): void; | ||
| remove(tool: string): void; | ||
| /** Toggle a tool's pinned state. Returns the new state (true = pinned). */ | ||
| toggle(tool: string): boolean; | ||
| /** Seed the favorites only when none are stored yet (first run). */ | ||
| seedDefaults(tools: string[]): void; | ||
| private load; | ||
| private persist; | ||
| } | ||
| //# sourceMappingURL=DrawingFavoritesStore.d.ts.map |
| {"version":3,"file":"DrawingFavoritesStore.d.ts","sourceRoot":"","sources":["../../src/widget/DrawingFavoritesStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAUjE;;;GAGG;AACH,qBAAa,qBAAqB;IAI9B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,OAAO;IAJjB,OAAO,CAAC,SAAS,CAAgB;gBAGvB,UAAU,SAAuB,EACjC,OAAO,GAAE,eAAe,GAAG,IAAuB;IAK5D,IAAI,IAAI,MAAM,EAAE;IAIhB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM1B,2EAA2E;IAC3E,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAS7B,oEAAoE;IACpE,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAMnC,OAAO,CAAC,IAAI;IAcZ,OAAO,CAAC,OAAO;CAQhB"} |
| import { DrawingStyle } from '@tradecanvas/commons'; | ||
| export interface DrawingStyleTemplate { | ||
| name: string; | ||
| style: Partial<DrawingStyle>; | ||
| } | ||
| /** Minimal storage surface — satisfied by `localStorage` and easy to mock. */ | ||
| export interface KeyValueStorage { | ||
| getItem(key: string): string | null; | ||
| setItem(key: string, value: string): void; | ||
| } | ||
| /** | ||
| * Named drawing-style presets, persisted to a key-value store. Templates are | ||
| * upserted by name (case-sensitive) and ordered most-recently-saved last. | ||
| */ | ||
| export declare class DrawingTemplateStore { | ||
| private storageKey; | ||
| private storage; | ||
| private templates; | ||
| constructor(storageKey?: string, storage?: KeyValueStorage | null); | ||
| list(): DrawingStyleTemplate[]; | ||
| get(name: string): DrawingStyleTemplate | null; | ||
| /** Insert or replace a template by name. */ | ||
| save(name: string, style: Partial<DrawingStyle>): void; | ||
| remove(name: string): void; | ||
| clear(): void; | ||
| private load; | ||
| private persist; | ||
| } | ||
| //# sourceMappingURL=DrawingTemplateStore.d.ts.map |
| {"version":3,"file":"DrawingTemplateStore.d.ts","sourceRoot":"","sources":["../../src/widget/DrawingTemplateStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9B;AAED,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAyBD;;;GAGG;AACH,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,OAAO;IAJjB,OAAO,CAAC,SAAS,CAA8B;gBAGrC,UAAU,SAAuB,EACjC,OAAO,GAAE,eAAe,GAAG,IAAuB;IAK5D,IAAI,IAAI,oBAAoB,EAAE;IAI9B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;IAK9C,4CAA4C;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;IAStD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAO1B,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,OAAO;CAQhB"} |
| import { DepthData } from '@tradecanvas/commons'; | ||
| export interface LadderRow { | ||
| price: number; | ||
| bidVolume: number; | ||
| askVolume: number; | ||
| } | ||
| export interface LadderModel { | ||
| /** Rows ordered high → low price (asks on top, bids below). */ | ||
| rows: LadderRow[]; | ||
| /** Largest single-side volume across the shown rows (for bar scaling). */ | ||
| maxVolume: number; | ||
| /** Midpoint between best bid and best ask, or null if a side is empty. */ | ||
| mid: number | null; | ||
| } | ||
| /** | ||
| * Build a depth-of-market ladder from an order book: the best `maxLevels` asks | ||
| * (lowest prices) and best `maxLevels` bids (highest prices), merged into rows | ||
| * ordered high→low. A price present on both sides is merged into one row. | ||
| */ | ||
| export declare function buildLadderRows(data: DepthData, maxLevels?: number): LadderModel; | ||
| //# sourceMappingURL=ladderRows.d.ts.map |
| {"version":3,"file":"ladderRows.d.ts","sourceRoot":"","sources":["../../src/widget/ladderRows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,SAAK,GAAG,WAAW,CAyB5E"} |
| import { AlertCondition } from '@tradecanvas/core'; | ||
| export interface AlertListItem { | ||
| id: string; | ||
| price: number; | ||
| condition: string; | ||
| message?: string; | ||
| triggered: boolean; | ||
| channel?: string; | ||
| label?: string; | ||
| } | ||
| export interface AlertSource { | ||
| /** `'price'` or `<instanceId>:<key>`. */ | ||
| channel: string; | ||
| label: string; | ||
| } | ||
| export interface AlertsPanelCallbacks { | ||
| onAdd: (price: number, condition: AlertCondition, message: string | undefined, channel: string, label: string) => void; | ||
| onRemove: (id: string) => void; | ||
| onClear: () => void; | ||
| /** Latest value for a source channel, used to prefill the add form. */ | ||
| getChannelValue: (channel: string) => number | null; | ||
| formatPrice: (price: number) => string; | ||
| } | ||
| /** | ||
| * Floating price-alerts panel. Lists current alerts (with condition, price, | ||
| * message, and a delete control) and an inline form to add a new one prefilled | ||
| * with the current price. Toggled from the toolbar bell button; the host wires | ||
| * add/remove back to the chart's `AlertManager`. | ||
| */ | ||
| export declare class WidgetAlertsPanel { | ||
| private el; | ||
| private listEl; | ||
| private priceInput; | ||
| private conditionSelect; | ||
| private sourceSelect; | ||
| private messageInput; | ||
| private emptyEl; | ||
| private callbacks; | ||
| private open; | ||
| private alerts; | ||
| private sources; | ||
| constructor(host: HTMLElement, callbacks: AlertsPanelCallbacks); | ||
| /** Replace the alert-source options (price + indicator lines). */ | ||
| setSources(sources: AlertSource[]): void; | ||
| private renderSources; | ||
| isOpen(): boolean; | ||
| toggle(): void; | ||
| openPanel(): void; | ||
| /** Fill the value input with the selected source's current value. */ | ||
| private prefillPrice; | ||
| close(): void; | ||
| /** Replace the displayed alert list. */ | ||
| setAlerts(alerts: AlertListItem[]): void; | ||
| destroy(): void; | ||
| private submitForm; | ||
| private renderList; | ||
| } | ||
| //# sourceMappingURL=WidgetAlertsPanel.d.ts.map |
| {"version":3,"file":"WidgetAlertsPanel.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetAlertsPanel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvH,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,uEAAuE;IACvE,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACpD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAqBD;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,OAAO,CAAyD;gBAE5D,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,oBAAoB;IAiF9D,kEAAkE;IAClE,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;IAKxC,OAAO,CAAC,aAAa;IAarB,MAAM,IAAI,OAAO;IAIjB,MAAM,IAAI,IAAI;IAId,SAAS,IAAI,IAAI;IAMjB,qEAAqE;IACrE,OAAO,CAAC,YAAY;IAKpB,KAAK,IAAI,IAAI;IAKb,wCAAwC;IACxC,SAAS,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI;IAKxC,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,UAAU;CAiDnB"} |
| export interface BracketBarCallbacks { | ||
| onConfirm: () => void; | ||
| onCancel: () => void; | ||
| } | ||
| /** | ||
| * Floating confirm/cancel bar shown while a bracket order is being placed. | ||
| * The live entry / SL / TP numbers are drawn on the chart canvas; this bar | ||
| * just carries the commit and discard actions (also bound to Enter / Esc). | ||
| */ | ||
| export declare class WidgetBracketBar { | ||
| private el; | ||
| private labelEl; | ||
| private callbacks; | ||
| private visible; | ||
| constructor(host: HTMLElement, callbacks: BracketBarCallbacks); | ||
| show(side: 'buy' | 'sell'): void; | ||
| hide(): void; | ||
| isVisible(): boolean; | ||
| destroy(): void; | ||
| } | ||
| //# sourceMappingURL=WidgetBracketBar.d.ts.map |
| {"version":3,"file":"WidgetBracketBar.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetBracketBar.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,OAAO,CAAS;gBAEZ,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB;IAiC7D,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI;IAOhC,IAAI,IAAI,IAAI;IAKZ,SAAS,IAAI,OAAO;IAIpB,OAAO,IAAI,IAAI;CAGhB"} |
| export interface DataWindowIndicator { | ||
| name: string; | ||
| values: { | ||
| key: string; | ||
| value: number; | ||
| }[]; | ||
| } | ||
| export interface DataWindowModel { | ||
| ohlc: { | ||
| open: number; | ||
| high: number; | ||
| low: number; | ||
| close: number; | ||
| volume: number; | ||
| } | null; | ||
| change: number; | ||
| changePct: number; | ||
| indicators: DataWindowIndicator[]; | ||
| } | ||
| export interface DataWindowCallbacks { | ||
| formatPrice: (price: number) => string; | ||
| } | ||
| /** | ||
| * Data Window — a floating readout of the exact O/H/L/C/V, change, and every | ||
| * active indicator value at the hovered bar. Updated from `crosshairMove`. | ||
| */ | ||
| export declare class WidgetDataWindow { | ||
| private el; | ||
| private bodyEl; | ||
| private callbacks; | ||
| private open; | ||
| constructor(host: HTMLElement, callbacks: DataWindowCallbacks); | ||
| isOpen(): boolean; | ||
| toggle(): void; | ||
| openPanel(): void; | ||
| close(): void; | ||
| destroy(): void; | ||
| render(model: DataWindowModel): void; | ||
| private row; | ||
| } | ||
| //# sourceMappingURL=WidgetDataWindow.d.ts.map |
| {"version":3,"file":"WidgetDataWindow.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetDataWindow.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACxF,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,IAAI,CAAS;gBAET,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB;IA4B7D,MAAM,IAAI,OAAO;IAIjB,MAAM,IAAI,IAAI;IAId,SAAS,IAAI,IAAI;IAKjB,KAAK,IAAI,IAAI;IAKb,OAAO,IAAI,IAAI;IAIf,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAkCpC,OAAO,CAAC,GAAG;CAaZ"} |
| import { DepthData } from '@tradecanvas/commons'; | ||
| export interface DepthLadderCallbacks { | ||
| /** Buy at `price` (clicked an ask cell) or sell at `price` (clicked a bid cell). */ | ||
| onTrade: (side: 'buy' | 'sell', price: number) => void; | ||
| formatPrice: (price: number) => string; | ||
| } | ||
| /** | ||
| * Depth-of-market ladder (DOM). Renders the order book as price rows with bid | ||
| * and ask size columns; clicking an ask cell buys at that price, a bid cell | ||
| * sells. Fed by `setData(depth)`; the bar widths scale to the largest visible | ||
| * size. | ||
| */ | ||
| export declare class WidgetDepthLadder { | ||
| private el; | ||
| private bodyEl; | ||
| private callbacks; | ||
| private open; | ||
| private levels; | ||
| constructor(host: HTMLElement, callbacks: DepthLadderCallbacks, levels?: number); | ||
| isOpen(): boolean; | ||
| toggle(): void; | ||
| openPanel(): void; | ||
| close(): void; | ||
| setData(depth: DepthData | null): void; | ||
| destroy(): void; | ||
| private renderEmpty; | ||
| private render; | ||
| } | ||
| //# sourceMappingURL=WidgetDepthLadder.d.ts.map |
| {"version":3,"file":"WidgetDepthLadder.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetDepthLadder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAItD,MAAM,WAAW,oBAAoB;IACnC,oFAAoF;IACpF,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAS;gBAEX,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,SAAK;IAkC3E,MAAM,IAAI,OAAO;IAIjB,MAAM,IAAI,IAAI;IAId,SAAS,IAAI,IAAI;IAKjB,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI;IAQtC,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,MAAM;CAiDf"} |
| import { DrawingStyle } from '@tradecanvas/commons'; | ||
| import { DrawingTemplateStore } from './DrawingTemplateStore.js'; | ||
| export interface DrawingStyleCallbacks { | ||
| /** Apply a style change to the active (next) drawing and the selected one. */ | ||
| onStyleChange: (style: Partial<DrawingStyle>) => void; | ||
| /** Current active drawing style, for seeding controls and saving templates. */ | ||
| getStyle: () => DrawingStyle; | ||
| } | ||
| /** | ||
| * Drawing style popover — pick colour, line width, and line style for the next | ||
| * drawing (and the selected one), plus save/apply named style templates | ||
| * persisted via `DrawingTemplateStore`. | ||
| */ | ||
| export declare class WidgetDrawingStyle { | ||
| private el; | ||
| private templatesEl; | ||
| private nameInput; | ||
| private callbacks; | ||
| private store; | ||
| private open; | ||
| constructor(host: HTMLElement, callbacks: DrawingStyleCallbacks, store: DrawingTemplateStore); | ||
| isOpen(): boolean; | ||
| toggle(): void; | ||
| openPanel(): void; | ||
| close(): void; | ||
| destroy(): void; | ||
| private colorRow; | ||
| private widthRow; | ||
| private lineStyleRow; | ||
| private applyStyle; | ||
| /** Mark the controls matching the current active style. */ | ||
| private syncActiveControls; | ||
| private saveTemplate; | ||
| private renderTemplates; | ||
| } | ||
| //# sourceMappingURL=WidgetDrawingStyle.d.ts.map |
| {"version":3,"file":"WidgetDrawingStyle.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetDrawingStyle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACtD,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,YAAY,CAAC;CAC9B;AAMD;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,IAAI,CAAS;gBAET,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,qBAAqB,EAAE,KAAK,EAAE,oBAAoB;IAuD5F,MAAM,IAAI,OAAO;IAIjB,MAAM,IAAI,IAAI;IAId,SAAS,IAAI,IAAI;IAOjB,KAAK,IAAI,IAAI;IAKb,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,QAAQ;IAqBhB,OAAO,CAAC,QAAQ;IAiBhB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,UAAU;IAKlB,2DAA2D;IAC3D,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,eAAe;CA4CxB"} |
| export type IndicatorParamValue = number | string | boolean; | ||
| export interface IndicatorSettingsTarget { | ||
| instanceId: string; | ||
| name: string; | ||
| /** Default config — defines the editable keys and their types. */ | ||
| defaults: Record<string, unknown>; | ||
| /** Current values, overlaid on defaults. */ | ||
| params: Record<string, unknown>; | ||
| } | ||
| export interface IndicatorSettingsCallbacks { | ||
| onApply: (instanceId: string, params: Record<string, IndicatorParamValue>) => void; | ||
| onClose: () => void; | ||
| } | ||
| /** | ||
| * Per-indicator parameter editor. Introspects the indicator's default config to | ||
| * decide each control (number → stepper, boolean → toggle, hex string → color, | ||
| * other string → text) and applies edits live via `onApply`. | ||
| */ | ||
| export declare class WidgetIndicatorSettings { | ||
| private backdrop; | ||
| private modal; | ||
| private bodyEl; | ||
| private titleEl; | ||
| private callbacks; | ||
| private target; | ||
| private draft; | ||
| constructor(host: HTMLElement, callbacks: IndicatorSettingsCallbacks); | ||
| open(target: IndicatorSettingsTarget): void; | ||
| close(): void; | ||
| isOpen(): boolean; | ||
| destroy(): void; | ||
| private currentValue; | ||
| private setValue; | ||
| private resetDefaults; | ||
| private renderFields; | ||
| private fieldRow; | ||
| private toggleControl; | ||
| private numberControl; | ||
| private colorControl; | ||
| private textControl; | ||
| } | ||
| //# sourceMappingURL=WidgetIndicatorSettings.d.ts.map |
| {"version":3,"file":"WidgetIndicatorSettings.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetIndicatorSettings.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE5D,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,KAAK,IAAI,CAAC;IACnF,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAYD;;;;GAIG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,KAAK,CAA2C;gBAE5C,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,0BAA0B;IAgDpE,IAAI,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI;IAQ3C,KAAK,IAAI,IAAI;IAMb,MAAM,IAAI,OAAO;IAIjB,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,WAAW;CAQpB"} |
| export interface ObjectTreeIndicator { | ||
| instanceId: string; | ||
| name: string; | ||
| visible: boolean; | ||
| } | ||
| export interface ObjectTreeDrawing { | ||
| id: string; | ||
| label: string; | ||
| visible: boolean; | ||
| locked: boolean; | ||
| } | ||
| export interface ObjectTreeCompare { | ||
| id: string; | ||
| label: string; | ||
| color: string; | ||
| } | ||
| export interface ObjectTreeCallbacks { | ||
| onRemoveIndicator: (instanceId: string) => void; | ||
| onConfigureIndicator?: (instanceId: string) => void; | ||
| onToggleIndicatorVisible?: (instanceId: string, visible: boolean) => void; | ||
| onRemoveDrawing: (id: string) => void; | ||
| onToggleDrawingVisible: (id: string, visible: boolean) => void; | ||
| onToggleDrawingLocked: (id: string, locked: boolean) => void; | ||
| /** When provided, a Compare section with an "add" button is shown. */ | ||
| onAddCompare?: () => void; | ||
| onRemoveCompare?: (id: string) => void; | ||
| } | ||
| /** | ||
| * Object-tree panel — TradingView's layers manager. Lists every active | ||
| * indicator and drawing on the chart with per-item controls: indicators can be | ||
| * removed; drawings can be shown/hidden, locked/unlocked, and removed. Toggled | ||
| * from the toolbar layers button; the host wires actions back to the chart. | ||
| */ | ||
| export declare class WidgetObjectTree { | ||
| private el; | ||
| private indicatorsEl; | ||
| private drawingsEl; | ||
| private compareEl; | ||
| private callbacks; | ||
| private open; | ||
| constructor(host: HTMLElement, callbacks: ObjectTreeCallbacks); | ||
| isOpen(): boolean; | ||
| toggle(): void; | ||
| openPanel(): void; | ||
| close(): void; | ||
| destroy(): void; | ||
| /** Replace all lists. Cheap full re-render — counts are small. */ | ||
| setObjects(indicators: ObjectTreeIndicator[], drawings: ObjectTreeDrawing[], compares?: ObjectTreeCompare[]): void; | ||
| private makeSection; | ||
| private renderIndicators; | ||
| private renderDrawings; | ||
| private renderCompares; | ||
| private row; | ||
| private emptyRow; | ||
| private iconButton; | ||
| } | ||
| /** Human-readable label for a drawing type, falling back to the raw key. */ | ||
| export declare function drawingTypeLabel(type: string): string; | ||
| //# sourceMappingURL=WidgetObjectTree.d.ts.map |
| {"version":3,"file":"WidgetObjectTree.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetObjectTree.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,wBAAwB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1E,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,sBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/D,qBAAqB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7D,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,IAAI,CAAS;gBAET,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB;IA8B7D,MAAM,IAAI,OAAO;IAIjB,MAAM,IAAI,IAAI;IAId,SAAS,IAAI,IAAI;IAKjB,KAAK,IAAI,IAAI;IAKb,OAAO,IAAI,IAAI;IAIf,kEAAkE;IAClE,UAAU,CACR,UAAU,EAAE,mBAAmB,EAAE,EACjC,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,QAAQ,GAAE,iBAAiB,EAAO,GACjC,IAAI;IAMP,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,gBAAgB;IAgCxB,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,GAAG;IAWX,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,UAAU;CAUnB;AA6BD,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD"} |
| import { ChartType, TimeFrame, DrawingState, PriceScaleMode } from '@tradecanvas/commons'; | ||
| export interface ShareableIndicator { | ||
| id: string; | ||
| params: Record<string, number | string | boolean>; | ||
| } | ||
| export interface ShareableWidgetState { | ||
| v: 1; | ||
| symbol: string; | ||
| timeframe: TimeFrame; | ||
| chartType: ChartType; | ||
| scaleMode: PriceScaleMode; | ||
| indicators: ShareableIndicator[]; | ||
| drawings: DrawingState[]; | ||
| } | ||
| /** Encode a shareable widget state to a compact, URL-safe string. */ | ||
| export declare function encodeWidgetState(state: ShareableWidgetState): string; | ||
| /** | ||
| * Decode a shareable-state string. Returns null for anything malformed or of an | ||
| * unknown version — callers should treat null as "ignore and keep current view". | ||
| */ | ||
| export declare function decodeWidgetState(encoded: string): ShareableWidgetState | null; | ||
| /** Read a `#tcw=<encoded>` fragment from a URL hash, or null. */ | ||
| export declare function readShareHash(hash: string): string | null; | ||
| /** Build a shareable URL by replacing the `tcw` hash param on `base`. */ | ||
| export declare function buildShareUrl(base: string, encoded: string): string; | ||
| //# sourceMappingURL=widgetShareState.d.ts.map |
| {"version":3,"file":"widgetShareState.d.ts","sourceRoot":"","sources":["../../src/widget/widgetShareState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE/F,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,EAAE,CAAC,CAAC;IACL,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,cAAc,CAAC;IAC1B,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAiCD,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAErE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAkB9E;AAID,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOzD;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnE"} |
+110
-1
@@ -28,2 +28,3 @@ import { ChartOptions, ChartType, OHLCBar, DataSeries, Theme, ThemeName, ChartEventType, ChartEvent, ChartEventMap, TauriBridgeOptions, IndicatorPlugin, IndicatorDescriptor, IndicatorOutput, DrawingToolType, DrawingState, DrawingStyle, DrawingPlugin, PanelPosition, TradingOrder, TradingPosition, DepthData, TradingConfig, MarketConfig, Locale, StreamConfig, ConnectionState, ConnectionInfo, TimeFrame, FeaturesConfig } from '@tradecanvas/commons'; | ||
| private sessionBreaks; | ||
| private sessionShading; | ||
| private compareRenderer; | ||
@@ -33,2 +34,6 @@ private countdownInterval; | ||
| private volumeProfile; | ||
| private marketProfile; | ||
| private depthHeatmap; | ||
| private periodLevels; | ||
| private pivotMarkers; | ||
| private alertManager; | ||
@@ -87,5 +92,25 @@ private signalMarkerManager; | ||
| setDrawingStyle(style: Partial<DrawingStyle>): void; | ||
| getDrawingStyle(): DrawingStyle; | ||
| getSelectedDrawingId(): string | null; | ||
| /** Restyle the selected drawing (or one by id). Returns true if applied. */ | ||
| setSelectedDrawingStyle(style: Partial<DrawingStyle>, id?: string): boolean; | ||
| getDrawings(): DrawingState[]; | ||
| setDrawings(drawings: DrawingState[]): void; | ||
| /** Append a drawing (id auto-assigned, active style applied). Returns the id. */ | ||
| addDrawing(state: { | ||
| type: import('@tradecanvas/commons').DrawingToolType; | ||
| anchors: import('@tradecanvas/commons').AnchorPoint[]; | ||
| style?: Partial<DrawingStyle>; | ||
| visible?: boolean; | ||
| locked?: boolean; | ||
| meta?: Record<string, unknown>; | ||
| }): string | null; | ||
| /** | ||
| * Draw a Fibonacci retracement over the dominant swing (extreme high/low) in | ||
| * the visible range. Returns the new drawing's id, or null if no swing. | ||
| */ | ||
| autoFib(): string | null; | ||
| removeDrawing(id: string): void; | ||
| setDrawingVisible(id: string, visible: boolean): void; | ||
| setDrawingLocked(id: string, locked: boolean): void; | ||
| clearDrawings(): void; | ||
@@ -122,3 +147,6 @@ registerDrawingTool(plugin: DrawingPlugin): void; | ||
| descriptor: IndicatorDescriptor; | ||
| visible: boolean; | ||
| }[]; | ||
| /** Show or hide an indicator without removing it. */ | ||
| setIndicatorVisible(instanceId: string, visible: boolean): void; | ||
| /** Get current config for a specific indicator instance */ | ||
@@ -136,5 +164,30 @@ getIndicatorConfig(instanceId: string): { | ||
| setOrders(orders: TradingOrder[]): void; | ||
| /** | ||
| * Begin placing a draggable bracket order (entry + stop-loss + take-profit). | ||
| * Defaults the entry to the latest close when `entry` is omitted. Drag the | ||
| * three lines to adjust; confirm with Enter (emits `bracketPlace`) or cancel | ||
| * with Esc. Returns false if trading is disabled or no price is available. | ||
| */ | ||
| startBracket(side: import('@tradecanvas/commons').OrderSide, entry?: number): boolean; | ||
| cancelBracket(): void; | ||
| confirmBracket(): boolean; | ||
| isBracketActive(): boolean; | ||
| /** | ||
| * Emit an `orderPlace` intent (e.g. from a depth-ladder click). The chart | ||
| * does not create the order itself — the host listens via | ||
| * `chart.on('orderPlace', …)` and submits to its OMS. | ||
| */ | ||
| placeOrderIntent(intent: import('@tradecanvas/commons').OrderPlaceIntent): void; | ||
| setPositions(positions: TradingPosition[]): void; | ||
| setDepthData(depth: DepthData | null): void; | ||
| setCurrentPrice(price: number, _pulseColor?: string): void; | ||
| /** | ||
| * Feed the latest indicator-line values to any indicator-channel alerts. | ||
| * Channel format: `<instanceId>:<key>`; instanceIds are `tc_<id>_<n>` and | ||
| * built-in keys are colon-free, so the first colon splits them. Values come | ||
| * from the recalculated series, so indicator alerts evaluate at bar cadence | ||
| * (the live intrabar tick doesn't repaint closed-bar indicator values). | ||
| * Cheap — only walks alerts whose channel isn't `'price'`, usually none. | ||
| */ | ||
| private feedIndicatorAlerts; | ||
| setTradingConfig(config: Partial<TradingConfig>): void; | ||
@@ -176,2 +229,9 @@ /** | ||
| isLogScale(): boolean; | ||
| /** | ||
| * Set the price-scale presentation: `regular`, `logarithmic`, `percentage` | ||
| * (axis labels show % change from the first visible bar), or `indexedTo100` | ||
| * (rebased so the first visible bar reads as 100). | ||
| */ | ||
| setScaleMode(mode: import('@tradecanvas/commons').PriceScaleMode): void; | ||
| getScaleMode(): import('@tradecanvas/commons').PriceScaleMode; | ||
| setSessionBreaksConfig(config: { | ||
@@ -221,2 +281,49 @@ color?: string; | ||
| }): void; | ||
| setMarketProfileVisible(visible: boolean): void; | ||
| isMarketProfileVisible(): boolean; | ||
| setMarketProfileConfig(config: { | ||
| buckets?: number; | ||
| widthRatio?: number; | ||
| opacity?: number; | ||
| valueAreaPct?: number; | ||
| highlightPoC?: boolean; | ||
| showStats?: boolean; | ||
| splitBySession?: boolean; | ||
| letters?: boolean; | ||
| }): void; | ||
| /** POC / VAH / VAL of the currently rendered Market Profile, or null. */ | ||
| getMarketProfileStats(): import('@tradecanvas/core').MarketProfileStats | null; | ||
| setDepthHeatmapVisible(visible: boolean): void; | ||
| isDepthHeatmapVisible(): boolean; | ||
| setDepthHeatmapConfig(config: { | ||
| opacity?: number; | ||
| capacity?: number; | ||
| }): void; | ||
| /** | ||
| * Record an order-book snapshot for the liquidity heatmap, stamped at the | ||
| * latest bar's time. Call alongside `setDepthData` on each book update. | ||
| */ | ||
| pushDepthSnapshot(depth: import('@tradecanvas/commons').DepthData): void; | ||
| clearDepthHeatmap(): void; | ||
| setPeriodLevelsVisible(visible: boolean): void; | ||
| isPeriodLevelsVisible(): boolean; | ||
| setPeriodLevelsPeriod(period: import('@tradecanvas/core').LevelPeriod): void; | ||
| /** | ||
| * Set the timezone for time-axis labels and the crosshair time pill. | ||
| * `null` = browser-local; a number = fixed UTC offset in minutes (e.g. -300 | ||
| * for EST, 330 for IST). | ||
| */ | ||
| setTimezoneOffset(minutes: number | null): void; | ||
| setPivotMarkersVisible(visible: boolean): void; | ||
| isPivotMarkersVisible(): boolean; | ||
| setPivotMarkersConfig(config: { | ||
| left?: number; | ||
| right?: number; | ||
| showLabels?: boolean; | ||
| structureLabels?: boolean; | ||
| }): void; | ||
| setSessionShadingVisible(visible: boolean): void; | ||
| isSessionShadingVisible(): boolean; | ||
| /** Configure the regular session window (minutes-of-day + tz offset). */ | ||
| setSessionShadingConfig(config: Partial<import('@tradecanvas/core').SessionHoursConfig>): void; | ||
| setTooltipVisible(visible: boolean): void; | ||
@@ -231,5 +338,7 @@ setLegend(config: Partial<import('@tradecanvas/core').LegendConfig>): void; | ||
| screenshot(filename?: string): void; | ||
| /** Copy the chart image to the clipboard. Returns false if unsupported/blocked. */ | ||
| copyScreenshot(): Promise<boolean>; | ||
| screenshotDataURL(): string | null; | ||
| screenshotBlob(): Promise<Blob | null>; | ||
| addAlert(price: number, condition?: import('@tradecanvas/core').AlertCondition, message?: string): string | null; | ||
| addAlert(price: number, condition?: import('@tradecanvas/core').AlertCondition, message?: string, channel?: string, label?: string): string | null; | ||
| removeAlert(id: string): void; | ||
@@ -236,0 +345,0 @@ getAlerts(): import('@tradecanvas/core').PriceAlert[]; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../src/Chart.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../src/Chart.ts"],"names":[],"mappings":"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"} |
@@ -7,2 +7,6 @@ export { SparklineChart } from './SparklineChart.js'; | ||
| export { GaugeChart } from './GaugeChart.js'; | ||
| export { PerformanceDashboard } from './PerformanceDashboard.js'; | ||
| export type { PerformanceDashboardOptions, PerformanceResult } from './PerformanceDashboard.js'; | ||
| export { toEquityPoints, computeDrawdownCurve, computeMonthlyReturns, selectKeyStats, } from './performanceData.js'; | ||
| export type { EquitySample, RiskMetricsLike, DashboardStat } from './performanceData.js'; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/finance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/finance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAChG,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"} |
+1
-1
@@ -1,2 +0,2 @@ | ||
| Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./DragDropImporter-CQ3EarQn.cjs`);let t=require(`@tradecanvas/commons`),n=require(`@tradecanvas/core`);var r={"1x1":{cols:1,rows:1},"1x2":{cols:2,rows:1},"2x1":{cols:1,rows:2},"2x2":{cols:2,rows:2},"1x3":{cols:3,rows:1},"3x1":{cols:1,rows:3},"2x3":{cols:3,rows:2},"3x2":{cols:2,rows:3}},i=class{root;cells=[];layout;options;destroyed=!1;syncing=!1;constructor(e,t={}){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()}applyLayout(){let{cols:e,rows:t}=r[this.layout],n=this.options.gap??1;this.root.style.gridTemplateColumns=`repeat(${e}, 1fr)`,this.root.style.gridTemplateRows=`repeat(${t}, 1fr)`,this.root.style.gap=`${n}px`}createCells(){let{cols:t,rows:n}=r[this.layout],i=t*n;for(let t=0;t<i;t++){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.r(r,{chartType:`candlestick`,autoScale:!0,features:{crosshair:!0,keyboard:!0,volume:!0,legend:!0,priceAxis:!0,timeAxis:!0,grid:!0},...this.options.chartOptions,...n.chartOptions,theme:this.options.theme}),a={container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`};this.options.syncCrosshair!==!1&&i.on(`crosshairMove`,e=>{if(!this.syncing){this.syncing=!0;for(let t of this.cells)t.chart!==i&&t.chart.setCrosshairPosition(e.payload.point);this.syncing=!1}}),this.options.syncTimeAxis!==!1&&i.on(`visibleRangeChange`,e=>{if(this.syncing)return;this.syncing=!0;let{from:t,to:n}=e.payload,r=i.getData();if(r.length>0&&t>=0&&n<r.length){let e=r[t]?.time,a=r[n]?.time;if(e&&a)for(let t of this.cells)t.chart!==i&&t.chart.setVisibleRange(e,a)}this.syncing=!1}),this.cells.push(a)}}setLayout(t){if(t===this.layout)return;let n=this.cells.length,{cols:i,rows:a}=r[t],o=i*a;if(o<n)for(let e=n-1;e>=o;e--){let t=this.cells[e];t.chart.destroy(),t.container.remove(),this.cells.pop()}if(this.layout=t,this.applyLayout(),o>n)for(let t=n;t<o;t++){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.r(r,{chartType:`candlestick`,autoScale:!0,...this.options.chartOptions,...n.chartOptions,theme:this.options.theme});this.cells.push({container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`})}}getChart(e){return this.cells[e]?.chart??null}getCharts(){return this.cells.map(e=>e.chart)}getCellCount(){return this.cells.length}setData(e,t){this.cells[e]?.chart.setData(t)}setAllData(e){for(let t of this.cells)t.chart.setData(e)}async connectCell(e,t){let n=this.cells[e];n&&(n.symbol=t.symbol,n.timeframe=t.timeframe,await n.chart.connect(t))}async connectAll(e,t,n,r=500){let i=[];for(let a=0;a<this.cells.length&&a<t.length;a++)i.push(this.connectCell(a,{adapter:e,symbol:t[a],timeframe:n,historyLimit:r}));await Promise.all(i)}setTheme(e){for(let t of this.cells)t.chart.setTheme(e)}destroy(){if(!this.destroyed){this.destroyed=!0;for(let e of this.cells)e.chart.destroy(),e.container.remove();this.cells=[],this.root.remove()}}},a=class extends n.BaseFinanceChart{options;constructor(e,t){super(e,t.theme),this.options=t,this.requestRender()}renderChart(e,t,r,i){(0,n.renderSparkline)(e,t,r,this.options,i)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}},o=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderDepthChart)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},s=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderEquityCurve)(e,t,r,this.options,i,a)}update(e,t){this.options={...this.options,data:e},t!==void 0&&(this.options={...this.options,benchmark:t}),this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},c=class extends n.BaseFinanceChart{options;crosshair=null;cachedRects=[];currentData=[];lastLayoutWidth=0;lastLayoutHeight=0;handleClick=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentData=t.data??[],t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),t.onCellClick&&(this.handleClick=e=>{let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top;this.onCanvasClick(n,r)},this.canvas.addEventListener(`click`,this.handleClick)),this.recomputeLayout(),this.requestRender()}recomputeLayout(){let e={x:0,y:0,width:this.width,height:this.height},t=this.options.cellPadding??2;if(this.lastLayoutWidth=this.width,this.lastLayoutHeight=this.height,this.options.weighted){let r=this.currentData.map(e=>({id:e.id,weight:e.weight??(Math.abs(e.value)||1)}));this.cachedRects=(0,n.layoutSquarifiedTreemap)(r,e,t)}else this.cachedRects=(0,n.layoutUniformGrid)(this.currentData.map(e=>({id:e.id})),e,t)}onCanvasClick(e,t){if(this.options.onCellClick)for(let n of this.cachedRects){let r=n.rect;if(e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height){let e=this.currentData.find(e=>e.id===n.id);e&&this.options.onCellClick(e);return}}}renderChart(e,t,r,i){(t!==this.lastLayoutWidth||r!==this.lastLayoutHeight)&&this.recomputeLayout();let a=this.crosshair?.getPosition()??null;(0,n.renderHeatmap)(e,t,r,this.currentData,this.cachedRects,this.options,i,a)}update(e){this.currentData=e,this.options={...this.options,data:e},this.recomputeLayout(),this.requestRender()}setOptions(e){this.options={...this.options,...e},e.data&&(this.currentData=e.data),this.recomputeLayout(),this.requestRender()}destroy(){this.crosshair?.destroy(),this.handleClick&&this.canvas.removeEventListener(`click`,this.handleClick),super.destroy()}},l=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderWaterfall)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},u=500;function d(e){let t=1-e;return 1-t*t*t}var f=class extends n.BaseFinanceChart{options;currentValue;targetValue;animationStart=null;animationFrom=0;animationFrameId=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentValue=t.value,this.targetValue=t.value,this.requestRender()}renderChart(e,t,r,i){(0,n.renderGauge)(e,t,r,this.options,i,this.currentValue)}setValue(e){if(this.options.animate===!1){this.cancelAnimation(),this.currentValue=e,this.targetValue=e,this.options={...this.options,value:e},this.requestRender();return}this.targetValue=e,this.animationFrom=this.currentValue,this.animationStart=performance.now(),this.options={...this.options,value:e},this.startAnimationLoop()}setOptions(e){let t={...this.options,...e};if(e.value!==void 0&&e.value!==this.targetValue){this.options=t,this.setValue(e.value);return}this.options=t,this.requestRender()}startAnimationLoop(){if(this.animationFrameId!==null)return;let e=()=>{if(this.animationFrameId=null,this.animationStart===null)return;let t=this.options.animationDuration??u,n=performance.now()-this.animationStart,r=Math.min(1,n/Math.max(1,t)),i=d(r);this.currentValue=this.animationFrom+(this.targetValue-this.animationFrom)*i,this.requestRender(),r<1?this.animationFrameId=requestAnimationFrame(e):(this.currentValue=this.targetValue,this.animationStart=null)};this.animationFrameId=requestAnimationFrame(e)}cancelAnimation(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStart=null}destroy(){this.cancelAnimation(),super.destroy()}};Object.defineProperty(exports,`AlertManager`,{enumerable:!0,get:function(){return n.AlertManager}}),Object.defineProperty(exports,`Animator`,{enumerable:!0,get:function(){return n.Animator}}),Object.defineProperty(exports,`BarCountdown`,{enumerable:!0,get:function(){return n.BarCountdown}}),Object.defineProperty(exports,`BinanceAdapter`,{enumerable:!0,get:function(){return n.BinanceAdapter}}),exports.Chart=e.r,exports.ChartGrid=i,Object.defineProperty(exports,`ChartLegend`,{enumerable:!0,get:function(){return n.ChartLegend}}),Object.defineProperty(exports,`ChartStateManager`,{enumerable:!0,get:function(){return n.ChartStateManager}}),Object.defineProperty(exports,`CompareRenderer`,{enumerable:!0,get:function(){return n.CompareRenderer}}),Object.defineProperty(exports,`CrosshairTooltip`,{enumerable:!0,get:function(){return n.CrosshairTooltip}}),Object.defineProperty(exports,`CurrentPriceLine`,{enumerable:!0,get:function(){return n.CurrentPriceLine}}),Object.defineProperty(exports,`DARK_TERMINAL`,{enumerable:!0,get:function(){return t.DARK_TERMINAL}}),Object.defineProperty(exports,`DARK_THEME`,{enumerable:!0,get:function(){return t.DARK_THEME}}),Object.defineProperty(exports,`DEFAULT_DRAWING_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_DRAWING_STYLE}}),Object.defineProperty(exports,`DEFAULT_LEGEND_CONFIG`,{enumerable:!0,get:function(){return n.DEFAULT_LEGEND_CONFIG}}),Object.defineProperty(exports,`DEFAULT_RECONNECT`,{enumerable:!0,get:function(){return t.DEFAULT_RECONNECT}}),Object.defineProperty(exports,`DEFAULT_SIGNAL_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_SIGNAL_STYLE}}),Object.defineProperty(exports,`DEFAULT_STREAM_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_STREAM_CONFIG}}),Object.defineProperty(exports,`DEFAULT_TIMEFRAME_FAVORITES`,{enumerable:!0,get:function(){return t.DEFAULT_TIMEFRAME_FAVORITES}}),Object.defineProperty(exports,`DEFAULT_TRADE_ZONE_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_TRADE_ZONE_STYLE}}),Object.defineProperty(exports,`DEFAULT_TRADING_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_TRADING_CONFIG}}),Object.defineProperty(exports,`DataExporter`,{enumerable:!0,get:function(){return n.DataExporter}}),exports.DataManager=e.s,exports.DepthChart=o,exports.DragDropImporter=e.t,Object.defineProperty(exports,`DrawingBase`,{enumerable:!0,get:function(){return n.DrawingBase}}),Object.defineProperty(exports,`Easing`,{enumerable:!0,get:function(){return n.Easing}}),exports.EquityCurveChart=s,exports.GaugeChart=f,exports.HeatmapChart=c,Object.defineProperty(exports,`IndicatorBase`,{enumerable:!0,get:function(){return n.IndicatorBase}}),Object.defineProperty(exports,`KeyboardHandler`,{enumerable:!0,get:function(){return n.KeyboardHandler}}),Object.defineProperty(exports,`LIGHT_THEME`,{enumerable:!0,get:function(){return t.LIGHT_THEME}}),exports.LayoutManager=e.a,Object.defineProperty(exports,`MARKET_CRYPTO`,{enumerable:!0,get:function(){return t.MARKET_CRYPTO}}),Object.defineProperty(exports,`MARKET_HNX`,{enumerable:!0,get:function(){return t.MARKET_HNX}}),Object.defineProperty(exports,`MARKET_HOSE`,{enumerable:!0,get:function(){return t.MARKET_HOSE}}),Object.defineProperty(exports,`MARKET_NYSE`,{enumerable:!0,get:function(){return t.MARKET_NYSE}}),Object.defineProperty(exports,`MARKET_UPCOM`,{enumerable:!0,get:function(){return t.MARKET_UPCOM}}),Object.defineProperty(exports,`MockAdapter`,{enumerable:!0,get:function(){return n.MockAdapter}}),exports.PluginManager=e.i,Object.defineProperty(exports,`ReplayManager`,{enumerable:!0,get:function(){return n.ReplayManager}}),Object.defineProperty(exports,`Screenshot`,{enumerable:!0,get:function(){return n.Screenshot}}),Object.defineProperty(exports,`SessionBreaks`,{enumerable:!0,get:function(){return n.SessionBreaks}}),Object.defineProperty(exports,`SignalMarkerManager`,{enumerable:!0,get:function(){return n.SignalMarkerManager}}),exports.SparklineChart=a,Object.defineProperty(exports,`StreamManager`,{enumerable:!0,get:function(){return n.StreamManager}}),Object.defineProperty(exports,`TIMEFRAMES_CRYPTO`,{enumerable:!0,get:function(){return t.TIMEFRAMES_CRYPTO}}),Object.defineProperty(exports,`TIMEFRAMES_FOREX`,{enumerable:!0,get:function(){return t.TIMEFRAMES_FOREX}}),Object.defineProperty(exports,`TIMEFRAMES_STOCK`,{enumerable:!0,get:function(){return t.TIMEFRAMES_STOCK}}),exports.ThemeManager=e.o,Object.defineProperty(exports,`TickAggregator`,{enumerable:!0,get:function(){return n.TickAggregator}}),Object.defineProperty(exports,`TradeZoneManager`,{enumerable:!0,get:function(){return n.TradeZoneManager}}),Object.defineProperty(exports,`UndoRedoManager`,{enumerable:!0,get:function(){return n.UndoRedoManager}}),Object.defineProperty(exports,`VN_COLORS`,{enumerable:!0,get:function(){return t.VN_COLORS}}),Object.defineProperty(exports,`VolumeRenderer`,{enumerable:!0,get:function(){return n.VolumeRenderer}}),exports.WaterfallChart=l,Object.defineProperty(exports,`Watermark`,{enumerable:!0,get:function(){return n.Watermark}}),Object.defineProperty(exports,`computePriceLimits`,{enumerable:!0,get:function(){return t.computePriceLimits}}),Object.defineProperty(exports,`createVNTheme`,{enumerable:!0,get:function(){return t.createVNTheme}}),Object.defineProperty(exports,`formatNumber`,{enumerable:!0,get:function(){return t.formatNumber}}),Object.defineProperty(exports,`formatVND`,{enumerable:!0,get:function(){return t.formatVND}}),Object.defineProperty(exports,`formatVolumeLoc`,{enumerable:!0,get:function(){return t.formatVolumeLoc}}),Object.defineProperty(exports,`getCurrentSession`,{enumerable:!0,get:function(){return t.getCurrentSession}}),Object.defineProperty(exports,`getLocale`,{enumerable:!0,get:function(){return t.getLocale}}),Object.defineProperty(exports,`normalizeBar`,{enumerable:!0,get:function(){return t.normalizeBar}}),Object.defineProperty(exports,`normalizeBarTime`,{enumerable:!0,get:function(){return t.normalizeBarTime}}),exports.parseOHLCV=e.n,Object.defineProperty(exports,`registerLocale`,{enumerable:!0,get:function(){return t.registerLocale}}),Object.defineProperty(exports,`setLocale`,{enumerable:!0,get:function(){return t.setLocale}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return t.t}}),Object.defineProperty(exports,`toHeikinAshi`,{enumerable:!0,get:function(){return n.toHeikinAshi}}),Object.defineProperty(exports,`toKagi`,{enumerable:!0,get:function(){return n.toKagi}}),Object.defineProperty(exports,`toLineBreak`,{enumerable:!0,get:function(){return n.toLineBreak}}),Object.defineProperty(exports,`toPointAndFigure`,{enumerable:!0,get:function(){return n.toPointAndFigure}}),Object.defineProperty(exports,`toRangeBars`,{enumerable:!0,get:function(){return n.toRangeBars}}),Object.defineProperty(exports,`toRenko`,{enumerable:!0,get:function(){return n.toRenko}}); | ||
| Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./DragDropImporter-ycI_Tcs6.cjs`);let t=require(`@tradecanvas/commons`),n=require(`@tradecanvas/core`);var r={"1x1":{cols:1,rows:1},"1x2":{cols:2,rows:1},"2x1":{cols:1,rows:2},"2x2":{cols:2,rows:2},"1x3":{cols:3,rows:1},"3x1":{cols:1,rows:3},"2x3":{cols:3,rows:2},"3x2":{cols:2,rows:3}},i=class{root;cells=[];layout;options;destroyed=!1;syncing=!1;constructor(e,t={}){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()}applyLayout(){let{cols:e,rows:t}=r[this.layout],n=this.options.gap??1;this.root.style.gridTemplateColumns=`repeat(${e}, 1fr)`,this.root.style.gridTemplateRows=`repeat(${t}, 1fr)`,this.root.style.gap=`${n}px`}createCells(){let{cols:t,rows:n}=r[this.layout],i=t*n;for(let t=0;t<i;t++){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.r(r,{chartType:`candlestick`,autoScale:!0,features:{crosshair:!0,keyboard:!0,volume:!0,legend:!0,priceAxis:!0,timeAxis:!0,grid:!0},...this.options.chartOptions,...n.chartOptions,theme:this.options.theme}),a={container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`};this.options.syncCrosshair!==!1&&i.on(`crosshairMove`,e=>{if(!this.syncing){this.syncing=!0;for(let t of this.cells)t.chart!==i&&t.chart.setCrosshairPosition(e.payload.point);this.syncing=!1}}),this.options.syncTimeAxis!==!1&&i.on(`visibleRangeChange`,e=>{if(this.syncing)return;this.syncing=!0;let{from:t,to:n}=e.payload,r=i.getData();if(r.length>0&&t>=0&&n<r.length){let e=r[t]?.time,a=r[n]?.time;if(e&&a)for(let t of this.cells)t.chart!==i&&t.chart.setVisibleRange(e,a)}this.syncing=!1}),this.cells.push(a)}}setLayout(t){if(t===this.layout)return;let n=this.cells.length,{cols:i,rows:a}=r[t],o=i*a;if(o<n)for(let e=n-1;e>=o;e--){let t=this.cells[e];t.chart.destroy(),t.container.remove(),this.cells.pop()}if(this.layout=t,this.applyLayout(),o>n)for(let t=n;t<o;t++){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.r(r,{chartType:`candlestick`,autoScale:!0,...this.options.chartOptions,...n.chartOptions,theme:this.options.theme});this.cells.push({container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`})}}getChart(e){return this.cells[e]?.chart??null}getCharts(){return this.cells.map(e=>e.chart)}getCellCount(){return this.cells.length}setData(e,t){this.cells[e]?.chart.setData(t)}setAllData(e){for(let t of this.cells)t.chart.setData(e)}async connectCell(e,t){let n=this.cells[e];n&&(n.symbol=t.symbol,n.timeframe=t.timeframe,await n.chart.connect(t))}async connectAll(e,t,n,r=500){let i=[];for(let a=0;a<this.cells.length&&a<t.length;a++)i.push(this.connectCell(a,{adapter:e,symbol:t[a],timeframe:n,historyLimit:r}));await Promise.all(i)}setTheme(e){for(let t of this.cells)t.chart.setTheme(e)}destroy(){if(!this.destroyed){this.destroyed=!0;for(let e of this.cells)e.chart.destroy(),e.container.remove();this.cells=[],this.root.remove()}}},a=class extends n.BaseFinanceChart{options;constructor(e,t){super(e,t.theme),this.options=t,this.requestRender()}renderChart(e,t,r,i){(0,n.renderSparkline)(e,t,r,this.options,i)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}},o=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderDepthChart)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},s=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderEquityCurve)(e,t,r,this.options,i,a)}update(e,t){this.options={...this.options,data:e},t!==void 0&&(this.options={...this.options,benchmark:t}),this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},c=class extends n.BaseFinanceChart{options;crosshair=null;cachedRects=[];currentData=[];lastLayoutWidth=0;lastLayoutHeight=0;handleClick=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentData=t.data??[],t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),t.onCellClick&&(this.handleClick=e=>{let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top;this.onCanvasClick(n,r)},this.canvas.addEventListener(`click`,this.handleClick)),this.recomputeLayout(),this.requestRender()}recomputeLayout(){let e={x:0,y:0,width:this.width,height:this.height},t=this.options.cellPadding??2;if(this.lastLayoutWidth=this.width,this.lastLayoutHeight=this.height,this.options.weighted){let r=this.currentData.map(e=>({id:e.id,weight:e.weight??(Math.abs(e.value)||1)}));this.cachedRects=(0,n.layoutSquarifiedTreemap)(r,e,t)}else this.cachedRects=(0,n.layoutUniformGrid)(this.currentData.map(e=>({id:e.id})),e,t)}onCanvasClick(e,t){if(this.options.onCellClick)for(let n of this.cachedRects){let r=n.rect;if(e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height){let e=this.currentData.find(e=>e.id===n.id);e&&this.options.onCellClick(e);return}}}renderChart(e,t,r,i){(t!==this.lastLayoutWidth||r!==this.lastLayoutHeight)&&this.recomputeLayout();let a=this.crosshair?.getPosition()??null;(0,n.renderHeatmap)(e,t,r,this.currentData,this.cachedRects,this.options,i,a)}update(e){this.currentData=e,this.options={...this.options,data:e},this.recomputeLayout(),this.requestRender()}setOptions(e){this.options={...this.options,...e},e.data&&(this.currentData=e.data),this.recomputeLayout(),this.requestRender()}destroy(){this.crosshair?.destroy(),this.handleClick&&this.canvas.removeEventListener(`click`,this.handleClick),super.destroy()}},l=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderWaterfall)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},u=500;function d(e){let t=1-e;return 1-t*t*t}var f=class extends n.BaseFinanceChart{options;currentValue;targetValue;animationStart=null;animationFrom=0;animationFrameId=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentValue=t.value,this.targetValue=t.value,this.requestRender()}renderChart(e,t,r,i){(0,n.renderGauge)(e,t,r,this.options,i,this.currentValue)}setValue(e){if(this.options.animate===!1){this.cancelAnimation(),this.currentValue=e,this.targetValue=e,this.options={...this.options,value:e},this.requestRender();return}this.targetValue=e,this.animationFrom=this.currentValue,this.animationStart=performance.now(),this.options={...this.options,value:e},this.startAnimationLoop()}setOptions(e){let t={...this.options,...e};if(e.value!==void 0&&e.value!==this.targetValue){this.options=t,this.setValue(e.value);return}this.options=t,this.requestRender()}startAnimationLoop(){if(this.animationFrameId!==null)return;let e=()=>{if(this.animationFrameId=null,this.animationStart===null)return;let t=this.options.animationDuration??u,n=performance.now()-this.animationStart,r=Math.min(1,n/Math.max(1,t)),i=d(r);this.currentValue=this.animationFrom+(this.targetValue-this.animationFrom)*i,this.requestRender(),r<1?this.animationFrameId=requestAnimationFrame(e):(this.currentValue=this.targetValue,this.animationStart=null)};this.animationFrameId=requestAnimationFrame(e)}cancelAnimation(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStart=null}destroy(){this.cancelAnimation(),super.destroy()}},p=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function m(e){return e.map(e=>({time:e.time,value:e.equity}))}function h(e){let t=-1/0;return e.map(e=>{e.equity>t&&(t=e.equity);let n=t>0?(e.equity/t-1)*100:0;return{time:e.time,value:n}})}function g(e){if(e.length===0)return[];let n=[];for(let r of e){let e=(0,t.timeframeBucketStart)(r.time,`1M`),i=n[n.length-1];i&&i.key===e?i.close=r.equity:n.push({key:e,close:r.equity})}let r=e[0].equity,i=[];for(let e of n){let t=r===0?1:r,n=(e.close/t-1)*100;r=e.close;let a=new Date(e.key),o=a.getUTCFullYear(),s=a.getUTCMonth();i.push({id:`${o}-${String(s+1).padStart(2,`0`)}`,label:p[s],group:String(o),value:n})}return i}function _(e){return`${e>0?`+`:``}${e.toFixed(2)}%`}function v(e){return e>0?`positive`:e<0?`negative`:`neutral`}function y(e){return[{label:`Total Return`,value:_(e.totalReturnPct),tone:v(e.totalReturnPct)},{label:`CAGR`,value:_(e.cagr*100),tone:v(e.cagr)},{label:`Sharpe`,value:e.sharpe.toFixed(2),tone:v(e.sharpe)},{label:`Sortino`,value:e.sortino.toFixed(2),tone:v(e.sortino)},{label:`Max Drawdown`,value:_(e.maxDrawdownPct),tone:`negative`},{label:`Win Rate`,value:`${(e.winRate*100).toFixed(1)}%`,tone:`neutral`},{label:`Profit Factor`,value:Number.isFinite(e.profitFactor)?e.profitFactor.toFixed(2):`∞`,tone:v(e.profitFactor-1)},{label:`Trades`,value:String(e.trades),tone:`neutral`}]}function b(e){return!e||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:e}var x=class{options;theme;root;equityChart=null;drawdownChart=null;heatmap=null;constructor(e,t){this.options=t,this.theme=b(t.theme),this.root=document.createElement(`div`),this.build(),e.appendChild(this.root)}build(){let e=this.theme,{result:t,title:n,subtitle:r}=this.options,i=this.panelBackground(),a=e.grid;if(this.root.style.cssText=[`display:flex`,`flex-direction:column`,`gap:14px`,`width:100%`,`box-sizing:border-box`,`padding:16px`,`background:${e.background}`,`color:${e.text}`,`font-family:${e.font.family}`].join(`;`),n||r){let t=document.createElement(`div`);if(n){let r=document.createElement(`div`);r.textContent=n,r.style.cssText=`font-size:${e.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`,t.appendChild(r)}if(r){let n=document.createElement(`div`);n.textContent=r,n.style.cssText=`font-size:${e.font.sizeSmall}px;color:${e.textSecondary};margin-top:2px;`,t.appendChild(n)}this.root.appendChild(t)}this.root.appendChild(this.buildStatsStrip(y(t.metrics),i,a));let o=document.createElement(`div`);o.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))`,`grid-auto-rows:220px`,`gap:14px`].join(`;`),this.root.appendChild(o);let l=this.buildPanel(`Equity Curve`,i,a);l.wrap.style.gridColumn=`1 / -1`,o.appendChild(l.wrap),this.equityChart=new s(l.body,{data:m(t.equityCurve),theme:e,lineColor:e.candleUp,fillArea:!0,crosshair:!0});let u=this.buildPanel(`Drawdown`,i,a);o.appendChild(u.wrap),this.drawdownChart=new s(u.body,{data:h(t.equityCurve),theme:e,lineColor:e.candleDown,fillArea:!0,crosshair:!0,valueFormat:e=>`${e.toFixed(1)}%`});let d=g(t.equityCurve),f=this.buildPanel(`Monthly Returns`,i,a);o.appendChild(f.wrap),this.heatmap=new c(f.body,{data:d,theme:e,showValues:!0,valueFormat:e=>`${e>=0?`+`:``}${e.toFixed(1)}`,colorScale:{negative:e.candleDown,zero:i,positive:e.candleUp}})}buildStatsStrip(e,t,n){let r=document.createElement(`div`);r.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))`,`gap:10px`].join(`;`);let i=this.theme;for(let a of e){let e=document.createElement(`div`);e.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`padding:10px 12px`,`display:flex`,`flex-direction:column`,`gap:4px`].join(`;`);let o=document.createElement(`div`);o.textContent=a.label,o.style.cssText=`font-size:${i.font.sizeSmall}px;color:${i.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;let s=document.createElement(`div`);s.textContent=a.value;let c=a.tone===`positive`?i.candleUp:a.tone===`negative`?i.candleDown:i.text;s.style.cssText=`font-size:${i.font.sizeLarge}px;font-weight:600;color:${c};font-variant-numeric:tabular-nums;`,e.appendChild(o),e.appendChild(s),r.appendChild(e)}return r}buildPanel(e,t,n){let r=this.theme,i=document.createElement(`div`);i.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`overflow:hidden`,`display:flex`,`flex-direction:column`].join(`;`);let a=document.createElement(`div`);a.textContent=e,a.style.cssText=[`font-size:${r.font.sizeSmall}px`,`font-weight:600`,`color:${r.textSecondary}`,`padding:8px 12px`,`border-bottom:1px solid ${n}`,`text-transform:uppercase`,`letter-spacing:0.04em`].join(`;`);let o=document.createElement(`div`);return o.style.cssText=`flex:1;min-height:0;position:relative;`,i.appendChild(a),i.appendChild(o),{wrap:i,body:o}}panelBackground(){return this.theme.name===`light`?`rgba(0,0,0,0.02)`:`rgba(255,255,255,0.03)`}update(e){this.options={...this.options,result:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}setTheme(e){this.theme=b(e),this.options={...this.options,theme:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}destroyCharts(){this.equityChart?.destroy(),this.drawdownChart?.destroy(),this.heatmap?.destroy(),this.equityChart=null,this.drawdownChart=null,this.heatmap=null}destroy(){this.destroyCharts(),this.root.remove()}};Object.defineProperty(exports,`AlertManager`,{enumerable:!0,get:function(){return n.AlertManager}}),Object.defineProperty(exports,`Animator`,{enumerable:!0,get:function(){return n.Animator}}),Object.defineProperty(exports,`BarCountdown`,{enumerable:!0,get:function(){return n.BarCountdown}}),Object.defineProperty(exports,`BinanceAdapter`,{enumerable:!0,get:function(){return n.BinanceAdapter}}),exports.Chart=e.r,exports.ChartGrid=i,Object.defineProperty(exports,`ChartLegend`,{enumerable:!0,get:function(){return n.ChartLegend}}),Object.defineProperty(exports,`ChartStateManager`,{enumerable:!0,get:function(){return n.ChartStateManager}}),Object.defineProperty(exports,`CompareRenderer`,{enumerable:!0,get:function(){return n.CompareRenderer}}),Object.defineProperty(exports,`CrosshairTooltip`,{enumerable:!0,get:function(){return n.CrosshairTooltip}}),Object.defineProperty(exports,`CurrentPriceLine`,{enumerable:!0,get:function(){return n.CurrentPriceLine}}),Object.defineProperty(exports,`DARK_TERMINAL`,{enumerable:!0,get:function(){return t.DARK_TERMINAL}}),Object.defineProperty(exports,`DARK_THEME`,{enumerable:!0,get:function(){return t.DARK_THEME}}),Object.defineProperty(exports,`DEFAULT_DRAWING_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_DRAWING_STYLE}}),Object.defineProperty(exports,`DEFAULT_LEGEND_CONFIG`,{enumerable:!0,get:function(){return n.DEFAULT_LEGEND_CONFIG}}),Object.defineProperty(exports,`DEFAULT_RECONNECT`,{enumerable:!0,get:function(){return t.DEFAULT_RECONNECT}}),Object.defineProperty(exports,`DEFAULT_SIGNAL_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_SIGNAL_STYLE}}),Object.defineProperty(exports,`DEFAULT_STREAM_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_STREAM_CONFIG}}),Object.defineProperty(exports,`DEFAULT_TIMEFRAME_FAVORITES`,{enumerable:!0,get:function(){return t.DEFAULT_TIMEFRAME_FAVORITES}}),Object.defineProperty(exports,`DEFAULT_TRADE_ZONE_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_TRADE_ZONE_STYLE}}),Object.defineProperty(exports,`DEFAULT_TRADING_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_TRADING_CONFIG}}),Object.defineProperty(exports,`DataExporter`,{enumerable:!0,get:function(){return n.DataExporter}}),exports.DataManager=e.s,exports.DepthChart=o,exports.DragDropImporter=e.t,Object.defineProperty(exports,`DrawingBase`,{enumerable:!0,get:function(){return n.DrawingBase}}),Object.defineProperty(exports,`Easing`,{enumerable:!0,get:function(){return n.Easing}}),exports.EquityCurveChart=s,exports.GaugeChart=f,exports.HeatmapChart=c,Object.defineProperty(exports,`IndicatorBase`,{enumerable:!0,get:function(){return n.IndicatorBase}}),Object.defineProperty(exports,`KeyboardHandler`,{enumerable:!0,get:function(){return n.KeyboardHandler}}),Object.defineProperty(exports,`LIGHT_THEME`,{enumerable:!0,get:function(){return t.LIGHT_THEME}}),exports.LayoutManager=e.a,Object.defineProperty(exports,`MARKET_CRYPTO`,{enumerable:!0,get:function(){return t.MARKET_CRYPTO}}),Object.defineProperty(exports,`MARKET_HNX`,{enumerable:!0,get:function(){return t.MARKET_HNX}}),Object.defineProperty(exports,`MARKET_HOSE`,{enumerable:!0,get:function(){return t.MARKET_HOSE}}),Object.defineProperty(exports,`MARKET_NYSE`,{enumerable:!0,get:function(){return t.MARKET_NYSE}}),Object.defineProperty(exports,`MARKET_UPCOM`,{enumerable:!0,get:function(){return t.MARKET_UPCOM}}),Object.defineProperty(exports,`MockAdapter`,{enumerable:!0,get:function(){return n.MockAdapter}}),exports.PerformanceDashboard=x,exports.PluginManager=e.i,Object.defineProperty(exports,`ReplayManager`,{enumerable:!0,get:function(){return n.ReplayManager}}),Object.defineProperty(exports,`Screenshot`,{enumerable:!0,get:function(){return n.Screenshot}}),Object.defineProperty(exports,`SessionBreaks`,{enumerable:!0,get:function(){return n.SessionBreaks}}),Object.defineProperty(exports,`SignalMarkerManager`,{enumerable:!0,get:function(){return n.SignalMarkerManager}}),exports.SparklineChart=a,Object.defineProperty(exports,`StreamManager`,{enumerable:!0,get:function(){return n.StreamManager}}),Object.defineProperty(exports,`TIMEFRAMES_CRYPTO`,{enumerable:!0,get:function(){return t.TIMEFRAMES_CRYPTO}}),Object.defineProperty(exports,`TIMEFRAMES_FOREX`,{enumerable:!0,get:function(){return t.TIMEFRAMES_FOREX}}),Object.defineProperty(exports,`TIMEFRAMES_STOCK`,{enumerable:!0,get:function(){return t.TIMEFRAMES_STOCK}}),exports.ThemeManager=e.o,Object.defineProperty(exports,`TickAggregator`,{enumerable:!0,get:function(){return n.TickAggregator}}),Object.defineProperty(exports,`TradeZoneManager`,{enumerable:!0,get:function(){return n.TradeZoneManager}}),Object.defineProperty(exports,`UndoRedoManager`,{enumerable:!0,get:function(){return n.UndoRedoManager}}),Object.defineProperty(exports,`VN_COLORS`,{enumerable:!0,get:function(){return t.VN_COLORS}}),Object.defineProperty(exports,`VolumeRenderer`,{enumerable:!0,get:function(){return n.VolumeRenderer}}),exports.WaterfallChart=l,Object.defineProperty(exports,`Watermark`,{enumerable:!0,get:function(){return n.Watermark}}),exports.computeDrawdownCurve=h,exports.computeMonthlyReturns=g,Object.defineProperty(exports,`computePriceLimits`,{enumerable:!0,get:function(){return t.computePriceLimits}}),Object.defineProperty(exports,`createVNTheme`,{enumerable:!0,get:function(){return t.createVNTheme}}),Object.defineProperty(exports,`formatNumber`,{enumerable:!0,get:function(){return t.formatNumber}}),Object.defineProperty(exports,`formatVND`,{enumerable:!0,get:function(){return t.formatVND}}),Object.defineProperty(exports,`formatVolumeLoc`,{enumerable:!0,get:function(){return t.formatVolumeLoc}}),Object.defineProperty(exports,`getCurrentSession`,{enumerable:!0,get:function(){return t.getCurrentSession}}),Object.defineProperty(exports,`getLocale`,{enumerable:!0,get:function(){return t.getLocale}}),Object.defineProperty(exports,`normalizeBar`,{enumerable:!0,get:function(){return t.normalizeBar}}),Object.defineProperty(exports,`normalizeBarTime`,{enumerable:!0,get:function(){return t.normalizeBarTime}}),exports.parseOHLCV=e.n,Object.defineProperty(exports,`registerLocale`,{enumerable:!0,get:function(){return t.registerLocale}}),exports.selectKeyStats=y,Object.defineProperty(exports,`setLocale`,{enumerable:!0,get:function(){return t.setLocale}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return t.t}}),exports.toEquityPoints=m,Object.defineProperty(exports,`toHeikinAshi`,{enumerable:!0,get:function(){return n.toHeikinAshi}}),Object.defineProperty(exports,`toKagi`,{enumerable:!0,get:function(){return n.toKagi}}),Object.defineProperty(exports,`toLineBreak`,{enumerable:!0,get:function(){return n.toLineBreak}}),Object.defineProperty(exports,`toPointAndFigure`,{enumerable:!0,get:function(){return n.toPointAndFigure}}),Object.defineProperty(exports,`toRangeBars`,{enumerable:!0,get:function(){return n.toRangeBars}}),Object.defineProperty(exports,`toRenko`,{enumerable:!0,get:function(){return n.toRenko}}); | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.cjs","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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"} | ||
| {"version":3,"file":"index.cjs","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","../src/finance/performanceData.ts","../src/finance/PerformanceDashboard.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","import type { EquityPoint, HeatmapCell } from '@tradecanvas/commons';\nimport { timeframeBucketStart } from '@tradecanvas/commons';\n\n/** Minimal equity sample shape — structurally satisfied by analytics' EquityPoint. */\nexport interface EquitySample {\n time: number;\n equity: number;\n}\n\n/** Subset of analytics RiskMetrics needed to render the stats strip. */\nexport interface RiskMetricsLike {\n totalReturnPct: number;\n cagr: number;\n sharpe: number;\n sortino: number;\n maxDrawdownPct: number;\n winRate: number;\n profitFactor: number;\n trades: number;\n}\n\nexport interface DashboardStat {\n label: string;\n value: string;\n tone: 'positive' | 'negative' | 'neutral';\n}\n\nconst MONTH_LABELS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\n/** Map an analytics equity curve to the finance EquityCurveChart point shape. */\nexport function toEquityPoints(curve: ReadonlyArray<EquitySample>): EquityPoint[] {\n return curve.map((p) => ({ time: p.time, value: p.equity }));\n}\n\n/**\n * Underwater drawdown curve as a percentage (<= 0). Each point is the equity's\n * shortfall from the running peak: `equity / peak - 1`, expressed in percent.\n */\nexport function computeDrawdownCurve(curve: ReadonlyArray<EquitySample>): EquityPoint[] {\n let peak = -Infinity;\n return curve.map((p) => {\n if (p.equity > peak) peak = p.equity;\n const dd = peak > 0 ? (p.equity / peak - 1) * 100 : 0;\n return { time: p.time, value: dd };\n });\n}\n\n/**\n * Calendar-month returns as heatmap cells. Each month's return is chained off\n * the prior month's closing equity (the first month chains off its own opening\n * equity), so the series reads as sequential monthly performance. `group` is\n * the year and `value` is the return in percent.\n */\nexport function computeMonthlyReturns(curve: ReadonlyArray<EquitySample>): HeatmapCell[] {\n if (curve.length === 0) return [];\n\n // Collapse the curve to one closing equity per calendar month, in order.\n const months: { key: number; close: number }[] = [];\n for (const p of curve) {\n const key = timeframeBucketStart(p.time, '1M');\n const last = months[months.length - 1];\n if (last && last.key === key) {\n last.close = p.equity;\n } else {\n months.push({ key, close: p.equity });\n }\n }\n\n let prevClose = curve[0].equity;\n const cells: HeatmapCell[] = [];\n for (const m of months) {\n const base = prevClose === 0 ? 1 : prevClose;\n const returnPct = (m.close / base - 1) * 100;\n prevClose = m.close;\n const d = new Date(m.key);\n const year = d.getUTCFullYear();\n const month = d.getUTCMonth();\n cells.push({\n id: `${year}-${String(month + 1).padStart(2, '0')}`,\n label: MONTH_LABELS[month],\n group: String(year),\n value: returnPct,\n });\n }\n return cells;\n}\n\nfunction pct(value: number): string {\n const sign = value > 0 ? '+' : '';\n return `${sign}${value.toFixed(2)}%`;\n}\n\nfunction tone(value: number): DashboardStat['tone'] {\n if (value > 0) return 'positive';\n if (value < 0) return 'negative';\n return 'neutral';\n}\n\n/** The headline stats rendered as cards above the charts. */\nexport function selectKeyStats(metrics: RiskMetricsLike): DashboardStat[] {\n return [\n { label: 'Total Return', value: pct(metrics.totalReturnPct), tone: tone(metrics.totalReturnPct) },\n { label: 'CAGR', value: pct(metrics.cagr * 100), tone: tone(metrics.cagr) },\n { label: 'Sharpe', value: metrics.sharpe.toFixed(2), tone: tone(metrics.sharpe) },\n { label: 'Sortino', value: metrics.sortino.toFixed(2), tone: tone(metrics.sortino) },\n { label: 'Max Drawdown', value: pct(metrics.maxDrawdownPct), tone: 'negative' },\n { label: 'Win Rate', value: `${(metrics.winRate * 100).toFixed(1)}%`, tone: 'neutral' },\n { label: 'Profit Factor', value: Number.isFinite(metrics.profitFactor) ? metrics.profitFactor.toFixed(2) : '∞', tone: tone(metrics.profitFactor - 1) },\n { label: 'Trades', value: String(metrics.trades), tone: 'neutral' },\n ];\n}\n","import type { Theme, ThemeName } from '@tradecanvas/commons';\nimport { DARK_THEME, LIGHT_THEME } from '@tradecanvas/commons';\nimport { EquityCurveChart } from './EquityCurveChart.js';\nimport { HeatmapChart } from './HeatmapChart.js';\nimport {\n toEquityPoints,\n computeDrawdownCurve,\n computeMonthlyReturns,\n selectKeyStats,\n type EquitySample,\n type RiskMetricsLike,\n type DashboardStat,\n} from './performanceData.js';\n\n/** Structurally satisfied by analytics' `BacktestResult`. */\nexport interface PerformanceResult {\n equityCurve: ReadonlyArray<EquitySample>;\n metrics: RiskMetricsLike;\n}\n\nexport interface PerformanceDashboardOptions {\n result: PerformanceResult;\n theme?: ThemeName | Theme;\n title?: string;\n subtitle?: string;\n}\n\nfunction resolveTheme(theme?: ThemeName | Theme): Theme {\n if (!theme || theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\n/**\n * A composed strategy-performance dashboard: a headline stats strip, an equity\n * curve, an underwater drawdown panel, and a monthly-returns heatmap. Built\n * entirely from a backtest `result`, reusing the finance chart renderers.\n *\n * ```ts\n * const result = new Backtester(opts).run(bars, strategy);\n * const dash = new PerformanceDashboard(el, { result, theme: 'dark' });\n * ```\n */\nexport class PerformanceDashboard {\n private options: PerformanceDashboardOptions;\n private theme: Theme;\n private root: HTMLDivElement;\n private equityChart: EquityCurveChart | null = null;\n private drawdownChart: EquityCurveChart | null = null;\n private heatmap: HeatmapChart | null = null;\n\n constructor(container: HTMLElement, options: PerformanceDashboardOptions) {\n this.options = options;\n this.theme = resolveTheme(options.theme);\n this.root = document.createElement('div');\n this.build();\n container.appendChild(this.root);\n }\n\n private build(): void {\n const t = this.theme;\n const { result, title, subtitle } = this.options;\n const surface = this.panelBackground();\n const border = t.grid;\n\n this.root.style.cssText = [\n 'display:flex',\n 'flex-direction:column',\n 'gap:14px',\n 'width:100%',\n 'box-sizing:border-box',\n 'padding:16px',\n `background:${t.background}`,\n `color:${t.text}`,\n `font-family:${t.font.family}`,\n ].join(';');\n\n if (title || subtitle) {\n const header = document.createElement('div');\n if (title) {\n const h = document.createElement('div');\n h.textContent = title;\n h.style.cssText = `font-size:${t.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`;\n header.appendChild(h);\n }\n if (subtitle) {\n const s = document.createElement('div');\n s.textContent = subtitle;\n s.style.cssText = `font-size:${t.font.sizeSmall}px;color:${t.textSecondary};margin-top:2px;`;\n header.appendChild(s);\n }\n this.root.appendChild(header);\n }\n\n // Stats strip\n this.root.appendChild(this.buildStatsStrip(selectKeyStats(result.metrics), surface, border));\n\n // Chart grid\n const grid = document.createElement('div');\n grid.style.cssText = [\n 'display:grid',\n 'grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))',\n 'grid-auto-rows:220px',\n 'gap:14px',\n ].join(';');\n this.root.appendChild(grid);\n\n const equityPanel = this.buildPanel('Equity Curve', surface, border);\n equityPanel.wrap.style.gridColumn = '1 / -1';\n grid.appendChild(equityPanel.wrap);\n this.equityChart = new EquityCurveChart(equityPanel.body, {\n data: toEquityPoints(result.equityCurve),\n theme: t,\n lineColor: t.candleUp,\n fillArea: true,\n crosshair: true,\n });\n\n const ddPanel = this.buildPanel('Drawdown', surface, border);\n grid.appendChild(ddPanel.wrap);\n this.drawdownChart = new EquityCurveChart(ddPanel.body, {\n data: computeDrawdownCurve(result.equityCurve),\n theme: t,\n lineColor: t.candleDown,\n fillArea: true,\n crosshair: true,\n valueFormat: (v) => `${v.toFixed(1)}%`,\n });\n\n const monthlyCells = computeMonthlyReturns(result.equityCurve);\n const heatPanel = this.buildPanel('Monthly Returns', surface, border);\n grid.appendChild(heatPanel.wrap);\n this.heatmap = new HeatmapChart(heatPanel.body, {\n data: monthlyCells,\n theme: t,\n showValues: true,\n valueFormat: (v) => `${v >= 0 ? '+' : ''}${v.toFixed(1)}`,\n colorScale: { negative: t.candleDown, zero: surface, positive: t.candleUp },\n });\n }\n\n private buildStatsStrip(stats: DashboardStat[], surface: string, border: string): HTMLDivElement {\n const strip = document.createElement('div');\n strip.style.cssText = [\n 'display:grid',\n 'grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))',\n 'gap:10px',\n ].join(';');\n\n const t = this.theme;\n for (const stat of stats) {\n const card = document.createElement('div');\n card.style.cssText = [\n `background:${surface}`,\n `border:1px solid ${border}`,\n 'border-radius:10px',\n 'padding:10px 12px',\n 'display:flex',\n 'flex-direction:column',\n 'gap:4px',\n ].join(';');\n\n const label = document.createElement('div');\n label.textContent = stat.label;\n label.style.cssText = `font-size:${t.font.sizeSmall}px;color:${t.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;\n\n const value = document.createElement('div');\n value.textContent = stat.value;\n const color = stat.tone === 'positive' ? t.candleUp : stat.tone === 'negative' ? t.candleDown : t.text;\n value.style.cssText = `font-size:${t.font.sizeLarge}px;font-weight:600;color:${color};font-variant-numeric:tabular-nums;`;\n\n card.appendChild(label);\n card.appendChild(value);\n strip.appendChild(card);\n }\n return strip;\n }\n\n private buildPanel(title: string, surface: string, border: string): { wrap: HTMLDivElement; body: HTMLDivElement } {\n const t = this.theme;\n const wrap = document.createElement('div');\n wrap.style.cssText = [\n `background:${surface}`,\n `border:1px solid ${border}`,\n 'border-radius:10px',\n 'overflow:hidden',\n 'display:flex',\n 'flex-direction:column',\n ].join(';');\n\n const head = document.createElement('div');\n head.textContent = title;\n head.style.cssText = [\n `font-size:${t.font.sizeSmall}px`,\n 'font-weight:600',\n `color:${t.textSecondary}`,\n 'padding:8px 12px',\n `border-bottom:1px solid ${border}`,\n 'text-transform:uppercase',\n 'letter-spacing:0.04em',\n ].join(';');\n\n const body = document.createElement('div');\n body.style.cssText = 'flex:1;min-height:0;position:relative;';\n\n wrap.appendChild(head);\n wrap.appendChild(body);\n return { wrap, body };\n }\n\n /** A subtle surface tint distinct from the page background, per theme. */\n private panelBackground(): string {\n return this.theme.name === 'light' ? 'rgba(0,0,0,0.02)' : 'rgba(255,255,255,0.03)';\n }\n\n /** Replace the displayed result and re-render all panels. */\n update(result: PerformanceResult): void {\n this.options = { ...this.options, result };\n this.destroyCharts();\n this.root.replaceChildren();\n this.build();\n }\n\n setTheme(theme: ThemeName | Theme): void {\n this.theme = resolveTheme(theme);\n this.options = { ...this.options, theme };\n this.destroyCharts();\n this.root.replaceChildren();\n this.build();\n }\n\n private destroyCharts(): void {\n this.equityChart?.destroy();\n this.drawdownChart?.destroy();\n this.heatmap?.destroy();\n this.equityChart = null;\n this.drawdownChart = null;\n this.heatmap = null;\n }\n\n destroy(): void {\n this.destroyCharts();\n this.root.remove();\n }\n}\n"],"mappings":"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"} |
+3
-1
@@ -29,4 +29,6 @@ export { Chart } from './Chart.js'; | ||
| export type { GridLayout, GridCellConfig, ChartGridOptions } from './grid/ChartGrid.js'; | ||
| export { SparklineChart, DepthChart, EquityCurveChart, HeatmapChart, WaterfallChart, GaugeChart } from './finance/index.js'; | ||
| export { SparklineChart, DepthChart, EquityCurveChart, HeatmapChart, WaterfallChart, GaugeChart, PerformanceDashboard } from './finance/index.js'; | ||
| export { toEquityPoints, computeDrawdownCurve, computeMonthlyReturns, selectKeyStats, } from './finance/index.js'; | ||
| export type { PerformanceDashboardOptions, PerformanceResult, EquitySample, RiskMetricsLike, DashboardStat, } from './finance/index.js'; | ||
| export type { BaseFinanceChartOptions, SparklineOptions, DepthChartOptions, EquityPoint, EquityCurveOptions, HeatmapCell, HeatmapOptions, WaterfallBar, WaterfallOptions, GaugeZone, GaugeOptions, } from '@tradecanvas/commons'; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} |
+287
-30
@@ -1,6 +0,6 @@ | ||
| import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./DragDropImporter-6QOjnfSj.js"; | ||
| import { DARK_TERMINAL as s, DARK_THEME as ee, DEFAULT_DRAWING_STYLE as te, DEFAULT_RECONNECT as c, DEFAULT_SIGNAL_STYLE as l, DEFAULT_STREAM_CONFIG as u, DEFAULT_TIMEFRAME_FAVORITES as d, DEFAULT_TRADE_ZONE_STYLE as f, DEFAULT_TRADING_CONFIG as p, LIGHT_THEME as m, MARKET_CRYPTO as h, MARKET_HNX as g, MARKET_HOSE as _, MARKET_NYSE as v, MARKET_UPCOM as y, TIMEFRAMES_CRYPTO as b, TIMEFRAMES_FOREX as x, TIMEFRAMES_STOCK as S, VN_COLORS as C, computePriceLimits as w, createVNTheme as T, formatNumber as E, formatVND as D, formatVolumeLoc as O, getCurrentSession as k, getLocale as A, normalizeBar as j, normalizeBarTime as M, registerLocale as N, setLocale as P, t as F } from "@tradecanvas/commons"; | ||
| import { AlertManager as I, Animator as L, BarCountdown as R, BaseFinanceChart as z, BinanceAdapter as B, ChartLegend as V, ChartStateManager as H, CompareRenderer as U, CrosshairTooltip as W, CurrentPriceLine as G, DEFAULT_LEGEND_CONFIG as K, DataExporter as q, DrawingBase as J, Easing as Y, FinanceCrosshair as X, IndicatorBase as Z, KeyboardHandler as ne, MockAdapter as re, ReplayManager as ie, Screenshot as ae, SessionBreaks as oe, SignalMarkerManager as se, StreamManager as ce, TickAggregator as le, TradeZoneManager as ue, UndoRedoManager as de, VolumeRenderer as fe, Watermark as pe, layoutSquarifiedTreemap as me, layoutUniformGrid as he, renderDepthChart as ge, renderEquityCurve as _e, renderGauge as ve, renderHeatmap as ye, renderSparkline as be, renderWaterfall as xe, toHeikinAshi as Se, toKagi as Ce, toLineBreak as we, toPointAndFigure as Te, toRangeBars as Ee, toRenko as De } from "@tradecanvas/core"; | ||
| import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./DragDropImporter-Br2ez5Gz.js"; | ||
| import { DARK_TERMINAL as s, DARK_THEME as c, DARK_THEME as l, DEFAULT_DRAWING_STYLE as u, DEFAULT_RECONNECT as d, DEFAULT_SIGNAL_STYLE as ee, DEFAULT_STREAM_CONFIG as te, DEFAULT_TIMEFRAME_FAVORITES as ne, DEFAULT_TRADE_ZONE_STYLE as re, DEFAULT_TRADING_CONFIG as ie, LIGHT_THEME as ae, LIGHT_THEME as oe, MARKET_CRYPTO as se, MARKET_HNX as ce, MARKET_HOSE as le, MARKET_NYSE as ue, MARKET_UPCOM as de, TIMEFRAMES_CRYPTO as fe, TIMEFRAMES_FOREX as f, TIMEFRAMES_STOCK as p, VN_COLORS as m, computePriceLimits as h, createVNTheme as g, formatNumber as _, formatVND as v, formatVolumeLoc as y, getCurrentSession as b, getLocale as x, normalizeBar as S, normalizeBarTime as C, registerLocale as w, setLocale as T, t as E, timeframeBucketStart as D } from "@tradecanvas/commons"; | ||
| import { AlertManager as O, Animator as k, BarCountdown as A, BaseFinanceChart as j, BinanceAdapter as M, ChartLegend as N, ChartStateManager as P, CompareRenderer as F, CrosshairTooltip as I, CurrentPriceLine as L, DEFAULT_LEGEND_CONFIG as R, DataExporter as z, DrawingBase as B, Easing as V, FinanceCrosshair as H, IndicatorBase as pe, KeyboardHandler as me, MockAdapter as he, ReplayManager as ge, Screenshot as _e, SessionBreaks as ve, SignalMarkerManager as ye, StreamManager as be, TickAggregator as xe, TradeZoneManager as Se, UndoRedoManager as Ce, VolumeRenderer as we, Watermark as Te, layoutSquarifiedTreemap as Ee, layoutUniformGrid as De, renderDepthChart as Oe, renderEquityCurve as ke, renderGauge as Ae, renderHeatmap as je, renderSparkline as Me, renderWaterfall as Ne, toHeikinAshi as Pe, toKagi as Fe, toLineBreak as Ie, toPointAndFigure as Le, toRangeBars as Re, toRenko as ze } from "@tradecanvas/core"; | ||
| //#region src/grid/ChartGrid.ts | ||
| var Q = { | ||
| var U = { | ||
| "1x1": { | ||
@@ -38,3 +38,3 @@ cols: 1, | ||
| } | ||
| }, $ = class { | ||
| }, Be = class { | ||
| root; | ||
@@ -50,7 +50,7 @@ cells = []; | ||
| applyLayout() { | ||
| let { cols: e, rows: t } = Q[this.layout], n = this.options.gap ?? 1; | ||
| let { cols: e, rows: t } = U[this.layout], n = this.options.gap ?? 1; | ||
| this.root.style.gridTemplateColumns = `repeat(${e}, 1fr)`, this.root.style.gridTemplateRows = `repeat(${t}, 1fr)`, this.root.style.gap = `${n}px`; | ||
| } | ||
| createCells() { | ||
| let { cols: e, rows: t } = Q[this.layout], n = e * t; | ||
| let { cols: e, rows: t } = U[this.layout], n = e * t; | ||
| for (let e = 0; e < n; e++) { | ||
@@ -100,3 +100,3 @@ let t = this.options.cells?.[e] ?? {}, n = document.createElement("div"); | ||
| if (e === this.layout) return; | ||
| let t = this.cells.length, { cols: n, rows: r } = Q[e], a = n * r; | ||
| let t = this.cells.length, { cols: n, rows: r } = U[e], a = n * r; | ||
| if (a < t) for (let e = t - 1; e >= a; e--) { | ||
@@ -163,3 +163,3 @@ let t = this.cells[e]; | ||
| } | ||
| }, Oe = class extends z { | ||
| }, Ve = class extends j { | ||
| options; | ||
@@ -170,3 +170,3 @@ constructor(e, t) { | ||
| renderChart(e, t, n, r) { | ||
| be(e, t, n, this.options, r); | ||
| Me(e, t, n, this.options, r); | ||
| } | ||
@@ -185,11 +185,11 @@ update(e) { | ||
| } | ||
| }, ke = class extends z { | ||
| }, He = class extends j { | ||
| options; | ||
| crosshair = null; | ||
| constructor(e, t) { | ||
| super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new X(this.canvas, () => this.requestRender())), this.requestRender(); | ||
| super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new H(this.canvas, () => this.requestRender())), this.requestRender(); | ||
| } | ||
| renderChart(e, t, n, r) { | ||
| let i = this.crosshair?.getPosition() ?? null; | ||
| ge(e, t, n, this.options, r, i); | ||
| Oe(e, t, n, this.options, r, i); | ||
| } | ||
@@ -211,11 +211,11 @@ update(e) { | ||
| } | ||
| }, Ae = class extends z { | ||
| }, W = class extends j { | ||
| options; | ||
| crosshair = null; | ||
| constructor(e, t) { | ||
| super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new X(this.canvas, () => this.requestRender())), this.requestRender(); | ||
| super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new H(this.canvas, () => this.requestRender())), this.requestRender(); | ||
| } | ||
| renderChart(e, t, n, r) { | ||
| let i = this.crosshair?.getPosition() ?? null; | ||
| _e(e, t, n, this.options, r, i); | ||
| ke(e, t, n, this.options, r, i); | ||
| } | ||
@@ -240,3 +240,3 @@ update(e, t) { | ||
| } | ||
| }, je = class extends z { | ||
| }, G = class extends j { | ||
| options; | ||
@@ -250,3 +250,3 @@ crosshair = null; | ||
| constructor(e, t) { | ||
| super(e, t.theme), this.options = t, this.currentData = t.data ?? [], t.crosshair !== !1 && (this.crosshair = new X(this.canvas, () => this.requestRender())), t.onCellClick && (this.handleClick = (e) => { | ||
| super(e, t.theme), this.options = t, this.currentData = t.data ?? [], t.crosshair !== !1 && (this.crosshair = new H(this.canvas, () => this.requestRender())), t.onCellClick && (this.handleClick = (e) => { | ||
| let t = this.canvas.getBoundingClientRect(), n = e.clientX - t.left, r = e.clientY - t.top; | ||
@@ -268,4 +268,4 @@ this.onCanvasClick(n, r); | ||
| })); | ||
| this.cachedRects = me(n, e, t); | ||
| } else this.cachedRects = he(this.currentData.map((e) => ({ id: e.id })), e, t); | ||
| this.cachedRects = Ee(n, e, t); | ||
| } else this.cachedRects = De(this.currentData.map((e) => ({ id: e.id })), e, t); | ||
| } | ||
@@ -285,3 +285,3 @@ onCanvasClick(e, t) { | ||
| let i = this.crosshair?.getPosition() ?? null; | ||
| ye(e, t, n, this.currentData, this.cachedRects, this.options, r, i); | ||
| je(e, t, n, this.currentData, this.cachedRects, this.options, r, i); | ||
| } | ||
@@ -303,11 +303,11 @@ update(e) { | ||
| } | ||
| }, Me = class extends z { | ||
| }, Ue = class extends j { | ||
| options; | ||
| crosshair = null; | ||
| constructor(e, t) { | ||
| super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new X(this.canvas, () => this.requestRender())), this.requestRender(); | ||
| super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new H(this.canvas, () => this.requestRender())), this.requestRender(); | ||
| } | ||
| renderChart(e, t, n, r) { | ||
| let i = this.crosshair?.getPosition() ?? null; | ||
| xe(e, t, n, this.options, r, i); | ||
| Ne(e, t, n, this.options, r, i); | ||
| } | ||
@@ -329,8 +329,8 @@ update(e) { | ||
| } | ||
| }, Ne = 500; | ||
| function Pe(e) { | ||
| }, We = 500; | ||
| function K(e) { | ||
| let t = 1 - e; | ||
| return 1 - t * t * t; | ||
| } | ||
| var Fe = class extends z { | ||
| var Ge = class extends j { | ||
| options; | ||
@@ -346,3 +346,3 @@ currentValue; | ||
| renderChart(e, t, n, r) { | ||
| ve(e, t, n, this.options, r, this.currentValue); | ||
| Ae(e, t, n, this.options, r, this.currentValue); | ||
| } | ||
@@ -377,3 +377,3 @@ setValue(e) { | ||
| if (this.animationFrameId = null, this.animationStart === null) return; | ||
| let t = this.options.animationDuration ?? Ne, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = Pe(r); | ||
| let t = this.options.animationDuration ?? We, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = K(r); | ||
| this.currentValue = this.animationFrom + (this.targetValue - this.animationFrom) * i, this.requestRender(), r < 1 ? this.animationFrameId = requestAnimationFrame(e) : (this.currentValue = this.targetValue, this.animationStart = null); | ||
@@ -389,6 +389,263 @@ }; | ||
| } | ||
| }, Ke = [ | ||
| "Jan", | ||
| "Feb", | ||
| "Mar", | ||
| "Apr", | ||
| "May", | ||
| "Jun", | ||
| "Jul", | ||
| "Aug", | ||
| "Sep", | ||
| "Oct", | ||
| "Nov", | ||
| "Dec" | ||
| ]; | ||
| function q(e) { | ||
| return e.map((e) => ({ | ||
| time: e.time, | ||
| value: e.equity | ||
| })); | ||
| } | ||
| function J(e) { | ||
| let t = -Infinity; | ||
| return e.map((e) => { | ||
| e.equity > t && (t = e.equity); | ||
| let n = t > 0 ? (e.equity / t - 1) * 100 : 0; | ||
| return { | ||
| time: e.time, | ||
| value: n | ||
| }; | ||
| }); | ||
| } | ||
| function Y(e) { | ||
| if (e.length === 0) return []; | ||
| let t = []; | ||
| for (let n of e) { | ||
| let e = D(n.time, "1M"), r = t[t.length - 1]; | ||
| r && r.key === e ? r.close = n.equity : t.push({ | ||
| key: e, | ||
| close: n.equity | ||
| }); | ||
| } | ||
| let n = e[0].equity, r = []; | ||
| for (let e of t) { | ||
| let t = n === 0 ? 1 : n, i = (e.close / t - 1) * 100; | ||
| n = e.close; | ||
| let a = new Date(e.key), o = a.getUTCFullYear(), s = a.getUTCMonth(); | ||
| r.push({ | ||
| id: `${o}-${String(s + 1).padStart(2, "0")}`, | ||
| label: Ke[s], | ||
| group: String(o), | ||
| value: i | ||
| }); | ||
| } | ||
| return r; | ||
| } | ||
| function X(e) { | ||
| return `${e > 0 ? "+" : ""}${e.toFixed(2)}%`; | ||
| } | ||
| function Z(e) { | ||
| return e > 0 ? "positive" : e < 0 ? "negative" : "neutral"; | ||
| } | ||
| function Q(e) { | ||
| return [ | ||
| { | ||
| label: "Total Return", | ||
| value: X(e.totalReturnPct), | ||
| tone: Z(e.totalReturnPct) | ||
| }, | ||
| { | ||
| label: "CAGR", | ||
| value: X(e.cagr * 100), | ||
| tone: Z(e.cagr) | ||
| }, | ||
| { | ||
| label: "Sharpe", | ||
| value: e.sharpe.toFixed(2), | ||
| tone: Z(e.sharpe) | ||
| }, | ||
| { | ||
| label: "Sortino", | ||
| value: e.sortino.toFixed(2), | ||
| tone: Z(e.sortino) | ||
| }, | ||
| { | ||
| label: "Max Drawdown", | ||
| value: X(e.maxDrawdownPct), | ||
| tone: "negative" | ||
| }, | ||
| { | ||
| label: "Win Rate", | ||
| value: `${(e.winRate * 100).toFixed(1)}%`, | ||
| tone: "neutral" | ||
| }, | ||
| { | ||
| label: "Profit Factor", | ||
| value: Number.isFinite(e.profitFactor) ? e.profitFactor.toFixed(2) : "∞", | ||
| tone: Z(e.profitFactor - 1) | ||
| }, | ||
| { | ||
| label: "Trades", | ||
| value: String(e.trades), | ||
| tone: "neutral" | ||
| } | ||
| ]; | ||
| } | ||
| //#endregion | ||
| //#region src/finance/PerformanceDashboard.ts | ||
| function $(e) { | ||
| return !e || e === "dark" ? l : e === "light" ? oe : e; | ||
| } | ||
| var qe = class { | ||
| options; | ||
| theme; | ||
| root; | ||
| equityChart = null; | ||
| drawdownChart = null; | ||
| heatmap = null; | ||
| constructor(e, t) { | ||
| this.options = t, this.theme = $(t.theme), this.root = document.createElement("div"), this.build(), e.appendChild(this.root); | ||
| } | ||
| build() { | ||
| let e = this.theme, { result: t, title: n, subtitle: r } = this.options, i = this.panelBackground(), a = e.grid; | ||
| if (this.root.style.cssText = [ | ||
| "display:flex", | ||
| "flex-direction:column", | ||
| "gap:14px", | ||
| "width:100%", | ||
| "box-sizing:border-box", | ||
| "padding:16px", | ||
| `background:${e.background}`, | ||
| `color:${e.text}`, | ||
| `font-family:${e.font.family}` | ||
| ].join(";"), n || r) { | ||
| let t = document.createElement("div"); | ||
| if (n) { | ||
| let r = document.createElement("div"); | ||
| r.textContent = n, r.style.cssText = `font-size:${e.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`, t.appendChild(r); | ||
| } | ||
| if (r) { | ||
| let n = document.createElement("div"); | ||
| n.textContent = r, n.style.cssText = `font-size:${e.font.sizeSmall}px;color:${e.textSecondary};margin-top:2px;`, t.appendChild(n); | ||
| } | ||
| this.root.appendChild(t); | ||
| } | ||
| this.root.appendChild(this.buildStatsStrip(Q(t.metrics), i, a)); | ||
| let o = document.createElement("div"); | ||
| o.style.cssText = [ | ||
| "display:grid", | ||
| "grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))", | ||
| "grid-auto-rows:220px", | ||
| "gap:14px" | ||
| ].join(";"), this.root.appendChild(o); | ||
| let s = this.buildPanel("Equity Curve", i, a); | ||
| s.wrap.style.gridColumn = "1 / -1", o.appendChild(s.wrap), this.equityChart = new W(s.body, { | ||
| data: q(t.equityCurve), | ||
| theme: e, | ||
| lineColor: e.candleUp, | ||
| fillArea: !0, | ||
| crosshair: !0 | ||
| }); | ||
| let c = this.buildPanel("Drawdown", i, a); | ||
| o.appendChild(c.wrap), this.drawdownChart = new W(c.body, { | ||
| data: J(t.equityCurve), | ||
| theme: e, | ||
| lineColor: e.candleDown, | ||
| fillArea: !0, | ||
| crosshair: !0, | ||
| valueFormat: (e) => `${e.toFixed(1)}%` | ||
| }); | ||
| let l = Y(t.equityCurve), u = this.buildPanel("Monthly Returns", i, a); | ||
| o.appendChild(u.wrap), this.heatmap = new G(u.body, { | ||
| data: l, | ||
| theme: e, | ||
| showValues: !0, | ||
| valueFormat: (e) => `${e >= 0 ? "+" : ""}${e.toFixed(1)}`, | ||
| colorScale: { | ||
| negative: e.candleDown, | ||
| zero: i, | ||
| positive: e.candleUp | ||
| } | ||
| }); | ||
| } | ||
| buildStatsStrip(e, t, n) { | ||
| let r = document.createElement("div"); | ||
| r.style.cssText = [ | ||
| "display:grid", | ||
| "grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))", | ||
| "gap:10px" | ||
| ].join(";"); | ||
| let i = this.theme; | ||
| for (let a of e) { | ||
| let e = document.createElement("div"); | ||
| e.style.cssText = [ | ||
| `background:${t}`, | ||
| `border:1px solid ${n}`, | ||
| "border-radius:10px", | ||
| "padding:10px 12px", | ||
| "display:flex", | ||
| "flex-direction:column", | ||
| "gap:4px" | ||
| ].join(";"); | ||
| let o = document.createElement("div"); | ||
| o.textContent = a.label, o.style.cssText = `font-size:${i.font.sizeSmall}px;color:${i.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`; | ||
| let s = document.createElement("div"); | ||
| s.textContent = a.value; | ||
| let c = a.tone === "positive" ? i.candleUp : a.tone === "negative" ? i.candleDown : i.text; | ||
| s.style.cssText = `font-size:${i.font.sizeLarge}px;font-weight:600;color:${c};font-variant-numeric:tabular-nums;`, e.appendChild(o), e.appendChild(s), r.appendChild(e); | ||
| } | ||
| return r; | ||
| } | ||
| buildPanel(e, t, n) { | ||
| let r = this.theme, i = document.createElement("div"); | ||
| i.style.cssText = [ | ||
| `background:${t}`, | ||
| `border:1px solid ${n}`, | ||
| "border-radius:10px", | ||
| "overflow:hidden", | ||
| "display:flex", | ||
| "flex-direction:column" | ||
| ].join(";"); | ||
| let a = document.createElement("div"); | ||
| a.textContent = e, a.style.cssText = [ | ||
| `font-size:${r.font.sizeSmall}px`, | ||
| "font-weight:600", | ||
| `color:${r.textSecondary}`, | ||
| "padding:8px 12px", | ||
| `border-bottom:1px solid ${n}`, | ||
| "text-transform:uppercase", | ||
| "letter-spacing:0.04em" | ||
| ].join(";"); | ||
| let o = document.createElement("div"); | ||
| return o.style.cssText = "flex:1;min-height:0;position:relative;", i.appendChild(a), i.appendChild(o), { | ||
| wrap: i, | ||
| body: o | ||
| }; | ||
| } | ||
| panelBackground() { | ||
| return this.theme.name === "light" ? "rgba(0,0,0,0.02)" : "rgba(255,255,255,0.03)"; | ||
| } | ||
| update(e) { | ||
| this.options = { | ||
| ...this.options, | ||
| result: e | ||
| }, this.destroyCharts(), this.root.replaceChildren(), this.build(); | ||
| } | ||
| setTheme(e) { | ||
| this.theme = $(e), this.options = { | ||
| ...this.options, | ||
| theme: e | ||
| }, this.destroyCharts(), this.root.replaceChildren(), this.build(); | ||
| } | ||
| destroyCharts() { | ||
| this.equityChart?.destroy(), this.drawdownChart?.destroy(), this.heatmap?.destroy(), this.equityChart = null, this.drawdownChart = null, this.heatmap = null; | ||
| } | ||
| destroy() { | ||
| this.destroyCharts(), this.root.remove(); | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { I as AlertManager, L as Animator, R as BarCountdown, B as BinanceAdapter, i as Chart, $ as ChartGrid, V as ChartLegend, H as ChartStateManager, U as CompareRenderer, W as CrosshairTooltip, G as CurrentPriceLine, s as DARK_TERMINAL, ee as DARK_THEME, te as DEFAULT_DRAWING_STYLE, K as DEFAULT_LEGEND_CONFIG, c as DEFAULT_RECONNECT, l as DEFAULT_SIGNAL_STYLE, u as DEFAULT_STREAM_CONFIG, d as DEFAULT_TIMEFRAME_FAVORITES, f as DEFAULT_TRADE_ZONE_STYLE, p as DEFAULT_TRADING_CONFIG, q as DataExporter, a as DataManager, ke as DepthChart, o as DragDropImporter, J as DrawingBase, Y as Easing, Ae as EquityCurveChart, Fe as GaugeChart, je as HeatmapChart, Z as IndicatorBase, ne as KeyboardHandler, m as LIGHT_THEME, e as LayoutManager, h as MARKET_CRYPTO, g as MARKET_HNX, _ as MARKET_HOSE, v as MARKET_NYSE, y as MARKET_UPCOM, re as MockAdapter, t as PluginManager, ie as ReplayManager, ae as Screenshot, oe as SessionBreaks, se as SignalMarkerManager, Oe as SparklineChart, ce as StreamManager, b as TIMEFRAMES_CRYPTO, x as TIMEFRAMES_FOREX, S as TIMEFRAMES_STOCK, r as ThemeManager, le as TickAggregator, ue as TradeZoneManager, de as UndoRedoManager, C as VN_COLORS, fe as VolumeRenderer, Me as WaterfallChart, pe as Watermark, w as computePriceLimits, T as createVNTheme, E as formatNumber, D as formatVND, O as formatVolumeLoc, k as getCurrentSession, A as getLocale, j as normalizeBar, M as normalizeBarTime, n as parseOHLCV, N as registerLocale, P as setLocale, F as t, Se as toHeikinAshi, Ce as toKagi, we as toLineBreak, Te as toPointAndFigure, Ee as toRangeBars, De as toRenko }; | ||
| export { O as AlertManager, k as Animator, A as BarCountdown, M as BinanceAdapter, i as Chart, Be as ChartGrid, N as ChartLegend, P as ChartStateManager, F as CompareRenderer, I as CrosshairTooltip, L as CurrentPriceLine, s as DARK_TERMINAL, c as DARK_THEME, u as DEFAULT_DRAWING_STYLE, R as DEFAULT_LEGEND_CONFIG, d as DEFAULT_RECONNECT, ee as DEFAULT_SIGNAL_STYLE, te as DEFAULT_STREAM_CONFIG, ne as DEFAULT_TIMEFRAME_FAVORITES, re as DEFAULT_TRADE_ZONE_STYLE, ie as DEFAULT_TRADING_CONFIG, z as DataExporter, a as DataManager, He as DepthChart, o as DragDropImporter, B as DrawingBase, V as Easing, W as EquityCurveChart, Ge as GaugeChart, G as HeatmapChart, pe as IndicatorBase, me as KeyboardHandler, ae as LIGHT_THEME, e as LayoutManager, se as MARKET_CRYPTO, ce as MARKET_HNX, le as MARKET_HOSE, ue as MARKET_NYSE, de as MARKET_UPCOM, he as MockAdapter, qe as PerformanceDashboard, t as PluginManager, ge as ReplayManager, _e as Screenshot, ve as SessionBreaks, ye as SignalMarkerManager, Ve as SparklineChart, be as StreamManager, fe as TIMEFRAMES_CRYPTO, f as TIMEFRAMES_FOREX, p as TIMEFRAMES_STOCK, r as ThemeManager, xe as TickAggregator, Se as TradeZoneManager, Ce as UndoRedoManager, m as VN_COLORS, we as VolumeRenderer, Ue as WaterfallChart, Te as Watermark, J as computeDrawdownCurve, Y as computeMonthlyReturns, h as computePriceLimits, g as createVNTheme, _ as formatNumber, v as formatVND, y as formatVolumeLoc, b as getCurrentSession, x as getLocale, S as normalizeBar, C as normalizeBarTime, n as parseOHLCV, w as registerLocale, Q as selectKeyStats, T as setLocale, E as t, q as toEquityPoints, Pe as toHeikinAshi, Fe as toKagi, Ie as toLineBreak, Le as toPointAndFigure, Re as toRangeBars, ze as toRenko }; | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,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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"} | ||
| {"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","../src/finance/performanceData.ts","../src/finance/PerformanceDashboard.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","import type { EquityPoint, HeatmapCell } from '@tradecanvas/commons';\nimport { timeframeBucketStart } from '@tradecanvas/commons';\n\n/** Minimal equity sample shape — structurally satisfied by analytics' EquityPoint. */\nexport interface EquitySample {\n time: number;\n equity: number;\n}\n\n/** Subset of analytics RiskMetrics needed to render the stats strip. */\nexport interface RiskMetricsLike {\n totalReturnPct: number;\n cagr: number;\n sharpe: number;\n sortino: number;\n maxDrawdownPct: number;\n winRate: number;\n profitFactor: number;\n trades: number;\n}\n\nexport interface DashboardStat {\n label: string;\n value: string;\n tone: 'positive' | 'negative' | 'neutral';\n}\n\nconst MONTH_LABELS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\n/** Map an analytics equity curve to the finance EquityCurveChart point shape. */\nexport function toEquityPoints(curve: ReadonlyArray<EquitySample>): EquityPoint[] {\n return curve.map((p) => ({ time: p.time, value: p.equity }));\n}\n\n/**\n * Underwater drawdown curve as a percentage (<= 0). Each point is the equity's\n * shortfall from the running peak: `equity / peak - 1`, expressed in percent.\n */\nexport function computeDrawdownCurve(curve: ReadonlyArray<EquitySample>): EquityPoint[] {\n let peak = -Infinity;\n return curve.map((p) => {\n if (p.equity > peak) peak = p.equity;\n const dd = peak > 0 ? (p.equity / peak - 1) * 100 : 0;\n return { time: p.time, value: dd };\n });\n}\n\n/**\n * Calendar-month returns as heatmap cells. Each month's return is chained off\n * the prior month's closing equity (the first month chains off its own opening\n * equity), so the series reads as sequential monthly performance. `group` is\n * the year and `value` is the return in percent.\n */\nexport function computeMonthlyReturns(curve: ReadonlyArray<EquitySample>): HeatmapCell[] {\n if (curve.length === 0) return [];\n\n // Collapse the curve to one closing equity per calendar month, in order.\n const months: { key: number; close: number }[] = [];\n for (const p of curve) {\n const key = timeframeBucketStart(p.time, '1M');\n const last = months[months.length - 1];\n if (last && last.key === key) {\n last.close = p.equity;\n } else {\n months.push({ key, close: p.equity });\n }\n }\n\n let prevClose = curve[0].equity;\n const cells: HeatmapCell[] = [];\n for (const m of months) {\n const base = prevClose === 0 ? 1 : prevClose;\n const returnPct = (m.close / base - 1) * 100;\n prevClose = m.close;\n const d = new Date(m.key);\n const year = d.getUTCFullYear();\n const month = d.getUTCMonth();\n cells.push({\n id: `${year}-${String(month + 1).padStart(2, '0')}`,\n label: MONTH_LABELS[month],\n group: String(year),\n value: returnPct,\n });\n }\n return cells;\n}\n\nfunction pct(value: number): string {\n const sign = value > 0 ? '+' : '';\n return `${sign}${value.toFixed(2)}%`;\n}\n\nfunction tone(value: number): DashboardStat['tone'] {\n if (value > 0) return 'positive';\n if (value < 0) return 'negative';\n return 'neutral';\n}\n\n/** The headline stats rendered as cards above the charts. */\nexport function selectKeyStats(metrics: RiskMetricsLike): DashboardStat[] {\n return [\n { label: 'Total Return', value: pct(metrics.totalReturnPct), tone: tone(metrics.totalReturnPct) },\n { label: 'CAGR', value: pct(metrics.cagr * 100), tone: tone(metrics.cagr) },\n { label: 'Sharpe', value: metrics.sharpe.toFixed(2), tone: tone(metrics.sharpe) },\n { label: 'Sortino', value: metrics.sortino.toFixed(2), tone: tone(metrics.sortino) },\n { label: 'Max Drawdown', value: pct(metrics.maxDrawdownPct), tone: 'negative' },\n { label: 'Win Rate', value: `${(metrics.winRate * 100).toFixed(1)}%`, tone: 'neutral' },\n { label: 'Profit Factor', value: Number.isFinite(metrics.profitFactor) ? metrics.profitFactor.toFixed(2) : '∞', tone: tone(metrics.profitFactor - 1) },\n { label: 'Trades', value: String(metrics.trades), tone: 'neutral' },\n ];\n}\n","import type { Theme, ThemeName } from '@tradecanvas/commons';\nimport { DARK_THEME, LIGHT_THEME } from '@tradecanvas/commons';\nimport { EquityCurveChart } from './EquityCurveChart.js';\nimport { HeatmapChart } from './HeatmapChart.js';\nimport {\n toEquityPoints,\n computeDrawdownCurve,\n computeMonthlyReturns,\n selectKeyStats,\n type EquitySample,\n type RiskMetricsLike,\n type DashboardStat,\n} from './performanceData.js';\n\n/** Structurally satisfied by analytics' `BacktestResult`. */\nexport interface PerformanceResult {\n equityCurve: ReadonlyArray<EquitySample>;\n metrics: RiskMetricsLike;\n}\n\nexport interface PerformanceDashboardOptions {\n result: PerformanceResult;\n theme?: ThemeName | Theme;\n title?: string;\n subtitle?: string;\n}\n\nfunction resolveTheme(theme?: ThemeName | Theme): Theme {\n if (!theme || theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\n/**\n * A composed strategy-performance dashboard: a headline stats strip, an equity\n * curve, an underwater drawdown panel, and a monthly-returns heatmap. Built\n * entirely from a backtest `result`, reusing the finance chart renderers.\n *\n * ```ts\n * const result = new Backtester(opts).run(bars, strategy);\n * const dash = new PerformanceDashboard(el, { result, theme: 'dark' });\n * ```\n */\nexport class PerformanceDashboard {\n private options: PerformanceDashboardOptions;\n private theme: Theme;\n private root: HTMLDivElement;\n private equityChart: EquityCurveChart | null = null;\n private drawdownChart: EquityCurveChart | null = null;\n private heatmap: HeatmapChart | null = null;\n\n constructor(container: HTMLElement, options: PerformanceDashboardOptions) {\n this.options = options;\n this.theme = resolveTheme(options.theme);\n this.root = document.createElement('div');\n this.build();\n container.appendChild(this.root);\n }\n\n private build(): void {\n const t = this.theme;\n const { result, title, subtitle } = this.options;\n const surface = this.panelBackground();\n const border = t.grid;\n\n this.root.style.cssText = [\n 'display:flex',\n 'flex-direction:column',\n 'gap:14px',\n 'width:100%',\n 'box-sizing:border-box',\n 'padding:16px',\n `background:${t.background}`,\n `color:${t.text}`,\n `font-family:${t.font.family}`,\n ].join(';');\n\n if (title || subtitle) {\n const header = document.createElement('div');\n if (title) {\n const h = document.createElement('div');\n h.textContent = title;\n h.style.cssText = `font-size:${t.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`;\n header.appendChild(h);\n }\n if (subtitle) {\n const s = document.createElement('div');\n s.textContent = subtitle;\n s.style.cssText = `font-size:${t.font.sizeSmall}px;color:${t.textSecondary};margin-top:2px;`;\n header.appendChild(s);\n }\n this.root.appendChild(header);\n }\n\n // Stats strip\n this.root.appendChild(this.buildStatsStrip(selectKeyStats(result.metrics), surface, border));\n\n // Chart grid\n const grid = document.createElement('div');\n grid.style.cssText = [\n 'display:grid',\n 'grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))',\n 'grid-auto-rows:220px',\n 'gap:14px',\n ].join(';');\n this.root.appendChild(grid);\n\n const equityPanel = this.buildPanel('Equity Curve', surface, border);\n equityPanel.wrap.style.gridColumn = '1 / -1';\n grid.appendChild(equityPanel.wrap);\n this.equityChart = new EquityCurveChart(equityPanel.body, {\n data: toEquityPoints(result.equityCurve),\n theme: t,\n lineColor: t.candleUp,\n fillArea: true,\n crosshair: true,\n });\n\n const ddPanel = this.buildPanel('Drawdown', surface, border);\n grid.appendChild(ddPanel.wrap);\n this.drawdownChart = new EquityCurveChart(ddPanel.body, {\n data: computeDrawdownCurve(result.equityCurve),\n theme: t,\n lineColor: t.candleDown,\n fillArea: true,\n crosshair: true,\n valueFormat: (v) => `${v.toFixed(1)}%`,\n });\n\n const monthlyCells = computeMonthlyReturns(result.equityCurve);\n const heatPanel = this.buildPanel('Monthly Returns', surface, border);\n grid.appendChild(heatPanel.wrap);\n this.heatmap = new HeatmapChart(heatPanel.body, {\n data: monthlyCells,\n theme: t,\n showValues: true,\n valueFormat: (v) => `${v >= 0 ? '+' : ''}${v.toFixed(1)}`,\n colorScale: { negative: t.candleDown, zero: surface, positive: t.candleUp },\n });\n }\n\n private buildStatsStrip(stats: DashboardStat[], surface: string, border: string): HTMLDivElement {\n const strip = document.createElement('div');\n strip.style.cssText = [\n 'display:grid',\n 'grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))',\n 'gap:10px',\n ].join(';');\n\n const t = this.theme;\n for (const stat of stats) {\n const card = document.createElement('div');\n card.style.cssText = [\n `background:${surface}`,\n `border:1px solid ${border}`,\n 'border-radius:10px',\n 'padding:10px 12px',\n 'display:flex',\n 'flex-direction:column',\n 'gap:4px',\n ].join(';');\n\n const label = document.createElement('div');\n label.textContent = stat.label;\n label.style.cssText = `font-size:${t.font.sizeSmall}px;color:${t.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;\n\n const value = document.createElement('div');\n value.textContent = stat.value;\n const color = stat.tone === 'positive' ? t.candleUp : stat.tone === 'negative' ? t.candleDown : t.text;\n value.style.cssText = `font-size:${t.font.sizeLarge}px;font-weight:600;color:${color};font-variant-numeric:tabular-nums;`;\n\n card.appendChild(label);\n card.appendChild(value);\n strip.appendChild(card);\n }\n return strip;\n }\n\n private buildPanel(title: string, surface: string, border: string): { wrap: HTMLDivElement; body: HTMLDivElement } {\n const t = this.theme;\n const wrap = document.createElement('div');\n wrap.style.cssText = [\n `background:${surface}`,\n `border:1px solid ${border}`,\n 'border-radius:10px',\n 'overflow:hidden',\n 'display:flex',\n 'flex-direction:column',\n ].join(';');\n\n const head = document.createElement('div');\n head.textContent = title;\n head.style.cssText = [\n `font-size:${t.font.sizeSmall}px`,\n 'font-weight:600',\n `color:${t.textSecondary}`,\n 'padding:8px 12px',\n `border-bottom:1px solid ${border}`,\n 'text-transform:uppercase',\n 'letter-spacing:0.04em',\n ].join(';');\n\n const body = document.createElement('div');\n body.style.cssText = 'flex:1;min-height:0;position:relative;';\n\n wrap.appendChild(head);\n wrap.appendChild(body);\n return { wrap, body };\n }\n\n /** A subtle surface tint distinct from the page background, per theme. */\n private panelBackground(): string {\n return this.theme.name === 'light' ? 'rgba(0,0,0,0.02)' : 'rgba(255,255,255,0.03)';\n }\n\n /** Replace the displayed result and re-render all panels. */\n update(result: PerformanceResult): void {\n this.options = { ...this.options, result };\n this.destroyCharts();\n this.root.replaceChildren();\n this.build();\n }\n\n setTheme(theme: ThemeName | Theme): void {\n this.theme = resolveTheme(theme);\n this.options = { ...this.options, theme };\n this.destroyCharts();\n this.root.replaceChildren();\n this.build();\n }\n\n private destroyCharts(): void {\n this.equityChart?.destroy();\n this.drawdownChart?.destroy();\n this.heatmap?.destroy();\n this.equityChart = null;\n this.drawdownChart = null;\n this.heatmap = null;\n }\n\n destroy(): void {\n this.destroyCharts();\n this.root.remove();\n }\n}\n"],"mappings":"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"} |
@@ -5,2 +5,4 @@ export { parseOHLCV } from './parseOHLCV.js'; | ||
| export type { DragDropImporterCallbacks } from './DragDropImporter.js'; | ||
| export { resampleOHLCV, inferTimeframeMs, canResample } from './resampleOHLCV.js'; | ||
| export type { ResampleOptions } from './resampleOHLCV.js'; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAClF,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"} |
@@ -1,2 +0,2 @@ | ||
| import { Theme, TimeFrame } from '@tradecanvas/commons'; | ||
| import { Theme, TimeFrame, DepthData, DataSeries } from '@tradecanvas/commons'; | ||
| import { Chart } from '../Chart.js'; | ||
@@ -17,2 +17,12 @@ import { ChartWidgetOptions } from './types.js'; | ||
| private dragDrop; | ||
| private alertsPanel; | ||
| private objectTree; | ||
| private indicatorSettings; | ||
| private drawingStyle; | ||
| private bracketBar; | ||
| private alertNotifier; | ||
| private depthLadder; | ||
| private dataWindow; | ||
| private lastHoverIndex; | ||
| private favoritesStore; | ||
| private watchlist; | ||
@@ -36,2 +46,5 @@ private watchlistSparkBuffer; | ||
| private boundGlobalKeydown; | ||
| private baseSeries; | ||
| private baseTimeframeMs; | ||
| private compares; | ||
| constructor(container: HTMLElement, options?: ChartWidgetOptions); | ||
@@ -54,2 +67,42 @@ /** Replace the searchable symbol catalog. Does not change the active symbol. */ | ||
| private handleTimeframe; | ||
| /** | ||
| * Load the widget's base series. Prefer this over `getChart().setData()` so | ||
| * client-side timeframe resampling has a finest-resolution source to | ||
| * aggregate from. The data is rendered at the current timeframe (resampled | ||
| * when that timeframe is coarser than the data's native spacing). | ||
| */ | ||
| setData(data: DataSeries): void; | ||
| /** Render the base series at the active timeframe, resampling when coarser. */ | ||
| private applyTimeframeData; | ||
| private toggleAlerts; | ||
| private handleToggleFavorite; | ||
| /** Encode the current view (symbol, timeframe, chart type, scale, indicators, drawings). */ | ||
| exportState(): string; | ||
| /** Restore a view from an `exportState()` string. Returns false if malformed. */ | ||
| importState(encoded: string): Promise<boolean>; | ||
| /** Copy the chart image to the clipboard, with a toast on success/failure. */ | ||
| copyChartImage(): Promise<void>; | ||
| /** Copy a shareable deep-link (current view encoded in the URL hash) to the clipboard. */ | ||
| copyShareLink(): Promise<void>; | ||
| /** Feed order-book depth to the chart overlay, depth ladder, and heatmap. */ | ||
| setDepth(depth: DepthData | null): void; | ||
| /** Begin a draggable bracket order at the latest price and show the action bar. */ | ||
| startBracket(side: 'buy' | 'sell'): void; | ||
| private buildDataWindowModel; | ||
| private toggleDataWindow; | ||
| private toggleObjects; | ||
| private openIndicatorSettings; | ||
| private refreshObjects; | ||
| private handleAddCompare; | ||
| /** Overlay another symbol's normalized series. Fetches history via the adapter. */ | ||
| addCompareSymbol(symbol: string): Promise<void>; | ||
| private handleRemoveCompare; | ||
| /** Refetch every comparison overlay at the current symbol/timeframe. */ | ||
| private refetchCompares; | ||
| private refreshAlerts; | ||
| /** Price + every active indicator line, as selectable alert sources. */ | ||
| private buildAlertSources; | ||
| /** Latest value for an alert source channel (price or indicator line). */ | ||
| private getAlertChannelValue; | ||
| private formatAlertPrice; | ||
| private handleChartType; | ||
@@ -56,0 +109,0 @@ private handleAddIndicator; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"ChartWidget.d.ts","sourceRoot":"","sources":["../../src/widget/ChartWidget.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"ChartWidget.d.ts","sourceRoot":"","sources":["../../src/widget/ChartWidget.ts"],"names":[],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/widget/icons.ts"],"names":[],"mappings":"AA4BA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM,CAI1D"} | ||
| {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/widget/icons.ts"],"names":[],"mappings":"AAuCA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM,CAI1D"} |
@@ -1,2 +0,2 @@ | ||
| import { Theme, ThemeName, ChartType, TimeFrame, DrawingToolType, DataAdapter, ChartOptions } from '@tradecanvas/commons'; | ||
| import { Theme, ThemeName, ChartType, TimeFrame, DrawingToolType, DataAdapter, ChartOptions, PriceScaleMode } from '@tradecanvas/commons'; | ||
| import { Chart } from '../Chart.js'; | ||
@@ -12,2 +12,26 @@ export interface ChartWidgetOptions { | ||
| statusBar?: boolean; | ||
| /** | ||
| * Price-alerts UI — a bell button in the toolbar that opens a floating panel | ||
| * to add / list / delete price alerts, plus a toast when one triggers. | ||
| * Default `true`. | ||
| */ | ||
| alerts?: boolean; | ||
| /** | ||
| * Sound and/or desktop notification when a price alert triggers. Both off by | ||
| * default. `sound: true` plays a built-in beep; pass a URL for a custom one. | ||
| * `desktop: true` uses the Notification API (asks permission on first use). | ||
| */ | ||
| alertNotifications?: import('./AlertNotifier.js').AlertNotifyOptions; | ||
| /** | ||
| * Object-tree panel — a layers button in the toolbar that opens a manager | ||
| * listing active indicators and drawings, with per-item show/hide, lock, and | ||
| * delete. Default `true`. | ||
| */ | ||
| objectTree?: boolean; | ||
| /** | ||
| * Depth-of-market ladder — a ladder button in the toolbar that opens a | ||
| * click-to-trade order-book panel. Off by default (needs trading + an | ||
| * order-book feed via `widget.setDepth`). Clicks emit `orderPlace` intents. | ||
| */ | ||
| depthLadder?: boolean; | ||
| symbols?: string[]; | ||
@@ -30,2 +54,25 @@ timeframes?: TimeFrame[]; | ||
| dragDropImport?: boolean; | ||
| /** | ||
| * Client-side timeframe resampling. When enabled (default `true`) and no | ||
| * live adapter is attached, switching to a coarser timeframe aggregates the | ||
| * loaded base series instead of refetching — one dataset drives every | ||
| * resolution. Disable to keep the timeframe buttons purely as a | ||
| * `onTimeframeChange` signal for the host app to refetch. | ||
| */ | ||
| resampleTimeframes?: boolean; | ||
| /** Anchor day for weekly resample buckets. `0` = Sunday, `1` = Monday (default). */ | ||
| weekStartsOn?: 0 | 1; | ||
| /** | ||
| * Deep-linking. When `true`, the widget restores a `#tcw=<encoded>` view from | ||
| * the URL hash on load, and the "Share View" command writes one back. Use | ||
| * `exportState()` / `importState()` for manual control. | ||
| */ | ||
| shareUrl?: boolean; | ||
| /** | ||
| * Drawing tools to pre-pin to the favorites strip at the top of the drawing | ||
| * sidebar on first run. Users pin/unpin any tool by right-clicking it; the | ||
| * set persists to localStorage. The strip is always available (hidden while | ||
| * empty) — this option only seeds the initial pins. | ||
| */ | ||
| drawingFavorites?: DrawingToolType[]; | ||
| persistLayouts?: boolean | { | ||
@@ -75,5 +122,11 @@ /** localStorage key prefix. The active symbol is appended. Default `tcw:layout:`. */ | ||
| onToggleReplay?: () => void; | ||
| onToggleAlerts?: () => void; | ||
| onToggleObjects?: () => void; | ||
| onBracket?: (side: 'buy' | 'sell') => void; | ||
| onToggleLadder?: () => void; | ||
| } | ||
| export interface SidebarConfig { | ||
| drawingToolGroups: DrawingToolGroupDef[]; | ||
| /** Initially pinned tools shown in the favorites strip. */ | ||
| favorites?: DrawingToolType[]; | ||
| } | ||
@@ -84,5 +137,7 @@ export interface SidebarCallbacks { | ||
| onToggleMagnet: () => void; | ||
| onToggleFavorite?: (tool: DrawingToolType) => void; | ||
| onUndo: () => void; | ||
| onRedo: () => void; | ||
| onClearDrawings: () => void; | ||
| onToggleStyle?: () => void; | ||
| } | ||
@@ -104,8 +159,24 @@ export interface SettingsCallbacks { | ||
| volumeProfileVisible: boolean; | ||
| marketProfileVisible: boolean; | ||
| marketProfileSplit: boolean; | ||
| marketProfileLetters: boolean; | ||
| marketProfileBuckets: number; | ||
| marketProfileOpacity: number; | ||
| depthHeatmapVisible: boolean; | ||
| depthHeatmapOpacity: number; | ||
| sessionShadingVisible: boolean; | ||
| pivotMarkersVisible: boolean; | ||
| pivotStrength: number; | ||
| pivotStructureLabels: boolean; | ||
| periodLevelsVisible: boolean; | ||
| periodLevelsPeriod: 'day' | 'week'; | ||
| legendVisible: boolean; | ||
| barCountdown: boolean; | ||
| logScale: boolean; | ||
| scaleMode: PriceScaleMode; | ||
| autoScale: boolean; | ||
| crosshairMode: 'normal' | 'magnet' | 'hidden'; | ||
| numberLocale: string; | ||
| /** 'local' = browser timezone, otherwise a fixed UTC offset in minutes (as a string). */ | ||
| timezone: string; | ||
| } | ||
@@ -112,0 +183,0 @@ export interface IndicatorDef { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/widget/types.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/widget/types.ts"],"names":[],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"widgetConfig.d.ts","sourceRoot":"","sources":["../../src/widget/widgetConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAmB,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAExF,eAAO,MAAM,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,EAO3D,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,EAa5D,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,EA8DpD,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,YAAY,EAkCpC,CAAC;AAEF,eAAO,MAAM,kBAAkB,UAG9B,CAAC;AAEF,eAAO,MAAM,eAAe,UAE3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,kBAgB9B,CAAC"} | ||
| {"version":3,"file":"widgetConfig.d.ts","sourceRoot":"","sources":["../../src/widget/widgetConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAmB,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAExF,eAAO,MAAM,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,EAO3D,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,EAa5D,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,EA8DpD,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,YAAY,EAmEpC,CAAC;AAEF,eAAO,MAAM,kBAAkB,UAG9B,CAAC;AAEF,eAAO,MAAM,eAAe,UAE3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,kBA+B9B,CAAC"} |
@@ -11,4 +11,10 @@ import { SidebarConfig, SidebarCallbacks, WidgetState } from './types.js'; | ||
| private flyoutEl; | ||
| private favoritesEl; | ||
| private favoritesDivider; | ||
| private favorites; | ||
| constructor(host: HTMLElement, config: SidebarConfig, callbacks: SidebarCallbacks); | ||
| private build; | ||
| /** Update the pinned-tools strip. */ | ||
| setFavorites(favorites: string[]): void; | ||
| private renderFavorites; | ||
| private showFlyout; | ||
@@ -15,0 +21,0 @@ private hideFlyout; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"WidgetDrawingSidebar.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetDrawingSidebar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO/E,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,QAAQ,CAA+B;gBAEnC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB;IASjF,OAAO,CAAC,KAAK;IA8Eb,OAAO,CAAC,UAAU;IA8BlB,OAAO,CAAC,UAAU;IAOlB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IA4BhC,OAAO,CAAC,OAAO;IAMf,OAAO,IAAI,IAAI;CAIhB"} | ||
| {"version":3,"file":"WidgetDrawingSidebar.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetDrawingSidebar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAgC/E,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,SAAS,CAAgB;gBAErB,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB;IASjF,OAAO,CAAC,KAAK;IAmGb,qCAAqC;IACrC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAKvC,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,UAAU;IAsClB,OAAO,CAAC,UAAU;IAOlB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IA4BhC,OAAO,CAAC,OAAO;IAMf,OAAO,IAAI,IAAI;CAIhB"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"WidgetHotkeySheet.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetHotkeySheet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAwDD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAA6B;gBAErC,SAAS,EAAE,oBAAoB;IAU3C,IAAI,IAAI,IAAI;IAsFZ,KAAK,IAAI,IAAI;IASb,MAAM,IAAI,OAAO;IAIjB,OAAO,IAAI,IAAI;CAGhB"} | ||
| {"version":3,"file":"WidgetHotkeySheet.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetHotkeySheet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAiED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAA6B;gBAErC,SAAS,EAAE,oBAAoB;IAU3C,IAAI,IAAI,IAAI;IAsFZ,KAAK,IAAI,IAAI;IASb,MAAM,IAAI,OAAO;IAIjB,OAAO,IAAI,IAAI;CAGhB"} |
@@ -23,4 +23,5 @@ import { ChartSettingsState, SettingsCallbacks } from './types.js'; | ||
| private selectRow; | ||
| private rangeRow; | ||
| destroy(): void; | ||
| } | ||
| //# sourceMappingURL=WidgetSettings.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"WidgetSettings.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetSettings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMxE,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,UAAU,CAA2B;gBAEjC,SAAS,EAAE,iBAAiB;IAIxC,IAAI,CAAC,eAAe,EAAE,kBAAkB,GAAG,IAAI;IAM/C,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,UAAU;IAuFlB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,gBAAgB;IA+BxB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,QAAQ;IA+BhB,OAAO,CAAC,SAAS;IAoBjB,OAAO,CAAC,SAAS;IA4BjB,OAAO,IAAI,IAAI;CAGhB"} | ||
| {"version":3,"file":"WidgetSettings.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetSettings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMxE,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,UAAU,CAA2B;gBAEjC,SAAS,EAAE,iBAAiB;IAIxC,IAAI,CAAC,eAAe,EAAE,kBAAkB,GAAG,IAAI;IAM/C,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,UAAU;IAuFlB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,gBAAgB;IAyDxB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,QAAQ;IA+BhB,OAAO,CAAC,SAAS;IAoBjB,OAAO,CAAC,SAAS;IA4BjB,OAAO,CAAC,QAAQ;IA2ChB,OAAO,IAAI,IAAI;CAGhB"} |
@@ -21,4 +21,6 @@ /** | ||
| private boundKeydown; | ||
| /** One-shot pick override — when set, this open() routes picks here instead. */ | ||
| private pickOverride; | ||
| constructor(callbacks: SymbolSearchCallbacks); | ||
| open(symbols: string[], current: string): void; | ||
| open(symbols: string[], current: string, onPick?: (symbol: string) => void): void; | ||
| close(): void; | ||
@@ -25,0 +27,0 @@ isOpen(): boolean; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"WidgetSymbolSearch.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetSymbolSearch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAOD,qBAAa,kBAAkB;IAC7B,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,OAAO,CAAgB;IAC/B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,YAAY,CAA6B;gBAErC,SAAS,EAAE,qBAAqB;IAK5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAuD9C,KAAK,IAAI,IAAI;IAWb,MAAM,IAAI,OAAO;IAIjB,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,UAAU;IA0ClB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,aAAa;CA0BtB"} | ||
| {"version":3,"file":"WidgetSymbolSearch.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetSymbolSearch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAOD,qBAAa,kBAAkB;IAC7B,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,OAAO,CAAgB;IAC/B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,YAAY,CAA6B;IACjD,gFAAgF;IAChF,OAAO,CAAC,YAAY,CAA2C;gBAEnD,SAAS,EAAE,qBAAqB;IAK5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAwDjF,KAAK,IAAI,IAAI;IAYb,MAAM,IAAI,OAAO;IAIjB,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,UAAU;IA0ClB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,aAAa;CA0BtB"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"WidgetToolbar.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetToolbar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAmB,MAAM,YAAY,CAAC;AAIhG,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAkC;gBAEtC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB;IASjF,OAAO,CAAC,KAAK;IAkFb,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,kBAAkB;IA4B1B,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAwDhC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,GAAG;IAMX,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,OAAO;IASf,OAAO,IAAI,IAAI;CAKhB"} | ||
| {"version":3,"file":"WidgetToolbar.d.ts","sourceRoot":"","sources":["../../src/widget/WidgetToolbar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAmB,MAAM,YAAY,CAAC;AAIhG,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAkC;gBAEtC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB;IASjF,OAAO,CAAC,KAAK;IAgHb,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,kBAAkB;IA4B1B,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAwDhC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,GAAG;IAMX,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,OAAO;IASf,OAAO,IAAI,IAAI;CAKhB"} |
+3
-3
| { | ||
| "name": "@tradecanvas/chart", | ||
| "version": "0.9.0", | ||
| "version": "0.14.0", | ||
| "type": "module", | ||
@@ -50,4 +50,4 @@ "description": "High-performance canvas trading chart with built-in indicators, drawing tools, and real-time streaming. Zero external dependencies.", | ||
| "dependencies": { | ||
| "@tradecanvas/commons": "0.9.0", | ||
| "@tradecanvas/core": "0.9.0" | ||
| "@tradecanvas/commons": "0.14.0", | ||
| "@tradecanvas/core": "0.14.0" | ||
| }, | ||
@@ -54,0 +54,0 @@ "devDependencies": { |
| import { DARK_THEME as e, DEFAULT_PANEL_HEIGHT as t, LIGHT_THEME as n, LayerType as r, MIN_PANEL_HEIGHT as i, PRICE_AXIS_WIDTH as a, TIME_AXIS_HEIGHT as o, computePriceLimits as s, mergeBar as c, setLocale as l, timeframeToMs as u } from "@tradecanvas/commons"; | ||
| import { AlertManager as d, Animator as f, AreaRenderer as p, AxisDragHandler as m, BarCountdown as ee, BarRenderer as te, BaselineRenderer as ne, CandlestickRenderer as h, ChartLegend as g, ChartStateManager as _, CompareRenderer as re, CrosshairHandler as ie, CrosshairTooltip as ae, CurrentPriceLine as oe, DataExporter as v, DrawingManager as se, DrawingRenderer as ce, EquivolumeRenderer as le, EventBus as ue, GridRenderer as de, HLCAreaRenderer as fe, HollowCandleRenderer as pe, IndicatorEngine as y, InteractionManager as me, KagiRenderer as he, KeyboardHandler as ge, LineRenderer as _e, LineWithMarkersRenderer as ve, MeasureOverlay as ye, PanHandler as be, PinnedTooltip as xe, PointAndFigureRenderer as Se, PriceAxis as Ce, RenderEngine as we, RenkoRenderer as Te, ReplayManager as b, Screenshot as x, SessionBreaks as S, SignalMarkerManager as C, StepLineRenderer as w, StreamManager as T, TimeAxis as E, TradeZoneManager as D, TradingManager as O, TradingRenderer as Ee, UndoRedoManager as De, Viewport as Oe, VolumeCandleRenderer as ke, VolumeProfileRenderer as Ae, VolumeRenderer as je, Watermark as Me, ZoomHandler as Ne, registerBuiltInDrawingTools as Pe, registerBuiltInIndicators as k, toHeikinAshi as Fe, toKagi as Ie, toLineBreak as Le, toPointAndFigure as Re, toRangeBars as ze, toRenko as Be } from "@tradecanvas/core"; | ||
| //#region src/charts/ChartTypeStrategy.ts | ||
| function Ve(e) { | ||
| switch (e) { | ||
| case "candlestick": | ||
| case "heikinAshi": | ||
| case "lineBreak": | ||
| case "rangeBars": return new h(); | ||
| case "line": return new _e(); | ||
| case "area": return new p(); | ||
| case "bar": return new te(); | ||
| case "hollowCandle": return new pe(); | ||
| case "baseline": return new ne(); | ||
| case "renko": return new Te(); | ||
| case "kagi": return new he(); | ||
| case "pointAndFigure": return new Se(); | ||
| case "volumeCandles": return new ke(); | ||
| case "equivolume": return new le(); | ||
| case "hlcArea": return new fe(); | ||
| case "stepLine": return new w(); | ||
| case "lineWithMarkers": return new ve(); | ||
| default: return new h(); | ||
| } | ||
| } | ||
| function He(e, t) { | ||
| if (t.length === 0) return t; | ||
| switch (e) { | ||
| case "heikinAshi": return Fe(t); | ||
| case "renko": return Be(t, { | ||
| brickSize: 0, | ||
| useATR: !0, | ||
| atrPeriod: 14 | ||
| }); | ||
| case "lineBreak": return Le(t, 3); | ||
| case "kagi": return Ie(t, 4); | ||
| case "pointAndFigure": return Re(t, A(t) * .01, 3); | ||
| case "rangeBars": return ze(t, { rangeSize: A(t) * .005 }); | ||
| default: return t; | ||
| } | ||
| } | ||
| function A(e) { | ||
| let t = 0; | ||
| for (let n of e) t += n.close; | ||
| return t / e.length; | ||
| } | ||
| //#endregion | ||
| //#region src/charts/IndicatorPriceRange.ts | ||
| var j = { | ||
| min: 0, | ||
| max: 100 | ||
| }, M = .1; | ||
| function Ue(e, t, n) { | ||
| if (!e) return { ...j }; | ||
| let r = Infinity, i = -Infinity, a = 0; | ||
| for (let [, o] of e.values) { | ||
| if (a >= t && a <= n) for (let e in o) { | ||
| let t = o[e]; | ||
| t !== void 0 && Number.isFinite(t) && (t < r && (r = t), t > i && (i = t)); | ||
| } | ||
| a++; | ||
| } | ||
| if (r === Infinity) return { ...j }; | ||
| let o = i - r || 1; | ||
| return { | ||
| min: r - o * M, | ||
| max: i + o * M | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/state/AutoSaveScheduler.ts | ||
| var We = class { | ||
| timer = null; | ||
| delayMs = 0; | ||
| key = null; | ||
| constructor(e) { | ||
| this.save = e; | ||
| } | ||
| enable(e, t) { | ||
| this.key = e, this.delayMs = t; | ||
| } | ||
| disable() { | ||
| this.key = null, this.delayMs = 0, this.cancel(); | ||
| } | ||
| schedule() { | ||
| this.delayMs <= 0 || !this.key || (this.timer && clearTimeout(this.timer), this.timer = setTimeout(() => { | ||
| this.timer = null, this.key && this.save(this.key); | ||
| }, this.delayMs)); | ||
| } | ||
| cancel() { | ||
| this.timer &&= (clearTimeout(this.timer), null); | ||
| } | ||
| isEnabled() { | ||
| return this.delayMs > 0 && this.key !== null; | ||
| } | ||
| hasPending() { | ||
| return this.timer !== null; | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/DataManager.ts | ||
| function N(e) { | ||
| if (!e || typeof e.time != "number") return !1; | ||
| let { open: t, high: n, low: r, close: i } = e; | ||
| return !(!isFinite(t) || !isFinite(n) || !isFinite(r) || !isFinite(i) || t < 0 || n < 0 || r < 0 || i < 0 || n < r || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0)); | ||
| } | ||
| function P(e) { | ||
| return { | ||
| ...e, | ||
| high: Math.max(e.open, e.high, e.low, e.close), | ||
| low: Math.min(e.open, e.high, e.low, e.close), | ||
| volume: e.volume === void 0 ? 0 : Math.max(0, e.volume) | ||
| }; | ||
| } | ||
| var F = class { | ||
| data = []; | ||
| getData() { | ||
| return this.data; | ||
| } | ||
| setData(e) { | ||
| this.data = e.filter(N).map(P); | ||
| } | ||
| appendBar(e) { | ||
| N(e) && this.data.push(P(e)); | ||
| } | ||
| updateLastBar(e) { | ||
| if (!N(e)) return; | ||
| let t = P(e); | ||
| if (this.data.length === 0) { | ||
| this.data.push(t); | ||
| return; | ||
| } | ||
| this.data[this.data.length - 1] = t; | ||
| } | ||
| updateLastBarFromTick(e) { | ||
| this.data.length !== 0 && (!isFinite(e.price) || e.price < 0 || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0) || (this.data[this.data.length - 1] = c(this.data[this.data.length - 1], e))); | ||
| } | ||
| getLength() { | ||
| return this.data.length; | ||
| } | ||
| clear() { | ||
| this.data = []; | ||
| } | ||
| }, I = class { | ||
| theme; | ||
| constructor(t) { | ||
| !t || t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t }; | ||
| } | ||
| getTheme() { | ||
| return this.theme; | ||
| } | ||
| setTheme(t) { | ||
| t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t }; | ||
| } | ||
| }, L = 200, R = 80, z = class { | ||
| panels = []; | ||
| containerWidth = 0; | ||
| containerHeight = 0; | ||
| resize(e, t) { | ||
| this.containerWidth = e, this.containerHeight = t; | ||
| } | ||
| addPanel(e, n = "bottom", r) { | ||
| let a = n === "left" || n === "right"; | ||
| this.panels.push({ | ||
| id: e, | ||
| position: n, | ||
| size: r ?? (a ? L : t), | ||
| minSize: a ? R : i, | ||
| content: { | ||
| type: "indicator", | ||
| indicatorInstanceId: e | ||
| } | ||
| }); | ||
| } | ||
| removePanel(e) { | ||
| this.panels = this.panels.filter((t) => t.id !== e); | ||
| } | ||
| setPanelPosition(e, n) { | ||
| let r = this.panels.find((t) => t.id === e); | ||
| if (r) { | ||
| let e = r.position === "left" || r.position === "right", a = n === "left" || n === "right"; | ||
| r.position = n, e !== a && (r.size = a ? L : t, r.minSize = a ? R : i); | ||
| } | ||
| } | ||
| setPanelSize(e, t) { | ||
| let n = this.panels.find((t) => t.id === e); | ||
| n && (n.size = Math.max(n.minSize, t)); | ||
| } | ||
| getPanels() { | ||
| return this.panels; | ||
| } | ||
| resolve() { | ||
| let e = this.panels.filter((e) => e.position === "left"), t = this.panels.filter((e) => e.position === "right"), n = this.panels.filter((e) => e.position === "top"), r = this.panels.filter((e) => e.position === "bottom"), i = e.reduce((e, t) => e + t.size, 0), s = t.reduce((e, t) => e + t.size, 0), c = n.reduce((e, t) => e + t.size, 0), l = r.reduce((e, t) => e + t.size, 0), u = { | ||
| x: i, | ||
| y: c, | ||
| width: Math.max(0, this.containerWidth - i - s - a), | ||
| height: Math.max(0, this.containerHeight - c - l - o) | ||
| }, d = [], f = [], p = 0; | ||
| for (let t of e) d.push({ | ||
| config: t, | ||
| rect: { | ||
| x: p, | ||
| y: 0, | ||
| width: t.size, | ||
| height: this.containerHeight - o | ||
| } | ||
| }), f.push({ | ||
| panelId: t.id, | ||
| rect: { | ||
| x: p + t.size - 2, | ||
| y: 0, | ||
| width: 4, | ||
| height: this.containerHeight | ||
| }, | ||
| orientation: "vertical" | ||
| }), p += t.size; | ||
| let m = 0; | ||
| for (let e of n) d.push({ | ||
| config: e, | ||
| rect: { | ||
| x: i, | ||
| y: m, | ||
| width: u.width, | ||
| height: e.size | ||
| } | ||
| }), f.push({ | ||
| panelId: e.id, | ||
| rect: { | ||
| x: i, | ||
| y: m + e.size - 2, | ||
| width: u.width, | ||
| height: 4 | ||
| }, | ||
| orientation: "horizontal" | ||
| }), m += e.size; | ||
| m = u.y + u.height; | ||
| for (let e of r) d.push({ | ||
| config: e, | ||
| rect: { | ||
| x: i, | ||
| y: m, | ||
| width: u.width, | ||
| height: e.size | ||
| } | ||
| }), f.push({ | ||
| panelId: e.id, | ||
| rect: { | ||
| x: i, | ||
| y: m - 2, | ||
| width: u.width, | ||
| height: 4 | ||
| }, | ||
| orientation: "horizontal" | ||
| }), m += e.size; | ||
| p = i + u.width + a; | ||
| for (let e of t) d.push({ | ||
| config: e, | ||
| rect: { | ||
| x: p, | ||
| y: 0, | ||
| width: e.size, | ||
| height: this.containerHeight - o | ||
| } | ||
| }), f.push({ | ||
| panelId: e.id, | ||
| rect: { | ||
| x: p - 2, | ||
| y: 0, | ||
| width: 4, | ||
| height: this.containerHeight | ||
| }, | ||
| orientation: "vertical" | ||
| }), p += e.size; | ||
| return { | ||
| mainChartRect: u, | ||
| panels: d, | ||
| dividers: f | ||
| }; | ||
| } | ||
| getMainChartRect() { | ||
| return this.resolve().mainChartRect; | ||
| } | ||
| }, B = class { | ||
| constructor(e) { | ||
| this.indicatorEngine = e; | ||
| } | ||
| registerIndicator(e) { | ||
| this.indicatorEngine.register(e); | ||
| } | ||
| }, Ge = class { | ||
| static version = "0.7.0"; | ||
| engine; | ||
| viewport; | ||
| dataManager; | ||
| themeManager; | ||
| layoutManager; | ||
| pluginManager; | ||
| indicatorEngine; | ||
| drawingManager; | ||
| drawingRenderer; | ||
| tradingManager; | ||
| tradingRenderer; | ||
| eventBus; | ||
| streamManager = null; | ||
| autoScrollOnNewBar = !0; | ||
| displayDataCache = null; | ||
| resolvedLayoutCache = null; | ||
| panelInfoCache = null; | ||
| renderScheduled = !1; | ||
| containerSizeCache = null; | ||
| containerSizeCacheTime = 0; | ||
| chartLegend; | ||
| watermark; | ||
| barCountdown; | ||
| sessionBreaks; | ||
| compareRenderer; | ||
| countdownInterval = null; | ||
| volumeRenderer; | ||
| volumeProfile; | ||
| alertManager; | ||
| signalMarkerManager; | ||
| tradeZoneManager; | ||
| measureOverlay; | ||
| replayManager; | ||
| undoRedoManager; | ||
| autoSaveScheduler = new We((e) => this.saveState(e)); | ||
| animator; | ||
| crosshairTooltip; | ||
| pinnedTooltip; | ||
| interactionManager; | ||
| crosshairHandler; | ||
| chartRenderer; | ||
| gridRenderer; | ||
| priceAxis; | ||
| timeAxis; | ||
| options; | ||
| features; | ||
| marketConfig = null; | ||
| container; | ||
| currentPriceLine; | ||
| numberLocale; | ||
| keyboardHandler = null; | ||
| onWindowKeyDown = null; | ||
| currentSymbol = ""; | ||
| constructor(e, t) { | ||
| this.container = e, this.options = t, this.numberLocale = t.numberLocale ?? "en-US"; | ||
| let n = t.features ?? {}; | ||
| this.features = { | ||
| drawings: n.drawings ?? !0, | ||
| drawingTools: n.drawingTools ?? [], | ||
| drawingMagnet: n.drawingMagnet ?? !0, | ||
| drawingUndoRedo: n.drawingUndoRedo ?? !0, | ||
| trading: n.trading ?? !0, | ||
| tradingContextMenu: n.tradingContextMenu ?? !0, | ||
| indicators: n.indicators ?? !0, | ||
| indicatorIds: n.indicatorIds ?? [], | ||
| panning: n.panning ?? !0, | ||
| zooming: n.zooming ?? !0, | ||
| crosshair: n.crosshair ?? !0, | ||
| keyboard: n.keyboard ?? !0, | ||
| priceAxis: n.priceAxis ?? !0, | ||
| timeAxis: n.timeAxis ?? !0, | ||
| grid: n.grid ?? t.grid?.visible ?? !0, | ||
| legend: n.legend ?? !0, | ||
| volume: n.volume ?? !0, | ||
| watermark: n.watermark ?? !0, | ||
| saveLoad: n.saveLoad ?? !0, | ||
| screenshot: n.screenshot ?? !0, | ||
| alerts: n.alerts ?? !0, | ||
| replay: n.replay ?? !0, | ||
| sessionBreaks: n.sessionBreaks ?? !0, | ||
| barCountdown: n.barCountdown ?? !0, | ||
| compareSymbols: n.compareSymbols ?? !0, | ||
| dataExport: n.dataExport ?? !0, | ||
| logScale: n.logScale ?? !0, | ||
| timeframes: n.timeframes ?? [], | ||
| defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? [] | ||
| }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new F(), this.themeManager = new I(t.theme), this.layoutManager = new z(), this.indicatorEngine = new y(), this.pluginManager = new B(this.indicatorEngine), this.eventBus = new ue(), k(this.indicatorEngine), this.drawingManager = new se(), Pe(this.drawingManager), this.drawingRenderer = new ce(this.drawingManager), this.drawingManager.setRequestRender(() => { | ||
| this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave(); | ||
| }), this.drawingManager.setEventCallback((e, t) => { | ||
| this.eventBus.emit(e, t); | ||
| }), this.undoRedoManager = new De(), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setDataGetter(() => this.dataManager.getData()), this.drawingManager.setDisplayDataGetter(() => this.getDisplayData()), t.crosshair?.mode === "magnet" && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new O({ | ||
| enabled: this.features.trading, | ||
| contextMenu: { enabled: this.features.tradingContextMenu } | ||
| }), this.tradingRenderer = new Ee(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => { | ||
| this.eventBus.emit(e, t); | ||
| }), this.engine = new we(e); | ||
| let i = this.engine.dprManager.getContainerSize(); | ||
| if (this.viewport = new Oe(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => { | ||
| if (e.width <= 0 || e.height <= 0) return; | ||
| let t = this.viewport.isAtEnd(); | ||
| this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t); | ||
| }, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new de(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new Ce(), this.priceAxis.setLocale(this.numberLocale), this.timeAxis = new E(), this.crosshairHandler = new ie(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => { | ||
| if (e !== null && t) { | ||
| let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0; | ||
| this.chartLegend.setHoverBar(r ?? null), r && this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize()), this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", { | ||
| point: t, | ||
| bar: r, | ||
| barIndex: e | ||
| }); | ||
| } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null); | ||
| }), this.chartLegend = new g(), this.chartLegend.setChartType(t.chartType), this.watermark = new Me(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new je(), this.volumeProfile = new Ae(), this.barCountdown = new ee(), this.sessionBreaks = new S(), this.compareRenderer = new re(), t.sessionBreaks ? this.sessionBreaks.setConfig({ | ||
| visible: t.sessionBreaks.visible ?? !0, | ||
| color: t.sessionBreaks.color, | ||
| lineStyle: t.sessionBreaks.lineStyle, | ||
| lineWidth: t.sessionBreaks.lineWidth | ||
| }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.viewport.setLogScale(!0), this.animator = new f(), this.crosshairTooltip = new ae(), this.crosshairTooltip.create(e), this.pinnedTooltip = new xe(), this.pinnedTooltip.create(e), this.keyboardHandler = new ge({ | ||
| scrollBars: (e) => { | ||
| let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing; | ||
| this.viewport.scrollBy(e * t), this.updateViewportAndRender(); | ||
| }, | ||
| zoom: (e) => { | ||
| let t = this.viewport.getState().chartRect.width; | ||
| this.viewport.zoom(e, t / 2), this.updateViewportAndRender(); | ||
| }, | ||
| goToStart: () => { | ||
| this.viewport.scrollBy(-Infinity), this.updateViewportAndRender(); | ||
| }, | ||
| goToEnd: () => { | ||
| this.viewport.scrollToEnd(), this.updateViewportAndRender(); | ||
| }, | ||
| fitContent: () => this.fitContent() | ||
| }), this.keyboardHandler.setEnabled(this.features.keyboard), this.onWindowKeyDown = (e) => { | ||
| if (!this.keyboardHandler) return; | ||
| let t = document.activeElement; | ||
| t && t !== this.container && !this.container.contains(t) || t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable) || this.keyboardHandler.handleKey(e) && e.preventDefault(); | ||
| }, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new oe(), this.alertManager = new d(), this.alertManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.alertManager.on("triggered", (e) => { | ||
| this.eventBus.emit("dataUpdate", { | ||
| alert: "triggered", | ||
| alertId: e.id, | ||
| price: e.price, | ||
| message: e.message | ||
| }); | ||
| }), this.signalMarkerManager = new C(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => { | ||
| this.eventBus.emit("signalMarkerAdd", { | ||
| id: e.id, | ||
| source: e.source, | ||
| direction: e.direction | ||
| }); | ||
| }), this.signalMarkerManager.on("removed", (e) => { | ||
| this.eventBus.emit("signalMarkerRemove", { id: e }); | ||
| }), this.tradeZoneManager = new D(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => { | ||
| this.eventBus.emit("tradeZoneAdd", { | ||
| id: e.id, | ||
| direction: e.direction | ||
| }); | ||
| }), this.tradeZoneManager.on("removed", (e) => { | ||
| this.eventBus.emit("tradeZoneRemove", { id: e }); | ||
| }), this.replayManager = new b(), this.measureOverlay = new ye(), this.interactionManager = new me(e), this.features.panning && this.interactionManager.setPanHandler(new be((e) => { | ||
| this.viewport.scrollBy(e), this.updateViewportAndRender(); | ||
| })), this.features.zooming) { | ||
| this.interactionManager.setZoomHandler(new Ne((e, t) => { | ||
| this.viewport.zoom(e, t), this.updateViewportAndRender(); | ||
| })); | ||
| let e = new m((e) => { | ||
| this.options.autoScale = !1, this.viewport.scalePriceRange(e), this.syncRenderContext(), this.engine.requestRender(); | ||
| }, (e) => { | ||
| let t = this.viewport.getState().chartRect.width; | ||
| this.viewport.zoom(1 / e - 1, t / 2), this.updateViewportAndRender(); | ||
| }); | ||
| this.interactionManager.setAxisDragHandler(e, () => this.viewport.getState(), (e) => { | ||
| e === "price" ? (this.options.autoScale = !0, this.updateViewportAndRender()) : this.fitContent(); | ||
| }); | ||
| } | ||
| this.features.crosshair && this.interactionManager.setCrosshairHandler(this.crosshairHandler), this.features.drawings && this.interactionManager.setDrawingManager(this.drawingManager, () => ({ | ||
| ...this.viewport.getState(), | ||
| data: this.getDisplayData() | ||
| })), this.features.trading && this.interactionManager.setTradingManager(this.tradingManager, () => ({ | ||
| ...this.viewport.getState(), | ||
| data: this.getDisplayData() | ||
| })), this.interactionManager.setAltClickHandler((e) => { | ||
| let t = this.getDisplayData(); | ||
| if (t.length === 0) return; | ||
| let n = this.viewport.getState(), i = n.barWidth + n.barSpacing, a = Math.round((n.offset + e.x) / i); | ||
| a < 0 || a >= t.length || (this.pinnedTooltip.isPinned() && this.pinnedTooltip.getPinnedIndex() === a ? this.pinnedTooltip.unpin() : this.pinnedTooltip.pin(t[a], a, this.themeManager.getTheme()), this.pinnedTooltip.reposition(this.viewport.getState(), this.dataManager.getData()[a] ?? null, a, this.themeManager.getTheme()), this.engine.requestRender(r.Overlay)); | ||
| }), this.interactionManager.setEscapeHandler(() => { | ||
| this.pinnedTooltip.isPinned() && (this.pinnedTooltip.unpin(), this.engine.requestRender(r.Overlay)); | ||
| }), this.interactionManager.setMeasureHandlers({ | ||
| begin: (e) => { | ||
| this.measureOverlay.begin(e, this.viewport.getState(), this.getDisplayData()); | ||
| }, | ||
| move: (e) => { | ||
| this.measureOverlay.update(e, this.viewport.getState(), this.getDisplayData()); | ||
| }, | ||
| end: () => { | ||
| this.measureOverlay.end(); | ||
| } | ||
| }), this.interactionManager.setOverlayDirtyCallback(() => { | ||
| this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI); | ||
| }), this.interactionManager.attach(), this.syncRenderContext(), this.engine.start(); | ||
| } | ||
| setData(e) { | ||
| this.dataManager.setData(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), e.length > 0 && this.currentPriceLine.setPrice(e[e.length - 1].close), this.updateViewportAndRender(!0), this.eventBus.emit("dataUpdate", { length: e.length }); | ||
| } | ||
| appendBar(e) { | ||
| this.dataManager.appendBar(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.autoScrollOnNewBar && this.viewport.scrollToEnd(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.updateViewportAndRender(); | ||
| } | ||
| appendBars(e) { | ||
| if (e.length !== 0) { | ||
| for (let t of e) this.dataManager.appendBar(t); | ||
| this.displayDataCache = null, this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(this.viewport.isAtEnd()); | ||
| } | ||
| } | ||
| updateLastBar(e) { | ||
| this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender(); | ||
| } | ||
| updateLastBarFromTick(e) { | ||
| this.dataManager.updateLastBarFromTick(e), this.currentPriceLine.setPrice(e.price), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender(); | ||
| } | ||
| setChartType(e) { | ||
| this.options.chartType = e, this.chartRenderer = this.createChartRenderer(e), this.chartLegend.setChartType(e), this.displayDataCache = null, this.updateViewportAndRender(!0); | ||
| } | ||
| addIndicator(e, t = {}, n = "bottom") { | ||
| if (!this.features.indicators || this.features.indicatorIds.length > 0 && !this.features.indicatorIds.includes(e)) return null; | ||
| let r = this.indicatorEngine.addIndicator(e, t, this.dataManager.getData()); | ||
| return this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e)?.placement === "panel" ? (this.layoutManager.addPanel(r, n), this.updateViewportAndRender()) : this.engine.requestRender(), this.eventBus.emit("indicatorAdd", { | ||
| instanceId: r, | ||
| id: e | ||
| }), r; | ||
| } | ||
| updateIndicator(e, t) { | ||
| this.indicatorEngine.updateIndicator(e, t, this.dataManager.getData()), this.engine.requestRender(); | ||
| } | ||
| removeIndicator(e) { | ||
| let t = this.layoutManager.getPanels().some((t) => t.id === e); | ||
| this.indicatorEngine.removeIndicator(e), this.layoutManager.removePanel(e), this.eventBus.emit("indicatorRemove", { instanceId: e }), t ? this.updateViewportAndRender() : this.engine.requestRender(); | ||
| } | ||
| getIndicatorOutput(e) { | ||
| return this.indicatorEngine.getOutput(e); | ||
| } | ||
| registerIndicator(e) { | ||
| this.pluginManager.registerIndicator(e); | ||
| } | ||
| static indicators() { | ||
| let e = new y(); | ||
| return k(e), e.getAvailableIndicators(); | ||
| } | ||
| setPanelPosition(e, t) { | ||
| this.layoutManager.setPanelPosition(e, t), this.engine.requestRender(); | ||
| } | ||
| setPanelSize(e, t) { | ||
| this.layoutManager.setPanelSize(e, t), this.engine.requestRender(); | ||
| } | ||
| setDrawingTool(e) { | ||
| this.features.drawings && (e && this.features.drawingTools.length > 0 && !this.features.drawingTools.includes(e) || this.drawingManager.setActiveTool(e)); | ||
| } | ||
| getDrawingTool() { | ||
| return this.drawingManager.getActiveTool(); | ||
| } | ||
| setDrawingStyle(e) { | ||
| this.drawingManager.setStyle(e); | ||
| } | ||
| getDrawings() { | ||
| return this.drawingManager.getDrawings(); | ||
| } | ||
| setDrawings(e) { | ||
| this.drawingManager.setDrawings(e); | ||
| } | ||
| removeDrawing(e) { | ||
| this.drawingManager.removeDrawing(e); | ||
| } | ||
| clearDrawings() { | ||
| this.drawingManager.clearDrawings(); | ||
| } | ||
| registerDrawingTool(e) { | ||
| this.drawingManager.register(e); | ||
| } | ||
| undo() { | ||
| return this.features.drawingUndoRedo ? this.drawingManager.undo() : !1; | ||
| } | ||
| redo() { | ||
| return this.features.drawingUndoRedo ? this.drawingManager.redo() : !1; | ||
| } | ||
| getUndoRedoState() { | ||
| return this.undoRedoManager.getState(); | ||
| } | ||
| setDrawingMagnet(e) { | ||
| this.drawingManager.setMagnetMode(e ? "magnet" : "none"); | ||
| } | ||
| getDrawingMagnet() { | ||
| return this.drawingManager.getMagnetMode() === "magnet"; | ||
| } | ||
| lockAllDrawings() { | ||
| this.drawingManager.lockAllDrawings(); | ||
| } | ||
| unlockAllDrawings() { | ||
| this.drawingManager.unlockAllDrawings(); | ||
| } | ||
| hideAllDrawings() { | ||
| this.drawingManager.hideAllDrawings(); | ||
| } | ||
| showAllDrawings() { | ||
| this.drawingManager.showAllDrawings(); | ||
| } | ||
| duplicateDrawing(e) { | ||
| let t = e ?? this.drawingManager.getSelectedDrawingId(); | ||
| return t ? this.drawingManager.duplicateDrawing(t) : null; | ||
| } | ||
| exportVisibleData(e = "csv", t) { | ||
| let n = this.viewport.getState(), r = this.dataManager.getData(), i = Math.max(0, n.visibleRange.from), a = Math.min(r.length - 1, n.visibleRange.to), o = r.slice(i, a + 1); | ||
| if (e === "json") { | ||
| let e = v.toJSON(o); | ||
| v.download(e, t ?? "chart-data.json", "application/json"); | ||
| } else { | ||
| let e = v.toCSV(o); | ||
| v.download(e, t ?? "chart-data.csv", "text/csv"); | ||
| } | ||
| } | ||
| exportAllData(e = "csv", t) { | ||
| let n = this.dataManager.getData(); | ||
| if (e === "json") { | ||
| let e = v.toJSON(n); | ||
| v.download(e, t ?? "chart-data.json", "application/json"); | ||
| } else { | ||
| let e = v.toCSV(n); | ||
| v.download(e, t ?? "chart-data.csv", "text/csv"); | ||
| } | ||
| } | ||
| setAutoSave(e, t = 5e3) { | ||
| this.autoSaveScheduler.enable(e, t); | ||
| } | ||
| disableAutoSave() { | ||
| this.autoSaveScheduler.disable(); | ||
| } | ||
| scheduleAutoSave() { | ||
| this.autoSaveScheduler.schedule(); | ||
| } | ||
| getAvailableIndicators() { | ||
| return this.indicatorEngine.getAvailableIndicators(); | ||
| } | ||
| getIndicatorInputs(e) { | ||
| let t = this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e); | ||
| return t ? { | ||
| id: t.id, | ||
| params: t.defaultConfig | ||
| } : null; | ||
| } | ||
| getActiveIndicators() { | ||
| return this.indicatorEngine.getActiveIndicators(); | ||
| } | ||
| getIndicatorConfig(e) { | ||
| let t = this.indicatorEngine.getIndicatorConfig(e); | ||
| return t ? { | ||
| id: t.id, | ||
| params: { ...t.params } | ||
| } : null; | ||
| } | ||
| updateIndicatorStyle(e, t) { | ||
| this.indicatorEngine.updateIndicatorStyle(e, t), this.engine.requestRender(); | ||
| } | ||
| setOrders(e) { | ||
| this.features.trading && this.tradingManager.setOrders(e); | ||
| } | ||
| setPositions(e) { | ||
| this.features.trading && this.tradingManager.setPositions(e); | ||
| } | ||
| setDepthData(e) { | ||
| this.features.trading && this.tradingManager.setDepthData(e); | ||
| } | ||
| setCurrentPrice(e, t) { | ||
| this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e), this.scheduleRender(), this.features.alerts && this.alertManager.checkPrice(e); | ||
| } | ||
| setTradingConfig(e) { | ||
| this.features.trading && this.tradingManager.setConfig(e); | ||
| } | ||
| async connect(e) { | ||
| this.disconnectStream(), this.streamManager = new T(), this.streamManager.on("snapshot", (e) => { | ||
| this.setData(e); | ||
| }), this.streamManager.on("barClose", (e) => { | ||
| this.dataManager.appendBar(e), this.crosshairHandler.setData(this.dataManager.getData()), this.autoScrollOnNewBar && this.viewport.scrollToEnd(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.updateViewportAndRender(); | ||
| }), this.streamManager.on("barUpdate", (e) => { | ||
| this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender(); | ||
| }), this.streamManager.on("priceChange", ({ price: e }) => { | ||
| this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e), this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI); | ||
| }), this.streamManager.on("connectionChange", (e) => { | ||
| this.eventBus.emit("dataUpdate", { connection: e }); | ||
| }), this.streamManager.on("error", (e) => { | ||
| this.eventBus.emit("dataUpdate", { error: e.message }); | ||
| }), this.autoScrollOnNewBar = e.autoScroll !== !1, this.currentSymbol = e.symbol, await this.streamManager.connect(e); | ||
| let t = u(e.timeframe); | ||
| this.barCountdown.setTimeframeMs(t), this.countdownInterval && clearInterval(this.countdownInterval), this.countdownInterval = setInterval(() => { | ||
| this.barCountdown.isVisible() && this.engine.requestRender(r.UI); | ||
| }, 1e3); | ||
| } | ||
| async switchStream(e, t) { | ||
| this.streamManager && (this.currentSymbol = e, await this.streamManager.switchTo(e, t)); | ||
| } | ||
| async setTimeframe(e) { | ||
| if (!this.streamManager) throw Error("No active stream. Call connect() first."); | ||
| await this.switchStream(this.currentSymbol, e); | ||
| } | ||
| disconnectStream() { | ||
| this.streamManager &&= (this.streamManager.dispose(), null); | ||
| } | ||
| setBarCountdownVisible(e) { | ||
| this.barCountdown.setVisible(e), this.engine.requestRender(r.UI); | ||
| } | ||
| setSessionBreaksVisible(e) { | ||
| this.sessionBreaks.setVisible(e), this.engine.requestRender(r.Background); | ||
| } | ||
| addCompareSymbol(e, t, n, i) { | ||
| this.compareRenderer.addSymbol({ | ||
| id: e, | ||
| label: t, | ||
| data: n, | ||
| color: i, | ||
| visible: !0 | ||
| }), this.engine.requestRender(r.Main); | ||
| } | ||
| removeCompareSymbol(e) { | ||
| this.compareRenderer.removeSymbol(e), this.engine.requestRender(r.Main); | ||
| } | ||
| updateCompareData(e, t) { | ||
| this.compareRenderer.setSymbolData(e, t), this.engine.requestRender(r.Main); | ||
| } | ||
| setCompareMode(e) { | ||
| this.compareRenderer.setMode(e), this.engine.requestRender(r.Main); | ||
| } | ||
| clearCompareSymbols() { | ||
| this.compareRenderer.clear(), this.engine.requestRender(r.Main); | ||
| } | ||
| setLogScale(e) { | ||
| this.viewport.setLogScale(e), this.updateViewportAndRender(); | ||
| } | ||
| isLogScale() { | ||
| return this.viewport.isLogScale(); | ||
| } | ||
| setSessionBreaksConfig(e) { | ||
| this.sessionBreaks.setConfig(e), this.engine.requestRender(r.Background); | ||
| } | ||
| getConnectionState() { | ||
| return this.streamManager?.getConnectionState() ?? "disconnected"; | ||
| } | ||
| getConnectionInfo() { | ||
| return this.streamManager?.getConnectionInfo() ?? { state: "disconnected" }; | ||
| } | ||
| setAutoScroll(e) { | ||
| this.autoScrollOnNewBar = e; | ||
| } | ||
| scrollTo(e) { | ||
| let t = this.dataManager.getData(); | ||
| for (let n = 0; n < t.length; n++) if (t[n].time >= e) { | ||
| let e = this.viewport.getState().barWidth + this.viewport.getState().barSpacing; | ||
| this.viewport.scrollBy(n * e - this.viewport.getState().offset), this.updateViewportAndRender(); | ||
| return; | ||
| } | ||
| } | ||
| scrollToEnd() { | ||
| this.viewport.scrollToEnd(), this.updateViewportAndRender(); | ||
| } | ||
| setVisibleRange(e, t) { | ||
| let n = this.dataManager.getData(), r = 0, i = n.length - 1; | ||
| for (let t = 0; t < n.length; t++) if (n[t].time >= e) { | ||
| r = t; | ||
| break; | ||
| } | ||
| for (let e = n.length - 1; e >= 0; e--) if (n[e].time <= t) { | ||
| i = e; | ||
| break; | ||
| } | ||
| let a = i - r + 1; | ||
| if (a > 0) { | ||
| let e = this.viewport.getState().chartRect.width, t = e / a, n = Math.max(2, t - this.viewport.getState().barSpacing); | ||
| this.viewport.zoom((n - this.viewport.getState().barWidth) / this.viewport.getState().barWidth, e / 2); | ||
| } | ||
| this.updateViewportAndRender(); | ||
| } | ||
| zoomIn() { | ||
| let e = this.viewport.getState().chartRect.width; | ||
| this.viewport.zoom(.2, e / 2), this.updateViewportAndRender(); | ||
| } | ||
| zoomOut() { | ||
| let e = this.viewport.getState().chartRect.width; | ||
| this.viewport.zoom(-.2, e / 2), this.updateViewportAndRender(); | ||
| } | ||
| fitContent() { | ||
| let e = this.dataManager.getData(); | ||
| e.length !== 0 && this.setVisibleRange(e[0].time, e[e.length - 1].time); | ||
| } | ||
| on(e, t) { | ||
| this.eventBus.on(e, t); | ||
| } | ||
| off(e, t) { | ||
| this.eventBus.off(e, t); | ||
| } | ||
| enableTauriBridge(e) { | ||
| this.eventBus.enableTauriBridge({ | ||
| enabled: !0, | ||
| ...e | ||
| }); | ||
| } | ||
| disableTauriBridge() { | ||
| this.eventBus.disableTauriBridge(); | ||
| } | ||
| setTheme(e) { | ||
| this.themeManager.setTheme(e), this.syncRenderContext(), this.container.style.backgroundColor = this.themeManager.getTheme().background, this.engine.requestRender(), this.eventBus.emit("themeChange", { theme: e }); | ||
| } | ||
| getTheme() { | ||
| return this.themeManager.getTheme(); | ||
| } | ||
| setWatermark(e, t) { | ||
| this.watermark.setConfig({ | ||
| text: e, | ||
| ...t | ||
| }), this.engine.requestRender(r.Background); | ||
| } | ||
| setAutoScale(e) { | ||
| this.options.autoScale = e, this.updateViewportAndRender(); | ||
| } | ||
| isAutoScale() { | ||
| return this.options.autoScale !== !1; | ||
| } | ||
| setCrosshairMode(e) { | ||
| this.crosshairHandler.setMode(e), this.engine.requestRender(r.Overlay); | ||
| } | ||
| getCrosshairMode() { | ||
| return this.crosshairHandler.getMode(); | ||
| } | ||
| setCrosshairPosition(e) { | ||
| e && this.crosshairHandler.onPointerMove(e), this.engine.requestRender(r.Overlay); | ||
| } | ||
| getData() { | ||
| return this.dataManager.getData(); | ||
| } | ||
| setGridVisible(e) { | ||
| this.gridRenderer.setVisible(e), this.engine.requestRender(r.Background); | ||
| } | ||
| isGridVisible() { | ||
| return this.gridRenderer.isVisible(); | ||
| } | ||
| setVolumeVisible(e) { | ||
| this.volumeRenderer.setVisible(e), this.engine.requestRender(r.Main); | ||
| } | ||
| setVolumeProfileVisible(e) { | ||
| this.volumeProfile.setVisible(e), this.engine.requestRender(r.Main); | ||
| } | ||
| isVolumeProfileVisible() { | ||
| return this.volumeProfile.isVisible(); | ||
| } | ||
| setVolumeProfileConfig(e) { | ||
| e.buckets !== void 0 && this.volumeProfile.setBuckets(e.buckets), e.widthRatio !== void 0 && this.volumeProfile.setWidthRatio(e.widthRatio), e.opacity !== void 0 && this.volumeProfile.setOpacity(e.opacity), e.highlightPoC !== void 0 && this.volumeProfile.setHighlightPoC(e.highlightPoC), this.engine.requestRender(r.Main); | ||
| } | ||
| setTooltipVisible(e) { | ||
| e || this.crosshairTooltip.hide(); | ||
| } | ||
| setLegend(e) { | ||
| this.chartLegend.setConfig(e), this.engine.requestRender(r.UI); | ||
| } | ||
| setSymbolName(e) { | ||
| this.chartLegend.setSymbol(e), this.engine.requestRender(r.UI); | ||
| } | ||
| setStatusText(e) { | ||
| this.chartLegend.setStatusText(e), this.engine.requestRender(r.UI); | ||
| } | ||
| screenshot(e) { | ||
| this.features.screenshot && x.download(this.container, e, this.themeManager.getTheme().background); | ||
| } | ||
| screenshotDataURL() { | ||
| return this.features.screenshot ? x.toDataURL(this.container, this.themeManager.getTheme().background) : null; | ||
| } | ||
| async screenshotBlob() { | ||
| return this.features.screenshot ? x.toBlob(this.container, this.themeManager.getTheme().background) : null; | ||
| } | ||
| addAlert(e, t = "crossing", n) { | ||
| if (!this.features.alerts) return null; | ||
| let r = this.alertManager.addAlert(e, t, n); | ||
| return this.scheduleAutoSave(), r; | ||
| } | ||
| removeAlert(e) { | ||
| this.alertManager.removeAlert(e), this.scheduleAutoSave(); | ||
| } | ||
| getAlerts() { | ||
| return this.alertManager.getAlerts(); | ||
| } | ||
| clearAlerts() { | ||
| this.alertManager.clearAlerts(), this.scheduleAutoSave(); | ||
| } | ||
| saveAlerts(e) { | ||
| this.alertManager.saveToStorage(e); | ||
| } | ||
| loadAlerts(e) { | ||
| this.alertManager.loadFromStorage(e), this.engine.requestRender(r.Overlay); | ||
| } | ||
| addSignalMarker(e) { | ||
| return this.signalMarkerManager.addMarker(e); | ||
| } | ||
| removeSignalMarker(e) { | ||
| this.signalMarkerManager.removeMarker(e); | ||
| } | ||
| getSignalMarkers() { | ||
| return this.signalMarkerManager.getMarkers(); | ||
| } | ||
| setSignalMarkers(e) { | ||
| this.signalMarkerManager.setMarkers(e); | ||
| } | ||
| clearSignalMarkers() { | ||
| this.signalMarkerManager.clearMarkers(); | ||
| } | ||
| setSignalMarkerStyle(e) { | ||
| this.signalMarkerManager.setStyle(e); | ||
| } | ||
| addTradeZone(e) { | ||
| return this.tradeZoneManager.addZone(e); | ||
| } | ||
| updateTradeZone(e, t) { | ||
| this.tradeZoneManager.updateZone(e, t); | ||
| } | ||
| removeTradeZone(e) { | ||
| this.tradeZoneManager.removeZone(e); | ||
| } | ||
| getTradeZones() { | ||
| return this.tradeZoneManager.getZones(); | ||
| } | ||
| setTradeZones(e) { | ||
| this.tradeZoneManager.setZones(e); | ||
| } | ||
| clearTradeZones() { | ||
| this.tradeZoneManager.clearZones(); | ||
| } | ||
| setTradeZoneStyle(e) { | ||
| this.tradeZoneManager.setStyle(e); | ||
| } | ||
| replay(e) { | ||
| if (!this.features.replay) return; | ||
| let t = this.dataManager.getData(); | ||
| this.replayManager.load(t), this.replayManager.on("bar", ({ bar: e, index: n }) => { | ||
| let r = t.slice(0, n + 1); | ||
| this.dataManager.setData(r), this.crosshairHandler.setData(r), this.indicatorEngine.recalculateAll(r), this.updateViewportAndRender(); | ||
| }), this.replayManager.play(e); | ||
| } | ||
| replayPause() { | ||
| this.replayManager.pause(); | ||
| } | ||
| replayResume() { | ||
| this.replayManager.resume(); | ||
| } | ||
| replayStop() { | ||
| this.replayManager.stop(); | ||
| } | ||
| replaySeek(e) { | ||
| this.replayManager.seekTo(e); | ||
| } | ||
| setReplaySpeed(e) { | ||
| this.replayManager.setSpeed(e); | ||
| } | ||
| getReplayState() { | ||
| return this.replayManager.getState(); | ||
| } | ||
| getReplayProgress() { | ||
| return this.replayManager.getProgress(); | ||
| } | ||
| saveState(e) { | ||
| if (!this.features.saveLoad) return null; | ||
| let t = _.capture({ | ||
| getDrawings: () => this.getDrawings(), | ||
| getTheme: () => this.getTheme(), | ||
| getAlerts: () => this.getAlerts() | ||
| }, { chartType: this.options.chartType }), n = _.serialize(t); | ||
| return e && _.saveToStorage(e, t), n; | ||
| } | ||
| loadState(e) { | ||
| if (!this.features.saveLoad) return; | ||
| let t = _.deserialize(e); | ||
| if (t.chartType && this.setChartType(t.chartType), t.drawings && this.setDrawings(t.drawings), t.theme && this.setTheme(t.theme), t.alerts) { | ||
| this.clearAlerts(); | ||
| for (let e of t.alerts) this.addAlert(e.price, e.condition, e.message); | ||
| } | ||
| } | ||
| loadStateFromStorage(e) { | ||
| if (!this.features.saveLoad) return !1; | ||
| let t = _.loadFromStorage(e); | ||
| return t ? (this.loadState(_.serialize(t)), !0) : !1; | ||
| } | ||
| downloadState(e) { | ||
| if (!this.features.saveLoad) return; | ||
| let t = _.capture({ | ||
| getDrawings: () => this.getDrawings(), | ||
| getTheme: () => this.getTheme(), | ||
| getAlerts: () => this.getAlerts() | ||
| }, { chartType: this.options.chartType }); | ||
| _.downloadFile(t, e); | ||
| } | ||
| async loadStateFromFile() { | ||
| if (!this.features.saveLoad) return; | ||
| let e = await _.loadFromFile(); | ||
| this.loadState(_.serialize(e)); | ||
| } | ||
| setLocale(e) { | ||
| l(e), this.engine.requestRender(); | ||
| } | ||
| setNumberLocale(e) { | ||
| this.numberLocale = e, this.priceAxis.setLocale(e), this.crosshairHandler.setLocale(e), this.syncRenderContext(), this.engine.requestRender(); | ||
| } | ||
| getNumberLocale() { | ||
| return this.numberLocale; | ||
| } | ||
| setMarket(e) { | ||
| if (this.marketConfig = e, e.colorScheme) { | ||
| let t = { | ||
| ...this.themeManager.getTheme(), | ||
| candleUp: e.colorScheme.up, | ||
| candleDown: e.colorScheme.down, | ||
| candleUpWick: e.colorScheme.up, | ||
| candleDownWick: e.colorScheme.down, | ||
| volumeUp: e.colorScheme.up.replace(")", ", 0.3)").replace("rgb(", "rgba(") || `${e.colorScheme.up}4D`, | ||
| volumeDown: e.colorScheme.down.replace(")", ", 0.3)").replace("rgb(", "rgba(") || `${e.colorScheme.down}4D` | ||
| }; | ||
| this.themeManager.setTheme(t); | ||
| } | ||
| e.pricePrecision !== void 0 && (this.tradingManager.setConfig({ pricePrecision: e.pricePrecision }), this.alertManager.setPricePrecision(e.pricePrecision), this.streamManager?.priceLine.setPricePrecision(e.pricePrecision), this.crosshairHandler.setPricePrecision(e.pricePrecision)), this.syncRenderContext(), this.engine.requestRender(); | ||
| } | ||
| getMarket() { | ||
| return this.marketConfig; | ||
| } | ||
| setPriceLimits(e) { | ||
| this.marketConfig && (s(e, this.marketConfig) && (this.marketConfig.priceLimits = { | ||
| ...this.marketConfig.priceLimits, | ||
| referencePrice: e | ||
| }), this.engine.requestRender()); | ||
| } | ||
| getFeatures() { | ||
| return this.features; | ||
| } | ||
| setFeatures(e) { | ||
| Object.assign(this.features, e), e.crosshair === !1 && this.crosshairTooltip.hide(), e.grid !== void 0 && this.engine.requestRender(r.Background), e.volume !== void 0 && (this.volumeRenderer.setVisible(e.volume), this.engine.requestRender(r.Main)), e.drawings === !1 && this.drawingManager.setActiveTool(null), e.trading === !1 && (this.tradingManager.setOrders([]), this.tradingManager.setPositions([])), e.keyboard !== void 0 && this.keyboardHandler?.setEnabled(e.keyboard), this.engine.requestRender(); | ||
| } | ||
| resize() { | ||
| let e = this.engine.dprManager.readContainerSize(); | ||
| if (e.width <= 0 || e.height <= 0) return; | ||
| this.containerSizeCache = e, this.containerSizeCacheTime = Date.now(); | ||
| let t = this.engine.dprManager.getDpr(); | ||
| this.engine.layerManager.resize(e, t); | ||
| let n = this.viewport.isAtEnd(); | ||
| this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(n), this.eventBus.emit("resize", e); | ||
| } | ||
| destroy() { | ||
| this.countdownInterval && clearInterval(this.countdownInterval), this.disableAutoSave(), this.disconnectStream(), this.onWindowKeyDown &&= (window.removeEventListener("keydown", this.onWindowKeyDown), null), this.keyboardHandler = null, this.interactionManager.detach(), this.tradingManager.destroy(), this.animator.dispose(), this.crosshairTooltip.destroy(), this.pinnedTooltip.destroy(), this.replayManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = ""; | ||
| } | ||
| createChartRenderer(e) { | ||
| return Ve(e); | ||
| } | ||
| getDisplayData() { | ||
| if (this.displayDataCache) return this.displayDataCache; | ||
| let e = this.dataManager.getData(); | ||
| if (e.length === 0) return e; | ||
| let t = He(this.options.chartType, e); | ||
| return this.displayDataCache = t, t; | ||
| } | ||
| scheduleRender() { | ||
| this.renderScheduled || (this.renderScheduled = !0, requestAnimationFrame(() => { | ||
| this.renderScheduled = !1; | ||
| let e = this.getDisplayData(); | ||
| this.viewport.updateData(e, this.options.autoScale !== !1), this.syncRenderContext(), this.engine.requestRender(); | ||
| })); | ||
| } | ||
| updateViewportAndRender(e = !1) { | ||
| this.resolvedLayoutCache = null, this.panelInfoCache = null; | ||
| let t = this.getResolvedLayout(); | ||
| this.viewport.setChartRect(t.mainChartRect); | ||
| let n = this.getDisplayData(); | ||
| if (this.viewport.updateData(n, this.options.autoScale !== !1), this.options.autoScale !== !1) { | ||
| let e = this.viewport.getState(), t = this.indicatorEngine.getOverlayPriceRange(e.visibleRange.from, Math.min(e.visibleRange.to, n.length - 1)); | ||
| if (t) { | ||
| let n = e.priceRange, r = Math.min(n.min, t.min), i = Math.max(n.max, t.max); | ||
| if (r < n.min || i > n.max) { | ||
| let e = i - r || 1; | ||
| this.viewport.setPriceRange(r - e * .02, i + e * .02); | ||
| } | ||
| } | ||
| } | ||
| e && this.viewport.scrollToEnd(), this.syncRenderContext(), this.engine.requestRender(); | ||
| } | ||
| getResolvedLayout() { | ||
| return this.resolvedLayoutCache ||= this.layoutManager.resolve(), this.resolvedLayoutCache; | ||
| } | ||
| cachedContainerSize() { | ||
| let e = Date.now(); | ||
| return (!this.containerSizeCache || e - this.containerSizeCacheTime > 500) && (this.containerSizeCache = this.engine.dprManager.getContainerSize(), this.containerSizeCacheTime = e), this.containerSizeCache; | ||
| } | ||
| buildPanelRenderInfos() { | ||
| if (this.panelInfoCache) return this.panelInfoCache; | ||
| let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => { | ||
| let i = Ue(this.indicatorEngine.getOutput(e.config.id), n, r), a = { | ||
| x: e.rect.x, | ||
| y: e.rect.y + 20, | ||
| width: e.rect.width, | ||
| height: Math.max(0, e.rect.height - 20) | ||
| }; | ||
| return { | ||
| instanceId: e.config.id, | ||
| rect: e.rect, | ||
| viewport: { | ||
| ...t, | ||
| chartRect: a, | ||
| priceRange: i | ||
| } | ||
| }; | ||
| }); | ||
| return this.panelInfoCache = i, i; | ||
| } | ||
| syncRenderContext() { | ||
| this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), null, null, this.themeManager.getTheme()); | ||
| let e = this.getResolvedLayout(), t = this.features.indicators ? this.buildPanelRenderInfos() : [], n = e.panels.filter((e) => e.config.position === "bottom").reduce((e, t) => e + t.rect.height, 0), r = e.mainChartRect.y + e.mainChartRect.height + n, i = this.getDisplayData(); | ||
| this.engine.setRenderContext({ | ||
| chartRenderer: this.chartRenderer, | ||
| gridRenderer: this.features.grid ? this.gridRenderer : null, | ||
| priceAxis: this.features.priceAxis ? this.priceAxis : null, | ||
| timeAxis: this.features.timeAxis ? this.timeAxis : null, | ||
| crosshairHandler: this.features.crosshair ? this.crosshairHandler : null, | ||
| indicatorEngine: this.features.indicators ? this.indicatorEngine : null, | ||
| drawingRenderer: this.features.drawings ? this.drawingRenderer : null, | ||
| tradingRenderer: this.features.trading ? this.tradingRenderer : null, | ||
| currentPriceLine: this.streamManager?.priceLine ?? this.currentPriceLine, | ||
| chartLegend: this.features.legend ? this.chartLegend : null, | ||
| volumeRenderer: this.features.volume ? this.volumeRenderer : null, | ||
| volumeProfile: this.volumeProfile, | ||
| watermark: this.features.watermark ? this.watermark : null, | ||
| barCountdown: this.barCountdown, | ||
| sessionBreaks: this.sessionBreaks, | ||
| compareRenderer: this.compareRenderer, | ||
| alertManager: this.features.alerts ? this.alertManager : null, | ||
| measureOverlay: this.measureOverlay, | ||
| signalMarkerManager: this.signalMarkerManager, | ||
| tradeZoneManager: this.tradeZoneManager, | ||
| panels: t, | ||
| priceLimits: this.buildPriceLimits(), | ||
| timeAxisY: r, | ||
| viewport: { | ||
| ...this.viewport.getState(), | ||
| data: i | ||
| }, | ||
| theme: this.themeManager.getTheme(), | ||
| data: i, | ||
| numberLocale: this.numberLocale | ||
| }); | ||
| } | ||
| buildPriceLimits() { | ||
| if (!this.marketConfig?.priceLimits?.enabled || !this.marketConfig.priceLimits.referencePrice) return null; | ||
| let e = s(this.marketConfig.priceLimits.referencePrice, this.marketConfig); | ||
| return e ? { | ||
| ...e, | ||
| colors: this.marketConfig.colorScheme ? { | ||
| ceiling: this.marketConfig.colorScheme.ceiling, | ||
| floor: this.marketConfig.colorScheme.floor, | ||
| reference: this.marketConfig.colorScheme.reference | ||
| } : void 0 | ||
| } : null; | ||
| } | ||
| }, V = [ | ||
| "time", | ||
| "timestamp", | ||
| "date", | ||
| "datetime", | ||
| "t" | ||
| ], H = ["open", "o"], U = ["high", "h"], W = ["low", "l"], G = ["close", "c"], K = [ | ||
| "volume", | ||
| "vol", | ||
| "v" | ||
| ]; | ||
| function q(e) { | ||
| let t = e.trim(); | ||
| return t ? t[0] === "[" || t[0] === "{" ? Ke(t) : qe(t) : { | ||
| data: [], | ||
| rowCount: 0, | ||
| skipped: 0 | ||
| }; | ||
| } | ||
| function Ke(e) { | ||
| let t; | ||
| try { | ||
| t = JSON.parse(e); | ||
| } catch (e) { | ||
| throw Error(`Invalid JSON: ${e.message}`); | ||
| } | ||
| if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows"); | ||
| let n = [], r = 0; | ||
| for (let e of t) { | ||
| let t = Array.isArray(e) ? Xe(e) : Ye(e); | ||
| t ? n.push(t) : r++; | ||
| } | ||
| return Q(n, t.length, r); | ||
| } | ||
| function qe(e) { | ||
| let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0); | ||
| if (t.length === 0) return { | ||
| data: [], | ||
| rowCount: 0, | ||
| skipped: 0 | ||
| }; | ||
| let n = Je(t[0]), r = J(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? Y(r) : { | ||
| time: 0, | ||
| open: 1, | ||
| high: 2, | ||
| low: 3, | ||
| close: 4, | ||
| volume: 5 | ||
| }; | ||
| if (a.time < 0 || a.open < 0 || a.high < 0 || a.low < 0 || a.close < 0) throw Error("CSV is missing required column(s): time, open, high, low, close"); | ||
| let o = [], s = 0; | ||
| for (let e = +!!i; e < t.length; e++) { | ||
| let r = J(t[e], n), i = Z(r[a.time]), c = X(r[a.open]), l = X(r[a.high]), u = X(r[a.low]), d = X(r[a.close]), f = a.volume >= 0 ? Number(r[a.volume]) : 0; | ||
| if (i === null || ![ | ||
| c, | ||
| l, | ||
| u, | ||
| d | ||
| ].every(Number.isFinite)) { | ||
| s++; | ||
| continue; | ||
| } | ||
| o.push({ | ||
| time: i, | ||
| open: c, | ||
| high: l, | ||
| low: u, | ||
| close: d, | ||
| volume: Number.isFinite(f) ? f : 0 | ||
| }); | ||
| } | ||
| return Q(o, t.length - +!!i, s); | ||
| } | ||
| function Je(e) { | ||
| let t = { | ||
| ",": 0, | ||
| ";": 0, | ||
| " ": 0, | ||
| "|": 0 | ||
| }; | ||
| for (let n of e) n in t && t[n]++; | ||
| let n = ",", r = 0; | ||
| for (let [e, i] of Object.entries(t)) i > r && (n = e, r = i); | ||
| return n; | ||
| } | ||
| function J(e, t) { | ||
| let n = [], r = "", i = !1; | ||
| for (let a = 0; a < e.length; a++) { | ||
| let o = e[a]; | ||
| o === "\"" ? i && e[a + 1] === "\"" ? (r += "\"", a++) : i = !i : o === t && !i ? (n.push(r), r = "") : r += o; | ||
| } | ||
| return n.push(r), n; | ||
| } | ||
| function Y(e) { | ||
| let t = (t) => e.findIndex((e) => t.includes(e)); | ||
| return { | ||
| time: t(V), | ||
| open: t(H), | ||
| high: t(U), | ||
| low: t(W), | ||
| close: t(G), | ||
| volume: t(K) | ||
| }; | ||
| } | ||
| function Ye(e) { | ||
| let t = (t) => { | ||
| for (let n of t) { | ||
| if (e[n] !== void 0) return e[n]; | ||
| let t = n.toUpperCase(); | ||
| if (e[t] !== void 0) return e[t]; | ||
| } | ||
| }, n = Z(String(t(V) ?? "")), r = Number(t(H)), i = Number(t(U)), a = Number(t(W)), o = Number(t(G)), s = Number(t(K) ?? 0); | ||
| return n === null || ![ | ||
| r, | ||
| i, | ||
| a, | ||
| o | ||
| ].every(Number.isFinite) ? null : { | ||
| time: n, | ||
| open: r, | ||
| high: i, | ||
| low: a, | ||
| close: o, | ||
| volume: Number.isFinite(s) ? s : 0 | ||
| }; | ||
| } | ||
| function Xe(e) { | ||
| if (e.length < 5) return null; | ||
| let t = Z(String(e[0])), n = Number(e[1]), r = Number(e[2]), i = Number(e[3]), a = Number(e[4]), o = e.length >= 6 ? Number(e[5]) : 0; | ||
| return t === null || ![ | ||
| n, | ||
| r, | ||
| i, | ||
| a | ||
| ].every(Number.isFinite) ? null : { | ||
| time: t, | ||
| open: n, | ||
| high: r, | ||
| low: i, | ||
| close: a, | ||
| volume: Number.isFinite(o) ? o : 0 | ||
| }; | ||
| } | ||
| function X(e) { | ||
| return e === void 0 || e.trim() === "" ? NaN : Number(e); | ||
| } | ||
| function Z(e) { | ||
| let t = e.trim(); | ||
| if (!t) return null; | ||
| let n = Number(t); | ||
| if (Number.isFinite(n) && n > 0) return n < 0xe8d4a51000 ? n * 1e3 : n; | ||
| let r = Date.parse(t); | ||
| return Number.isFinite(r) ? r : null; | ||
| } | ||
| function Q(e, t, n) { | ||
| e.sort((e, t) => e.time - t.time); | ||
| let r = []; | ||
| for (let t of e) r.length > 0 && r[r.length - 1].time === t.time ? r[r.length - 1] = t : r.push(t); | ||
| return { | ||
| data: r, | ||
| rowCount: t, | ||
| skipped: n | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/io/DragDropImporter.ts | ||
| var Ze = class { | ||
| host; | ||
| overlay = null; | ||
| callbacks; | ||
| bound; | ||
| depth = 0; | ||
| constructor(e, t) { | ||
| this.host = e, this.callbacks = t, this.bound = { | ||
| dragenter: (e) => this.onDragEnter(e), | ||
| dragover: (e) => this.onDragOver(e), | ||
| dragleave: (e) => this.onDragLeave(e), | ||
| drop: (e) => this.onDrop(e) | ||
| }; | ||
| } | ||
| attach() { | ||
| this.host.addEventListener("dragenter", this.bound.dragenter), this.host.addEventListener("dragover", this.bound.dragover), this.host.addEventListener("dragleave", this.bound.dragleave), this.host.addEventListener("drop", this.bound.drop); | ||
| } | ||
| detach() { | ||
| this.host.removeEventListener("dragenter", this.bound.dragenter), this.host.removeEventListener("dragover", this.bound.dragover), this.host.removeEventListener("dragleave", this.bound.dragleave), this.host.removeEventListener("drop", this.bound.drop), this.hideOverlay(); | ||
| } | ||
| onDragEnter(e) { | ||
| $(e) && (e.preventDefault(), this.depth++, this.showOverlay()); | ||
| } | ||
| onDragOver(e) { | ||
| $(e) && (e.preventDefault(), e.dataTransfer && (e.dataTransfer.dropEffect = "copy")); | ||
| } | ||
| onDragLeave(e) { | ||
| $(e) && (this.depth = Math.max(0, this.depth - 1), this.depth === 0 && this.hideOverlay()); | ||
| } | ||
| async onDrop(e) { | ||
| e.preventDefault(), this.depth = 0, this.hideOverlay(); | ||
| let t = e.dataTransfer?.files?.[0]; | ||
| if (t) try { | ||
| let e = q(await t.text()); | ||
| if (e.data.length === 0) throw Error(`No valid OHLCV rows found in "${t.name}"`); | ||
| this.callbacks.onData(e.data, e, t); | ||
| } catch (e) { | ||
| this.callbacks.onError?.(e, t); | ||
| } | ||
| } | ||
| showOverlay() { | ||
| this.overlay || (this.overlay = document.createElement("div"), Object.assign(this.overlay.style, { | ||
| position: "absolute", | ||
| inset: "8px", | ||
| zIndex: "90", | ||
| pointerEvents: "none", | ||
| borderRadius: "10px", | ||
| border: "2px dashed var(--tcw-accent, #4f88ff)", | ||
| background: "rgba(79, 136, 255, 0.06)", | ||
| display: "flex", | ||
| alignItems: "center", | ||
| justifyContent: "center", | ||
| color: "var(--tcw-accent, #4f88ff)", | ||
| fontSize: "14px", | ||
| fontWeight: "600", | ||
| letterSpacing: "-0.005em", | ||
| fontFamily: "inherit", | ||
| backdropFilter: "blur(2px)" | ||
| }), this.overlay.textContent = "Drop CSV or JSON to load chart data", getComputedStyle(this.host).position === "static" && (this.host.style.position = "relative"), this.host.appendChild(this.overlay)); | ||
| } | ||
| hideOverlay() { | ||
| this.overlay?.remove(), this.overlay = null; | ||
| } | ||
| }; | ||
| function $(e) { | ||
| return e.dataTransfer?.types?.includes("Files") ?? !1; | ||
| } | ||
| //#endregion | ||
| export { z as a, B as i, q as n, I as o, Ge as r, F as s, Ze as t }; | ||
| //# sourceMappingURL=DragDropImporter-6QOjnfSj.js.map |
Sorry, the diff of this file is too big to display
| let e=require(`@tradecanvas/commons`),t=require(`@tradecanvas/core`);function n(e){switch(e){case`candlestick`:case`heikinAshi`:case`lineBreak`:case`rangeBars`:return new t.CandlestickRenderer;case`line`:return new t.LineRenderer;case`area`:return new t.AreaRenderer;case`bar`:return new t.BarRenderer;case`hollowCandle`:return new t.HollowCandleRenderer;case`baseline`:return new t.BaselineRenderer;case`renko`:return new t.RenkoRenderer;case`kagi`:return new t.KagiRenderer;case`pointAndFigure`:return new t.PointAndFigureRenderer;case`volumeCandles`:return new t.VolumeCandleRenderer;case`equivolume`:return new t.EquivolumeRenderer;case`hlcArea`:return new t.HLCAreaRenderer;case`stepLine`:return new t.StepLineRenderer;case`lineWithMarkers`:return new t.LineWithMarkersRenderer;default:return new t.CandlestickRenderer}}function r(e,n){if(n.length===0)return n;switch(e){case`heikinAshi`:return(0,t.toHeikinAshi)(n);case`renko`:return(0,t.toRenko)(n,{brickSize:0,useATR:!0,atrPeriod:14});case`lineBreak`:return(0,t.toLineBreak)(n,3);case`kagi`:return(0,t.toKagi)(n,4);case`pointAndFigure`:return(0,t.toPointAndFigure)(n,i(n)*.01,3);case`rangeBars`:return(0,t.toRangeBars)(n,{rangeSize:i(n)*.005});default:return n}}function i(e){let t=0;for(let n of e)t+=n.close;return t/e.length}var a={min:0,max:100},o=.1;function s(e,t,n){if(!e)return{...a};let r=1/0,i=-1/0,s=0;for(let[,a]of e.values){if(s>=t&&s<=n)for(let e in a){let t=a[e];t!==void 0&&Number.isFinite(t)&&(t<r&&(r=t),t>i&&(i=t))}s++}if(r===1/0)return{...a};let c=i-r||1;return{min:r-c*o,max:i+c*o}}var c=class{timer=null;delayMs=0;key=null;constructor(e){this.save=e}enable(e,t){this.key=e,this.delayMs=t}disable(){this.key=null,this.delayMs=0,this.cancel()}schedule(){this.delayMs<=0||!this.key||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.timer=null,this.key&&this.save(this.key)},this.delayMs))}cancel(){this.timer&&=(clearTimeout(this.timer),null)}isEnabled(){return this.delayMs>0&&this.key!==null}hasPending(){return this.timer!==null}};function l(e){if(!e||typeof e.time!=`number`)return!1;let{open:t,high:n,low:r,close:i}=e;return!(!isFinite(t)||!isFinite(n)||!isFinite(r)||!isFinite(i)||t<0||n<0||r<0||i<0||n<r||e.volume!==void 0&&(!isFinite(e.volume)||e.volume<0))}function u(e){return{...e,high:Math.max(e.open,e.high,e.low,e.close),low:Math.min(e.open,e.high,e.low,e.close),volume:e.volume===void 0?0:Math.max(0,e.volume)}}var d=class{data=[];getData(){return this.data}setData(e){this.data=e.filter(l).map(u)}appendBar(e){l(e)&&this.data.push(u(e))}updateLastBar(e){if(!l(e))return;let t=u(e);if(this.data.length===0){this.data.push(t);return}this.data[this.data.length-1]=t}updateLastBarFromTick(t){this.data.length!==0&&(!isFinite(t.price)||t.price<0||t.volume!==void 0&&(!isFinite(t.volume)||t.volume<0)||(this.data[this.data.length-1]=(0,e.mergeBar)(this.data[this.data.length-1],t)))}getLength(){return this.data.length}clear(){this.data=[]}},f=class{theme;constructor(t){!t||t===`dark`?this.theme={...e.DARK_THEME}:t===`light`?this.theme={...e.LIGHT_THEME}:this.theme={...t}}getTheme(){return this.theme}setTheme(t){t===`dark`?this.theme={...e.DARK_THEME}:t===`light`?this.theme={...e.LIGHT_THEME}:this.theme={...t}}},p=200,m=80,h=class{panels=[];containerWidth=0;containerHeight=0;resize(e,t){this.containerWidth=e,this.containerHeight=t}addPanel(t,n=`bottom`,r){let i=n===`left`||n===`right`;this.panels.push({id:t,position:n,size:r??(i?p:e.DEFAULT_PANEL_HEIGHT),minSize:i?m:e.MIN_PANEL_HEIGHT,content:{type:`indicator`,indicatorInstanceId:t}})}removePanel(e){this.panels=this.panels.filter(t=>t.id!==e)}setPanelPosition(t,n){let r=this.panels.find(e=>e.id===t);if(r){let t=r.position===`left`||r.position===`right`,i=n===`left`||n===`right`;r.position=n,t!==i&&(r.size=i?p:e.DEFAULT_PANEL_HEIGHT,r.minSize=i?m:e.MIN_PANEL_HEIGHT)}}setPanelSize(e,t){let n=this.panels.find(t=>t.id===e);n&&(n.size=Math.max(n.minSize,t))}getPanels(){return this.panels}resolve(){let t=this.panels.filter(e=>e.position===`left`),n=this.panels.filter(e=>e.position===`right`),r=this.panels.filter(e=>e.position===`top`),i=this.panels.filter(e=>e.position===`bottom`),a=t.reduce((e,t)=>e+t.size,0),o=n.reduce((e,t)=>e+t.size,0),s=r.reduce((e,t)=>e+t.size,0),c=i.reduce((e,t)=>e+t.size,0),l={x:a,y:s,width:Math.max(0,this.containerWidth-a-o-e.PRICE_AXIS_WIDTH),height:Math.max(0,this.containerHeight-s-c-e.TIME_AXIS_HEIGHT)},u=[],d=[],f=0;for(let n of t)u.push({config:n,rect:{x:f,y:0,width:n.size,height:this.containerHeight-e.TIME_AXIS_HEIGHT}}),d.push({panelId:n.id,rect:{x:f+n.size-2,y:0,width:4,height:this.containerHeight},orientation:`vertical`}),f+=n.size;let p=0;for(let e of r)u.push({config:e,rect:{x:a,y:p,width:l.width,height:e.size}}),d.push({panelId:e.id,rect:{x:a,y:p+e.size-2,width:l.width,height:4},orientation:`horizontal`}),p+=e.size;p=l.y+l.height;for(let e of i)u.push({config:e,rect:{x:a,y:p,width:l.width,height:e.size}}),d.push({panelId:e.id,rect:{x:a,y:p-2,width:l.width,height:4},orientation:`horizontal`}),p+=e.size;f=a+l.width+e.PRICE_AXIS_WIDTH;for(let t of n)u.push({config:t,rect:{x:f,y:0,width:t.size,height:this.containerHeight-e.TIME_AXIS_HEIGHT}}),d.push({panelId:t.id,rect:{x:f-2,y:0,width:4,height:this.containerHeight},orientation:`vertical`}),f+=t.size;return{mainChartRect:l,panels:u,dividers:d}}getMainChartRect(){return this.resolve().mainChartRect}},g=class{constructor(e){this.indicatorEngine=e}registerIndicator(e){this.indicatorEngine.register(e)}},_=class{static version=`0.7.0`;engine;viewport;dataManager;themeManager;layoutManager;pluginManager;indicatorEngine;drawingManager;drawingRenderer;tradingManager;tradingRenderer;eventBus;streamManager=null;autoScrollOnNewBar=!0;displayDataCache=null;resolvedLayoutCache=null;panelInfoCache=null;renderScheduled=!1;containerSizeCache=null;containerSizeCacheTime=0;chartLegend;watermark;barCountdown;sessionBreaks;compareRenderer;countdownInterval=null;volumeRenderer;volumeProfile;alertManager;signalMarkerManager;tradeZoneManager;measureOverlay;replayManager;undoRedoManager;autoSaveScheduler=new c(e=>this.saveState(e));animator;crosshairTooltip;pinnedTooltip;interactionManager;crosshairHandler;chartRenderer;gridRenderer;priceAxis;timeAxis;options;features;marketConfig=null;container;currentPriceLine;numberLocale;keyboardHandler=null;onWindowKeyDown=null;currentSymbol=``;constructor(n,r){this.container=n,this.options=r,this.numberLocale=r.numberLocale??`en-US`;let i=r.features??{};this.features={drawings:i.drawings??!0,drawingTools:i.drawingTools??[],drawingMagnet:i.drawingMagnet??!0,drawingUndoRedo:i.drawingUndoRedo??!0,trading:i.trading??!0,tradingContextMenu:i.tradingContextMenu??!0,indicators:i.indicators??!0,indicatorIds:i.indicatorIds??[],panning:i.panning??!0,zooming:i.zooming??!0,crosshair:i.crosshair??!0,keyboard:i.keyboard??!0,priceAxis:i.priceAxis??!0,timeAxis:i.timeAxis??!0,grid:i.grid??r.grid?.visible??!0,legend:i.legend??!0,volume:i.volume??!0,watermark:i.watermark??!0,saveLoad:i.saveLoad??!0,screenshot:i.screenshot??!0,alerts:i.alerts??!0,replay:i.replay??!0,sessionBreaks:i.sessionBreaks??!0,barCountdown:i.barCountdown??!0,compareSymbols:i.compareSymbols??!0,dataExport:i.dataExport??!0,logScale:i.logScale??!0,timeframes:i.timeframes??[],defaultTimeframeFavorites:i.defaultTimeframeFavorites??[]},n.style.position=`relative`,n.style.overflow=`hidden`,n.tabIndex=0,n.style.outline=`none`,this.dataManager=new d,this.themeManager=new f(r.theme),this.layoutManager=new h,this.indicatorEngine=new t.IndicatorEngine,this.pluginManager=new g(this.indicatorEngine),this.eventBus=new t.EventBus,(0,t.registerBuiltInIndicators)(this.indicatorEngine),this.drawingManager=new t.DrawingManager,(0,t.registerBuiltInDrawingTools)(this.drawingManager),this.drawingRenderer=new t.DrawingRenderer(this.drawingManager),this.drawingManager.setRequestRender(()=>{this.syncRenderContext(),this.engine.requestRender(e.LayerType.Overlay),this.scheduleAutoSave()}),this.drawingManager.setEventCallback((e,t)=>{this.eventBus.emit(e,t)}),this.undoRedoManager=new t.UndoRedoManager,this.drawingManager.setUndoRedoManager(this.undoRedoManager),this.drawingManager.setDataGetter(()=>this.dataManager.getData()),this.drawingManager.setDisplayDataGetter(()=>this.getDisplayData()),r.crosshair?.mode===`magnet`&&this.drawingManager.setMagnetMode(`magnet`),this.tradingManager=new t.TradingManager({enabled:this.features.trading,contextMenu:{enabled:this.features.tradingContextMenu}}),this.tradingRenderer=new t.TradingRenderer(this.tradingManager),this.tradingManager.setContainer(n),this.tradingManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.tradingManager.setEventCallback((e,t)=>{this.eventBus.emit(e,t)}),this.engine=new t.RenderEngine(n);let a=this.engine.dprManager.getContainerSize();if(this.viewport=new t.Viewport(a.width,a.height,r.minBarSpacing??2,r.maxBarSpacing??30,r.rightMargin??5),this.layoutManager.resize(a.width,a.height),this.engine.onContainerResize=e=>{if(e.width<=0||e.height<=0)return;let t=this.viewport.isAtEnd();this.viewport.resize(e.width,e.height),this.layoutManager.resize(e.width,e.height),this.updateViewportAndRender(t)},this.chartRenderer=this.createChartRenderer(r.chartType),this.gridRenderer=new t.GridRenderer,r.grid?.visible===!1&&this.gridRenderer.setVisible(!1),this.priceAxis=new t.PriceAxis,this.priceAxis.setLocale(this.numberLocale),this.timeAxis=new t.TimeAxis,this.crosshairHandler=new t.CrosshairHandler,this.crosshairHandler.setLocale(this.numberLocale),r.crosshair?.mode&&this.crosshairHandler.setMode(r.crosshair.mode),this.crosshairHandler.setCallback((e,t)=>{if(e!==null&&t){let n=this.dataManager.getData(),r=e<n.length?n[e]:void 0;this.chartLegend.setHoverBar(r??null),r&&this.crosshairTooltip.show(t,r,this.themeManager.getTheme(),this.cachedContainerSize()),this.pinnedTooltip.isPinned()&&this.pinnedTooltip.reposition(this.viewport.getState(),r??null,e,this.themeManager.getTheme()),this.eventBus.emit(`crosshairMove`,{point:t,bar:r,barIndex:e})}else this.crosshairTooltip.hide(),this.chartLegend.setHoverBar(null)}),this.chartLegend=new t.ChartLegend,this.chartLegend.setChartType(r.chartType),this.watermark=new t.Watermark,r.watermark&&this.watermark.setConfig(r.watermark),this.volumeRenderer=new t.VolumeRenderer,this.volumeProfile=new t.VolumeProfileRenderer,this.barCountdown=new t.BarCountdown,this.sessionBreaks=new t.SessionBreaks,this.compareRenderer=new t.CompareRenderer,r.sessionBreaks?this.sessionBreaks.setConfig({visible:r.sessionBreaks.visible??!0,color:r.sessionBreaks.color,lineStyle:r.sessionBreaks.lineStyle,lineWidth:r.sessionBreaks.lineWidth}):r.features?.sessionBreaks!==!1&&this.sessionBreaks.setVisible(!0),r.logScale&&this.viewport.setLogScale(!0),this.animator=new t.Animator,this.crosshairTooltip=new t.CrosshairTooltip,this.crosshairTooltip.create(n),this.pinnedTooltip=new t.PinnedTooltip,this.pinnedTooltip.create(n),this.keyboardHandler=new t.KeyboardHandler({scrollBars:e=>{let t=this.viewport.getState().barWidth+this.viewport.getState().barSpacing;this.viewport.scrollBy(e*t),this.updateViewportAndRender()},zoom:e=>{let t=this.viewport.getState().chartRect.width;this.viewport.zoom(e,t/2),this.updateViewportAndRender()},goToStart:()=>{this.viewport.scrollBy(-1/0),this.updateViewportAndRender()},goToEnd:()=>{this.viewport.scrollToEnd(),this.updateViewportAndRender()},fitContent:()=>this.fitContent()}),this.keyboardHandler.setEnabled(this.features.keyboard),this.onWindowKeyDown=e=>{if(!this.keyboardHandler)return;let t=document.activeElement;t&&t!==this.container&&!this.container.contains(t)||t&&(t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.isContentEditable)||this.keyboardHandler.handleKey(e)&&e.preventDefault()},window.addEventListener(`keydown`,this.onWindowKeyDown),this.currentPriceLine=new t.CurrentPriceLine,this.alertManager=new t.AlertManager,this.alertManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.alertManager.on(`triggered`,e=>{this.eventBus.emit(`dataUpdate`,{alert:`triggered`,alertId:e.id,price:e.price,message:e.message})}),this.signalMarkerManager=new t.SignalMarkerManager,this.signalMarkerManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.signalMarkerManager.setDataGetter(()=>this.dataManager.getData()),this.signalMarkerManager.on(`added`,e=>{this.eventBus.emit(`signalMarkerAdd`,{id:e.id,source:e.source,direction:e.direction})}),this.signalMarkerManager.on(`removed`,e=>{this.eventBus.emit(`signalMarkerRemove`,{id:e})}),this.tradeZoneManager=new t.TradeZoneManager,this.tradeZoneManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.tradeZoneManager.setDataGetter(()=>this.dataManager.getData()),this.tradeZoneManager.on(`added`,e=>{this.eventBus.emit(`tradeZoneAdd`,{id:e.id,direction:e.direction})}),this.tradeZoneManager.on(`removed`,e=>{this.eventBus.emit(`tradeZoneRemove`,{id:e})}),this.replayManager=new t.ReplayManager,this.measureOverlay=new t.MeasureOverlay,this.interactionManager=new t.InteractionManager(n),this.features.panning&&this.interactionManager.setPanHandler(new t.PanHandler(e=>{this.viewport.scrollBy(e),this.updateViewportAndRender()})),this.features.zooming){this.interactionManager.setZoomHandler(new t.ZoomHandler((e,t)=>{this.viewport.zoom(e,t),this.updateViewportAndRender()}));let e=new t.AxisDragHandler(e=>{this.options.autoScale=!1,this.viewport.scalePriceRange(e),this.syncRenderContext(),this.engine.requestRender()},e=>{let t=this.viewport.getState().chartRect.width;this.viewport.zoom(1/e-1,t/2),this.updateViewportAndRender()});this.interactionManager.setAxisDragHandler(e,()=>this.viewport.getState(),e=>{e===`price`?(this.options.autoScale=!0,this.updateViewportAndRender()):this.fitContent()})}this.features.crosshair&&this.interactionManager.setCrosshairHandler(this.crosshairHandler),this.features.drawings&&this.interactionManager.setDrawingManager(this.drawingManager,()=>({...this.viewport.getState(),data:this.getDisplayData()})),this.features.trading&&this.interactionManager.setTradingManager(this.tradingManager,()=>({...this.viewport.getState(),data:this.getDisplayData()})),this.interactionManager.setAltClickHandler(t=>{let n=this.getDisplayData();if(n.length===0)return;let r=this.viewport.getState(),i=r.barWidth+r.barSpacing,a=Math.round((r.offset+t.x)/i);a<0||a>=n.length||(this.pinnedTooltip.isPinned()&&this.pinnedTooltip.getPinnedIndex()===a?this.pinnedTooltip.unpin():this.pinnedTooltip.pin(n[a],a,this.themeManager.getTheme()),this.pinnedTooltip.reposition(this.viewport.getState(),this.dataManager.getData()[a]??null,a,this.themeManager.getTheme()),this.engine.requestRender(e.LayerType.Overlay))}),this.interactionManager.setEscapeHandler(()=>{this.pinnedTooltip.isPinned()&&(this.pinnedTooltip.unpin(),this.engine.requestRender(e.LayerType.Overlay))}),this.interactionManager.setMeasureHandlers({begin:e=>{this.measureOverlay.begin(e,this.viewport.getState(),this.getDisplayData())},move:e=>{this.measureOverlay.update(e,this.viewport.getState(),this.getDisplayData())},end:()=>{this.measureOverlay.end()}}),this.interactionManager.setOverlayDirtyCallback(()=>{this.engine.requestRender(e.LayerType.Overlay),this.engine.requestRender(e.LayerType.UI)}),this.interactionManager.attach(),this.syncRenderContext(),this.engine.start()}setData(e){this.dataManager.setData(e),this.crosshairHandler.setData(this.dataManager.getData()),this.displayDataCache=null,this.sessionBreaks.invalidateCache(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),e.length>0&&this.currentPriceLine.setPrice(e[e.length-1].close),this.updateViewportAndRender(!0),this.eventBus.emit(`dataUpdate`,{length:e.length})}appendBar(e){this.dataManager.appendBar(e),this.crosshairHandler.setData(this.dataManager.getData()),this.displayDataCache=null,this.autoScrollOnNewBar&&this.viewport.scrollToEnd(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.updateViewportAndRender()}appendBars(e){if(e.length!==0){for(let t of e)this.dataManager.appendBar(t);this.displayDataCache=null,this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.crosshairHandler.setData(this.dataManager.getData()),this.updateViewportAndRender(this.viewport.isAtEnd())}}updateLastBar(e){this.dataManager.updateLastBar(e),this.currentPriceLine.setPrice(e.close),this.options.chartType!==`candlestick`&&this.options.chartType!==`line`&&this.options.chartType!==`area`&&this.options.chartType!==`bar`&&this.options.chartType!==`hollowCandle`&&(this.displayDataCache=null),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.scheduleRender()}updateLastBarFromTick(e){this.dataManager.updateLastBarFromTick(e),this.currentPriceLine.setPrice(e.price),this.options.chartType!==`candlestick`&&this.options.chartType!==`line`&&this.options.chartType!==`area`&&this.options.chartType!==`bar`&&this.options.chartType!==`hollowCandle`&&(this.displayDataCache=null),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.scheduleRender()}setChartType(e){this.options.chartType=e,this.chartRenderer=this.createChartRenderer(e),this.chartLegend.setChartType(e),this.displayDataCache=null,this.updateViewportAndRender(!0)}addIndicator(e,t={},n=`bottom`){if(!this.features.indicators||this.features.indicatorIds.length>0&&!this.features.indicatorIds.includes(e))return null;let r=this.indicatorEngine.addIndicator(e,t,this.dataManager.getData());return this.indicatorEngine.getAvailableIndicators().find(t=>t.id===e)?.placement===`panel`?(this.layoutManager.addPanel(r,n),this.updateViewportAndRender()):this.engine.requestRender(),this.eventBus.emit(`indicatorAdd`,{instanceId:r,id:e}),r}updateIndicator(e,t){this.indicatorEngine.updateIndicator(e,t,this.dataManager.getData()),this.engine.requestRender()}removeIndicator(e){let t=this.layoutManager.getPanels().some(t=>t.id===e);this.indicatorEngine.removeIndicator(e),this.layoutManager.removePanel(e),this.eventBus.emit(`indicatorRemove`,{instanceId:e}),t?this.updateViewportAndRender():this.engine.requestRender()}getIndicatorOutput(e){return this.indicatorEngine.getOutput(e)}registerIndicator(e){this.pluginManager.registerIndicator(e)}static indicators(){let e=new t.IndicatorEngine;return(0,t.registerBuiltInIndicators)(e),e.getAvailableIndicators()}setPanelPosition(e,t){this.layoutManager.setPanelPosition(e,t),this.engine.requestRender()}setPanelSize(e,t){this.layoutManager.setPanelSize(e,t),this.engine.requestRender()}setDrawingTool(e){this.features.drawings&&(e&&this.features.drawingTools.length>0&&!this.features.drawingTools.includes(e)||this.drawingManager.setActiveTool(e))}getDrawingTool(){return this.drawingManager.getActiveTool()}setDrawingStyle(e){this.drawingManager.setStyle(e)}getDrawings(){return this.drawingManager.getDrawings()}setDrawings(e){this.drawingManager.setDrawings(e)}removeDrawing(e){this.drawingManager.removeDrawing(e)}clearDrawings(){this.drawingManager.clearDrawings()}registerDrawingTool(e){this.drawingManager.register(e)}undo(){return this.features.drawingUndoRedo?this.drawingManager.undo():!1}redo(){return this.features.drawingUndoRedo?this.drawingManager.redo():!1}getUndoRedoState(){return this.undoRedoManager.getState()}setDrawingMagnet(e){this.drawingManager.setMagnetMode(e?`magnet`:`none`)}getDrawingMagnet(){return this.drawingManager.getMagnetMode()===`magnet`}lockAllDrawings(){this.drawingManager.lockAllDrawings()}unlockAllDrawings(){this.drawingManager.unlockAllDrawings()}hideAllDrawings(){this.drawingManager.hideAllDrawings()}showAllDrawings(){this.drawingManager.showAllDrawings()}duplicateDrawing(e){let t=e??this.drawingManager.getSelectedDrawingId();return t?this.drawingManager.duplicateDrawing(t):null}exportVisibleData(e=`csv`,n){let r=this.viewport.getState(),i=this.dataManager.getData(),a=Math.max(0,r.visibleRange.from),o=Math.min(i.length-1,r.visibleRange.to),s=i.slice(a,o+1);if(e===`json`){let e=t.DataExporter.toJSON(s);t.DataExporter.download(e,n??`chart-data.json`,`application/json`)}else{let e=t.DataExporter.toCSV(s);t.DataExporter.download(e,n??`chart-data.csv`,`text/csv`)}}exportAllData(e=`csv`,n){let r=this.dataManager.getData();if(e===`json`){let e=t.DataExporter.toJSON(r);t.DataExporter.download(e,n??`chart-data.json`,`application/json`)}else{let e=t.DataExporter.toCSV(r);t.DataExporter.download(e,n??`chart-data.csv`,`text/csv`)}}setAutoSave(e,t=5e3){this.autoSaveScheduler.enable(e,t)}disableAutoSave(){this.autoSaveScheduler.disable()}scheduleAutoSave(){this.autoSaveScheduler.schedule()}getAvailableIndicators(){return this.indicatorEngine.getAvailableIndicators()}getIndicatorInputs(e){let t=this.indicatorEngine.getAvailableIndicators().find(t=>t.id===e);return t?{id:t.id,params:t.defaultConfig}:null}getActiveIndicators(){return this.indicatorEngine.getActiveIndicators()}getIndicatorConfig(e){let t=this.indicatorEngine.getIndicatorConfig(e);return t?{id:t.id,params:{...t.params}}:null}updateIndicatorStyle(e,t){this.indicatorEngine.updateIndicatorStyle(e,t),this.engine.requestRender()}setOrders(e){this.features.trading&&this.tradingManager.setOrders(e)}setPositions(e){this.features.trading&&this.tradingManager.setPositions(e)}setDepthData(e){this.features.trading&&this.tradingManager.setDepthData(e)}setCurrentPrice(e,t){this.tradingManager.setCurrentPrice(e),this.currentPriceLine.setPrice(e),this.scheduleRender(),this.features.alerts&&this.alertManager.checkPrice(e)}setTradingConfig(e){this.features.trading&&this.tradingManager.setConfig(e)}async connect(n){this.disconnectStream(),this.streamManager=new t.StreamManager,this.streamManager.on(`snapshot`,e=>{this.setData(e)}),this.streamManager.on(`barClose`,e=>{this.dataManager.appendBar(e),this.crosshairHandler.setData(this.dataManager.getData()),this.autoScrollOnNewBar&&this.viewport.scrollToEnd(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.updateViewportAndRender()}),this.streamManager.on(`barUpdate`,e=>{this.dataManager.updateLastBar(e),this.currentPriceLine.setPrice(e.close),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.scheduleRender()}),this.streamManager.on(`priceChange`,({price:t})=>{this.tradingManager.setCurrentPrice(t),this.currentPriceLine.setPrice(t),this.engine.requestRender(e.LayerType.Overlay),this.engine.requestRender(e.LayerType.UI)}),this.streamManager.on(`connectionChange`,e=>{this.eventBus.emit(`dataUpdate`,{connection:e})}),this.streamManager.on(`error`,e=>{this.eventBus.emit(`dataUpdate`,{error:e.message})}),this.autoScrollOnNewBar=n.autoScroll!==!1,this.currentSymbol=n.symbol,await this.streamManager.connect(n);let r=(0,e.timeframeToMs)(n.timeframe);this.barCountdown.setTimeframeMs(r),this.countdownInterval&&clearInterval(this.countdownInterval),this.countdownInterval=setInterval(()=>{this.barCountdown.isVisible()&&this.engine.requestRender(e.LayerType.UI)},1e3)}async switchStream(e,t){this.streamManager&&(this.currentSymbol=e,await this.streamManager.switchTo(e,t))}async setTimeframe(e){if(!this.streamManager)throw Error(`No active stream. Call connect() first.`);await this.switchStream(this.currentSymbol,e)}disconnectStream(){this.streamManager&&=(this.streamManager.dispose(),null)}setBarCountdownVisible(t){this.barCountdown.setVisible(t),this.engine.requestRender(e.LayerType.UI)}setSessionBreaksVisible(t){this.sessionBreaks.setVisible(t),this.engine.requestRender(e.LayerType.Background)}addCompareSymbol(t,n,r,i){this.compareRenderer.addSymbol({id:t,label:n,data:r,color:i,visible:!0}),this.engine.requestRender(e.LayerType.Main)}removeCompareSymbol(t){this.compareRenderer.removeSymbol(t),this.engine.requestRender(e.LayerType.Main)}updateCompareData(t,n){this.compareRenderer.setSymbolData(t,n),this.engine.requestRender(e.LayerType.Main)}setCompareMode(t){this.compareRenderer.setMode(t),this.engine.requestRender(e.LayerType.Main)}clearCompareSymbols(){this.compareRenderer.clear(),this.engine.requestRender(e.LayerType.Main)}setLogScale(e){this.viewport.setLogScale(e),this.updateViewportAndRender()}isLogScale(){return this.viewport.isLogScale()}setSessionBreaksConfig(t){this.sessionBreaks.setConfig(t),this.engine.requestRender(e.LayerType.Background)}getConnectionState(){return this.streamManager?.getConnectionState()??`disconnected`}getConnectionInfo(){return this.streamManager?.getConnectionInfo()??{state:`disconnected`}}setAutoScroll(e){this.autoScrollOnNewBar=e}scrollTo(e){let t=this.dataManager.getData();for(let n=0;n<t.length;n++)if(t[n].time>=e){let e=this.viewport.getState().barWidth+this.viewport.getState().barSpacing;this.viewport.scrollBy(n*e-this.viewport.getState().offset),this.updateViewportAndRender();return}}scrollToEnd(){this.viewport.scrollToEnd(),this.updateViewportAndRender()}setVisibleRange(e,t){let n=this.dataManager.getData(),r=0,i=n.length-1;for(let t=0;t<n.length;t++)if(n[t].time>=e){r=t;break}for(let e=n.length-1;e>=0;e--)if(n[e].time<=t){i=e;break}let a=i-r+1;if(a>0){let e=this.viewport.getState().chartRect.width,t=e/a,n=Math.max(2,t-this.viewport.getState().barSpacing);this.viewport.zoom((n-this.viewport.getState().barWidth)/this.viewport.getState().barWidth,e/2)}this.updateViewportAndRender()}zoomIn(){let e=this.viewport.getState().chartRect.width;this.viewport.zoom(.2,e/2),this.updateViewportAndRender()}zoomOut(){let e=this.viewport.getState().chartRect.width;this.viewport.zoom(-.2,e/2),this.updateViewportAndRender()}fitContent(){let e=this.dataManager.getData();e.length!==0&&this.setVisibleRange(e[0].time,e[e.length-1].time)}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}enableTauriBridge(e){this.eventBus.enableTauriBridge({enabled:!0,...e})}disableTauriBridge(){this.eventBus.disableTauriBridge()}setTheme(e){this.themeManager.setTheme(e),this.syncRenderContext(),this.container.style.backgroundColor=this.themeManager.getTheme().background,this.engine.requestRender(),this.eventBus.emit(`themeChange`,{theme:e})}getTheme(){return this.themeManager.getTheme()}setWatermark(t,n){this.watermark.setConfig({text:t,...n}),this.engine.requestRender(e.LayerType.Background)}setAutoScale(e){this.options.autoScale=e,this.updateViewportAndRender()}isAutoScale(){return this.options.autoScale!==!1}setCrosshairMode(t){this.crosshairHandler.setMode(t),this.engine.requestRender(e.LayerType.Overlay)}getCrosshairMode(){return this.crosshairHandler.getMode()}setCrosshairPosition(t){t&&this.crosshairHandler.onPointerMove(t),this.engine.requestRender(e.LayerType.Overlay)}getData(){return this.dataManager.getData()}setGridVisible(t){this.gridRenderer.setVisible(t),this.engine.requestRender(e.LayerType.Background)}isGridVisible(){return this.gridRenderer.isVisible()}setVolumeVisible(t){this.volumeRenderer.setVisible(t),this.engine.requestRender(e.LayerType.Main)}setVolumeProfileVisible(t){this.volumeProfile.setVisible(t),this.engine.requestRender(e.LayerType.Main)}isVolumeProfileVisible(){return this.volumeProfile.isVisible()}setVolumeProfileConfig(t){t.buckets!==void 0&&this.volumeProfile.setBuckets(t.buckets),t.widthRatio!==void 0&&this.volumeProfile.setWidthRatio(t.widthRatio),t.opacity!==void 0&&this.volumeProfile.setOpacity(t.opacity),t.highlightPoC!==void 0&&this.volumeProfile.setHighlightPoC(t.highlightPoC),this.engine.requestRender(e.LayerType.Main)}setTooltipVisible(e){e||this.crosshairTooltip.hide()}setLegend(t){this.chartLegend.setConfig(t),this.engine.requestRender(e.LayerType.UI)}setSymbolName(t){this.chartLegend.setSymbol(t),this.engine.requestRender(e.LayerType.UI)}setStatusText(t){this.chartLegend.setStatusText(t),this.engine.requestRender(e.LayerType.UI)}screenshot(e){this.features.screenshot&&t.Screenshot.download(this.container,e,this.themeManager.getTheme().background)}screenshotDataURL(){return this.features.screenshot?t.Screenshot.toDataURL(this.container,this.themeManager.getTheme().background):null}async screenshotBlob(){return this.features.screenshot?t.Screenshot.toBlob(this.container,this.themeManager.getTheme().background):null}addAlert(e,t=`crossing`,n){if(!this.features.alerts)return null;let r=this.alertManager.addAlert(e,t,n);return this.scheduleAutoSave(),r}removeAlert(e){this.alertManager.removeAlert(e),this.scheduleAutoSave()}getAlerts(){return this.alertManager.getAlerts()}clearAlerts(){this.alertManager.clearAlerts(),this.scheduleAutoSave()}saveAlerts(e){this.alertManager.saveToStorage(e)}loadAlerts(t){this.alertManager.loadFromStorage(t),this.engine.requestRender(e.LayerType.Overlay)}addSignalMarker(e){return this.signalMarkerManager.addMarker(e)}removeSignalMarker(e){this.signalMarkerManager.removeMarker(e)}getSignalMarkers(){return this.signalMarkerManager.getMarkers()}setSignalMarkers(e){this.signalMarkerManager.setMarkers(e)}clearSignalMarkers(){this.signalMarkerManager.clearMarkers()}setSignalMarkerStyle(e){this.signalMarkerManager.setStyle(e)}addTradeZone(e){return this.tradeZoneManager.addZone(e)}updateTradeZone(e,t){this.tradeZoneManager.updateZone(e,t)}removeTradeZone(e){this.tradeZoneManager.removeZone(e)}getTradeZones(){return this.tradeZoneManager.getZones()}setTradeZones(e){this.tradeZoneManager.setZones(e)}clearTradeZones(){this.tradeZoneManager.clearZones()}setTradeZoneStyle(e){this.tradeZoneManager.setStyle(e)}replay(e){if(!this.features.replay)return;let t=this.dataManager.getData();this.replayManager.load(t),this.replayManager.on(`bar`,({bar:e,index:n})=>{let r=t.slice(0,n+1);this.dataManager.setData(r),this.crosshairHandler.setData(r),this.indicatorEngine.recalculateAll(r),this.updateViewportAndRender()}),this.replayManager.play(e)}replayPause(){this.replayManager.pause()}replayResume(){this.replayManager.resume()}replayStop(){this.replayManager.stop()}replaySeek(e){this.replayManager.seekTo(e)}setReplaySpeed(e){this.replayManager.setSpeed(e)}getReplayState(){return this.replayManager.getState()}getReplayProgress(){return this.replayManager.getProgress()}saveState(e){if(!this.features.saveLoad)return null;let n=t.ChartStateManager.capture({getDrawings:()=>this.getDrawings(),getTheme:()=>this.getTheme(),getAlerts:()=>this.getAlerts()},{chartType:this.options.chartType}),r=t.ChartStateManager.serialize(n);return e&&t.ChartStateManager.saveToStorage(e,n),r}loadState(e){if(!this.features.saveLoad)return;let n=t.ChartStateManager.deserialize(e);if(n.chartType&&this.setChartType(n.chartType),n.drawings&&this.setDrawings(n.drawings),n.theme&&this.setTheme(n.theme),n.alerts){this.clearAlerts();for(let e of n.alerts)this.addAlert(e.price,e.condition,e.message)}}loadStateFromStorage(e){if(!this.features.saveLoad)return!1;let n=t.ChartStateManager.loadFromStorage(e);return n?(this.loadState(t.ChartStateManager.serialize(n)),!0):!1}downloadState(e){if(!this.features.saveLoad)return;let n=t.ChartStateManager.capture({getDrawings:()=>this.getDrawings(),getTheme:()=>this.getTheme(),getAlerts:()=>this.getAlerts()},{chartType:this.options.chartType});t.ChartStateManager.downloadFile(n,e)}async loadStateFromFile(){if(!this.features.saveLoad)return;let e=await t.ChartStateManager.loadFromFile();this.loadState(t.ChartStateManager.serialize(e))}setLocale(t){(0,e.setLocale)(t),this.engine.requestRender()}setNumberLocale(e){this.numberLocale=e,this.priceAxis.setLocale(e),this.crosshairHandler.setLocale(e),this.syncRenderContext(),this.engine.requestRender()}getNumberLocale(){return this.numberLocale}setMarket(e){if(this.marketConfig=e,e.colorScheme){let t={...this.themeManager.getTheme(),candleUp:e.colorScheme.up,candleDown:e.colorScheme.down,candleUpWick:e.colorScheme.up,candleDownWick:e.colorScheme.down,volumeUp:e.colorScheme.up.replace(`)`,`, 0.3)`).replace(`rgb(`,`rgba(`)||`${e.colorScheme.up}4D`,volumeDown:e.colorScheme.down.replace(`)`,`, 0.3)`).replace(`rgb(`,`rgba(`)||`${e.colorScheme.down}4D`};this.themeManager.setTheme(t)}e.pricePrecision!==void 0&&(this.tradingManager.setConfig({pricePrecision:e.pricePrecision}),this.alertManager.setPricePrecision(e.pricePrecision),this.streamManager?.priceLine.setPricePrecision(e.pricePrecision),this.crosshairHandler.setPricePrecision(e.pricePrecision)),this.syncRenderContext(),this.engine.requestRender()}getMarket(){return this.marketConfig}setPriceLimits(t){this.marketConfig&&((0,e.computePriceLimits)(t,this.marketConfig)&&(this.marketConfig.priceLimits={...this.marketConfig.priceLimits,referencePrice:t}),this.engine.requestRender())}getFeatures(){return this.features}setFeatures(t){Object.assign(this.features,t),t.crosshair===!1&&this.crosshairTooltip.hide(),t.grid!==void 0&&this.engine.requestRender(e.LayerType.Background),t.volume!==void 0&&(this.volumeRenderer.setVisible(t.volume),this.engine.requestRender(e.LayerType.Main)),t.drawings===!1&&this.drawingManager.setActiveTool(null),t.trading===!1&&(this.tradingManager.setOrders([]),this.tradingManager.setPositions([])),t.keyboard!==void 0&&this.keyboardHandler?.setEnabled(t.keyboard),this.engine.requestRender()}resize(){let e=this.engine.dprManager.readContainerSize();if(e.width<=0||e.height<=0)return;this.containerSizeCache=e,this.containerSizeCacheTime=Date.now();let t=this.engine.dprManager.getDpr();this.engine.layerManager.resize(e,t);let n=this.viewport.isAtEnd();this.viewport.resize(e.width,e.height),this.layoutManager.resize(e.width,e.height),this.updateViewportAndRender(n),this.eventBus.emit(`resize`,e)}destroy(){this.countdownInterval&&clearInterval(this.countdownInterval),this.disableAutoSave(),this.disconnectStream(),this.onWindowKeyDown&&=(window.removeEventListener(`keydown`,this.onWindowKeyDown),null),this.keyboardHandler=null,this.interactionManager.detach(),this.tradingManager.destroy(),this.animator.dispose(),this.crosshairTooltip.destroy(),this.pinnedTooltip.destroy(),this.replayManager.dispose(),this.undoRedoManager.clear(),this.engine.destroy(),this.eventBus.destroy(),this.container.innerHTML=``}createChartRenderer(e){return n(e)}getDisplayData(){if(this.displayDataCache)return this.displayDataCache;let e=this.dataManager.getData();if(e.length===0)return e;let t=r(this.options.chartType,e);return this.displayDataCache=t,t}scheduleRender(){this.renderScheduled||(this.renderScheduled=!0,requestAnimationFrame(()=>{this.renderScheduled=!1;let e=this.getDisplayData();this.viewport.updateData(e,this.options.autoScale!==!1),this.syncRenderContext(),this.engine.requestRender()}))}updateViewportAndRender(e=!1){this.resolvedLayoutCache=null,this.panelInfoCache=null;let t=this.getResolvedLayout();this.viewport.setChartRect(t.mainChartRect);let n=this.getDisplayData();if(this.viewport.updateData(n,this.options.autoScale!==!1),this.options.autoScale!==!1){let e=this.viewport.getState(),t=this.indicatorEngine.getOverlayPriceRange(e.visibleRange.from,Math.min(e.visibleRange.to,n.length-1));if(t){let n=e.priceRange,r=Math.min(n.min,t.min),i=Math.max(n.max,t.max);if(r<n.min||i>n.max){let e=i-r||1;this.viewport.setPriceRange(r-e*.02,i+e*.02)}}}e&&this.viewport.scrollToEnd(),this.syncRenderContext(),this.engine.requestRender()}getResolvedLayout(){return this.resolvedLayoutCache||=this.layoutManager.resolve(),this.resolvedLayoutCache}cachedContainerSize(){let e=Date.now();return(!this.containerSizeCache||e-this.containerSizeCacheTime>500)&&(this.containerSizeCache=this.engine.dprManager.getContainerSize(),this.containerSizeCacheTime=e),this.containerSizeCache}buildPanelRenderInfos(){if(this.panelInfoCache)return this.panelInfoCache;let e=this.getResolvedLayout(),t=this.viewport.getState(),{from:n,to:r}=t.visibleRange,i=e.panels.map(e=>{let i=s(this.indicatorEngine.getOutput(e.config.id),n,r),a={x:e.rect.x,y:e.rect.y+20,width:e.rect.width,height:Math.max(0,e.rect.height-20)};return{instanceId:e.config.id,rect:e.rect,viewport:{...t,chartRect:a,priceRange:i}}});return this.panelInfoCache=i,i}syncRenderContext(){this.pinnedTooltip.isPinned()&&this.pinnedTooltip.reposition(this.viewport.getState(),null,null,this.themeManager.getTheme());let e=this.getResolvedLayout(),t=this.features.indicators?this.buildPanelRenderInfos():[],n=e.panels.filter(e=>e.config.position===`bottom`).reduce((e,t)=>e+t.rect.height,0),r=e.mainChartRect.y+e.mainChartRect.height+n,i=this.getDisplayData();this.engine.setRenderContext({chartRenderer:this.chartRenderer,gridRenderer:this.features.grid?this.gridRenderer:null,priceAxis:this.features.priceAxis?this.priceAxis:null,timeAxis:this.features.timeAxis?this.timeAxis:null,crosshairHandler:this.features.crosshair?this.crosshairHandler:null,indicatorEngine:this.features.indicators?this.indicatorEngine:null,drawingRenderer:this.features.drawings?this.drawingRenderer:null,tradingRenderer:this.features.trading?this.tradingRenderer:null,currentPriceLine:this.streamManager?.priceLine??this.currentPriceLine,chartLegend:this.features.legend?this.chartLegend:null,volumeRenderer:this.features.volume?this.volumeRenderer:null,volumeProfile:this.volumeProfile,watermark:this.features.watermark?this.watermark:null,barCountdown:this.barCountdown,sessionBreaks:this.sessionBreaks,compareRenderer:this.compareRenderer,alertManager:this.features.alerts?this.alertManager:null,measureOverlay:this.measureOverlay,signalMarkerManager:this.signalMarkerManager,tradeZoneManager:this.tradeZoneManager,panels:t,priceLimits:this.buildPriceLimits(),timeAxisY:r,viewport:{...this.viewport.getState(),data:i},theme:this.themeManager.getTheme(),data:i,numberLocale:this.numberLocale})}buildPriceLimits(){if(!this.marketConfig?.priceLimits?.enabled||!this.marketConfig.priceLimits.referencePrice)return null;let t=(0,e.computePriceLimits)(this.marketConfig.priceLimits.referencePrice,this.marketConfig);return t?{...t,colors:this.marketConfig.colorScheme?{ceiling:this.marketConfig.colorScheme.ceiling,floor:this.marketConfig.colorScheme.floor,reference:this.marketConfig.colorScheme.reference}:void 0}:null}},v=[`time`,`timestamp`,`date`,`datetime`,`t`],y=[`open`,`o`],b=[`high`,`h`],x=[`low`,`l`],S=[`close`,`c`],C=[`volume`,`vol`,`v`];function w(e){let t=e.trim();return t?t[0]===`[`||t[0]===`{`?T(t):E(t):{data:[],rowCount:0,skipped:0}}function T(e){let t;try{t=JSON.parse(e)}catch(e){throw Error(`Invalid JSON: ${e.message}`)}if(!Array.isArray(t))throw Error(`Expected a JSON array of OHLCV rows`);let n=[],r=0;for(let e of t){let t=Array.isArray(e)?j(e):A(e);t?n.push(t):r++}return P(n,t.length,r)}function E(e){let t=e.split(/\r?\n/).filter(e=>e.trim().length>0);if(t.length===0)return{data:[],rowCount:0,skipped:0};let n=D(t[0]),r=O(t[0],n).map(e=>e.trim().toLowerCase()),i=r.some(e=>isNaN(Number(e))&&e.length>0),a=i?k(r):{time:0,open:1,high:2,low:3,close:4,volume:5};if(a.time<0||a.open<0||a.high<0||a.low<0||a.close<0)throw Error(`CSV is missing required column(s): time, open, high, low, close`);let o=[],s=0;for(let e=+!!i;e<t.length;e++){let r=O(t[e],n),i=N(r[a.time]),c=M(r[a.open]),l=M(r[a.high]),u=M(r[a.low]),d=M(r[a.close]),f=a.volume>=0?Number(r[a.volume]):0;if(i===null||![c,l,u,d].every(Number.isFinite)){s++;continue}o.push({time:i,open:c,high:l,low:u,close:d,volume:Number.isFinite(f)?f:0})}return P(o,t.length-+!!i,s)}function D(e){let t={",":0,";":0," ":0,"|":0};for(let n of e)n in t&&t[n]++;let n=`,`,r=0;for(let[e,i]of Object.entries(t))i>r&&(n=e,r=i);return n}function O(e,t){let n=[],r=``,i=!1;for(let a=0;a<e.length;a++){let o=e[a];o===`"`?i&&e[a+1]===`"`?(r+=`"`,a++):i=!i:o===t&&!i?(n.push(r),r=``):r+=o}return n.push(r),n}function k(e){let t=t=>e.findIndex(e=>t.includes(e));return{time:t(v),open:t(y),high:t(b),low:t(x),close:t(S),volume:t(C)}}function A(e){let t=t=>{for(let n of t){if(e[n]!==void 0)return e[n];let t=n.toUpperCase();if(e[t]!==void 0)return e[t]}},n=N(String(t(v)??``)),r=Number(t(y)),i=Number(t(b)),a=Number(t(x)),o=Number(t(S)),s=Number(t(C)??0);return n===null||![r,i,a,o].every(Number.isFinite)?null:{time:n,open:r,high:i,low:a,close:o,volume:Number.isFinite(s)?s:0}}function j(e){if(e.length<5)return null;let t=N(String(e[0])),n=Number(e[1]),r=Number(e[2]),i=Number(e[3]),a=Number(e[4]),o=e.length>=6?Number(e[5]):0;return t===null||![n,r,i,a].every(Number.isFinite)?null:{time:t,open:n,high:r,low:i,close:a,volume:Number.isFinite(o)?o:0}}function M(e){return e===void 0||e.trim()===``?NaN:Number(e)}function N(e){let t=e.trim();if(!t)return null;let n=Number(t);if(Number.isFinite(n)&&n>0)return n<0xe8d4a51000?n*1e3:n;let r=Date.parse(t);return Number.isFinite(r)?r:null}function P(e,t,n){e.sort((e,t)=>e.time-t.time);let r=[];for(let t of e)r.length>0&&r[r.length-1].time===t.time?r[r.length-1]=t:r.push(t);return{data:r,rowCount:t,skipped:n}}var F=class{host;overlay=null;callbacks;bound;depth=0;constructor(e,t){this.host=e,this.callbacks=t,this.bound={dragenter:e=>this.onDragEnter(e),dragover:e=>this.onDragOver(e),dragleave:e=>this.onDragLeave(e),drop:e=>this.onDrop(e)}}attach(){this.host.addEventListener(`dragenter`,this.bound.dragenter),this.host.addEventListener(`dragover`,this.bound.dragover),this.host.addEventListener(`dragleave`,this.bound.dragleave),this.host.addEventListener(`drop`,this.bound.drop)}detach(){this.host.removeEventListener(`dragenter`,this.bound.dragenter),this.host.removeEventListener(`dragover`,this.bound.dragover),this.host.removeEventListener(`dragleave`,this.bound.dragleave),this.host.removeEventListener(`drop`,this.bound.drop),this.hideOverlay()}onDragEnter(e){I(e)&&(e.preventDefault(),this.depth++,this.showOverlay())}onDragOver(e){I(e)&&(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect=`copy`))}onDragLeave(e){I(e)&&(this.depth=Math.max(0,this.depth-1),this.depth===0&&this.hideOverlay())}async onDrop(e){e.preventDefault(),this.depth=0,this.hideOverlay();let t=e.dataTransfer?.files?.[0];if(t)try{let e=w(await t.text());if(e.data.length===0)throw Error(`No valid OHLCV rows found in "${t.name}"`);this.callbacks.onData(e.data,e,t)}catch(e){this.callbacks.onError?.(e,t)}}showOverlay(){this.overlay||(this.overlay=document.createElement(`div`),Object.assign(this.overlay.style,{position:`absolute`,inset:`8px`,zIndex:`90`,pointerEvents:`none`,borderRadius:`10px`,border:`2px dashed var(--tcw-accent, #4f88ff)`,background:`rgba(79, 136, 255, 0.06)`,display:`flex`,alignItems:`center`,justifyContent:`center`,color:`var(--tcw-accent, #4f88ff)`,fontSize:`14px`,fontWeight:`600`,letterSpacing:`-0.005em`,fontFamily:`inherit`,backdropFilter:`blur(2px)`}),this.overlay.textContent=`Drop CSV or JSON to load chart data`,getComputedStyle(this.host).position===`static`&&(this.host.style.position=`relative`),this.host.appendChild(this.overlay))}hideOverlay(){this.overlay?.remove(),this.overlay=null}};function I(e){return e.dataTransfer?.types?.includes(`Files`)??!1}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return F}}); | ||
| //# sourceMappingURL=DragDropImporter-CQ3EarQn.cjs.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 3 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 3 instances in 1 package
1670459
58.05%121
32.97%10804
61.4%+ Added
+ Added
- Removed
- Removed
Updated
Updated