@tradecanvas/chart 0.8.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -4
- package/dist/Chart.d.ts +11 -0
- package/dist/Chart.d.ts.map +1 -1
- package/dist/{Chart-Cn_TSMO7.js → DragDropImporter-6QOjnfSj.js} +361 -85
- package/dist/DragDropImporter-6QOjnfSj.js.map +1 -0
- package/dist/DragDropImporter-CQ3EarQn.cjs +2 -0
- package/dist/DragDropImporter-CQ3EarQn.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -26
- package/dist/index.js.map +1 -1
- package/dist/io/DragDropImporter.d.ts +34 -0
- package/dist/io/DragDropImporter.d.ts.map +1 -0
- package/dist/io/index.d.ts +5 -0
- package/dist/io/index.d.ts.map +1 -0
- package/dist/io/parseOHLCV.d.ts +21 -0
- package/dist/io/parseOHLCV.d.ts.map +1 -0
- package/dist/widget/ChartWidget.d.ts +46 -1
- package/dist/widget/ChartWidget.d.ts.map +1 -1
- package/dist/widget/WidgetHotkeySheet.d.ts +20 -0
- package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -0
- package/dist/widget/WidgetReplayBar.d.ts +41 -0
- package/dist/widget/WidgetReplayBar.d.ts.map +1 -0
- package/dist/widget/WidgetSettings.d.ts.map +1 -1
- package/dist/widget/WidgetSymbolSearch.d.ts +32 -0
- package/dist/widget/WidgetSymbolSearch.d.ts.map +1 -0
- package/dist/widget/WidgetToolbar.d.ts.map +1 -1
- package/dist/widget/WidgetWatchlist.d.ts +39 -0
- package/dist/widget/WidgetWatchlist.d.ts.map +1 -0
- package/dist/widget/index.cjs +1455 -877
- package/dist/widget/index.cjs.map +1 -1
- package/dist/widget/index.js +695 -92
- package/dist/widget/index.js.map +1 -1
- package/dist/widget/types.d.ts +19 -0
- package/dist/widget/types.d.ts.map +1 -1
- package/dist/widget/widgetConfig.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/Chart-Br_N-BCL.cjs +0 -2
- package/dist/Chart-Br_N-BCL.cjs.map +0 -1
- package/dist/Chart-Cn_TSMO7.js.map +0 -1
|
@@ -1,57 +1,57 @@
|
|
|
1
1
|
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";
|
|
2
|
-
import { AlertManager as d, Animator as f, AreaRenderer as p,
|
|
2
|
+
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";
|
|
3
3
|
//#region src/charts/ChartTypeStrategy.ts
|
|
4
|
-
function
|
|
4
|
+
function Ve(e) {
|
|
5
5
|
switch (e) {
|
|
6
6
|
case "candlestick":
|
|
7
7
|
case "heikinAshi":
|
|
8
8
|
case "lineBreak":
|
|
9
|
-
case "rangeBars": return new
|
|
10
|
-
case "line": return new
|
|
9
|
+
case "rangeBars": return new h();
|
|
10
|
+
case "line": return new _e();
|
|
11
11
|
case "area": return new p();
|
|
12
|
-
case "bar": return new
|
|
13
|
-
case "hollowCandle": return new
|
|
14
|
-
case "baseline": return new
|
|
15
|
-
case "renko": return new
|
|
16
|
-
case "kagi": return new
|
|
17
|
-
case "pointAndFigure": return new
|
|
18
|
-
case "volumeCandles": return new
|
|
19
|
-
case "equivolume": return new
|
|
20
|
-
case "hlcArea": return new
|
|
21
|
-
case "stepLine": return new
|
|
22
|
-
case "lineWithMarkers": return new
|
|
23
|
-
default: return new
|
|
12
|
+
case "bar": return new te();
|
|
13
|
+
case "hollowCandle": return new pe();
|
|
14
|
+
case "baseline": return new ne();
|
|
15
|
+
case "renko": return new Te();
|
|
16
|
+
case "kagi": return new he();
|
|
17
|
+
case "pointAndFigure": return new Se();
|
|
18
|
+
case "volumeCandles": return new ke();
|
|
19
|
+
case "equivolume": return new le();
|
|
20
|
+
case "hlcArea": return new fe();
|
|
21
|
+
case "stepLine": return new w();
|
|
22
|
+
case "lineWithMarkers": return new ve();
|
|
23
|
+
default: return new h();
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
function
|
|
26
|
+
function He(e, t) {
|
|
27
27
|
if (t.length === 0) return t;
|
|
28
28
|
switch (e) {
|
|
29
|
-
case "heikinAshi": return
|
|
30
|
-
case "renko": return
|
|
29
|
+
case "heikinAshi": return Fe(t);
|
|
30
|
+
case "renko": return Be(t, {
|
|
31
31
|
brickSize: 0,
|
|
32
32
|
useATR: !0,
|
|
33
33
|
atrPeriod: 14
|
|
34
34
|
});
|
|
35
|
-
case "lineBreak": return
|
|
36
|
-
case "kagi": return
|
|
37
|
-
case "pointAndFigure": return
|
|
38
|
-
case "rangeBars": return
|
|
35
|
+
case "lineBreak": return Le(t, 3);
|
|
36
|
+
case "kagi": return Ie(t, 4);
|
|
37
|
+
case "pointAndFigure": return Re(t, A(t) * .01, 3);
|
|
38
|
+
case "rangeBars": return ze(t, { rangeSize: A(t) * .005 });
|
|
39
39
|
default: return t;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
function
|
|
42
|
+
function A(e) {
|
|
43
43
|
let t = 0;
|
|
44
44
|
for (let n of e) t += n.close;
|
|
45
45
|
return t / e.length;
|
|
46
46
|
}
|
|
47
47
|
//#endregion
|
|
48
48
|
//#region src/charts/IndicatorPriceRange.ts
|
|
49
|
-
var
|
|
49
|
+
var j = {
|
|
50
50
|
min: 0,
|
|
51
51
|
max: 100
|
|
52
|
-
},
|
|
53
|
-
function
|
|
54
|
-
if (!e) return { ...
|
|
52
|
+
}, M = .1;
|
|
53
|
+
function Ue(e, t, n) {
|
|
54
|
+
if (!e) return { ...j };
|
|
55
55
|
let r = Infinity, i = -Infinity, a = 0;
|
|
56
56
|
for (let [, o] of e.values) {
|
|
57
57
|
if (a >= t && a <= n) for (let e in o) {
|
|
@@ -60,16 +60,16 @@ function Ee(e, t, n) {
|
|
|
60
60
|
}
|
|
61
61
|
a++;
|
|
62
62
|
}
|
|
63
|
-
if (r === Infinity) return { ...
|
|
63
|
+
if (r === Infinity) return { ...j };
|
|
64
64
|
let o = i - r || 1;
|
|
65
65
|
return {
|
|
66
|
-
min: r - o *
|
|
67
|
-
max: i + o *
|
|
66
|
+
min: r - o * M,
|
|
67
|
+
max: i + o * M
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
//#endregion
|
|
71
71
|
//#region src/state/AutoSaveScheduler.ts
|
|
72
|
-
var
|
|
72
|
+
var We = class {
|
|
73
73
|
timer = null;
|
|
74
74
|
delayMs = 0;
|
|
75
75
|
key = null;
|
|
@@ -99,12 +99,12 @@ var De = class {
|
|
|
99
99
|
};
|
|
100
100
|
//#endregion
|
|
101
101
|
//#region src/DataManager.ts
|
|
102
|
-
function
|
|
102
|
+
function N(e) {
|
|
103
103
|
if (!e || typeof e.time != "number") return !1;
|
|
104
104
|
let { open: t, high: n, low: r, close: i } = e;
|
|
105
105
|
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));
|
|
106
106
|
}
|
|
107
|
-
function
|
|
107
|
+
function P(e) {
|
|
108
108
|
return {
|
|
109
109
|
...e,
|
|
110
110
|
high: Math.max(e.open, e.high, e.low, e.close),
|
|
@@ -112,20 +112,20 @@ function q(e) {
|
|
|
112
112
|
volume: e.volume === void 0 ? 0 : Math.max(0, e.volume)
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
|
-
var
|
|
115
|
+
var F = class {
|
|
116
116
|
data = [];
|
|
117
117
|
getData() {
|
|
118
118
|
return this.data;
|
|
119
119
|
}
|
|
120
120
|
setData(e) {
|
|
121
|
-
this.data = e.filter(
|
|
121
|
+
this.data = e.filter(N).map(P);
|
|
122
122
|
}
|
|
123
123
|
appendBar(e) {
|
|
124
|
-
|
|
124
|
+
N(e) && this.data.push(P(e));
|
|
125
125
|
}
|
|
126
126
|
updateLastBar(e) {
|
|
127
|
-
if (!
|
|
128
|
-
let t =
|
|
127
|
+
if (!N(e)) return;
|
|
128
|
+
let t = P(e);
|
|
129
129
|
if (this.data.length === 0) {
|
|
130
130
|
this.data.push(t);
|
|
131
131
|
return;
|
|
@@ -141,7 +141,7 @@ var J = class {
|
|
|
141
141
|
clear() {
|
|
142
142
|
this.data = [];
|
|
143
143
|
}
|
|
144
|
-
},
|
|
144
|
+
}, I = class {
|
|
145
145
|
theme;
|
|
146
146
|
constructor(t) {
|
|
147
147
|
!t || t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
|
|
@@ -152,7 +152,7 @@ var J = class {
|
|
|
152
152
|
setTheme(t) {
|
|
153
153
|
t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
|
|
154
154
|
}
|
|
155
|
-
},
|
|
155
|
+
}, L = 200, R = 80, z = class {
|
|
156
156
|
panels = [];
|
|
157
157
|
containerWidth = 0;
|
|
158
158
|
containerHeight = 0;
|
|
@@ -164,8 +164,8 @@ var J = class {
|
|
|
164
164
|
this.panels.push({
|
|
165
165
|
id: e,
|
|
166
166
|
position: n,
|
|
167
|
-
size: r ?? (a ?
|
|
168
|
-
minSize: a ?
|
|
167
|
+
size: r ?? (a ? L : t),
|
|
168
|
+
minSize: a ? R : i,
|
|
169
169
|
content: {
|
|
170
170
|
type: "indicator",
|
|
171
171
|
indicatorInstanceId: e
|
|
@@ -179,7 +179,7 @@ var J = class {
|
|
|
179
179
|
let r = this.panels.find((t) => t.id === e);
|
|
180
180
|
if (r) {
|
|
181
181
|
let e = r.position === "left" || r.position === "right", a = n === "left" || n === "right";
|
|
182
|
-
r.position = n, e !== a && (r.size = a ?
|
|
182
|
+
r.position = n, e !== a && (r.size = a ? L : t, r.minSize = a ? R : i);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
setPanelSize(e, t) {
|
|
@@ -280,14 +280,14 @@ var J = class {
|
|
|
280
280
|
getMainChartRect() {
|
|
281
281
|
return this.resolve().mainChartRect;
|
|
282
282
|
}
|
|
283
|
-
},
|
|
283
|
+
}, B = class {
|
|
284
284
|
constructor(e) {
|
|
285
285
|
this.indicatorEngine = e;
|
|
286
286
|
}
|
|
287
287
|
registerIndicator(e) {
|
|
288
288
|
this.indicatorEngine.register(e);
|
|
289
289
|
}
|
|
290
|
-
},
|
|
290
|
+
}, Ge = class {
|
|
291
291
|
static version = "0.7.0";
|
|
292
292
|
engine;
|
|
293
293
|
viewport;
|
|
@@ -316,14 +316,17 @@ var J = class {
|
|
|
316
316
|
compareRenderer;
|
|
317
317
|
countdownInterval = null;
|
|
318
318
|
volumeRenderer;
|
|
319
|
+
volumeProfile;
|
|
319
320
|
alertManager;
|
|
320
321
|
signalMarkerManager;
|
|
321
322
|
tradeZoneManager;
|
|
323
|
+
measureOverlay;
|
|
322
324
|
replayManager;
|
|
323
325
|
undoRedoManager;
|
|
324
|
-
autoSaveScheduler = new
|
|
326
|
+
autoSaveScheduler = new We((e) => this.saveState(e));
|
|
325
327
|
animator;
|
|
326
328
|
crosshairTooltip;
|
|
329
|
+
pinnedTooltip;
|
|
327
330
|
interactionManager;
|
|
328
331
|
crosshairHandler;
|
|
329
332
|
chartRenderer;
|
|
@@ -372,36 +375,36 @@ var J = class {
|
|
|
372
375
|
logScale: n.logScale ?? !0,
|
|
373
376
|
timeframes: n.timeframes ?? [],
|
|
374
377
|
defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? []
|
|
375
|
-
}, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new
|
|
378
|
+
}, 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(() => {
|
|
376
379
|
this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave();
|
|
377
380
|
}), this.drawingManager.setEventCallback((e, t) => {
|
|
378
381
|
this.eventBus.emit(e, t);
|
|
379
|
-
}), this.undoRedoManager = new
|
|
382
|
+
}), 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({
|
|
380
383
|
enabled: this.features.trading,
|
|
381
384
|
contextMenu: { enabled: this.features.tradingContextMenu }
|
|
382
|
-
}), this.tradingRenderer = new
|
|
385
|
+
}), this.tradingRenderer = new Ee(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
|
|
383
386
|
this.eventBus.emit(e, t);
|
|
384
|
-
}), this.engine = new
|
|
387
|
+
}), this.engine = new we(e);
|
|
385
388
|
let i = this.engine.dprManager.getContainerSize();
|
|
386
|
-
this.viewport = new
|
|
389
|
+
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) => {
|
|
387
390
|
if (e.width <= 0 || e.height <= 0) return;
|
|
388
391
|
let t = this.viewport.isAtEnd();
|
|
389
392
|
this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t);
|
|
390
|
-
}, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new
|
|
393
|
+
}, 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) => {
|
|
391
394
|
if (e !== null && t) {
|
|
392
395
|
let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0;
|
|
393
|
-
this.chartLegend.setHoverBar(r ?? null), r && this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize()), this.eventBus.emit("crosshairMove", {
|
|
396
|
+
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", {
|
|
394
397
|
point: t,
|
|
395
398
|
bar: r,
|
|
396
399
|
barIndex: e
|
|
397
400
|
});
|
|
398
401
|
} else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null);
|
|
399
|
-
}), this.chartLegend = new
|
|
402
|
+
}), 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({
|
|
400
403
|
visible: t.sessionBreaks.visible ?? !0,
|
|
401
404
|
color: t.sessionBreaks.color,
|
|
402
405
|
lineStyle: t.sessionBreaks.lineStyle,
|
|
403
406
|
lineWidth: t.sessionBreaks.lineWidth
|
|
404
|
-
}) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.viewport.setLogScale(!0), this.animator = new f(), this.crosshairTooltip = new
|
|
407
|
+
}) : 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({
|
|
405
408
|
scrollBars: (e) => {
|
|
406
409
|
let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
|
|
407
410
|
this.viewport.scrollBy(e * t), this.updateViewportAndRender();
|
|
@@ -421,14 +424,14 @@ var J = class {
|
|
|
421
424
|
if (!this.keyboardHandler) return;
|
|
422
425
|
let t = document.activeElement;
|
|
423
426
|
t && t !== this.container && !this.container.contains(t) || t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable) || this.keyboardHandler.handleKey(e) && e.preventDefault();
|
|
424
|
-
}, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new
|
|
427
|
+
}, 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) => {
|
|
425
428
|
this.eventBus.emit("dataUpdate", {
|
|
426
429
|
alert: "triggered",
|
|
427
430
|
alertId: e.id,
|
|
428
431
|
price: e.price,
|
|
429
432
|
message: e.message
|
|
430
433
|
});
|
|
431
|
-
}), this.signalMarkerManager = new
|
|
434
|
+
}), this.signalMarkerManager = new C(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
|
|
432
435
|
this.eventBus.emit("signalMarkerAdd", {
|
|
433
436
|
id: e.id,
|
|
434
437
|
source: e.source,
|
|
@@ -436,25 +439,54 @@ var J = class {
|
|
|
436
439
|
});
|
|
437
440
|
}), this.signalMarkerManager.on("removed", (e) => {
|
|
438
441
|
this.eventBus.emit("signalMarkerRemove", { id: e });
|
|
439
|
-
}), this.tradeZoneManager = new
|
|
442
|
+
}), this.tradeZoneManager = new D(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
|
|
440
443
|
this.eventBus.emit("tradeZoneAdd", {
|
|
441
444
|
id: e.id,
|
|
442
445
|
direction: e.direction
|
|
443
446
|
});
|
|
444
447
|
}), this.tradeZoneManager.on("removed", (e) => {
|
|
445
448
|
this.eventBus.emit("tradeZoneRemove", { id: e });
|
|
446
|
-
}), this.replayManager = new
|
|
449
|
+
}), this.replayManager = new b(), this.measureOverlay = new ye(), this.interactionManager = new me(e), this.features.panning && this.interactionManager.setPanHandler(new be((e) => {
|
|
447
450
|
this.viewport.scrollBy(e), this.updateViewportAndRender();
|
|
448
|
-
})), this.features.zooming
|
|
449
|
-
this.
|
|
450
|
-
|
|
451
|
+
})), this.features.zooming) {
|
|
452
|
+
this.interactionManager.setZoomHandler(new Ne((e, t) => {
|
|
453
|
+
this.viewport.zoom(e, t), this.updateViewportAndRender();
|
|
454
|
+
}));
|
|
455
|
+
let e = new m((e) => {
|
|
456
|
+
this.options.autoScale = !1, this.viewport.scalePriceRange(e), this.syncRenderContext(), this.engine.requestRender();
|
|
457
|
+
}, (e) => {
|
|
458
|
+
let t = this.viewport.getState().chartRect.width;
|
|
459
|
+
this.viewport.zoom(1 / e - 1, t / 2), this.updateViewportAndRender();
|
|
460
|
+
});
|
|
461
|
+
this.interactionManager.setAxisDragHandler(e, () => this.viewport.getState(), (e) => {
|
|
462
|
+
e === "price" ? (this.options.autoScale = !0, this.updateViewportAndRender()) : this.fitContent();
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
this.features.crosshair && this.interactionManager.setCrosshairHandler(this.crosshairHandler), this.features.drawings && this.interactionManager.setDrawingManager(this.drawingManager, () => ({
|
|
451
466
|
...this.viewport.getState(),
|
|
452
467
|
data: this.getDisplayData()
|
|
453
468
|
})), this.features.trading && this.interactionManager.setTradingManager(this.tradingManager, () => ({
|
|
454
469
|
...this.viewport.getState(),
|
|
455
470
|
data: this.getDisplayData()
|
|
456
|
-
})), this.interactionManager.
|
|
457
|
-
|
|
471
|
+
})), this.interactionManager.setAltClickHandler((e) => {
|
|
472
|
+
let t = this.getDisplayData();
|
|
473
|
+
if (t.length === 0) return;
|
|
474
|
+
let n = this.viewport.getState(), i = n.barWidth + n.barSpacing, a = Math.round((n.offset + e.x) / i);
|
|
475
|
+
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));
|
|
476
|
+
}), this.interactionManager.setEscapeHandler(() => {
|
|
477
|
+
this.pinnedTooltip.isPinned() && (this.pinnedTooltip.unpin(), this.engine.requestRender(r.Overlay));
|
|
478
|
+
}), this.interactionManager.setMeasureHandlers({
|
|
479
|
+
begin: (e) => {
|
|
480
|
+
this.measureOverlay.begin(e, this.viewport.getState(), this.getDisplayData());
|
|
481
|
+
},
|
|
482
|
+
move: (e) => {
|
|
483
|
+
this.measureOverlay.update(e, this.viewport.getState(), this.getDisplayData());
|
|
484
|
+
},
|
|
485
|
+
end: () => {
|
|
486
|
+
this.measureOverlay.end();
|
|
487
|
+
}
|
|
488
|
+
}), this.interactionManager.setOverlayDirtyCallback(() => {
|
|
489
|
+
this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI);
|
|
458
490
|
}), this.interactionManager.attach(), this.syncRenderContext(), this.engine.start();
|
|
459
491
|
}
|
|
460
492
|
setData(e) {
|
|
@@ -500,8 +532,8 @@ var J = class {
|
|
|
500
532
|
this.pluginManager.registerIndicator(e);
|
|
501
533
|
}
|
|
502
534
|
static indicators() {
|
|
503
|
-
let e = new
|
|
504
|
-
return
|
|
535
|
+
let e = new y();
|
|
536
|
+
return k(e), e.getAvailableIndicators();
|
|
505
537
|
}
|
|
506
538
|
setPanelPosition(e, t) {
|
|
507
539
|
this.layoutManager.setPanelPosition(e, t), this.engine.requestRender();
|
|
@@ -567,21 +599,21 @@ var J = class {
|
|
|
567
599
|
exportVisibleData(e = "csv", t) {
|
|
568
600
|
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);
|
|
569
601
|
if (e === "json") {
|
|
570
|
-
let e =
|
|
571
|
-
|
|
602
|
+
let e = v.toJSON(o);
|
|
603
|
+
v.download(e, t ?? "chart-data.json", "application/json");
|
|
572
604
|
} else {
|
|
573
|
-
let e =
|
|
574
|
-
|
|
605
|
+
let e = v.toCSV(o);
|
|
606
|
+
v.download(e, t ?? "chart-data.csv", "text/csv");
|
|
575
607
|
}
|
|
576
608
|
}
|
|
577
609
|
exportAllData(e = "csv", t) {
|
|
578
610
|
let n = this.dataManager.getData();
|
|
579
611
|
if (e === "json") {
|
|
580
|
-
let e =
|
|
581
|
-
|
|
612
|
+
let e = v.toJSON(n);
|
|
613
|
+
v.download(e, t ?? "chart-data.json", "application/json");
|
|
582
614
|
} else {
|
|
583
|
-
let e =
|
|
584
|
-
|
|
615
|
+
let e = v.toCSV(n);
|
|
616
|
+
v.download(e, t ?? "chart-data.csv", "text/csv");
|
|
585
617
|
}
|
|
586
618
|
}
|
|
587
619
|
setAutoSave(e, t = 5e3) {
|
|
@@ -632,7 +664,7 @@ var J = class {
|
|
|
632
664
|
this.features.trading && this.tradingManager.setConfig(e);
|
|
633
665
|
}
|
|
634
666
|
async connect(e) {
|
|
635
|
-
this.disconnectStream(), this.streamManager = new
|
|
667
|
+
this.disconnectStream(), this.streamManager = new T(), this.streamManager.on("snapshot", (e) => {
|
|
636
668
|
this.setData(e);
|
|
637
669
|
}), this.streamManager.on("barClose", (e) => {
|
|
638
670
|
this.dataManager.appendBar(e), this.crosshairHandler.setData(this.dataManager.getData()), this.autoScrollOnNewBar && this.viewport.scrollToEnd(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.updateViewportAndRender();
|
|
@@ -799,6 +831,15 @@ var J = class {
|
|
|
799
831
|
setVolumeVisible(e) {
|
|
800
832
|
this.volumeRenderer.setVisible(e), this.engine.requestRender(r.Main);
|
|
801
833
|
}
|
|
834
|
+
setVolumeProfileVisible(e) {
|
|
835
|
+
this.volumeProfile.setVisible(e), this.engine.requestRender(r.Main);
|
|
836
|
+
}
|
|
837
|
+
isVolumeProfileVisible() {
|
|
838
|
+
return this.volumeProfile.isVisible();
|
|
839
|
+
}
|
|
840
|
+
setVolumeProfileConfig(e) {
|
|
841
|
+
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);
|
|
842
|
+
}
|
|
802
843
|
setTooltipVisible(e) {
|
|
803
844
|
e || this.crosshairTooltip.hide();
|
|
804
845
|
}
|
|
@@ -812,13 +853,13 @@ var J = class {
|
|
|
812
853
|
this.chartLegend.setStatusText(e), this.engine.requestRender(r.UI);
|
|
813
854
|
}
|
|
814
855
|
screenshot(e) {
|
|
815
|
-
this.features.screenshot &&
|
|
856
|
+
this.features.screenshot && x.download(this.container, e, this.themeManager.getTheme().background);
|
|
816
857
|
}
|
|
817
858
|
screenshotDataURL() {
|
|
818
|
-
return this.features.screenshot ?
|
|
859
|
+
return this.features.screenshot ? x.toDataURL(this.container, this.themeManager.getTheme().background) : null;
|
|
819
860
|
}
|
|
820
861
|
async screenshotBlob() {
|
|
821
|
-
return this.features.screenshot ?
|
|
862
|
+
return this.features.screenshot ? x.toBlob(this.container, this.themeManager.getTheme().background) : null;
|
|
822
863
|
}
|
|
823
864
|
addAlert(e, t = "crossing", n) {
|
|
824
865
|
if (!this.features.alerts) return null;
|
|
@@ -993,16 +1034,16 @@ var J = class {
|
|
|
993
1034
|
this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(n), this.eventBus.emit("resize", e);
|
|
994
1035
|
}
|
|
995
1036
|
destroy() {
|
|
996
|
-
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.replayManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = "";
|
|
1037
|
+
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 = "";
|
|
997
1038
|
}
|
|
998
1039
|
createChartRenderer(e) {
|
|
999
|
-
return
|
|
1040
|
+
return Ve(e);
|
|
1000
1041
|
}
|
|
1001
1042
|
getDisplayData() {
|
|
1002
1043
|
if (this.displayDataCache) return this.displayDataCache;
|
|
1003
1044
|
let e = this.dataManager.getData();
|
|
1004
1045
|
if (e.length === 0) return e;
|
|
1005
|
-
let t =
|
|
1046
|
+
let t = He(this.options.chartType, e);
|
|
1006
1047
|
return this.displayDataCache = t, t;
|
|
1007
1048
|
}
|
|
1008
1049
|
scheduleRender() {
|
|
@@ -1039,7 +1080,7 @@ var J = class {
|
|
|
1039
1080
|
buildPanelRenderInfos() {
|
|
1040
1081
|
if (this.panelInfoCache) return this.panelInfoCache;
|
|
1041
1082
|
let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => {
|
|
1042
|
-
let i =
|
|
1083
|
+
let i = Ue(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
|
|
1043
1084
|
x: e.rect.x,
|
|
1044
1085
|
y: e.rect.y + 20,
|
|
1045
1086
|
width: e.rect.width,
|
|
@@ -1058,6 +1099,7 @@ var J = class {
|
|
|
1058
1099
|
return this.panelInfoCache = i, i;
|
|
1059
1100
|
}
|
|
1060
1101
|
syncRenderContext() {
|
|
1102
|
+
this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), null, null, this.themeManager.getTheme());
|
|
1061
1103
|
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();
|
|
1062
1104
|
this.engine.setRenderContext({
|
|
1063
1105
|
chartRenderer: this.chartRenderer,
|
|
@@ -1071,11 +1113,13 @@ var J = class {
|
|
|
1071
1113
|
currentPriceLine: this.streamManager?.priceLine ?? this.currentPriceLine,
|
|
1072
1114
|
chartLegend: this.features.legend ? this.chartLegend : null,
|
|
1073
1115
|
volumeRenderer: this.features.volume ? this.volumeRenderer : null,
|
|
1116
|
+
volumeProfile: this.volumeProfile,
|
|
1074
1117
|
watermark: this.features.watermark ? this.watermark : null,
|
|
1075
1118
|
barCountdown: this.barCountdown,
|
|
1076
1119
|
sessionBreaks: this.sessionBreaks,
|
|
1077
1120
|
compareRenderer: this.compareRenderer,
|
|
1078
1121
|
alertManager: this.features.alerts ? this.alertManager : null,
|
|
1122
|
+
measureOverlay: this.measureOverlay,
|
|
1079
1123
|
signalMarkerManager: this.signalMarkerManager,
|
|
1080
1124
|
tradeZoneManager: this.tradeZoneManager,
|
|
1081
1125
|
panels: t,
|
|
@@ -1102,8 +1146,240 @@ var J = class {
|
|
|
1102
1146
|
} : void 0
|
|
1103
1147
|
} : null;
|
|
1104
1148
|
}
|
|
1149
|
+
}, V = [
|
|
1150
|
+
"time",
|
|
1151
|
+
"timestamp",
|
|
1152
|
+
"date",
|
|
1153
|
+
"datetime",
|
|
1154
|
+
"t"
|
|
1155
|
+
], H = ["open", "o"], U = ["high", "h"], W = ["low", "l"], G = ["close", "c"], K = [
|
|
1156
|
+
"volume",
|
|
1157
|
+
"vol",
|
|
1158
|
+
"v"
|
|
1159
|
+
];
|
|
1160
|
+
function q(e) {
|
|
1161
|
+
let t = e.trim();
|
|
1162
|
+
return t ? t[0] === "[" || t[0] === "{" ? Ke(t) : qe(t) : {
|
|
1163
|
+
data: [],
|
|
1164
|
+
rowCount: 0,
|
|
1165
|
+
skipped: 0
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
function Ke(e) {
|
|
1169
|
+
let t;
|
|
1170
|
+
try {
|
|
1171
|
+
t = JSON.parse(e);
|
|
1172
|
+
} catch (e) {
|
|
1173
|
+
throw Error(`Invalid JSON: ${e.message}`);
|
|
1174
|
+
}
|
|
1175
|
+
if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows");
|
|
1176
|
+
let n = [], r = 0;
|
|
1177
|
+
for (let e of t) {
|
|
1178
|
+
let t = Array.isArray(e) ? Xe(e) : Ye(e);
|
|
1179
|
+
t ? n.push(t) : r++;
|
|
1180
|
+
}
|
|
1181
|
+
return Q(n, t.length, r);
|
|
1182
|
+
}
|
|
1183
|
+
function qe(e) {
|
|
1184
|
+
let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0);
|
|
1185
|
+
if (t.length === 0) return {
|
|
1186
|
+
data: [],
|
|
1187
|
+
rowCount: 0,
|
|
1188
|
+
skipped: 0
|
|
1189
|
+
};
|
|
1190
|
+
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) : {
|
|
1191
|
+
time: 0,
|
|
1192
|
+
open: 1,
|
|
1193
|
+
high: 2,
|
|
1194
|
+
low: 3,
|
|
1195
|
+
close: 4,
|
|
1196
|
+
volume: 5
|
|
1197
|
+
};
|
|
1198
|
+
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");
|
|
1199
|
+
let o = [], s = 0;
|
|
1200
|
+
for (let e = +!!i; e < t.length; e++) {
|
|
1201
|
+
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;
|
|
1202
|
+
if (i === null || ![
|
|
1203
|
+
c,
|
|
1204
|
+
l,
|
|
1205
|
+
u,
|
|
1206
|
+
d
|
|
1207
|
+
].every(Number.isFinite)) {
|
|
1208
|
+
s++;
|
|
1209
|
+
continue;
|
|
1210
|
+
}
|
|
1211
|
+
o.push({
|
|
1212
|
+
time: i,
|
|
1213
|
+
open: c,
|
|
1214
|
+
high: l,
|
|
1215
|
+
low: u,
|
|
1216
|
+
close: d,
|
|
1217
|
+
volume: Number.isFinite(f) ? f : 0
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
return Q(o, t.length - +!!i, s);
|
|
1221
|
+
}
|
|
1222
|
+
function Je(e) {
|
|
1223
|
+
let t = {
|
|
1224
|
+
",": 0,
|
|
1225
|
+
";": 0,
|
|
1226
|
+
" ": 0,
|
|
1227
|
+
"|": 0
|
|
1228
|
+
};
|
|
1229
|
+
for (let n of e) n in t && t[n]++;
|
|
1230
|
+
let n = ",", r = 0;
|
|
1231
|
+
for (let [e, i] of Object.entries(t)) i > r && (n = e, r = i);
|
|
1232
|
+
return n;
|
|
1233
|
+
}
|
|
1234
|
+
function J(e, t) {
|
|
1235
|
+
let n = [], r = "", i = !1;
|
|
1236
|
+
for (let a = 0; a < e.length; a++) {
|
|
1237
|
+
let o = e[a];
|
|
1238
|
+
o === "\"" ? i && e[a + 1] === "\"" ? (r += "\"", a++) : i = !i : o === t && !i ? (n.push(r), r = "") : r += o;
|
|
1239
|
+
}
|
|
1240
|
+
return n.push(r), n;
|
|
1241
|
+
}
|
|
1242
|
+
function Y(e) {
|
|
1243
|
+
let t = (t) => e.findIndex((e) => t.includes(e));
|
|
1244
|
+
return {
|
|
1245
|
+
time: t(V),
|
|
1246
|
+
open: t(H),
|
|
1247
|
+
high: t(U),
|
|
1248
|
+
low: t(W),
|
|
1249
|
+
close: t(G),
|
|
1250
|
+
volume: t(K)
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
function Ye(e) {
|
|
1254
|
+
let t = (t) => {
|
|
1255
|
+
for (let n of t) {
|
|
1256
|
+
if (e[n] !== void 0) return e[n];
|
|
1257
|
+
let t = n.toUpperCase();
|
|
1258
|
+
if (e[t] !== void 0) return e[t];
|
|
1259
|
+
}
|
|
1260
|
+
}, 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);
|
|
1261
|
+
return n === null || ![
|
|
1262
|
+
r,
|
|
1263
|
+
i,
|
|
1264
|
+
a,
|
|
1265
|
+
o
|
|
1266
|
+
].every(Number.isFinite) ? null : {
|
|
1267
|
+
time: n,
|
|
1268
|
+
open: r,
|
|
1269
|
+
high: i,
|
|
1270
|
+
low: a,
|
|
1271
|
+
close: o,
|
|
1272
|
+
volume: Number.isFinite(s) ? s : 0
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
function Xe(e) {
|
|
1276
|
+
if (e.length < 5) return null;
|
|
1277
|
+
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;
|
|
1278
|
+
return t === null || ![
|
|
1279
|
+
n,
|
|
1280
|
+
r,
|
|
1281
|
+
i,
|
|
1282
|
+
a
|
|
1283
|
+
].every(Number.isFinite) ? null : {
|
|
1284
|
+
time: t,
|
|
1285
|
+
open: n,
|
|
1286
|
+
high: r,
|
|
1287
|
+
low: i,
|
|
1288
|
+
close: a,
|
|
1289
|
+
volume: Number.isFinite(o) ? o : 0
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
function X(e) {
|
|
1293
|
+
return e === void 0 || e.trim() === "" ? NaN : Number(e);
|
|
1294
|
+
}
|
|
1295
|
+
function Z(e) {
|
|
1296
|
+
let t = e.trim();
|
|
1297
|
+
if (!t) return null;
|
|
1298
|
+
let n = Number(t);
|
|
1299
|
+
if (Number.isFinite(n) && n > 0) return n < 0xe8d4a51000 ? n * 1e3 : n;
|
|
1300
|
+
let r = Date.parse(t);
|
|
1301
|
+
return Number.isFinite(r) ? r : null;
|
|
1302
|
+
}
|
|
1303
|
+
function Q(e, t, n) {
|
|
1304
|
+
e.sort((e, t) => e.time - t.time);
|
|
1305
|
+
let r = [];
|
|
1306
|
+
for (let t of e) r.length > 0 && r[r.length - 1].time === t.time ? r[r.length - 1] = t : r.push(t);
|
|
1307
|
+
return {
|
|
1308
|
+
data: r,
|
|
1309
|
+
rowCount: t,
|
|
1310
|
+
skipped: n
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
//#endregion
|
|
1314
|
+
//#region src/io/DragDropImporter.ts
|
|
1315
|
+
var Ze = class {
|
|
1316
|
+
host;
|
|
1317
|
+
overlay = null;
|
|
1318
|
+
callbacks;
|
|
1319
|
+
bound;
|
|
1320
|
+
depth = 0;
|
|
1321
|
+
constructor(e, t) {
|
|
1322
|
+
this.host = e, this.callbacks = t, this.bound = {
|
|
1323
|
+
dragenter: (e) => this.onDragEnter(e),
|
|
1324
|
+
dragover: (e) => this.onDragOver(e),
|
|
1325
|
+
dragleave: (e) => this.onDragLeave(e),
|
|
1326
|
+
drop: (e) => this.onDrop(e)
|
|
1327
|
+
};
|
|
1328
|
+
}
|
|
1329
|
+
attach() {
|
|
1330
|
+
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);
|
|
1331
|
+
}
|
|
1332
|
+
detach() {
|
|
1333
|
+
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();
|
|
1334
|
+
}
|
|
1335
|
+
onDragEnter(e) {
|
|
1336
|
+
$(e) && (e.preventDefault(), this.depth++, this.showOverlay());
|
|
1337
|
+
}
|
|
1338
|
+
onDragOver(e) {
|
|
1339
|
+
$(e) && (e.preventDefault(), e.dataTransfer && (e.dataTransfer.dropEffect = "copy"));
|
|
1340
|
+
}
|
|
1341
|
+
onDragLeave(e) {
|
|
1342
|
+
$(e) && (this.depth = Math.max(0, this.depth - 1), this.depth === 0 && this.hideOverlay());
|
|
1343
|
+
}
|
|
1344
|
+
async onDrop(e) {
|
|
1345
|
+
e.preventDefault(), this.depth = 0, this.hideOverlay();
|
|
1346
|
+
let t = e.dataTransfer?.files?.[0];
|
|
1347
|
+
if (t) try {
|
|
1348
|
+
let e = q(await t.text());
|
|
1349
|
+
if (e.data.length === 0) throw Error(`No valid OHLCV rows found in "${t.name}"`);
|
|
1350
|
+
this.callbacks.onData(e.data, e, t);
|
|
1351
|
+
} catch (e) {
|
|
1352
|
+
this.callbacks.onError?.(e, t);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
showOverlay() {
|
|
1356
|
+
this.overlay || (this.overlay = document.createElement("div"), Object.assign(this.overlay.style, {
|
|
1357
|
+
position: "absolute",
|
|
1358
|
+
inset: "8px",
|
|
1359
|
+
zIndex: "90",
|
|
1360
|
+
pointerEvents: "none",
|
|
1361
|
+
borderRadius: "10px",
|
|
1362
|
+
border: "2px dashed var(--tcw-accent, #4f88ff)",
|
|
1363
|
+
background: "rgba(79, 136, 255, 0.06)",
|
|
1364
|
+
display: "flex",
|
|
1365
|
+
alignItems: "center",
|
|
1366
|
+
justifyContent: "center",
|
|
1367
|
+
color: "var(--tcw-accent, #4f88ff)",
|
|
1368
|
+
fontSize: "14px",
|
|
1369
|
+
fontWeight: "600",
|
|
1370
|
+
letterSpacing: "-0.005em",
|
|
1371
|
+
fontFamily: "inherit",
|
|
1372
|
+
backdropFilter: "blur(2px)"
|
|
1373
|
+
}), 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));
|
|
1374
|
+
}
|
|
1375
|
+
hideOverlay() {
|
|
1376
|
+
this.overlay?.remove(), this.overlay = null;
|
|
1377
|
+
}
|
|
1105
1378
|
};
|
|
1379
|
+
function $(e) {
|
|
1380
|
+
return e.dataTransfer?.types?.includes("Files") ?? !1;
|
|
1381
|
+
}
|
|
1106
1382
|
//#endregion
|
|
1107
|
-
export {
|
|
1383
|
+
export { z as a, B as i, q as n, I as o, Ge as r, F as s, Ze as t };
|
|
1108
1384
|
|
|
1109
|
-
//# sourceMappingURL=
|
|
1385
|
+
//# sourceMappingURL=DragDropImporter-6QOjnfSj.js.map
|