@pradeepjadhav/trading-reload-chart 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas/layers/CrosshairLayer.d.ts +1 -0
- package/dist/canvas/layers/ExistingCandlesLayer.d.ts +37 -0
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.d.ts +1 -0
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.types.d.ts +1 -0
- package/dist/chart/ChartController.d.ts +5 -0
- package/dist/chart/ChartController.types.d.ts +21 -0
- package/dist/config/chartConfig.types.d.ts +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/models/ChartSync.types.d.ts +16 -0
- package/dist/react/TradingReload.types.d.ts +40 -0
- package/dist/trading-reload-chart.js +631 -475
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { forwardRef as
|
|
2
|
-
import { jsx as
|
|
1
|
+
import { forwardRef as kt, useEffect as st, useImperativeHandle as Rt, useRef as _ } from "react";
|
|
2
|
+
import { jsx as Dt } from "react/jsx-runtime";
|
|
3
3
|
var h = {
|
|
4
4
|
primary: "#7959F7",
|
|
5
5
|
blue: "#2962FF",
|
|
@@ -129,17 +129,17 @@ var h = {
|
|
|
129
129
|
paddingX: 6
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
},
|
|
132
|
+
}, I = { default: "12px Arial" }, nt = {
|
|
133
133
|
width: 1,
|
|
134
134
|
opacity: 0.9,
|
|
135
135
|
style: "dashed",
|
|
136
136
|
dash: [4, 4]
|
|
137
|
-
},
|
|
137
|
+
}, G = {
|
|
138
138
|
width: 1,
|
|
139
139
|
opacity: 0.9,
|
|
140
140
|
style: "dotted",
|
|
141
141
|
dash: [2, 4]
|
|
142
|
-
},
|
|
142
|
+
}, U = {
|
|
143
143
|
height: 22,
|
|
144
144
|
widthVolume: 60,
|
|
145
145
|
widthPNL: 80,
|
|
@@ -159,7 +159,7 @@ var h = {
|
|
|
159
159
|
showVolumeSection: !0,
|
|
160
160
|
showPnlSection: !0,
|
|
161
161
|
showCloseSection: !0
|
|
162
|
-
},
|
|
162
|
+
}, at = {
|
|
163
163
|
width: 32,
|
|
164
164
|
height: 22,
|
|
165
165
|
gapFromStartPriceHandle: 6,
|
|
@@ -172,8 +172,8 @@ var h = {
|
|
|
172
172
|
backgroundOpacity: 0.1,
|
|
173
173
|
textColor: h.white,
|
|
174
174
|
textOpacity: 0.6,
|
|
175
|
-
font:
|
|
176
|
-
},
|
|
175
|
+
font: I.default
|
|
176
|
+
}, ot = {
|
|
177
177
|
height: 22,
|
|
178
178
|
widthPNL: 80,
|
|
179
179
|
position: {
|
|
@@ -188,7 +188,7 @@ var h = {
|
|
|
188
188
|
paddingX: 10,
|
|
189
189
|
textColor: h.white,
|
|
190
190
|
textOpacity: 0.85,
|
|
191
|
-
font:
|
|
191
|
+
font: I.default
|
|
192
192
|
}, c = {
|
|
193
193
|
zoom: {
|
|
194
194
|
x: {
|
|
@@ -247,7 +247,7 @@ var h = {
|
|
|
247
247
|
borderColor: h.axisBorder,
|
|
248
248
|
borderWidth: 1,
|
|
249
249
|
textColor: h.axisText,
|
|
250
|
-
font:
|
|
250
|
+
font: I.default,
|
|
251
251
|
textAlign: "center",
|
|
252
252
|
tickColor: h.axisTick,
|
|
253
253
|
tickWidth: 1,
|
|
@@ -259,7 +259,7 @@ var h = {
|
|
|
259
259
|
borderColor: h.crosshairLabelBackground,
|
|
260
260
|
borderWidth: 1,
|
|
261
261
|
textColor: h.white,
|
|
262
|
-
font:
|
|
262
|
+
font: I.default,
|
|
263
263
|
paddingX: 8,
|
|
264
264
|
height: 26
|
|
265
265
|
}
|
|
@@ -270,7 +270,7 @@ var h = {
|
|
|
270
270
|
borderColor: h.axisBorder,
|
|
271
271
|
borderWidth: 1,
|
|
272
272
|
textColor: h.axisText,
|
|
273
|
-
font:
|
|
273
|
+
font: I.default,
|
|
274
274
|
textAlign: "left",
|
|
275
275
|
tickCount: 12,
|
|
276
276
|
tickColor: h.axisYTick,
|
|
@@ -283,14 +283,14 @@ var h = {
|
|
|
283
283
|
borderColor: h.crosshairLabelBackground,
|
|
284
284
|
borderWidth: 1,
|
|
285
285
|
textColor: h.white,
|
|
286
|
-
font:
|
|
286
|
+
font: I.default,
|
|
287
287
|
paddingX: 8,
|
|
288
288
|
height: 20
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
},
|
|
292
292
|
tradeHandles: {
|
|
293
|
-
font:
|
|
293
|
+
font: I.default,
|
|
294
294
|
textColor: h.white,
|
|
295
295
|
textOpacity: 0.8,
|
|
296
296
|
pnlTextColors: {
|
|
@@ -299,7 +299,7 @@ var h = {
|
|
|
299
299
|
},
|
|
300
300
|
slHandle: {
|
|
301
301
|
handle: {
|
|
302
|
-
...
|
|
302
|
+
...U,
|
|
303
303
|
borderColor: h.red,
|
|
304
304
|
borderOpacity: 0.4,
|
|
305
305
|
backgroundColor: h.slBackground,
|
|
@@ -313,7 +313,7 @@ var h = {
|
|
|
313
313
|
},
|
|
314
314
|
tpHandle: {
|
|
315
315
|
handle: {
|
|
316
|
-
...
|
|
316
|
+
...U,
|
|
317
317
|
borderColor: h.green,
|
|
318
318
|
borderOpacity: 0.4,
|
|
319
319
|
backgroundColor: h.tpBackground,
|
|
@@ -326,7 +326,7 @@ var h = {
|
|
|
326
326
|
}
|
|
327
327
|
},
|
|
328
328
|
startPriceHandle: {
|
|
329
|
-
handle: { ...
|
|
329
|
+
handle: { ...U },
|
|
330
330
|
handleLine: {
|
|
331
331
|
width: 1,
|
|
332
332
|
color: h.blue,
|
|
@@ -338,35 +338,35 @@ var h = {
|
|
|
338
338
|
visible: !0,
|
|
339
339
|
dragActivationThresholdPx: 2,
|
|
340
340
|
slHandle: {
|
|
341
|
-
...
|
|
341
|
+
...at,
|
|
342
342
|
borderColor: h.red,
|
|
343
343
|
backgroundColor: h.slBackground,
|
|
344
344
|
textColor: h.red
|
|
345
345
|
},
|
|
346
346
|
tpHandle: {
|
|
347
|
-
...
|
|
347
|
+
...at,
|
|
348
348
|
borderColor: h.green,
|
|
349
349
|
backgroundColor: h.tpBackground,
|
|
350
350
|
textColor: h.green
|
|
351
351
|
},
|
|
352
352
|
temporarySlHandle: {
|
|
353
|
-
...
|
|
353
|
+
...ot,
|
|
354
354
|
borderColor: h.red,
|
|
355
355
|
backgroundColor: h.slBackground,
|
|
356
356
|
textColor: h.red
|
|
357
357
|
},
|
|
358
358
|
temporaryTpHandle: {
|
|
359
|
-
...
|
|
359
|
+
...ot,
|
|
360
360
|
borderColor: h.green,
|
|
361
361
|
backgroundColor: h.tpBackground,
|
|
362
362
|
textColor: h.green
|
|
363
363
|
},
|
|
364
364
|
temporarySlLine: {
|
|
365
|
-
...
|
|
365
|
+
...G,
|
|
366
366
|
color: h.red
|
|
367
367
|
},
|
|
368
368
|
temporaryTpLine: {
|
|
369
|
-
...
|
|
369
|
+
...G,
|
|
370
370
|
color: h.green
|
|
371
371
|
}
|
|
372
372
|
}
|
|
@@ -375,8 +375,8 @@ var h = {
|
|
|
375
375
|
visible: !0,
|
|
376
376
|
arrow: {
|
|
377
377
|
visible: !0,
|
|
378
|
-
width:
|
|
379
|
-
height:
|
|
378
|
+
width: 20,
|
|
379
|
+
height: 10,
|
|
380
380
|
headHeightRatio: 0.45,
|
|
381
381
|
shaftWidthRatio: 6,
|
|
382
382
|
buyColor: h.green,
|
|
@@ -387,7 +387,7 @@ var h = {
|
|
|
387
387
|
opacity: 1
|
|
388
388
|
},
|
|
389
389
|
connectorLine: {
|
|
390
|
-
...
|
|
390
|
+
...G,
|
|
391
391
|
color: h.white,
|
|
392
392
|
opacity: 0.65
|
|
393
393
|
}
|
|
@@ -413,22 +413,22 @@ var h = {
|
|
|
413
413
|
const e = [];
|
|
414
414
|
for (let i = 1; i < Math.min(t.length, 10); i++) e.push(t[i].time - t[i - 1].time);
|
|
415
415
|
return e.sort((i, s) => i - s), e[Math.floor(e.length / 2)];
|
|
416
|
-
},
|
|
416
|
+
}, At = ({ candleSpacing: t, candleTimeframeMs: e, labelWidth: i, minLabelGap: s }) => {
|
|
417
417
|
if (t <= 0 || e <= 0) return lt[0];
|
|
418
418
|
const r = i + s;
|
|
419
|
-
for (const
|
|
420
|
-
const n = 1440 * 60 * 1e3,
|
|
421
|
-
return n * Math.ceil(r /
|
|
422
|
-
},
|
|
419
|
+
for (const o of lt) if (o / e * t >= r) return o;
|
|
420
|
+
const n = 1440 * 60 * 1e3, a = n / e * t;
|
|
421
|
+
return n * Math.ceil(r / a);
|
|
422
|
+
}, Bt = (t, e) => {
|
|
423
423
|
const i = new Date(t), s = (i.getHours() * 60 + i.getMinutes()) * 60 * 1e3 + i.getSeconds() * 1e3 + i.getMilliseconds();
|
|
424
424
|
return e >= 1440 * 60 * 1e3 ? s === 0 : s % e === 0;
|
|
425
|
-
},
|
|
425
|
+
}, Wt = (t) => {
|
|
426
426
|
const e = new Date(t), i = e.getHours(), s = e.getMinutes();
|
|
427
427
|
return i === 0 && s === 0 ? String(e.getDate()) : `${String(i).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
428
|
-
},
|
|
428
|
+
}, Ft = (t) => {
|
|
429
429
|
const e = new Date(t), i = e.toLocaleDateString("en-US", { weekday: "short" }), s = e.toLocaleDateString("en-US", { month: "short" });
|
|
430
430
|
return `${i} ${e.getDate()} ${s} ${e.getHours().toString().padStart(2, "0")}.${e.getMinutes().toString().padStart(2, "0")}`;
|
|
431
|
-
},
|
|
431
|
+
}, Vt = class {
|
|
432
432
|
#t;
|
|
433
433
|
#e;
|
|
434
434
|
candles;
|
|
@@ -461,10 +461,10 @@ var h = {
|
|
|
461
461
|
}
|
|
462
462
|
drawCrosshairTimeLabel() {
|
|
463
463
|
if (!this.crosshair.visible || !this.crosshair.candle) return;
|
|
464
|
-
const t = this.#e, e = this.#t.width, i = this.#t.height, s = c.axis.axisX.crosshairLabel, r =
|
|
464
|
+
const t = this.#e, e = this.#t.width, i = this.#t.height, s = c.axis.axisX.crosshairLabel, r = Ft(this.crosshair.candle.time);
|
|
465
465
|
t.save(), t.font = s.font;
|
|
466
|
-
const n = t.measureText(r).width + s.paddingX * 2,
|
|
467
|
-
t.fillStyle = s.backgroundColor, t.fillRect(
|
|
466
|
+
const n = t.measureText(r).width + s.paddingX * 2, a = s.height, o = this.getCrosshairLabelX(n, e), l = Math.max(0, (i - a) / 2);
|
|
467
|
+
t.fillStyle = s.backgroundColor, t.fillRect(o, l, n, a), t.strokeStyle = s.borderColor, t.lineWidth = s.borderWidth, t.strokeRect(o, l, n, a), t.fillStyle = s.textColor, t.textAlign = "center", t.textBaseline = "middle", t.fillText(r, o + n / 2, l + a / 2), t.restore();
|
|
468
468
|
}
|
|
469
469
|
clearCanvas() {
|
|
470
470
|
this.#e.clearRect(0, 0, this.#t.width, this.#t.height);
|
|
@@ -481,17 +481,17 @@ var h = {
|
|
|
481
481
|
if (!this.viewport) return;
|
|
482
482
|
const t = this.#e, e = c.axis.axisX, i = this.#t.width, s = It(this.candles);
|
|
483
483
|
t.save(), t.font = e.font, t.fillStyle = e.textColor, t.textAlign = e.textAlign, t.textBaseline = "middle";
|
|
484
|
-
const r = t.measureText("00:00").width, n =
|
|
484
|
+
const r = t.measureText("00:00").width, n = At({
|
|
485
485
|
candleSpacing: this.viewport.candleSpacing,
|
|
486
486
|
candleTimeframeMs: s,
|
|
487
487
|
labelWidth: r,
|
|
488
488
|
minLabelGap: e.minLabelGap
|
|
489
|
-
}), { startIndex:
|
|
490
|
-
for (let l =
|
|
489
|
+
}), { startIndex: a, endIndex: o } = this.getVisibleCandleIndexRange(i);
|
|
490
|
+
for (let l = a; l <= o; l += 1) {
|
|
491
491
|
const d = this.getSlotTime(l, s);
|
|
492
|
-
if (d === null || !
|
|
493
|
-
const u = this.getCandleCenterX(l), g =
|
|
494
|
-
this.isLabelOutsideCanvas(u,
|
|
492
|
+
if (d === null || !Bt(d, n)) continue;
|
|
493
|
+
const u = this.getCandleCenterX(l), g = Wt(d), v = t.measureText(g).width;
|
|
494
|
+
this.isLabelOutsideCanvas(u, v, i) || (this.drawTick(u), this.drawLabel(g, u));
|
|
495
495
|
}
|
|
496
496
|
t.restore();
|
|
497
497
|
}
|
|
@@ -535,7 +535,7 @@ var h = {
|
|
|
535
535
|
getCrosshairLabelX(t, e) {
|
|
536
536
|
return Math.max(120, Math.min(e - t, this.crosshair.x - t / 2));
|
|
537
537
|
}
|
|
538
|
-
}, p = (t, e = 5) => Number(t.toFixed(e)),
|
|
538
|
+
}, p = (t, e = 5) => Number(t.toFixed(e)), Y = ({ price: t, minPrice: e, priceRange: i, chartHeight: s }) => s - (t - e) / i * s, mt = ({ y: t, minPrice: e, priceRange: i, chartHeight: s }) => e + (1 - t / s) * i, Yt = ({ priceRange: t, canvasHeight: e }) => {
|
|
539
539
|
const i = t / (e / c.axis.axisY.tickGap), s = 10 ** Math.floor(Math.log10(i));
|
|
540
540
|
for (const r of [
|
|
541
541
|
1,
|
|
@@ -547,7 +547,7 @@ var h = {
|
|
|
547
547
|
if (n >= i) return n;
|
|
548
548
|
}
|
|
549
549
|
return 10 * s;
|
|
550
|
-
},
|
|
550
|
+
}, Et = class {
|
|
551
551
|
#t;
|
|
552
552
|
#e;
|
|
553
553
|
viewport = null;
|
|
@@ -576,8 +576,8 @@ var h = {
|
|
|
576
576
|
}
|
|
577
577
|
drawCrosshairPriceLabel() {
|
|
578
578
|
if (!this.crosshair.visible) return;
|
|
579
|
-
const t = this.#e, e = this.#t.width, i = this.#t.height, s = c.axis.axisY.crosshairLabel, r = p(this.crosshair.price).toFixed(5), n = s.height,
|
|
580
|
-
t.save(), t.fillStyle = s.backgroundColor, t.fillRect(0,
|
|
579
|
+
const t = this.#e, e = this.#t.width, i = this.#t.height, s = c.axis.axisY.crosshairLabel, r = p(this.crosshair.price).toFixed(5), n = s.height, a = this.getCrosshairLabelY(n, i);
|
|
580
|
+
t.save(), t.fillStyle = s.backgroundColor, t.fillRect(0, a, e, n), t.strokeStyle = s.borderColor, t.lineWidth = s.borderWidth, t.strokeRect(0, a, e, n), t.font = s.font, t.fillStyle = s.textColor, t.textAlign = "left", t.textBaseline = "middle", t.fillText(r, s.paddingX, a + n / 2), t.restore();
|
|
581
581
|
}
|
|
582
582
|
clearCanvas() {
|
|
583
583
|
this.#e.clearRect(0, 0, this.#t.width, this.#t.height);
|
|
@@ -592,15 +592,15 @@ var h = {
|
|
|
592
592
|
}
|
|
593
593
|
drawPriceLabels() {
|
|
594
594
|
if (!this.viewport) return;
|
|
595
|
-
const t = this.#e, e = this.#t.height, i = c.axis.axisY, s =
|
|
595
|
+
const t = this.#e, e = this.#t.height, i = c.axis.axisY, s = Yt({
|
|
596
596
|
priceRange: this.viewport.priceRange,
|
|
597
597
|
canvasHeight: e
|
|
598
598
|
});
|
|
599
599
|
t.save(), t.font = i.font, t.fillStyle = i.textColor, t.textAlign = i.textAlign, t.textBaseline = "middle";
|
|
600
600
|
const { startPrice: r, endPrice: n } = this.getVisiblePriceRange(s);
|
|
601
|
-
for (let
|
|
602
|
-
const
|
|
603
|
-
this.isPriceOutsideCanvas(
|
|
601
|
+
for (let a = r; a <= n; a += s) {
|
|
602
|
+
const o = this.getPriceY(a, e);
|
|
603
|
+
this.isPriceOutsideCanvas(o, e) || (this.drawTick(o), this.drawPriceLabel(a, o));
|
|
604
604
|
}
|
|
605
605
|
t.restore();
|
|
606
606
|
}
|
|
@@ -614,7 +614,7 @@ var h = {
|
|
|
614
614
|
};
|
|
615
615
|
}
|
|
616
616
|
getPriceY(t, e) {
|
|
617
|
-
return this.viewport ?
|
|
617
|
+
return this.viewport ? Y({
|
|
618
618
|
price: t,
|
|
619
619
|
minPrice: this.viewport.minPrice,
|
|
620
620
|
priceRange: this.viewport.priceRange,
|
|
@@ -635,7 +635,7 @@ var h = {
|
|
|
635
635
|
getCrosshairLabelY(t, e) {
|
|
636
636
|
return Math.max(0, Math.min(e - t, this.crosshair.y - t / 2));
|
|
637
637
|
}
|
|
638
|
-
},
|
|
638
|
+
}, Ot = class {
|
|
639
639
|
#t;
|
|
640
640
|
#e;
|
|
641
641
|
mouseX = 0;
|
|
@@ -654,6 +654,9 @@ var h = {
|
|
|
654
654
|
const s = this.getLocalCanvasPoint(t, e), r = i.snapX ?? s.x;
|
|
655
655
|
this.mouseX = this.clampX(r), this.mouseY = this.clampY(s.y), this.visible = !0;
|
|
656
656
|
}
|
|
657
|
+
setPosition(t, e) {
|
|
658
|
+
this.mouseX = this.clampX(t), this.mouseY = this.clampY(e), this.visible = !0;
|
|
659
|
+
}
|
|
657
660
|
hide() {
|
|
658
661
|
this.visible = !1;
|
|
659
662
|
}
|
|
@@ -712,7 +715,7 @@ var h = {
|
|
|
712
715
|
drawLine({ ctx: t, fromX: e, fromY: i, toX: s, toY: r }) {
|
|
713
716
|
t.beginPath(), t.moveTo(e, i), t.lineTo(s, r), t.stroke();
|
|
714
717
|
}
|
|
715
|
-
}, F = 60 * 1e3, Ct = 60 * F,
|
|
718
|
+
}, F = 60 * 1e3, Ct = 60 * F, zt = 24 * Ct, Nt = class {
|
|
716
719
|
#t;
|
|
717
720
|
#e;
|
|
718
721
|
candles;
|
|
@@ -790,6 +793,31 @@ var h = {
|
|
|
790
793
|
endIndex: Math.min(this.candles.length - 1, Math.ceil((t - this.offsetX) / this.candleSpacing))
|
|
791
794
|
};
|
|
792
795
|
}
|
|
796
|
+
getViewState() {
|
|
797
|
+
return this.candles.length === 0 || this.candleSpacing <= 0 || this.#t.width <= 0 ? null : {
|
|
798
|
+
rightmostVisibleTime: this.getRightmostVisibleTime(),
|
|
799
|
+
rightmostVisibleX: this.getRightmostVisibleX(),
|
|
800
|
+
rightEdgeTime: this.getRightEdgeTime(),
|
|
801
|
+
visibleDurationMs: this.getVisibleDurationMs()
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
setViewState(t) {
|
|
805
|
+
if (this.candles.length === 0 || this.#t.width <= 0 || !this.hasUsableTimeframe()) return;
|
|
806
|
+
const e = Number.isFinite(t.rightmostVisibleTime) ? t.rightmostVisibleTime : t.rightEdgeTime, i = Number.isFinite(t.visibleDurationMs) ? t.visibleDurationMs : 0, s = Number.isFinite(t.rightmostVisibleX) ? t.rightmostVisibleX : 1;
|
|
807
|
+
if (!Number.isFinite(e) || i <= 0) return;
|
|
808
|
+
const r = this.detectCandleTimeframeMs(), n = this.baseCandleWidth + this.baseCandleGap, a = this.#t.width * r / i, o = n > 0 ? a / n : this.zoomX;
|
|
809
|
+
this.zoomX = Math.max(c.zoom.x.min, Math.min(o, c.zoom.x.max)), this.offsetX = this.#t.width * s - this.getTimeDeltaInCandleSlots(e) * this.candleSpacing - this.candleWidth / 2, this.isFollowingLatest = this.isWithinAutoFollowThreshold();
|
|
810
|
+
}
|
|
811
|
+
setCursorState(t) {
|
|
812
|
+
if (this.candles.length === 0 || !Number.isFinite(t.time) || !Number.isFinite(t.price)) return null;
|
|
813
|
+
const e = this.getCandleIndexByTime(t.time), i = this.candles[e];
|
|
814
|
+
return i ? {
|
|
815
|
+
candle: i,
|
|
816
|
+
candleIndex: e,
|
|
817
|
+
x: this.getCandleCenterX(e),
|
|
818
|
+
y: this.getPriceY(t.price, this.#t.height)
|
|
819
|
+
} : null;
|
|
820
|
+
}
|
|
793
821
|
getCandleX(t) {
|
|
794
822
|
return t * this.candleSpacing + this.offsetX;
|
|
795
823
|
}
|
|
@@ -840,34 +868,34 @@ var h = {
|
|
|
840
868
|
startIndex: s,
|
|
841
869
|
chartHeight: i
|
|
842
870
|
});
|
|
843
|
-
const
|
|
871
|
+
const a = {
|
|
844
872
|
ctx: t,
|
|
845
873
|
chartWidth: e,
|
|
846
874
|
chartHeight: i
|
|
847
875
|
};
|
|
848
|
-
this.drawAskPriceLine(
|
|
876
|
+
this.drawAskPriceLine(a), this.drawBidPriceLine(a);
|
|
849
877
|
}
|
|
850
878
|
drawCandles({ ctx: t, candles: e, startIndex: i, chartHeight: s }) {
|
|
851
879
|
e.forEach((r, n) => {
|
|
852
|
-
const
|
|
880
|
+
const a = i + n, o = this.getCandleX(a), l = this.getCandleColor(r), d = this.getCandleYCoordinates(r, s);
|
|
853
881
|
this.drawSingleCandle({
|
|
854
882
|
ctx: t,
|
|
855
|
-
candleX:
|
|
883
|
+
candleX: o,
|
|
856
884
|
candleColor: l,
|
|
857
885
|
...d
|
|
858
886
|
});
|
|
859
887
|
});
|
|
860
888
|
}
|
|
861
|
-
drawSingleCandle({ ctx: t, candleX: e, openY: i, closeY: s, highY: r, lowY: n, candleColor:
|
|
862
|
-
t.strokeStyle =
|
|
863
|
-
const
|
|
864
|
-
t.beginPath(), t.moveTo(
|
|
889
|
+
drawSingleCandle({ ctx: t, candleX: e, openY: i, closeY: s, highY: r, lowY: n, candleColor: a }) {
|
|
890
|
+
t.strokeStyle = a, t.fillStyle = a;
|
|
891
|
+
const o = e + this.candleWidth / 2;
|
|
892
|
+
t.beginPath(), t.moveTo(o, r), t.lineTo(o, n), t.stroke();
|
|
865
893
|
const l = Math.min(i, s), d = Math.max(Math.abs(s - i), c.candles.minBodyHeight);
|
|
866
894
|
t.fillRect(e, l, this.candleWidth, d);
|
|
867
895
|
}
|
|
868
|
-
drawPriceLine({ ctx: t, chartWidth: e, chartHeight: i, price: s, color: r, opacity: n, lineWidth:
|
|
896
|
+
drawPriceLine({ ctx: t, chartWidth: e, chartHeight: i, price: s, color: r, opacity: n, lineWidth: a, dash: o }) {
|
|
869
897
|
const l = this.getPriceY(p(s), i);
|
|
870
|
-
t.save(), t.globalAlpha = n, t.strokeStyle = r, t.lineWidth =
|
|
898
|
+
t.save(), t.globalAlpha = n, t.strokeStyle = r, t.lineWidth = a, t.setLineDash(o), t.beginPath(), t.moveTo(0, l), t.lineTo(e, l), t.stroke(), t.restore();
|
|
871
899
|
}
|
|
872
900
|
drawBidPriceLine({ ctx: t, chartWidth: e, chartHeight: i }) {
|
|
873
901
|
const s = this.candles.at(-1);
|
|
@@ -930,7 +958,7 @@ var h = {
|
|
|
930
958
|
}
|
|
931
959
|
getInitialFallbackPercent() {
|
|
932
960
|
const t = this.detectCandleTimeframeMs();
|
|
933
|
-
return t <= F ? 25e-4 : t <= 5 * F ? 35e-4 : t <= 15 * F ? 5e-3 : t <= Ct ? 75e-4 : (t <
|
|
961
|
+
return t <= F ? 25e-4 : t <= 5 * F ? 35e-4 : t <= 15 * F ? 5e-3 : t <= Ct ? 75e-4 : (t < zt, 0.01);
|
|
934
962
|
}
|
|
935
963
|
detectCandleTimeframeMs() {
|
|
936
964
|
if (this.candles.length < 2) return 15 * F;
|
|
@@ -938,6 +966,9 @@ var h = {
|
|
|
938
966
|
for (let e = 1; e < Math.min(this.candles.length, 10); e++) t.push(this.candles[e].time - this.candles[e - 1].time);
|
|
939
967
|
return t.sort((e, i) => e - i), t[Math.floor(t.length / 2)];
|
|
940
968
|
}
|
|
969
|
+
hasUsableTimeframe() {
|
|
970
|
+
return this.detectCandleTimeframeMs() > 0;
|
|
971
|
+
}
|
|
941
972
|
applyManualViewportOverrides(t) {
|
|
942
973
|
t.priceCenter !== void 0 && (this.priceCenter = t.priceCenter), t.priceRange !== void 0 && (this.priceRange = t.priceRange, this.initialPriceRange = t.priceRange);
|
|
943
974
|
}
|
|
@@ -956,13 +987,58 @@ var h = {
|
|
|
956
987
|
getRightEdgeCandleIndex() {
|
|
957
988
|
return (this.#t.width - this.offsetX) / this.candleSpacing;
|
|
958
989
|
}
|
|
990
|
+
getRightmostVisibleTime() {
|
|
991
|
+
const t = this.getRightmostVisibleIndex();
|
|
992
|
+
return this.candles[t]?.time ?? 0;
|
|
993
|
+
}
|
|
994
|
+
getRightmostVisibleX() {
|
|
995
|
+
const t = this.getRightmostVisibleIndex();
|
|
996
|
+
if (this.#t.width <= 0) return 1;
|
|
997
|
+
const e = this.getCandleCenterX(t) / this.#t.width;
|
|
998
|
+
return Math.max(0, Math.min(e, 1));
|
|
999
|
+
}
|
|
1000
|
+
getRightmostVisibleIndex() {
|
|
1001
|
+
return this.candles.length === 0 ? 0 : this.clampCandleIndex(Math.round((this.#t.width - this.offsetX - this.candleWidth) / this.candleSpacing));
|
|
1002
|
+
}
|
|
1003
|
+
getRightEdgeTime() {
|
|
1004
|
+
const t = this.candles.at(-1), e = this.detectCandleTimeframeMs();
|
|
1005
|
+
if (!t || e <= 0) return 0;
|
|
1006
|
+
const i = this.getRightEdgeCandleIndex() - (this.candles.length - 1);
|
|
1007
|
+
return t.time + i * e;
|
|
1008
|
+
}
|
|
1009
|
+
getVisibleDurationMs() {
|
|
1010
|
+
const t = this.detectCandleTimeframeMs();
|
|
1011
|
+
return t <= 0 || this.candleSpacing <= 0 ? 0 : this.#t.width * t / this.candleSpacing;
|
|
1012
|
+
}
|
|
1013
|
+
getTimeDeltaInCandleSlots(t) {
|
|
1014
|
+
const e = this.candles[0];
|
|
1015
|
+
return !e || this.detectCandleTimeframeMs() <= 0 ? 0 : (t - e.time) / this.detectCandleTimeframeMs();
|
|
1016
|
+
}
|
|
1017
|
+
getCandleIndexByTime(t) {
|
|
1018
|
+
if (this.candles.length === 0 || !Number.isFinite(t)) return 0;
|
|
1019
|
+
const e = this.candles.length - 1, i = this.candles[0]?.time ?? 0, s = this.candles[e]?.time ?? 0, r = this.detectCandleTimeframeMs();
|
|
1020
|
+
if (t <= i) return 0;
|
|
1021
|
+
if (t >= s + Math.max(r, 0)) return e;
|
|
1022
|
+
const n = this.findCandleIndexAtOrAfter(t);
|
|
1023
|
+
if (this.candles[n]?.time === t) return n;
|
|
1024
|
+
const a = Math.max(0, n - 1), o = this.candles[a]?.time ?? 0, l = this.candles[n]?.time ?? 0;
|
|
1025
|
+
return t < o + r || t - o <= l - t ? a : n;
|
|
1026
|
+
}
|
|
1027
|
+
findCandleIndexAtOrAfter(t) {
|
|
1028
|
+
let e = 0, i = this.candles.length - 1;
|
|
1029
|
+
for (; e < i; ) {
|
|
1030
|
+
const s = Math.floor((e + i) / 2);
|
|
1031
|
+
(this.candles[s]?.time ?? 0) < t ? e = s + 1 : i = s;
|
|
1032
|
+
}
|
|
1033
|
+
return e;
|
|
1034
|
+
}
|
|
959
1035
|
getNextHorizontalZoom(t) {
|
|
960
1036
|
const { speed: e, min: i, max: s } = c.zoom.x, r = this.zoomX + t * e;
|
|
961
1037
|
return Math.max(i, Math.min(r, s));
|
|
962
1038
|
}
|
|
963
1039
|
getNextVerticalPriceRange(t) {
|
|
964
|
-
const { speed: e, min: i, max: s } = c.zoom.y, r = 1 - t * e, n = this.priceRange * r,
|
|
965
|
-
return Math.max(
|
|
1040
|
+
const { speed: e, min: i, max: s } = c.zoom.y, r = 1 - t * e, n = this.priceRange * r, a = this.initialPriceRange * (i / 100), o = this.initialPriceRange * (s / 100);
|
|
1041
|
+
return Math.max(a, Math.min(n, o));
|
|
966
1042
|
}
|
|
967
1043
|
clearCanvas(t, e, i) {
|
|
968
1044
|
t.clearRect(0, 0, e, i);
|
|
@@ -979,7 +1055,7 @@ var h = {
|
|
|
979
1055
|
};
|
|
980
1056
|
}
|
|
981
1057
|
getPriceY(t, e) {
|
|
982
|
-
return
|
|
1058
|
+
return Y({
|
|
983
1059
|
price: t,
|
|
984
1060
|
minPrice: this.minPrice,
|
|
985
1061
|
priceRange: this.priceRange,
|
|
@@ -992,11 +1068,11 @@ var h = {
|
|
|
992
1068
|
getAskPriceLineColor(t) {
|
|
993
1069
|
return t.close >= t.open ? c.candles.liveAskPriceLine.bullishColor : c.candles.liveAskPriceLine.bearishColor;
|
|
994
1070
|
}
|
|
995
|
-
},
|
|
1071
|
+
}, _t = class {
|
|
996
1072
|
#t;
|
|
997
1073
|
#e;
|
|
998
1074
|
#r = null;
|
|
999
|
-
#
|
|
1075
|
+
#s = null;
|
|
1000
1076
|
constructor({ ctx: t, config: e }) {
|
|
1001
1077
|
this.#t = t, this.#e = e;
|
|
1002
1078
|
}
|
|
@@ -1007,26 +1083,26 @@ var h = {
|
|
|
1007
1083
|
this.#e = t;
|
|
1008
1084
|
}
|
|
1009
1085
|
setPreviousDay(t) {
|
|
1010
|
-
this.#
|
|
1086
|
+
this.#s = t ?? null;
|
|
1011
1087
|
}
|
|
1012
1088
|
render() {
|
|
1013
|
-
if (!this.#r || !this.#
|
|
1014
|
-
const { high: t, low: e } = this.#
|
|
1089
|
+
if (!this.#r || !this.#s) return;
|
|
1090
|
+
const { high: t, low: e } = this.#s;
|
|
1015
1091
|
Number.isFinite(t) && t > 0 && this.#u(t, "PDH"), Number.isFinite(e) && e > 0 && this.#u(e, "PDL");
|
|
1016
1092
|
}
|
|
1017
1093
|
#u(t, e) {
|
|
1018
1094
|
if (!this.#r || !this.#e) return;
|
|
1019
|
-
const i = this.#t, s = i.canvas, r =
|
|
1095
|
+
const i = this.#t, s = i.canvas, r = Y({
|
|
1020
1096
|
price: t,
|
|
1021
1097
|
minPrice: this.#r.minPrice,
|
|
1022
1098
|
priceRange: this.#r.priceRange,
|
|
1023
1099
|
chartHeight: s.height
|
|
1024
1100
|
});
|
|
1025
1101
|
if (r < 0 || r > s.height) return;
|
|
1026
|
-
const { line: n, text:
|
|
1027
|
-
i.save(), i.font =
|
|
1028
|
-
const l = i.measureText(e).width, d =
|
|
1029
|
-
i.globalAlpha = n.opacity, i.strokeStyle = n.color, i.lineWidth = n.width, i.setLineDash(n.dash), i.beginPath(), i.moveTo(0, r), i.lineTo(d - u, r), i.stroke(), i.beginPath(), i.moveTo(d + u, r), i.lineTo(
|
|
1102
|
+
const { line: n, text: a } = this.#e, o = s.width;
|
|
1103
|
+
i.save(), i.font = a.font;
|
|
1104
|
+
const l = i.measureText(e).width, d = o / 2, u = l / 2 + a.paddingX;
|
|
1105
|
+
i.globalAlpha = n.opacity, i.strokeStyle = n.color, i.lineWidth = n.width, i.setLineDash(n.dash), i.beginPath(), i.moveTo(0, r), i.lineTo(d - u, r), i.stroke(), i.beginPath(), i.moveTo(d + u, r), i.lineTo(o, r), i.stroke(), i.setLineDash([]), i.globalAlpha = 1, i.fillStyle = a.color, i.textAlign = "center", i.textBaseline = "middle", i.fillText(e, d, r), i.restore();
|
|
1030
1106
|
}
|
|
1031
1107
|
}, vt = (t, e) => {
|
|
1032
1108
|
const i = t.getBoundingClientRect(), s = t.width / i.width, r = t.height / i.height;
|
|
@@ -1035,13 +1111,13 @@ var h = {
|
|
|
1035
1111
|
y: (e.clientY - i.top) * r
|
|
1036
1112
|
};
|
|
1037
1113
|
};
|
|
1038
|
-
var
|
|
1114
|
+
var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID() : `shape-${Date.now()}-${Math.random().toString(16).slice(2)}`, q = (t, e) => vt(t, e), ht = (t, e) => ({
|
|
1039
1115
|
time: e.getNearestCandleTimeForX(t.x),
|
|
1040
1116
|
price: e.getPriceForY(t.y)
|
|
1041
1117
|
}), C = (t, e) => ({
|
|
1042
1118
|
x: e.getXForTime(t.time),
|
|
1043
1119
|
y: e.getYForPrice(t.price)
|
|
1044
|
-
}),
|
|
1120
|
+
}), Gt = (t, e) => {
|
|
1045
1121
|
const i = Math.min(t.x, e.x), s = Math.max(t.x, e.x), r = Math.min(t.y, e.y), n = Math.max(t.y, e.y);
|
|
1046
1122
|
return {
|
|
1047
1123
|
left: i,
|
|
@@ -1051,21 +1127,21 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1051
1127
|
width: s - i,
|
|
1052
1128
|
height: n - r
|
|
1053
1129
|
};
|
|
1054
|
-
},
|
|
1130
|
+
}, K = (t, e, i) => Gt(C(t, i), C(e, i)), J = (t, e) => {
|
|
1055
1131
|
const i = t.x - e.x, s = t.y - e.y;
|
|
1056
1132
|
return Math.sqrt(i * i + s * s);
|
|
1057
1133
|
}, yt = (t, e, i) => {
|
|
1058
1134
|
const s = i.x - e.x, r = i.y - e.y, n = s * s + r * r;
|
|
1059
|
-
if (n === 0) return
|
|
1060
|
-
const
|
|
1061
|
-
return
|
|
1062
|
-
x: e.x +
|
|
1063
|
-
y: e.y +
|
|
1135
|
+
if (n === 0) return J(t, e);
|
|
1136
|
+
const a = Math.max(0, Math.min(1, ((t.x - e.x) * s + (t.y - e.y) * r) / n));
|
|
1137
|
+
return J(t, {
|
|
1138
|
+
x: e.x + a * s,
|
|
1139
|
+
y: e.y + a * r
|
|
1064
1140
|
});
|
|
1065
|
-
}, wt = (t, e, i = 0) => t.x >= e.left - i && t.x <= e.right + i && t.y >= e.top - i && t.y <= e.bottom + i,
|
|
1141
|
+
}, wt = (t, e, i = 0) => t.x >= e.left - i && t.x <= e.right + i && t.y >= e.top - i && t.y <= e.bottom + i, Ut = (t, e, i = 8) => {
|
|
1066
1142
|
if (!wt(t, e, i)) return !1;
|
|
1067
|
-
const s = Math.abs(t.x - e.left) <= i, r = Math.abs(t.x - e.right) <= i, n = Math.abs(t.y - e.top) <= i,
|
|
1068
|
-
return (s || r) && l || (n ||
|
|
1143
|
+
const s = Math.abs(t.x - e.left) <= i, r = Math.abs(t.x - e.right) <= i, n = Math.abs(t.y - e.top) <= i, a = Math.abs(t.y - e.bottom) <= i, o = t.x >= e.left - i && t.x <= e.right + i, l = t.y >= e.top - i && t.y <= e.bottom + i;
|
|
1144
|
+
return (s || r) && l || (n || a) && o;
|
|
1069
1145
|
}, x = ({ shapeId: t, type: e, point: i, radius: s = 5, cursor: r, index: n }) => ({
|
|
1070
1146
|
shapeId: t,
|
|
1071
1147
|
type: e,
|
|
@@ -1074,27 +1150,27 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1074
1150
|
radius: s,
|
|
1075
1151
|
cursor: r,
|
|
1076
1152
|
index: n
|
|
1077
|
-
}), j = (t, e) =>
|
|
1078
|
-
t.strokeStyle = P(e.lineColor, e.lineOpacity), t.lineWidth = i ?? e.lineWidth, t.setLineDash(
|
|
1079
|
-
},
|
|
1153
|
+
}), j = (t, e) => J(t, e) <= e.radius + 2, z = (t, e = 1) => t === "dashed" ? [e * 6, e * 4] : t === "dotted" ? [e, e * 3] : [], tt = (t, e, i) => {
|
|
1154
|
+
t.strokeStyle = P(e.lineColor, e.lineOpacity), t.lineWidth = i ?? e.lineWidth, t.setLineDash(z(e.lineStyle, t.lineWidth));
|
|
1155
|
+
}, bt = (t, e, i) => !e || i === void 0 || i <= 0 ? !1 : (t.fillStyle = P(e, i), !0), E = (t) => {
|
|
1080
1156
|
t.setLineDash([]);
|
|
1081
|
-
},
|
|
1157
|
+
}, $t = (t, e, i = {
|
|
1082
1158
|
fillColor: "#ffffff",
|
|
1083
1159
|
borderColor: "#2962ff",
|
|
1084
1160
|
borderThickness: 3
|
|
1085
1161
|
}) => {
|
|
1086
1162
|
t.save(), t.beginPath(), t.arc(e.x, e.y, e.radius, 0, Math.PI * 2), t.fillStyle = i.fillColor, t.fill(), t.lineWidth = i.borderThickness, t.strokeStyle = i.borderColor, t.stroke(), t.restore();
|
|
1087
|
-
},
|
|
1163
|
+
}, O = (t, e, i) => {
|
|
1088
1164
|
e.forEach((s) => {
|
|
1089
|
-
|
|
1165
|
+
$t(t, s, i);
|
|
1090
1166
|
});
|
|
1091
1167
|
}, P = (t, e) => {
|
|
1092
|
-
const i =
|
|
1093
|
-
return t.startsWith("rgba(") ? t : t.startsWith("rgb(") ? t.replace("rgb(", "rgba(").replace(")", `, ${i})`) : t.startsWith("#") ?
|
|
1094
|
-
},
|
|
1168
|
+
const i = Kt(e, 0, 1);
|
|
1169
|
+
return t.startsWith("rgba(") ? t : t.startsWith("rgb(") ? t.replace("rgb(", "rgba(").replace(")", `, ${i})`) : t.startsWith("#") ? qt(t, i) : t;
|
|
1170
|
+
}, qt = (t, e) => {
|
|
1095
1171
|
const i = t.replace("#", ""), s = i.length === 3 ? i.split("").map((r) => `${r}${r}`).join("") : i;
|
|
1096
1172
|
return `rgba(${parseInt(s.slice(0, 2), 16)}, ${parseInt(s.slice(2, 4), 16)}, ${parseInt(s.slice(4, 6), 16)}, ${e})`;
|
|
1097
|
-
},
|
|
1173
|
+
}, Kt = (t, e, i) => Math.min(i, Math.max(e, t)), dt = (t, e, i) => e + (t - e) * i, Z = (t, e) => {
|
|
1098
1174
|
if (t.length === 0) return -1;
|
|
1099
1175
|
let i = 0, s = Math.abs(t[0].time - e);
|
|
1100
1176
|
for (let r = 1; r < t.length; r += 1) {
|
|
@@ -1102,7 +1178,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1102
1178
|
n < s && (s = n, i = r);
|
|
1103
1179
|
}
|
|
1104
1180
|
return i;
|
|
1105
|
-
},
|
|
1181
|
+
}, Q = (t) => {
|
|
1106
1182
|
if (t.length < 2) return 900 * 1e3;
|
|
1107
1183
|
const e = [];
|
|
1108
1184
|
for (let i = 1; i < t.length; i += 1) {
|
|
@@ -1110,15 +1186,15 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1110
1186
|
s > 0 && e.push(s);
|
|
1111
1187
|
}
|
|
1112
1188
|
return e.length === 0 ? 900 * 1e3 : e.reduce((i, s) => i + s, 0) / e.length;
|
|
1113
|
-
},
|
|
1189
|
+
}, Jt = (t, e, i) => {
|
|
1114
1190
|
const s = Z(t, e), r = s + i;
|
|
1115
|
-
return s >= 0 && r >= 0 && r < t.length ? t[r].time : e +
|
|
1191
|
+
return s >= 0 && r >= 0 && r < t.length ? t[r].time : e + Q(t) * i;
|
|
1116
1192
|
}, ct = (t) => t instanceof MouseEvent && t.type === "contextmenu" ? !1 : "button" in t && t.type === "pointerdown" ? t.button === 0 : !0, f = {
|
|
1117
1193
|
handleColor: h.background,
|
|
1118
1194
|
handleBorderColor: h.blue,
|
|
1119
1195
|
handleBorderThickness: 1.5,
|
|
1120
1196
|
handleRadius: 5
|
|
1121
|
-
}, L = class
|
|
1197
|
+
}, L = class A {
|
|
1122
1198
|
static defaultConfig = {
|
|
1123
1199
|
levels: [
|
|
1124
1200
|
{
|
|
@@ -1165,21 +1241,21 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1165
1241
|
fillColor: "#808080",
|
|
1166
1242
|
fillOpacity: 0.04
|
|
1167
1243
|
};
|
|
1168
|
-
static draw({ ctx: e, shape: i, converter: s, config: r =
|
|
1169
|
-
const [
|
|
1170
|
-
e.save(),
|
|
1171
|
-
for (const
|
|
1172
|
-
const S = dt(
|
|
1173
|
-
e.beginPath(), e.strokeStyle = P(
|
|
1244
|
+
static draw({ ctx: e, shape: i, converter: s, config: r = A.defaultConfig, selected: n = !1, hovered: a = !1 }) {
|
|
1245
|
+
const [o, l] = i.vertices, d = C(o, s), u = C(l, s), g = K(o, l, s), v = Math.min(d.x, u.x), w = Math.max(d.x, u.x);
|
|
1246
|
+
e.save(), bt(e, r.fillColor, r.fillOpacity) && e.fillRect(g.left, g.top, g.width, g.height);
|
|
1247
|
+
for (const m of r.levels) {
|
|
1248
|
+
const S = dt(o.price, l.price, m.level), T = s.getYForPrice(S), M = m.lineWidth;
|
|
1249
|
+
e.beginPath(), e.strokeStyle = P(m.color, m.opacity), e.lineWidth = M, e.setLineDash(z(m.lineStyle, M)), e.moveTo(v, T), e.lineTo(w, T), e.stroke(), m.label && (e.setLineDash([]), e.fillStyle = P(m.color, m.opacity), e.font = "11px sans-serif", e.textBaseline = "middle", e.fillText(Number(m.label).toFixed(2).toString(), w + 12, T));
|
|
1174
1250
|
}
|
|
1175
|
-
E(e), (n ||
|
|
1251
|
+
E(e), (n || a) && O(e, A.getHandles(i, s), {
|
|
1176
1252
|
fillColor: f.handleColor,
|
|
1177
1253
|
borderColor: f.handleBorderColor,
|
|
1178
1254
|
borderThickness: f.handleBorderThickness
|
|
1179
1255
|
}), e.restore();
|
|
1180
1256
|
}
|
|
1181
|
-
static drawDraft({ ctx: e, vertices: i, converter: s, config: r =
|
|
1182
|
-
|
|
1257
|
+
static drawDraft({ ctx: e, vertices: i, converter: s, config: r = A.defaultConfig }) {
|
|
1258
|
+
A.draw({
|
|
1183
1259
|
ctx: e,
|
|
1184
1260
|
shape: {
|
|
1185
1261
|
id: "__draft_fib_retracement__",
|
|
@@ -1192,7 +1268,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1192
1268
|
});
|
|
1193
1269
|
}
|
|
1194
1270
|
static getHandles(e, i) {
|
|
1195
|
-
const [s, r] = e.vertices, n = C(s, i),
|
|
1271
|
+
const [s, r] = e.vertices, n = C(s, i), a = C(r, i);
|
|
1196
1272
|
return [x({
|
|
1197
1273
|
shapeId: e.id,
|
|
1198
1274
|
type: "start",
|
|
@@ -1202,17 +1278,17 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1202
1278
|
}), x({
|
|
1203
1279
|
shapeId: e.id,
|
|
1204
1280
|
type: "end",
|
|
1205
|
-
point:
|
|
1281
|
+
point: a,
|
|
1206
1282
|
radius: f.handleRadius,
|
|
1207
1283
|
cursor: "grab"
|
|
1208
1284
|
})];
|
|
1209
1285
|
}
|
|
1210
|
-
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8, config: n =
|
|
1211
|
-
const [
|
|
1286
|
+
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8, config: n = A.defaultConfig }) {
|
|
1287
|
+
const [a, o] = i.vertices, l = C(a, s), d = C(o, s), u = Math.min(l.x, d.x), g = Math.max(l.x, d.x);
|
|
1212
1288
|
if (e.x < u - r || e.x > g + r) return !1;
|
|
1213
|
-
for (const
|
|
1214
|
-
const
|
|
1215
|
-
if (Math.abs(e.y -
|
|
1289
|
+
for (const v of n.levels) {
|
|
1290
|
+
const w = dt(a.price, o.price, v.level), m = s.getYForPrice(w);
|
|
1291
|
+
if (Math.abs(e.y - m) <= r) return !0;
|
|
1216
1292
|
}
|
|
1217
1293
|
return !1;
|
|
1218
1294
|
}
|
|
@@ -1237,23 +1313,23 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1237
1313
|
vertices: [e.vertices[0], s]
|
|
1238
1314
|
} : e;
|
|
1239
1315
|
}
|
|
1240
|
-
},
|
|
1316
|
+
}, k = class V {
|
|
1241
1317
|
static defaultConfig = {
|
|
1242
1318
|
lineWidth: 2,
|
|
1243
1319
|
lineColor: "#2962ff",
|
|
1244
1320
|
lineOpacity: 1,
|
|
1245
1321
|
lineStyle: "solid"
|
|
1246
1322
|
};
|
|
1247
|
-
static draw({ ctx: e, shape: i, converter: s, config: r =
|
|
1248
|
-
const [
|
|
1249
|
-
e.save(),
|
|
1323
|
+
static draw({ ctx: e, shape: i, converter: s, config: r = V.defaultConfig, selected: n = !1, hovered: a = !1 }) {
|
|
1324
|
+
const [o, l] = i.vertices, d = C(o, s), u = C(l, s);
|
|
1325
|
+
e.save(), tt(e, r), e.beginPath(), e.moveTo(d.x, d.y), e.lineTo(u.x, u.y), e.stroke(), E(e), (n || a) && O(e, V.getHandles(i, s), {
|
|
1250
1326
|
fillColor: f.handleColor,
|
|
1251
1327
|
borderColor: f.handleBorderColor,
|
|
1252
1328
|
borderThickness: f.handleBorderThickness
|
|
1253
1329
|
}), e.restore();
|
|
1254
1330
|
}
|
|
1255
|
-
static drawDraft({ ctx: e, vertices: i, converter: s, config: r =
|
|
1256
|
-
|
|
1331
|
+
static drawDraft({ ctx: e, vertices: i, converter: s, config: r = V.defaultConfig }) {
|
|
1332
|
+
V.draw({
|
|
1257
1333
|
ctx: e,
|
|
1258
1334
|
shape: {
|
|
1259
1335
|
id: "__draft_trendline__",
|
|
@@ -1266,7 +1342,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1266
1342
|
});
|
|
1267
1343
|
}
|
|
1268
1344
|
static getHandles(e, i) {
|
|
1269
|
-
const [s, r] = e.vertices, n = C(s, i),
|
|
1345
|
+
const [s, r] = e.vertices, n = C(s, i), a = C(r, i);
|
|
1270
1346
|
return [x({
|
|
1271
1347
|
shapeId: e.id,
|
|
1272
1348
|
type: "start",
|
|
@@ -1276,14 +1352,14 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1276
1352
|
}), x({
|
|
1277
1353
|
shapeId: e.id,
|
|
1278
1354
|
type: "end",
|
|
1279
|
-
point:
|
|
1355
|
+
point: a,
|
|
1280
1356
|
radius: f.handleRadius,
|
|
1281
1357
|
cursor: "grab"
|
|
1282
1358
|
})];
|
|
1283
1359
|
}
|
|
1284
1360
|
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8 }) {
|
|
1285
|
-
const [n,
|
|
1286
|
-
return yt(e, C(n, s), C(
|
|
1361
|
+
const [n, a] = i.vertices;
|
|
1362
|
+
return yt(e, C(n, s), C(a, s)) <= r;
|
|
1287
1363
|
}
|
|
1288
1364
|
static move(e, i) {
|
|
1289
1365
|
return {
|
|
@@ -1315,19 +1391,19 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1315
1391
|
fillColor: "#2962ff",
|
|
1316
1392
|
fillOpacity: 0
|
|
1317
1393
|
};
|
|
1318
|
-
static draw({ ctx: e, shape: i, converter: s, config: r = B.defaultConfig, selected: n = !1, hovered:
|
|
1319
|
-
const
|
|
1320
|
-
if (
|
|
1321
|
-
e.save(),
|
|
1322
|
-
for (let l = 1; l <
|
|
1323
|
-
e.stroke(), E(e),
|
|
1394
|
+
static draw({ ctx: e, shape: i, converter: s, config: r = B.defaultConfig, selected: n = !1, hovered: a = !1 }) {
|
|
1395
|
+
const o = i.vertices.map((l) => C(l, s));
|
|
1396
|
+
if (o.length !== 0) {
|
|
1397
|
+
e.save(), tt(e, r), e.beginPath(), e.moveTo(o[0].x, o[0].y);
|
|
1398
|
+
for (let l = 1; l < o.length; l += 1) e.lineTo(o[l].x, o[l].y);
|
|
1399
|
+
e.stroke(), E(e), o.length >= 2 && B.drawEndArrow({
|
|
1324
1400
|
ctx: e,
|
|
1325
|
-
previousPoint:
|
|
1326
|
-
endPoint:
|
|
1401
|
+
previousPoint: o[o.length - 2],
|
|
1402
|
+
endPoint: o[o.length - 1],
|
|
1327
1403
|
color: r.lineColor,
|
|
1328
1404
|
opacity: r.lineOpacity,
|
|
1329
1405
|
lineWidth: r.lineWidth
|
|
1330
|
-
}), (n ||
|
|
1406
|
+
}), (n || a) && O(e, B.getHandles(i, s), {
|
|
1331
1407
|
fillColor: f.handleColor,
|
|
1332
1408
|
borderColor: f.handleBorderColor,
|
|
1333
1409
|
borderThickness: f.handleBorderThickness
|
|
@@ -1335,13 +1411,13 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1335
1411
|
}
|
|
1336
1412
|
}
|
|
1337
1413
|
static drawDraft({ ctx: e, vertices: i, previewVertex: s, converter: r, config: n = B.defaultConfig }) {
|
|
1338
|
-
const
|
|
1414
|
+
const a = s ? [...i, s] : i;
|
|
1339
1415
|
B.draw({
|
|
1340
1416
|
ctx: e,
|
|
1341
1417
|
shape: {
|
|
1342
1418
|
id: "__draft_path__",
|
|
1343
1419
|
type: "path",
|
|
1344
|
-
vertices:
|
|
1420
|
+
vertices: a
|
|
1345
1421
|
},
|
|
1346
1422
|
converter: r,
|
|
1347
1423
|
config: n,
|
|
@@ -1359,12 +1435,12 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1359
1435
|
}));
|
|
1360
1436
|
}
|
|
1361
1437
|
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8 }) {
|
|
1362
|
-
const n = i.vertices.map((
|
|
1438
|
+
const n = i.vertices.map((a) => C(a, s));
|
|
1363
1439
|
if (n.length === 1) {
|
|
1364
|
-
const
|
|
1365
|
-
return Math.sqrt(
|
|
1440
|
+
const a = n[0], o = e.x - a.x, l = e.y - a.y;
|
|
1441
|
+
return Math.sqrt(o * o + l * l) <= r;
|
|
1366
1442
|
}
|
|
1367
|
-
for (let
|
|
1443
|
+
for (let a = 1; a < n.length; a += 1) if (yt(e, n[a - 1], n[a]) <= r) return !0;
|
|
1368
1444
|
return !1;
|
|
1369
1445
|
}
|
|
1370
1446
|
static move(e, i) {
|
|
@@ -1382,9 +1458,9 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1382
1458
|
vertices: e.vertices.map((r, n) => n === i ? s : r)
|
|
1383
1459
|
};
|
|
1384
1460
|
}
|
|
1385
|
-
static drawEndArrow({ ctx: e, previousPoint: i, endPoint: s, color: r, opacity: n, lineWidth:
|
|
1386
|
-
const
|
|
1387
|
-
e.save(), e.beginPath(), e.strokeStyle = P(r, n), e.fillStyle = P(r, n), e.lineWidth =
|
|
1461
|
+
static drawEndArrow({ ctx: e, previousPoint: i, endPoint: s, color: r, opacity: n, lineWidth: a }) {
|
|
1462
|
+
const o = Math.atan2(s.y - i.y, s.x - i.x), l = 12, d = Math.PI / 7;
|
|
1463
|
+
e.save(), e.beginPath(), e.strokeStyle = P(r, n), e.fillStyle = P(r, n), e.lineWidth = a, e.setLineDash([]), e.moveTo(s.x, s.y), e.lineTo(s.x - l * Math.cos(o - d), s.y - l * Math.sin(o - d)), e.lineTo(s.x - l * Math.cos(o + d), s.y - l * Math.sin(o + d)), e.closePath(), e.fill(), e.stroke(), e.restore();
|
|
1388
1464
|
}
|
|
1389
1465
|
}, D = class W {
|
|
1390
1466
|
static defaultConfig = {
|
|
@@ -1399,9 +1475,9 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1399
1475
|
textFontFamily: "Arial",
|
|
1400
1476
|
textFontSize: 20
|
|
1401
1477
|
};
|
|
1402
|
-
static draw({ ctx: e, shape: i, converter: s, config: r = W.defaultConfig, selected: n = !1, hovered:
|
|
1403
|
-
const [
|
|
1404
|
-
e.save(),
|
|
1478
|
+
static draw({ ctx: e, shape: i, converter: s, config: r = W.defaultConfig, selected: n = !1, hovered: a = !1 }) {
|
|
1479
|
+
const [o, l] = i.vertices, d = K(o, l, s);
|
|
1480
|
+
e.save(), bt(e, r.fillColor, r.fillOpacity) && e.fillRect(d.left, d.top, d.width, d.height), tt(e, r), e.strokeRect(d.left, d.top, d.width, d.height), E(e), W.drawText(e, d, i.text, r), (n || a) && O(e, W.getHandles(i, s), {
|
|
1405
1481
|
fillColor: f.handleColor,
|
|
1406
1482
|
borderColor: f.handleBorderColor,
|
|
1407
1483
|
borderThickness: f.handleBorderThickness
|
|
@@ -1421,7 +1497,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1421
1497
|
});
|
|
1422
1498
|
}
|
|
1423
1499
|
static getHandles(e, i) {
|
|
1424
|
-
const [s, r] = e.vertices, n = C(s, i),
|
|
1500
|
+
const [s, r] = e.vertices, n = C(s, i), a = C(r, i), o = n.x <= a.x, l = n.y <= a.y, d = o === l ? "nwse-resize" : "nesw-resize", u = o === l ? "nwse-resize" : "nesw-resize";
|
|
1425
1501
|
return [x({
|
|
1426
1502
|
shapeId: e.id,
|
|
1427
1503
|
type: "start",
|
|
@@ -1431,14 +1507,14 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1431
1507
|
}), x({
|
|
1432
1508
|
shapeId: e.id,
|
|
1433
1509
|
type: "end",
|
|
1434
|
-
point:
|
|
1510
|
+
point: a,
|
|
1435
1511
|
radius: f.handleRadius,
|
|
1436
1512
|
cursor: u
|
|
1437
1513
|
})];
|
|
1438
1514
|
}
|
|
1439
1515
|
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8 }) {
|
|
1440
|
-
const [n,
|
|
1441
|
-
return
|
|
1516
|
+
const [n, a] = i.vertices;
|
|
1517
|
+
return Ut(e, K(n, a, s), r);
|
|
1442
1518
|
}
|
|
1443
1519
|
static move(e, i) {
|
|
1444
1520
|
return {
|
|
@@ -1465,7 +1541,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1465
1541
|
const n = s?.trim();
|
|
1466
1542
|
n && (e.save(), e.beginPath(), e.rect(i.left, i.top, i.width, i.height), e.clip(), e.font = `${r.textFontSize}px ${r.textFontFamily}`, e.globalAlpha = r.textOpacity, e.fillStyle = r.textColor, e.textAlign = "center", e.textBaseline = "middle", e.fillText(n, i.left + i.width / 2, i.top + i.height / 2), e.restore());
|
|
1467
1543
|
}
|
|
1468
|
-
},
|
|
1544
|
+
}, Pt = [
|
|
1469
1545
|
"USDJPY",
|
|
1470
1546
|
"GBPJPY",
|
|
1471
1547
|
"AUDJPY",
|
|
@@ -1477,10 +1553,10 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1477
1553
|
"USOIL",
|
|
1478
1554
|
"UKOIL",
|
|
1479
1555
|
"XAGUSD"
|
|
1480
|
-
], Tt = (t) =>
|
|
1481
|
-
const n = r.split(".")[0],
|
|
1482
|
-
return (t === "buy" ? i - e : e - i) /
|
|
1483
|
-
}, H = class
|
|
1556
|
+
], Tt = (t) => Pt.some((e) => t.includes(e.slice(3))) ? 0.01 : xt.includes(t) ? 1 : St.includes(t) ? 0.01 : 1e-4, jt = (t, e) => Pt.includes(t) ? e * 6.33806 : xt.includes(t) ? e * 1 : (St.includes(t), e * 10), ut = (t, e, i, s, r) => {
|
|
1557
|
+
const n = r.split(".")[0], a = Tt(n), o = jt(n, s);
|
|
1558
|
+
return (t === "buy" ? i - e : e - i) / a * o;
|
|
1559
|
+
}, H = class b {
|
|
1484
1560
|
static defaultLongConfig = {
|
|
1485
1561
|
defaultWidthCandles: 10,
|
|
1486
1562
|
defaultStopLossPercent: 0.25,
|
|
@@ -1498,48 +1574,48 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1498
1574
|
midLineWidth: 1,
|
|
1499
1575
|
midLineStyle: "dashed"
|
|
1500
1576
|
};
|
|
1501
|
-
static defaultShortConfig = { ...
|
|
1502
|
-
static draw({ ctx: e, activeSymbol: i, shape: s, converter: r, config: n = s.type === "longPosition" ?
|
|
1503
|
-
const l =
|
|
1577
|
+
static defaultShortConfig = { ...b.defaultLongConfig };
|
|
1578
|
+
static draw({ ctx: e, activeSymbol: i, shape: s, converter: r, config: n = s.type === "longPosition" ? b.defaultLongConfig : b.defaultShortConfig, selected: a = !1, hovered: o = !1 }) {
|
|
1579
|
+
const l = b.getGeometry(s, r);
|
|
1504
1580
|
e.save(), e.fillStyle = P(n.profitFillColor, n.profitFillOpacity), e.fillRect(l.profitBox.left, l.profitBox.top, l.profitBox.width, l.profitBox.height), e.fillStyle = P(n.lossFillColor, n.lossFillOpacity), e.fillRect(l.lossBox.left, l.lossBox.top, l.lossBox.width, l.lossBox.height);
|
|
1505
1581
|
const d = n.borderWidth;
|
|
1506
|
-
e.strokeStyle = P(n.borderColor, n.borderOpacity), e.lineWidth = d, e.setLineDash(
|
|
1582
|
+
e.strokeStyle = P(n.borderColor, n.borderOpacity), e.lineWidth = d, e.setLineDash(z(n.borderStyle, d)), e.strokeRect(l.box.left, l.box.top, l.box.width, l.box.height), e.beginPath(), e.strokeStyle = P(n.midLineColor, n.midLineOpacity), e.lineWidth = n.midLineWidth, e.setLineDash(z(n.midLineStyle, n.midLineWidth)), e.moveTo(l.box.left, l.entryY), e.lineTo(l.box.right, l.entryY), e.stroke(), E(e), b.drawLabels({
|
|
1507
1583
|
ctx: e,
|
|
1508
1584
|
activeSymbol: i,
|
|
1509
1585
|
shape: s,
|
|
1510
1586
|
geometry: l,
|
|
1511
1587
|
config: n
|
|
1512
|
-
}), (
|
|
1588
|
+
}), (a || o) && O(e, b.getHandles(s, r), {
|
|
1513
1589
|
fillColor: f.handleColor,
|
|
1514
1590
|
borderColor: f.handleBorderColor,
|
|
1515
1591
|
borderThickness: f.handleBorderThickness
|
|
1516
1592
|
}), e.restore();
|
|
1517
1593
|
}
|
|
1518
|
-
static createFromVertex({ id: e, type: i, entry: s, converter: r, config: n = i === "longPosition" ?
|
|
1519
|
-
const
|
|
1594
|
+
static createFromVertex({ id: e, type: i, entry: s, converter: r, config: n = i === "longPosition" ? b.defaultLongConfig : b.defaultShortConfig }) {
|
|
1595
|
+
const a = r.getTimeForX(r.getXForTime(s.time) + r.getCandleWidth() * n.defaultWidthCandles), o = n.defaultStopLossPercent;
|
|
1520
1596
|
return {
|
|
1521
1597
|
id: e,
|
|
1522
1598
|
type: i,
|
|
1523
1599
|
entry: s,
|
|
1524
|
-
endTime:
|
|
1525
|
-
stopLossPercent:
|
|
1526
|
-
takeProfitPercent:
|
|
1600
|
+
endTime: a,
|
|
1601
|
+
stopLossPercent: o,
|
|
1602
|
+
takeProfitPercent: o * n.defaultRiskRewardRatio
|
|
1527
1603
|
};
|
|
1528
1604
|
}
|
|
1529
1605
|
static getGeometry(e, i) {
|
|
1530
|
-
const s = C(e.entry, i), r = i.getXForTime(e.endTime), n = Math.min(s.x, r),
|
|
1606
|
+
const s = C(e.entry, i), r = i.getXForTime(e.endTime), n = Math.min(s.x, r), a = Math.max(s.x, r), o = e.type === "longPosition", l = o ? e.takeProfitPercent : e.stopLossPercent, d = o ? e.stopLossPercent : e.takeProfitPercent, u = e.entry.price * (1 + l / 100), g = e.entry.price * (1 - d / 100), v = i.getYForPrice(u), w = i.getYForPrice(g), m = Math.min(v, w, s.y), S = Math.max(v, w, s.y), T = {
|
|
1531
1607
|
left: n,
|
|
1532
|
-
top:
|
|
1533
|
-
right:
|
|
1608
|
+
top: m,
|
|
1609
|
+
right: a,
|
|
1534
1610
|
bottom: s.y,
|
|
1535
|
-
width:
|
|
1536
|
-
height: Math.abs(s.y -
|
|
1537
|
-
},
|
|
1611
|
+
width: a - n,
|
|
1612
|
+
height: Math.abs(s.y - m)
|
|
1613
|
+
}, M = {
|
|
1538
1614
|
left: n,
|
|
1539
1615
|
top: s.y,
|
|
1540
|
-
right:
|
|
1616
|
+
right: a,
|
|
1541
1617
|
bottom: S,
|
|
1542
|
-
width:
|
|
1618
|
+
width: a - n,
|
|
1543
1619
|
height: Math.abs(S - s.y)
|
|
1544
1620
|
};
|
|
1545
1621
|
return {
|
|
@@ -1550,18 +1626,18 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1550
1626
|
lowerPrice: g,
|
|
1551
1627
|
box: {
|
|
1552
1628
|
left: n,
|
|
1553
|
-
top:
|
|
1554
|
-
right:
|
|
1629
|
+
top: m,
|
|
1630
|
+
right: a,
|
|
1555
1631
|
bottom: S,
|
|
1556
|
-
width:
|
|
1557
|
-
height: S -
|
|
1632
|
+
width: a - n,
|
|
1633
|
+
height: S - m
|
|
1558
1634
|
},
|
|
1559
|
-
profitBox:
|
|
1560
|
-
lossBox:
|
|
1635
|
+
profitBox: o ? T : M,
|
|
1636
|
+
lossBox: o ? M : T
|
|
1561
1637
|
};
|
|
1562
1638
|
}
|
|
1563
1639
|
static getHandles(e, i) {
|
|
1564
|
-
const s =
|
|
1640
|
+
const s = b.getGeometry(e, i);
|
|
1565
1641
|
return [
|
|
1566
1642
|
x({
|
|
1567
1643
|
shapeId: e.id,
|
|
@@ -1606,7 +1682,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1606
1682
|
];
|
|
1607
1683
|
}
|
|
1608
1684
|
static hitTest({ point: e, shape: i, converter: s }) {
|
|
1609
|
-
return
|
|
1685
|
+
return b.getHandles(i, s).some((r) => j(e, r)) ? !0 : wt(e, b.getGeometry(i, s).box);
|
|
1610
1686
|
}
|
|
1611
1687
|
static move(e, i) {
|
|
1612
1688
|
return {
|
|
@@ -1628,7 +1704,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1628
1704
|
} : i === "end" ? {
|
|
1629
1705
|
...e,
|
|
1630
1706
|
endTime: s.time
|
|
1631
|
-
} : i === "upperHeight" ?
|
|
1707
|
+
} : i === "upperHeight" ? b.resizeUpperHeight(e, s.price) : i === "lowerHeight" ? b.resizeLowerHeight(e, s.price) : {
|
|
1632
1708
|
...e,
|
|
1633
1709
|
endTime: r.getTimeForX(r.getXForTime(e.endTime))
|
|
1634
1710
|
};
|
|
@@ -1655,14 +1731,14 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1655
1731
|
}
|
|
1656
1732
|
static drawLabels({ ctx: e, activeSymbol: i, shape: s, geometry: r, config: n }) {
|
|
1657
1733
|
e.save(), e.font = "11px sans-serif", e.textBaseline = "middle";
|
|
1658
|
-
const
|
|
1734
|
+
const a = s.type, o = Tt(i), l = s.entry.price * (s.takeProfitPercent / 100) / o, d = s.entry.price * (s.stopLossPercent / 100) / o, u = r.box.left + 6, g = l / d;
|
|
1659
1735
|
e.fillStyle = P(n.profitFillColor, 0.95);
|
|
1660
|
-
const
|
|
1661
|
-
e.fillText(`${l.toFixed(2)} (${g.toFixed(2)})`, u,
|
|
1662
|
-
const
|
|
1663
|
-
e.fillText(d.toFixed(1), u,
|
|
1736
|
+
const v = a === "longPosition" ? r.profitBox.top + r.profitBox.height / 10 : r.profitBox.bottom - r.profitBox.height / 10;
|
|
1737
|
+
e.fillText(`${l.toFixed(2)} (${g.toFixed(2)})`, u, v), e.fillStyle = P(n.lossFillColor, 0.95);
|
|
1738
|
+
const w = a === "shortPosition" ? r.lossBox.top + r.lossBox.height / 10 : r.lossBox.bottom - r.lossBox.height / 10;
|
|
1739
|
+
e.fillText(d.toFixed(1), u, w);
|
|
1664
1740
|
}
|
|
1665
|
-
},
|
|
1741
|
+
}, Zt = class {
|
|
1666
1742
|
canvas;
|
|
1667
1743
|
ctx;
|
|
1668
1744
|
activeSymbol;
|
|
@@ -1682,12 +1758,13 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1682
1758
|
onShapeModified;
|
|
1683
1759
|
onShapeSelected;
|
|
1684
1760
|
onShapeDoubleClicked;
|
|
1761
|
+
onShapeDeleteRequested;
|
|
1685
1762
|
onToolChange;
|
|
1686
1763
|
constructor(t) {
|
|
1687
1764
|
this.canvas = t.canvas;
|
|
1688
1765
|
const e = this.canvas.getContext("2d");
|
|
1689
1766
|
if (!e) throw new Error("Failed to get 2d context for ShapesLayer");
|
|
1690
|
-
this.ctx = e, this.activeSymbol = t.activeSymbol, this.candles = t.candles, this.shapes = t.shapes, this.activeTool = t.activeTool ?? null, this.config = this.mergeConfig(t.config), this.onShapeAdded = t.onShapeAdded, this.onShapeModified = t.onShapeModified, this.onShapeSelected = t.onShapeSelected, this.onShapeDoubleClicked = t.onShapeDoubleClicked, this.onToolChange = t.onToolChange;
|
|
1767
|
+
this.ctx = e, this.activeSymbol = t.activeSymbol, this.candles = t.candles, this.shapes = t.shapes, this.activeTool = t.activeTool ?? null, this.config = this.mergeConfig(t.config), this.onShapeAdded = t.onShapeAdded, this.onShapeModified = t.onShapeModified, this.onShapeSelected = t.onShapeSelected, this.onShapeDoubleClicked = t.onShapeDoubleClicked, this.onShapeDeleteRequested = t.onShapeDeleteRequested, this.onToolChange = t.onToolChange;
|
|
1691
1768
|
}
|
|
1692
1769
|
setCandles(t) {
|
|
1693
1770
|
this.candles = t;
|
|
@@ -1728,6 +1805,8 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1728
1805
|
return this.draft = null, this.setActiveToolAndEmit(null), !0;
|
|
1729
1806
|
if (t.key === "Escape" && this.selectedShapeId)
|
|
1730
1807
|
return this.setSelectedShapeId(null), !0;
|
|
1808
|
+
if ((t.key === "Delete" || t.key === "Backspace") && this.selectedShapeId && !this.draft && this.onShapeDeleteRequested)
|
|
1809
|
+
return this.onShapeDeleteRequested(this.selectedShapeId), !0;
|
|
1731
1810
|
if (this.selectedShapeId && !this.draft && !this.activeTool && (t.key === "ArrowLeft" || t.key === "ArrowRight" || t.key === "ArrowUp" || t.key === "ArrowDown")) {
|
|
1732
1811
|
const e = this.shapes.find((i) => i.id === this.selectedShapeId);
|
|
1733
1812
|
if (e) {
|
|
@@ -1738,7 +1817,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1738
1817
|
return !1;
|
|
1739
1818
|
}
|
|
1740
1819
|
getArrowKeyDelta(t) {
|
|
1741
|
-
const e =
|
|
1820
|
+
const e = Q(this.candles);
|
|
1742
1821
|
if (t === "ArrowLeft") return {
|
|
1743
1822
|
time: -e,
|
|
1744
1823
|
price: 0
|
|
@@ -1757,7 +1836,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1757
1836
|
};
|
|
1758
1837
|
}
|
|
1759
1838
|
handlePointerDown(t) {
|
|
1760
|
-
const e =
|
|
1839
|
+
const e = q(this.canvas, t), i = ht(e, this.getConverter());
|
|
1761
1840
|
if (this.activeTool)
|
|
1762
1841
|
return ct(t) && this.handleToolPointerDown({
|
|
1763
1842
|
point: e,
|
|
@@ -1766,7 +1845,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1766
1845
|
if (!ct(t)) return !1;
|
|
1767
1846
|
const s = this.findHandleAtPoint(e);
|
|
1768
1847
|
if (s) {
|
|
1769
|
-
const n = this.shapes.find((
|
|
1848
|
+
const n = this.shapes.find((a) => a.id === s.shapeId);
|
|
1770
1849
|
return n ? (this.setSelectedShapeId(n.id), this.checkTouchDoubleTap(n, t), this.dragState = {
|
|
1771
1850
|
edit: {
|
|
1772
1851
|
mode: "resize",
|
|
@@ -1805,7 +1884,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1805
1884
|
return this.setSelectedShapeId(null), this.hoveredShapeId = null, this.canvas.style.cursor = "crosshair", !1;
|
|
1806
1885
|
}
|
|
1807
1886
|
handlePointerMove(t) {
|
|
1808
|
-
const e =
|
|
1887
|
+
const e = q(this.canvas, t), i = ht(e, this.getConverter());
|
|
1809
1888
|
if (this.draft)
|
|
1810
1889
|
return this.updateDraftPreview(i), !0;
|
|
1811
1890
|
if (this.dragState) {
|
|
@@ -1827,7 +1906,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1827
1906
|
}
|
|
1828
1907
|
handleDoubleClick(t) {
|
|
1829
1908
|
if (!this.onShapeDoubleClicked) return !1;
|
|
1830
|
-
const e =
|
|
1909
|
+
const e = q(this.canvas, t), i = this.findShapeAtPoint(e);
|
|
1831
1910
|
return i ? (this.onShapeDoubleClicked(this.createShapeSelectedPayload(i)), !0) : !1;
|
|
1832
1911
|
}
|
|
1833
1912
|
checkTouchDoubleTap(t, e) {
|
|
@@ -1863,7 +1942,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1863
1942
|
if (!this.draft || this.draft.type !== t) {
|
|
1864
1943
|
this.draft = {
|
|
1865
1944
|
type: t,
|
|
1866
|
-
id:
|
|
1945
|
+
id: $(),
|
|
1867
1946
|
vertices: [e, e]
|
|
1868
1947
|
};
|
|
1869
1948
|
return;
|
|
@@ -1879,7 +1958,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1879
1958
|
if (!this.draft || this.draft.type !== "path") {
|
|
1880
1959
|
this.draft = {
|
|
1881
1960
|
type: "path",
|
|
1882
|
-
id:
|
|
1961
|
+
id: $(),
|
|
1883
1962
|
vertices: [t],
|
|
1884
1963
|
previewVertex: null
|
|
1885
1964
|
};
|
|
@@ -1900,7 +1979,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1900
1979
|
}
|
|
1901
1980
|
addPositionShape(t, e) {
|
|
1902
1981
|
const i = this.getConverter(), s = t === "longPosition" ? this.config.longPosition : this.config.shortPosition, r = H.createFromVertex({
|
|
1903
|
-
id:
|
|
1982
|
+
id: $(),
|
|
1904
1983
|
type: t,
|
|
1905
1984
|
entry: e,
|
|
1906
1985
|
converter: i,
|
|
@@ -1950,10 +2029,10 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1950
2029
|
return this.resizeShape(e.shape, e.handleType, t, e.handleIndex);
|
|
1951
2030
|
}
|
|
1952
2031
|
moveShape(t, e) {
|
|
1953
|
-
return t.type === "trendline" ?
|
|
2032
|
+
return t.type === "trendline" ? k.move(t, e) : t.type === "rectangle" ? D.move(t, e) : t.type === "path" ? R.move(t, e) : t.type === "fibRetracement" ? L.move(t, e) : H.move(t, e);
|
|
1954
2033
|
}
|
|
1955
2034
|
resizeShape(t, e, i, s) {
|
|
1956
|
-
return t.type === "trendline" ?
|
|
2035
|
+
return t.type === "trendline" ? k.resize(t, e, i) : t.type === "rectangle" ? D.resize(t, e, i) : t.type === "fibRetracement" ? L.resize(t, e, i) : t.type === "path" ? R.resize(t, s ?? -1, i) : H.resize({
|
|
1957
2036
|
shape: t,
|
|
1958
2037
|
handleType: e,
|
|
1959
2038
|
vertex: i,
|
|
@@ -1963,7 +2042,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1963
2042
|
drawShape({ shape: t, converter: e, selected: i, hovered: s }) {
|
|
1964
2043
|
if (t.type === "trendline") {
|
|
1965
2044
|
const n = this.getTrendlineConfig(t);
|
|
1966
|
-
|
|
2045
|
+
k.draw({
|
|
1967
2046
|
ctx: this.ctx,
|
|
1968
2047
|
shape: t,
|
|
1969
2048
|
converter: e,
|
|
@@ -2023,7 +2102,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2023
2102
|
drawDraft(t) {
|
|
2024
2103
|
if (this.draft) {
|
|
2025
2104
|
if (this.draft.type === "trendline") {
|
|
2026
|
-
|
|
2105
|
+
k.drawDraft({
|
|
2027
2106
|
ctx: this.ctx,
|
|
2028
2107
|
vertices: this.draft.vertices,
|
|
2029
2108
|
converter: t,
|
|
@@ -2067,7 +2146,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2067
2146
|
i && e.push(i), s && e.push(s), this.handleHitboxes = e.flatMap((r) => this.getShapeHandles(r, t));
|
|
2068
2147
|
}
|
|
2069
2148
|
getShapeHandles(t, e) {
|
|
2070
|
-
return t.type === "trendline" ?
|
|
2149
|
+
return t.type === "trendline" ? k.getHandles(t, e) : t.type === "rectangle" ? D.getHandles(t, e) : t.type === "path" ? R.getHandles(t, e) : t.type === "fibRetracement" ? L.getHandles(t, e) : H.getHandles(t, e);
|
|
2071
2150
|
}
|
|
2072
2151
|
findHandleAtPoint(t) {
|
|
2073
2152
|
for (let e = this.handleHitboxes.length - 1; e >= 0; e -= 1) {
|
|
@@ -2090,7 +2169,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2090
2169
|
return null;
|
|
2091
2170
|
}
|
|
2092
2171
|
isShapeHit(t, e, i) {
|
|
2093
|
-
return t.type === "trendline" ?
|
|
2172
|
+
return t.type === "trendline" ? k.hitTest({
|
|
2094
2173
|
point: e,
|
|
2095
2174
|
shape: t,
|
|
2096
2175
|
converter: i
|
|
@@ -2204,7 +2283,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2204
2283
|
getXForTime(t) {
|
|
2205
2284
|
if (!this.viewport || this.candles.length === 0) return 0;
|
|
2206
2285
|
if (t > this.candles[this.candles.length - 1].time) {
|
|
2207
|
-
const i =
|
|
2286
|
+
const i = Q(this.candles);
|
|
2208
2287
|
return (t - this.candles[0].time) / i * this.viewport.candleSpacing + this.viewport.offsetX + this.viewport.candleWidth / 2;
|
|
2209
2288
|
}
|
|
2210
2289
|
const e = Z(this.candles, t);
|
|
@@ -2213,10 +2292,10 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2213
2292
|
getTimeForX(t) {
|
|
2214
2293
|
if (!this.viewport) return Date.now();
|
|
2215
2294
|
const e = Math.round((t - this.viewport.offsetX - this.viewport.candleWidth / 2) / this.viewport.candleSpacing);
|
|
2216
|
-
return e >= 0 && e < this.candles.length ? this.candles[e].time : this.candles.length === 0 ? Date.now() :
|
|
2295
|
+
return e >= 0 && e < this.candles.length ? this.candles[e].time : this.candles.length === 0 ? Date.now() : Jt(this.candles, this.candles[0].time, e);
|
|
2217
2296
|
}
|
|
2218
2297
|
getYForPrice(t) {
|
|
2219
|
-
return this.viewport ?
|
|
2298
|
+
return this.viewport ? Y({
|
|
2220
2299
|
price: t,
|
|
2221
2300
|
minPrice: this.viewport.minPrice,
|
|
2222
2301
|
priceRange: this.viewport.priceRange,
|
|
@@ -2237,7 +2316,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2237
2316
|
mergeConfig(t) {
|
|
2238
2317
|
return {
|
|
2239
2318
|
trendline: {
|
|
2240
|
-
...
|
|
2319
|
+
...k.defaultConfig,
|
|
2241
2320
|
...t?.trendline ?? {}
|
|
2242
2321
|
},
|
|
2243
2322
|
rectangle: {
|
|
@@ -2263,7 +2342,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2263
2342
|
}
|
|
2264
2343
|
};
|
|
2265
2344
|
}
|
|
2266
|
-
},
|
|
2345
|
+
}, Qt = class {
|
|
2267
2346
|
#t;
|
|
2268
2347
|
#e;
|
|
2269
2348
|
isDragging;
|
|
@@ -2312,8 +2391,8 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2312
2391
|
for (const t of this.trades) this.drawTrade({ trade: t });
|
|
2313
2392
|
this.drawTemporaryProtectionDrag();
|
|
2314
2393
|
}
|
|
2315
|
-
createHitBox = ({ price: t, trade: e, type: i, x: s, y: r, width: n, height:
|
|
2316
|
-
const { showCloseSection: l, widthClose: d } = this.getHandleStyleConfig(i).handle, u = l ? d : 0, g = n - u,
|
|
2394
|
+
createHitBox = ({ price: t, trade: e, type: i, x: s, y: r, width: n, height: a, viewport: o }) => {
|
|
2395
|
+
const { showCloseSection: l, widthClose: d } = this.getHandleStyleConfig(i).handle, u = l ? d : 0, g = n - u, v = s + n - u;
|
|
2317
2396
|
return {
|
|
2318
2397
|
kind: "existingHandle",
|
|
2319
2398
|
price: p(t),
|
|
@@ -2322,23 +2401,23 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2322
2401
|
x: s,
|
|
2323
2402
|
y: r,
|
|
2324
2403
|
width: n,
|
|
2325
|
-
height:
|
|
2326
|
-
viewport:
|
|
2404
|
+
height: a,
|
|
2405
|
+
viewport: o,
|
|
2327
2406
|
labelArea: {
|
|
2328
2407
|
x: s,
|
|
2329
2408
|
y: r,
|
|
2330
2409
|
width: g,
|
|
2331
|
-
height:
|
|
2410
|
+
height: a
|
|
2332
2411
|
},
|
|
2333
2412
|
closeButtonArea: {
|
|
2334
|
-
x:
|
|
2413
|
+
x: v,
|
|
2335
2414
|
y: r,
|
|
2336
2415
|
width: u,
|
|
2337
|
-
height:
|
|
2416
|
+
height: a
|
|
2338
2417
|
}
|
|
2339
2418
|
};
|
|
2340
2419
|
};
|
|
2341
|
-
createMissingProtectionHitBox = ({ price: t, trade: e, type: i, x: s, y: r, width: n, height:
|
|
2420
|
+
createMissingProtectionHitBox = ({ price: t, trade: e, type: i, x: s, y: r, width: n, height: a, viewport: o }) => ({
|
|
2342
2421
|
kind: "missingProtectionHandle",
|
|
2343
2422
|
price: p(t),
|
|
2344
2423
|
trade: e,
|
|
@@ -2346,19 +2425,19 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2346
2425
|
x: s,
|
|
2347
2426
|
y: r,
|
|
2348
2427
|
width: n,
|
|
2349
|
-
height:
|
|
2350
|
-
viewport:
|
|
2428
|
+
height: a,
|
|
2429
|
+
viewport: o,
|
|
2351
2430
|
labelArea: {
|
|
2352
2431
|
x: s,
|
|
2353
2432
|
y: r,
|
|
2354
2433
|
width: n,
|
|
2355
|
-
height:
|
|
2434
|
+
height: a
|
|
2356
2435
|
},
|
|
2357
2436
|
closeButtonArea: {
|
|
2358
2437
|
x: s + n,
|
|
2359
2438
|
y: r,
|
|
2360
2439
|
width: 0,
|
|
2361
|
-
height:
|
|
2440
|
+
height: a
|
|
2362
2441
|
}
|
|
2363
2442
|
});
|
|
2364
2443
|
drawTrade({ trade: t }) {
|
|
@@ -2439,20 +2518,20 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2439
2518
|
padding: Math.max(1, s.borderWidth)
|
|
2440
2519
|
}), r.save(), r.globalAlpha = s.backgroundOpacity, r.fillStyle = s.backgroundColor, r.fillRect(t, e, i, s.height), r.globalAlpha = s.borderOpacity, r.strokeStyle = s.borderColor, r.lineWidth = s.borderWidth, r.strokeRect(t, e, i, s.height), r.restore();
|
|
2441
2520
|
}
|
|
2442
|
-
drawHandleSections({ handleType: t, handleX: e, handleY: i, handleWidth: s, handleHeight: r, handleConfig: n, trade:
|
|
2521
|
+
drawHandleSections({ handleType: t, handleX: e, handleY: i, handleWidth: s, handleHeight: r, handleConfig: n, trade: a, y: o }) {
|
|
2443
2522
|
const l = this.#e, d = c.tradeHandles, u = this.getHandleSections({
|
|
2444
2523
|
handleType: t,
|
|
2445
2524
|
handleConfig: n,
|
|
2446
|
-
trade:
|
|
2525
|
+
trade: a
|
|
2447
2526
|
});
|
|
2448
2527
|
let g = e;
|
|
2449
2528
|
l.save(), l.font = d.font, l.textBaseline = "middle", l.globalAlpha = d.textOpacity;
|
|
2450
|
-
for (const
|
|
2451
|
-
|
|
2452
|
-
section:
|
|
2529
|
+
for (const v of u)
|
|
2530
|
+
v.visible && (this.drawHandleSectionLabel({
|
|
2531
|
+
section: v,
|
|
2453
2532
|
currentX: g,
|
|
2454
|
-
y:
|
|
2455
|
-
}), g +=
|
|
2533
|
+
y: o
|
|
2534
|
+
}), g += v.width, g < e + s && this.drawHandleSectionDivider({
|
|
2456
2535
|
x: g,
|
|
2457
2536
|
y1: i + 4,
|
|
2458
2537
|
y2: i + r - 4,
|
|
@@ -2520,7 +2599,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2520
2599
|
if (!this.viewport) return null;
|
|
2521
2600
|
const e = this.getTimeX(t.openTime), i = this.getTimeX(t.closeTime);
|
|
2522
2601
|
if (e === null || i === null) return null;
|
|
2523
|
-
const s = this.getPriceY(t.openPrice, this.viewport), r = this.getPriceY(t.closePrice, this.viewport), n = c.closedTradeIndicators.arrow,
|
|
2602
|
+
const s = this.getPriceY(t.openPrice, this.viewport), r = this.getPriceY(t.closePrice, this.viewport), n = c.closedTradeIndicators.arrow, a = n.width, o = n.height;
|
|
2524
2603
|
return {
|
|
2525
2604
|
trade: t,
|
|
2526
2605
|
start: {
|
|
@@ -2535,8 +2614,8 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2535
2614
|
time: t.closeTime,
|
|
2536
2615
|
price: t.closePrice
|
|
2537
2616
|
},
|
|
2538
|
-
arrowWidth:
|
|
2539
|
-
arrowHeight:
|
|
2617
|
+
arrowWidth: a,
|
|
2618
|
+
arrowHeight: o
|
|
2540
2619
|
};
|
|
2541
2620
|
}
|
|
2542
2621
|
drawClosedTradeConnector({ start: t, close: e }) {
|
|
@@ -2552,7 +2631,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2552
2631
|
drawClosedTradeArrows({ trade: t, start: e, close: i, arrowWidth: s, arrowHeight: r }) {
|
|
2553
2632
|
const n = c.closedTradeIndicators.arrow;
|
|
2554
2633
|
if (!n.visible) return;
|
|
2555
|
-
const
|
|
2634
|
+
const a = t.type === "buy" ? "sell" : "buy";
|
|
2556
2635
|
this.drawClosedTradeArrow({
|
|
2557
2636
|
x: e.x,
|
|
2558
2637
|
y: e.y,
|
|
@@ -2563,7 +2642,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2563
2642
|
}), this.drawClosedTradeArrow({
|
|
2564
2643
|
x: i.x,
|
|
2565
2644
|
y: i.y,
|
|
2566
|
-
type:
|
|
2645
|
+
type: a,
|
|
2567
2646
|
width: s,
|
|
2568
2647
|
height: r,
|
|
2569
2648
|
config: n
|
|
@@ -2571,10 +2650,10 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2571
2650
|
}
|
|
2572
2651
|
drawClosedTradeArrow({ x: t, y: e, type: i, width: s, height: r, config: n }) {
|
|
2573
2652
|
if (s <= 0 || r <= 0) return;
|
|
2574
|
-
const
|
|
2575
|
-
|
|
2653
|
+
const a = this.#e, o = i === "buy", l = o ? n.buyColor : n.sellColor, d = o ? n.buyBorderColor : n.sellBorderColor, u = o ? 1 : -1, g = Math.max(1, s / n.shaftWidthRatio), v = g + n.borderWidth * 2, w = t, m = e + u * (v / 2), S = t, T = m + u * r, M = r * n.headHeightRatio, et = s / 2, Ht = w - et, Mt = w + et, N = m + u * M, it = () => {
|
|
2654
|
+
a.beginPath(), a.moveTo(S, T), a.lineTo(w, N), a.moveTo(w, m), a.lineTo(Ht, N), a.moveTo(w, m), a.lineTo(Mt, N), a.stroke();
|
|
2576
2655
|
};
|
|
2577
|
-
|
|
2656
|
+
a.save(), a.globalAlpha = n.opacity, a.lineCap = "round", a.lineJoin = "round", a.strokeStyle = d, a.lineWidth = v, it(), a.strokeStyle = l, a.lineWidth = g, it(), a.restore();
|
|
2578
2657
|
}
|
|
2579
2658
|
getTimeX(t) {
|
|
2580
2659
|
if (!this.viewport || this.candles.length === 0 || !Number.isFinite(t)) return null;
|
|
@@ -2589,9 +2668,9 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2589
2668
|
const d = this.candles.length - 1, u = this.getCandleTimeInterval(d), g = (e - s.time) / u;
|
|
2590
2669
|
return this.getCandleCenterX(d) + g * this.viewport.candleSpacing;
|
|
2591
2670
|
}
|
|
2592
|
-
const r = this.getFirstCandleIndexAtOrAfterTime(e), n = Math.max(0, r - 1),
|
|
2593
|
-
if (!
|
|
2594
|
-
const l = (e -
|
|
2671
|
+
const r = this.getFirstCandleIndexAtOrAfterTime(e), n = Math.max(0, r - 1), a = this.candles[n], o = this.candles[r];
|
|
2672
|
+
if (!a || !o || o.time === a.time) return this.getCandleCenterX(n);
|
|
2673
|
+
const l = (e - a.time) / (o.time - a.time);
|
|
2595
2674
|
return this.getCandleCenterX(n) + l * this.viewport.candleSpacing;
|
|
2596
2675
|
}
|
|
2597
2676
|
normalizeTimestamp(t) {
|
|
@@ -2614,7 +2693,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2614
2693
|
}
|
|
2615
2694
|
getTradeHandleRenderState({ price: t, type: e, trade: i }) {
|
|
2616
2695
|
if (!this.viewport) return null;
|
|
2617
|
-
const s = this.viewport, r = this.getPriceY(t, s), n = this.getHandleStyleConfig(e),
|
|
2696
|
+
const s = this.viewport, r = this.getPriceY(t, s), n = this.getHandleStyleConfig(e), a = n.handle, o = n.handleLine, l = this.getHandleWidth(a), d = a.height;
|
|
2618
2697
|
return {
|
|
2619
2698
|
price: t,
|
|
2620
2699
|
type: e,
|
|
@@ -2622,11 +2701,11 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2622
2701
|
viewport: s,
|
|
2623
2702
|
y: r,
|
|
2624
2703
|
handleStyleConfig: n,
|
|
2625
|
-
handleConfig:
|
|
2626
|
-
lineConfig:
|
|
2704
|
+
handleConfig: a,
|
|
2705
|
+
lineConfig: o,
|
|
2627
2706
|
handleX: this.getHandleX({
|
|
2628
2707
|
handleWidth: l,
|
|
2629
|
-
config:
|
|
2708
|
+
config: a
|
|
2630
2709
|
}),
|
|
2631
2710
|
handleY: r - d / 2,
|
|
2632
2711
|
handleWidth: l,
|
|
@@ -2634,7 +2713,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2634
2713
|
};
|
|
2635
2714
|
}
|
|
2636
2715
|
getPriceY(t, e) {
|
|
2637
|
-
return
|
|
2716
|
+
return Y({
|
|
2638
2717
|
price: t,
|
|
2639
2718
|
minPrice: e.minPrice,
|
|
2640
2719
|
priceRange: e.priceRange,
|
|
@@ -2778,12 +2857,12 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2778
2857
|
return t.sl || e.push("stopLoss"), t.tp || e.push("takeProfit"), e;
|
|
2779
2858
|
}
|
|
2780
2859
|
getMissingProtectionHandleRenderState({ type: t, trade: e, startPriceRenderState: i, visibleTypes: s }) {
|
|
2781
|
-
const r = this.getMissingProtectionHandleConfig(t), n = r.width,
|
|
2860
|
+
const r = this.getMissingProtectionHandleConfig(t), n = r.width, a = r.height, o = this.getMissingProtectionHandleX({
|
|
2782
2861
|
type: t,
|
|
2783
2862
|
config: r,
|
|
2784
2863
|
startPriceRenderState: i,
|
|
2785
2864
|
visibleTypes: s
|
|
2786
|
-
}), l = i.y -
|
|
2865
|
+
}), l = i.y - a / 2;
|
|
2787
2866
|
return {
|
|
2788
2867
|
price: e.openPrice,
|
|
2789
2868
|
type: t,
|
|
@@ -2791,10 +2870,10 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2791
2870
|
viewport: i.viewport,
|
|
2792
2871
|
y: i.y,
|
|
2793
2872
|
config: r,
|
|
2794
|
-
handleX:
|
|
2873
|
+
handleX: o,
|
|
2795
2874
|
handleY: l,
|
|
2796
2875
|
handleWidth: n,
|
|
2797
|
-
handleHeight:
|
|
2876
|
+
handleHeight: a
|
|
2798
2877
|
};
|
|
2799
2878
|
}
|
|
2800
2879
|
getMissingProtectionHandleX({ type: t, config: e, startPriceRenderState: i, visibleTypes: s }) {
|
|
@@ -2822,8 +2901,8 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2822
2901
|
}), r.save(), r.globalAlpha = s.backgroundOpacity, r.fillStyle = s.backgroundColor, r.fillRect(t, e, i, s.height), r.globalAlpha = s.borderOpacity, r.strokeStyle = s.borderColor, r.lineWidth = s.borderWidth, r.strokeRect(t, e, i, s.height), r.restore();
|
|
2823
2902
|
}
|
|
2824
2903
|
drawMissingProtectionHandleLabel({ type: t, handleX: e, y: i, handleWidth: s, config: r }) {
|
|
2825
|
-
const n = this.#e,
|
|
2826
|
-
n.save(), n.font = r.font, n.textBaseline = "middle", n.globalAlpha = r.textOpacity, n.fillStyle = r.textColor, n.fillText(
|
|
2904
|
+
const n = this.#e, a = t === "stopLoss" ? "SL" : "TP", o = e + s / 2;
|
|
2905
|
+
n.save(), n.font = r.font, n.textBaseline = "middle", n.globalAlpha = r.textOpacity, n.fillStyle = r.textColor, n.fillText(a, o - n.measureText(a).width / 2, i), n.restore();
|
|
2827
2906
|
}
|
|
2828
2907
|
drawTemporaryProtectionDrag() {
|
|
2829
2908
|
const t = this.getTemporaryProtectionRenderState();
|
|
@@ -2836,7 +2915,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2836
2915
|
}
|
|
2837
2916
|
getTemporaryProtectionRenderState() {
|
|
2838
2917
|
if (!this.temporaryProtectionDrag) return null;
|
|
2839
|
-
const { trade: t, type: e, viewport: i } = this.temporaryProtectionDrag, s = p(this.temporaryProtectionDrag.price), r = this.getPriceY(s, i), n = this.getTemporaryProtectionHandleConfig(e),
|
|
2918
|
+
const { trade: t, type: e, viewport: i } = this.temporaryProtectionDrag, s = p(this.temporaryProtectionDrag.price), r = this.getPriceY(s, i), n = this.getTemporaryProtectionHandleConfig(e), a = this.getTemporaryProtectionLineConfig(e), o = n.widthPNL, l = n.height;
|
|
2840
2919
|
return {
|
|
2841
2920
|
price: s,
|
|
2842
2921
|
type: e,
|
|
@@ -2844,13 +2923,13 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2844
2923
|
viewport: i,
|
|
2845
2924
|
y: r,
|
|
2846
2925
|
handleConfig: n,
|
|
2847
|
-
lineConfig:
|
|
2926
|
+
lineConfig: a,
|
|
2848
2927
|
handleX: this.getTemporaryProtectionHandleX({
|
|
2849
|
-
handleWidth:
|
|
2928
|
+
handleWidth: o,
|
|
2850
2929
|
config: n
|
|
2851
2930
|
}),
|
|
2852
2931
|
handleY: r - l / 2,
|
|
2853
|
-
handleWidth:
|
|
2932
|
+
handleWidth: o,
|
|
2854
2933
|
handleHeight: l
|
|
2855
2934
|
};
|
|
2856
2935
|
}
|
|
@@ -2872,9 +2951,9 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2872
2951
|
padding: Math.max(1, s.borderWidth)
|
|
2873
2952
|
}), r.save(), r.globalAlpha = s.backgroundOpacity, r.fillStyle = s.backgroundColor, r.fillRect(t, e, i, s.height), r.globalAlpha = s.borderOpacity, r.strokeStyle = s.borderColor, r.lineWidth = s.borderWidth, r.strokeRect(t, e, i, s.height), r.restore();
|
|
2874
2953
|
}
|
|
2875
|
-
drawTemporaryProtectionPnLLabel({ trade: t, type: e, price: i, handleX: s, y: r, handleWidth: n, handleConfig:
|
|
2876
|
-
const
|
|
2877
|
-
|
|
2954
|
+
drawTemporaryProtectionPnLLabel({ trade: t, type: e, price: i, handleX: s, y: r, handleWidth: n, handleConfig: a }) {
|
|
2955
|
+
const o = this.#e, l = ut(t.type, t.openPrice, i, t.volume, t.symbol), d = this.formatPnlLabel(l), u = s + n / 2;
|
|
2956
|
+
o.save(), o.font = a.font, o.textBaseline = "middle", o.globalAlpha = a.textOpacity, o.fillStyle = this.getProtectionPnlTextColor(e), o.fillText(d, u - o.measureText(d).width / 2, r), o.restore();
|
|
2878
2957
|
}
|
|
2879
2958
|
clearRectArea({ x: t, y: e, width: i, height: s, padding: r = 0 }) {
|
|
2880
2959
|
this.#e.clearRect(t - r, e - r, i + r * 2, s + r * 2);
|
|
@@ -2902,43 +2981,43 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2902
2981
|
formatPnlLabel(t) {
|
|
2903
2982
|
return `${t >= 0 ? "+" : ""}${t.toFixed(2)}`;
|
|
2904
2983
|
}
|
|
2905
|
-
},
|
|
2984
|
+
}, te = [
|
|
2906
2985
|
"pointerdown",
|
|
2907
2986
|
"pointermove",
|
|
2908
2987
|
"pointerup"
|
|
2909
|
-
],
|
|
2988
|
+
], ee = class {
|
|
2910
2989
|
#t;
|
|
2911
2990
|
#e;
|
|
2912
2991
|
#r;
|
|
2913
|
-
#i;
|
|
2914
|
-
#u;
|
|
2915
2992
|
#s;
|
|
2916
|
-
#
|
|
2993
|
+
#u;
|
|
2994
|
+
#i;
|
|
2995
|
+
#h;
|
|
2917
2996
|
#g;
|
|
2918
2997
|
#n;
|
|
2919
|
-
#a = null;
|
|
2920
2998
|
#o = null;
|
|
2999
|
+
#a = null;
|
|
2921
3000
|
#d = !1;
|
|
2922
|
-
#
|
|
2923
|
-
#
|
|
3001
|
+
#l = 0;
|
|
3002
|
+
#C = 0;
|
|
2924
3003
|
constructor(t) {
|
|
2925
|
-
this.#t = t.canvas, this.#e = t.getHandleHitboxes, this.#r = t.getCurrentPrice, this.#
|
|
3004
|
+
this.#t = t.canvas, this.#e = t.getHandleHitboxes, this.#r = t.getCurrentPrice, this.#s = t.onDrag, this.#u = t.onMissingProtectionDrag, this.#i = t.onMissingProtectionDragEnd, this.#h = t.onMissingProtectionDragCancel, this.#g = t.onTradeModified, this.#n = t.onTradeCloseClicked;
|
|
2926
3005
|
}
|
|
2927
3006
|
cancelActiveInteraction() {
|
|
2928
|
-
this.#
|
|
3007
|
+
this.#a && this.#h?.(), this.#o = null, this.#a = null, this.#d = !1, this.#l = 0, this.#C = 0;
|
|
2929
3008
|
}
|
|
2930
3009
|
handlePointerEvent(t) {
|
|
2931
3010
|
if (!this.isSupportedEventType(t.type)) return !1;
|
|
2932
3011
|
const e = this.getCanvasMousePoint(t);
|
|
2933
|
-
if (t.type === "pointermove" && this.#
|
|
2934
|
-
if (t.type === "pointermove" && this.#
|
|
3012
|
+
if (t.type === "pointermove" && this.#a) return this.handleActiveMissingProtectionDrag(t, e);
|
|
3013
|
+
if (t.type === "pointermove" && this.#o) return this.handleActiveDrag(t, e);
|
|
2935
3014
|
if (t.type === "pointerup")
|
|
2936
|
-
return this.#
|
|
3015
|
+
return this.#a ? this.handleMissingProtectionDragEnd() : this.handleDragEnd();
|
|
2937
3016
|
const i = this.getHoveredHitbox(e);
|
|
2938
3017
|
return i ? this.handleHoveredHitbox(t, i, e) : (this.resetCursorIfIdle(), !1);
|
|
2939
3018
|
}
|
|
2940
3019
|
isSupportedEventType(t) {
|
|
2941
|
-
return
|
|
3020
|
+
return te.includes(t);
|
|
2942
3021
|
}
|
|
2943
3022
|
getCanvasMousePoint(t) {
|
|
2944
3023
|
const e = this.#t.getBoundingClientRect(), i = this.#t.width / e.width, s = this.#t.height / e.height;
|
|
@@ -2948,67 +3027,67 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2948
3027
|
};
|
|
2949
3028
|
}
|
|
2950
3029
|
handleActiveDrag(t, e) {
|
|
2951
|
-
if (!this.#
|
|
3030
|
+
if (!this.#o) return !1;
|
|
2952
3031
|
const i = this.getNextDragPrice(e.y);
|
|
2953
|
-
return this.#
|
|
2954
|
-
trade: this.#
|
|
2955
|
-
type: this.#
|
|
3032
|
+
return this.#o.price = i, this.#s?.({
|
|
3033
|
+
trade: this.#o.trade,
|
|
3034
|
+
type: this.#o.type,
|
|
2956
3035
|
price: i
|
|
2957
3036
|
}), this.consumeEvent(t), !0;
|
|
2958
3037
|
}
|
|
2959
3038
|
handleActiveMissingProtectionDrag(t, e) {
|
|
2960
|
-
if (!this.#
|
|
2961
|
-
const i = e.y - this.#
|
|
3039
|
+
if (!this.#a || !this.isProtectionHandleType(this.#a.type)) return !1;
|
|
3040
|
+
const i = e.y - this.#l, s = c.tradeHandles.missingProtectionHandles.dragActivationThresholdPx;
|
|
2962
3041
|
if (!this.#d && Math.abs(i) < s)
|
|
2963
3042
|
return this.consumeEvent(t), !0;
|
|
2964
3043
|
this.#d = !0;
|
|
2965
3044
|
const r = this.getNextMissingProtectionPrice(e.y);
|
|
2966
|
-
return this.#
|
|
2967
|
-
trade: this.#
|
|
2968
|
-
type: this.#
|
|
3045
|
+
return this.#a.price = r, this.#u?.({
|
|
3046
|
+
trade: this.#a.trade,
|
|
3047
|
+
type: this.#a.type,
|
|
2969
3048
|
price: r
|
|
2970
3049
|
}), this.consumeEvent(t), !0;
|
|
2971
3050
|
}
|
|
2972
3051
|
getNextDragPrice(t) {
|
|
2973
|
-
if (!this.#
|
|
2974
|
-
const e = t - this.#
|
|
2975
|
-
return this.isProtectionHandleType(this.#
|
|
3052
|
+
if (!this.#o) return 0;
|
|
3053
|
+
const e = t - this.#l, i = this.#o.viewport.priceRange / this.#t.height, s = p(this.#C - e * i);
|
|
3054
|
+
return this.isProtectionHandleType(this.#o.type) ? this.constrainExistingProtectionPrice({
|
|
2976
3055
|
price: s,
|
|
2977
|
-
hitbox: this.#
|
|
2978
|
-
type: this.#
|
|
3056
|
+
hitbox: this.#o,
|
|
3057
|
+
type: this.#o.type
|
|
2979
3058
|
}) : s;
|
|
2980
3059
|
}
|
|
2981
3060
|
getNextMissingProtectionPrice(t) {
|
|
2982
|
-
if (!this.#
|
|
2983
|
-
const e = p(this.#
|
|
3061
|
+
if (!this.#a || !this.isProtectionHandleType(this.#a.type)) return 0;
|
|
3062
|
+
const e = p(this.#a.viewport.minPrice + (this.#t.height - t) / this.#t.height * this.#a.viewport.priceRange);
|
|
2984
3063
|
return this.constrainProtectionPrice({
|
|
2985
3064
|
price: e,
|
|
2986
|
-
hitbox: this.#
|
|
2987
|
-
type: this.#
|
|
3065
|
+
hitbox: this.#a,
|
|
3066
|
+
type: this.#a.type
|
|
2988
3067
|
});
|
|
2989
3068
|
}
|
|
2990
3069
|
handleDragEnd() {
|
|
2991
|
-
return this.#
|
|
3070
|
+
return this.#o && this.modifyActiveDragTrade(), this.#o = null, !1;
|
|
2992
3071
|
}
|
|
2993
3072
|
handleMissingProtectionDragEnd() {
|
|
2994
|
-
return this.#
|
|
2995
|
-
trade: this.#
|
|
2996
|
-
type: this.#
|
|
2997
|
-
price: p(this.#
|
|
2998
|
-
}) : this.#
|
|
3073
|
+
return this.#a && this.#d && this.isProtectionHandleType(this.#a.type) ? this.#i?.({
|
|
3074
|
+
trade: this.#a.trade,
|
|
3075
|
+
type: this.#a.type,
|
|
3076
|
+
price: p(this.#a.price)
|
|
3077
|
+
}) : this.#h?.(), this.#a = null, this.#d = !1, !1;
|
|
2999
3078
|
}
|
|
3000
3079
|
modifyActiveDragTrade() {
|
|
3001
|
-
if (!this.#
|
|
3002
|
-
const t = p(this.#
|
|
3003
|
-
if (this.#
|
|
3080
|
+
if (!this.#o) return;
|
|
3081
|
+
const t = p(this.#o.price);
|
|
3082
|
+
if (this.#o.type === "stopLoss") {
|
|
3004
3083
|
this.#g?.({
|
|
3005
|
-
ticket: this.#
|
|
3084
|
+
ticket: this.#o.trade.ticket,
|
|
3006
3085
|
sl: t
|
|
3007
3086
|
});
|
|
3008
3087
|
return;
|
|
3009
3088
|
}
|
|
3010
3089
|
this.#g?.({
|
|
3011
|
-
ticket: this.#
|
|
3090
|
+
ticket: this.#o.trade.ticket,
|
|
3012
3091
|
tp: t
|
|
3013
3092
|
});
|
|
3014
3093
|
}
|
|
@@ -3041,13 +3120,13 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3041
3120
|
document.body.style.cursor = t.type === "startPrice" ? "crosshair" : "ns-resize";
|
|
3042
3121
|
}
|
|
3043
3122
|
startDrag(t, e) {
|
|
3044
|
-
this.#
|
|
3123
|
+
this.#o = t, this.#l = e, this.#C = t.price;
|
|
3045
3124
|
}
|
|
3046
3125
|
startMissingProtectionDrag(t, e) {
|
|
3047
|
-
this.#
|
|
3126
|
+
this.#a = t, this.#l = e, this.#d = !1;
|
|
3048
3127
|
}
|
|
3049
3128
|
resetCursorIfIdle() {
|
|
3050
|
-
!this.#
|
|
3129
|
+
!this.#o && !this.#a && (document.body.style.cursor = "crosshair");
|
|
3051
3130
|
}
|
|
3052
3131
|
isPointInsideArea(t, e) {
|
|
3053
3132
|
const i = t.x >= e.x && t.x <= e.x + e.width, s = t.y >= e.y && t.y <= e.y + e.height;
|
|
@@ -3070,7 +3149,7 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3070
3149
|
consumeEvent(t) {
|
|
3071
3150
|
t.stopPropagation(), t.preventDefault();
|
|
3072
3151
|
}
|
|
3073
|
-
},
|
|
3152
|
+
}, ie = class {
|
|
3074
3153
|
#t;
|
|
3075
3154
|
#e;
|
|
3076
3155
|
candles;
|
|
@@ -3099,18 +3178,18 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3099
3178
|
if (this.clearCanvas(), !c.volume.visible || !this.viewport || this.candles.length === 0) return;
|
|
3100
3179
|
const t = this.#e, e = this.#t.width, i = this.#t.height, { startIndex: s, endIndex: r } = this.getVisibleRange(e);
|
|
3101
3180
|
if (r < s) return;
|
|
3102
|
-
const n = this.candles.slice(s, r + 1),
|
|
3103
|
-
|
|
3181
|
+
const n = this.candles.slice(s, r + 1), a = this.getMaxVolume(n);
|
|
3182
|
+
a <= 0 || this.drawVolumeBars({
|
|
3104
3183
|
ctx: t,
|
|
3105
3184
|
candles: n,
|
|
3106
3185
|
startIndex: s,
|
|
3107
|
-
maxVolume:
|
|
3186
|
+
maxVolume: a,
|
|
3108
3187
|
chartHeight: i
|
|
3109
3188
|
});
|
|
3110
3189
|
}
|
|
3111
3190
|
drawVolumeBars({ ctx: t, candles: e, startIndex: i, maxVolume: s, chartHeight: r }) {
|
|
3112
|
-
t.save(), t.globalAlpha = this.opacity, e.forEach((n,
|
|
3113
|
-
const
|
|
3191
|
+
t.save(), t.globalAlpha = this.opacity, e.forEach((n, a) => {
|
|
3192
|
+
const o = i + a, l = this.getCandleX(o);
|
|
3114
3193
|
this.drawSingleVolumeBar({
|
|
3115
3194
|
ctx: t,
|
|
3116
3195
|
candle: n,
|
|
@@ -3124,8 +3203,8 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3124
3203
|
if (!this.viewport || e.volume <= 0) return;
|
|
3125
3204
|
const n = this.getVolumeAreaHeight(r);
|
|
3126
3205
|
if (n <= 0) return;
|
|
3127
|
-
const
|
|
3128
|
-
t.fillStyle = this.getVolumeBarColor(e), t.fillRect(i, l, d,
|
|
3206
|
+
const a = n * (e.volume / s), o = Math.min(n, Math.max(a, this.minBarHeight)), l = r - this.bottomOffset - o, d = Math.max(1, this.viewport.candleWidth);
|
|
3207
|
+
t.fillStyle = this.getVolumeBarColor(e), t.fillRect(i, l, d, o);
|
|
3129
3208
|
}
|
|
3130
3209
|
getVisibleRange(t) {
|
|
3131
3210
|
if (!this.viewport) return {
|
|
@@ -3156,26 +3235,26 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3156
3235
|
clearCanvas() {
|
|
3157
3236
|
this.#e.clearRect(0, 0, this.#t.width, this.#t.height);
|
|
3158
3237
|
}
|
|
3159
|
-
},
|
|
3238
|
+
}, X = (t) => {
|
|
3160
3239
|
const e = document.createElement("canvas");
|
|
3161
3240
|
return e.className = t, e;
|
|
3162
|
-
},
|
|
3241
|
+
}, se = (t, e) => {
|
|
3163
3242
|
const i = document.createElement("div");
|
|
3164
3243
|
i.className = "trading-reload-chart", i.style.backgroundColor = e, i.tabIndex = 0;
|
|
3165
3244
|
const s = document.createElement("div");
|
|
3166
3245
|
s.className = "trading-reload-chart__layout";
|
|
3167
3246
|
const r = document.createElement("div");
|
|
3168
3247
|
r.className = "trading-reload-chart__stack";
|
|
3169
|
-
const n =
|
|
3170
|
-
r.append(n,
|
|
3171
|
-
const g =
|
|
3248
|
+
const n = X("trading-reload-chart__volume"), a = X("trading-reload-chart__plot"), o = X("trading-reload-chart__shapes"), l = X("trading-reload-chart__trades"), d = X("trading-reload-chart__overlay"), u = X("trading-reload-chart__axis-x");
|
|
3249
|
+
r.append(n, a, o, l, d, u);
|
|
3250
|
+
const g = X("trading-reload-chart__axis-y");
|
|
3172
3251
|
return s.append(r, g), i.append(s), t.append(i), {
|
|
3173
3252
|
root: i,
|
|
3174
3253
|
layout: s,
|
|
3175
3254
|
stack: r,
|
|
3176
3255
|
volumeCanvas: n,
|
|
3177
|
-
candleCanvas:
|
|
3178
|
-
shapesCanvas:
|
|
3256
|
+
candleCanvas: a,
|
|
3257
|
+
shapesCanvas: o,
|
|
3179
3258
|
tradesCanvas: l,
|
|
3180
3259
|
overlayCanvas: d,
|
|
3181
3260
|
axisXCanvas: u,
|
|
@@ -3198,52 +3277,85 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3198
3277
|
}, ft = (t) => Lt(c, t ?? {}), pt = (t, e) => e === void 0 || t.time >= 1e12 ? t : {
|
|
3199
3278
|
...t,
|
|
3200
3279
|
time: t.time * 1e3 - e
|
|
3201
|
-
},
|
|
3280
|
+
}, re = 12, ne = class {
|
|
3202
3281
|
#t;
|
|
3203
3282
|
#e;
|
|
3204
3283
|
#r;
|
|
3205
|
-
#i = null;
|
|
3206
|
-
#u = null;
|
|
3207
3284
|
#s = null;
|
|
3208
|
-
#
|
|
3285
|
+
#u = null;
|
|
3286
|
+
#i = null;
|
|
3287
|
+
#h = null;
|
|
3209
3288
|
#g = null;
|
|
3210
3289
|
#n = null;
|
|
3211
|
-
#a = null;
|
|
3212
3290
|
#o = null;
|
|
3291
|
+
#a = null;
|
|
3213
3292
|
#d = null;
|
|
3214
|
-
#
|
|
3215
|
-
#
|
|
3216
|
-
#
|
|
3217
|
-
#
|
|
3218
|
-
#
|
|
3219
|
-
#
|
|
3293
|
+
#l = null;
|
|
3294
|
+
#C = !1;
|
|
3295
|
+
#P = 0;
|
|
3296
|
+
#x = !1;
|
|
3297
|
+
#R = 0;
|
|
3298
|
+
#D = 0;
|
|
3220
3299
|
#f = null;
|
|
3221
|
-
#
|
|
3222
|
-
#
|
|
3223
|
-
#
|
|
3300
|
+
#v = null;
|
|
3301
|
+
#S = null;
|
|
3302
|
+
#T = null;
|
|
3303
|
+
#X = !1;
|
|
3304
|
+
#b = !1;
|
|
3305
|
+
#I = null;
|
|
3306
|
+
#y = null;
|
|
3224
3307
|
constructor(t, e) {
|
|
3225
|
-
this.#t = t, this.#e = e, this.#r = ft(e.config), this.#
|
|
3226
|
-
canvas: this.#
|
|
3308
|
+
this.#t = t, this.#e = e, this.#r = ft(e.config), this.#s = se(t, this.#r.colors.background), this.#l = new Ot({
|
|
3309
|
+
canvas: this.#s.overlayCanvas,
|
|
3227
3310
|
crosshairColor: this.#r.crosshair.color,
|
|
3228
3311
|
crosshairThickness: this.#r.crosshair.thickness,
|
|
3229
3312
|
crosshairStyle: this.#r.crosshair.style
|
|
3230
|
-
}), this.#
|
|
3313
|
+
}), this.#z(), this.#N(), this.#B(), this.updateProps(e);
|
|
3231
3314
|
}
|
|
3232
3315
|
updateProps(t) {
|
|
3233
3316
|
const e = this.#e.activeShapeTool;
|
|
3234
|
-
this.#e = t, this.#r = ft(t.config), this.#
|
|
3317
|
+
this.#e = t, this.#r = ft(t.config), this.#s && (this.#s.root.style.backgroundColor = this.#r.colors.background, this.#s.layout.style.setProperty("--axis-x-height", `${this.#r.axis.axisX.height}px`)), !this.#C && t.candles.length > 0 && this.#O(t.candles), this.#i && (t.activeShapeTool !== e && this.#U(t.activeShapeTool), this.#h?.setConfig(this.#r.shapes), this.#h?.setShapes(t.shapes), this.#h?.setActiveTool(t.activeShapeTool), this.#g?.setConfig(this.#r.shapes.previousDayHighLow ?? null), this.#g?.setPreviousDay(t.previousDay), this.#n?.setClosedTrades(t.closedTrades ?? []), this.#M(), this.#q(), this.#c(), this.#m());
|
|
3235
3318
|
}
|
|
3236
3319
|
resetChartView() {
|
|
3237
|
-
this.#
|
|
3320
|
+
this.#i?.resetView(), this.#c(), this.#m();
|
|
3321
|
+
}
|
|
3322
|
+
setView(t) {
|
|
3323
|
+
this.#i && (this.#X = !0, this.#i.setViewState(t), this.#X = !1, this.#I = this.#i.getViewState(), this.#c());
|
|
3324
|
+
}
|
|
3325
|
+
getView() {
|
|
3326
|
+
return this.#i?.getViewState() ?? null;
|
|
3327
|
+
}
|
|
3328
|
+
setCursor(t) {
|
|
3329
|
+
if (!t) {
|
|
3330
|
+
this.#b = !0, this.#F(), this.#b = !1, this.#y = null;
|
|
3331
|
+
return;
|
|
3332
|
+
}
|
|
3333
|
+
if (!this.#i || !this.#l || !this.#s) return;
|
|
3334
|
+
const e = this.#i.setCursorState(t);
|
|
3335
|
+
e && (this.#b = !0, this.#l.setPosition(e.x, e.y), this.#a?.setCrosshair({
|
|
3336
|
+
visible: !0,
|
|
3337
|
+
x: e.x,
|
|
3338
|
+
candle: e.candle
|
|
3339
|
+
}), this.#d?.setCrosshair({
|
|
3340
|
+
visible: !0,
|
|
3341
|
+
y: e.y,
|
|
3342
|
+
price: t.price
|
|
3343
|
+
}), this.#L(), this.#l.render(), this.#b = !1, this.#y = {
|
|
3344
|
+
...t,
|
|
3345
|
+
time: e.candle.time
|
|
3346
|
+
});
|
|
3347
|
+
}
|
|
3348
|
+
hideCursor() {
|
|
3349
|
+
this.setCursor(null);
|
|
3238
3350
|
}
|
|
3239
3351
|
destroy() {
|
|
3240
|
-
this.#
|
|
3352
|
+
this.#T?.abort(), this.#T = null, this.#S?.disconnect(), this.#S = null, this.#s?.root.remove(), this.#s = null, this.#u = null, this.#i = null, this.#h = null, this.#g = null, this.#n = null, this.#o = null, this.#a = null, this.#d = null, this.#l = null, this.#f = null, this.#C = !1;
|
|
3241
3353
|
}
|
|
3242
|
-
#
|
|
3243
|
-
if (!this.#
|
|
3354
|
+
#O(t) {
|
|
3355
|
+
if (!this.#s || this.#C) return;
|
|
3244
3356
|
const e = t.map((s) => pt(s, this.#e.brokerTimezoneOffsetMs));
|
|
3245
|
-
this.#u = new
|
|
3246
|
-
canvas: this.#
|
|
3357
|
+
this.#u = new ie({
|
|
3358
|
+
canvas: this.#s.volumeCanvas,
|
|
3247
3359
|
candles: e,
|
|
3248
3360
|
bullishColor: this.#r.volume.bullishColor,
|
|
3249
3361
|
bearishColor: this.#r.volume.bearishColor,
|
|
@@ -3251,8 +3363,8 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3251
3363
|
height: this.#r.volume.height,
|
|
3252
3364
|
bottomOffset: this.#r.volume.bottomOffset,
|
|
3253
3365
|
minBarHeight: this.#r.volume.minBarHeight
|
|
3254
|
-
}), this.#
|
|
3255
|
-
canvas: this.#
|
|
3366
|
+
}), this.#i = new Nt({
|
|
3367
|
+
canvas: this.#s.candleCanvas,
|
|
3256
3368
|
candles: e,
|
|
3257
3369
|
baseCandleWidth: this.#r.candles.defaultWidth,
|
|
3258
3370
|
baseCandleGap: this.#r.candles.defaultGap,
|
|
@@ -3261,8 +3373,8 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3261
3373
|
autoFollowLatestCandle: this.#r.candles.autoFollowLatestCandle,
|
|
3262
3374
|
autoFollowThresholdCandles: this.#r.candles.autoFollowThresholdCandles,
|
|
3263
3375
|
rightOffsetCandles: this.#r.candles.rightOffsetCandles
|
|
3264
|
-
}), this.#
|
|
3265
|
-
canvas: this.#
|
|
3376
|
+
}), this.#h = new Zt({
|
|
3377
|
+
canvas: this.#s.shapesCanvas,
|
|
3266
3378
|
activeSymbol: this.#e.activeSymbol,
|
|
3267
3379
|
candles: e,
|
|
3268
3380
|
shapes: this.#e.shapes,
|
|
@@ -3280,47 +3392,50 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3280
3392
|
onShapeDoubleClicked: (s) => {
|
|
3281
3393
|
this.#e.onShapeDoubleClicked?.(s);
|
|
3282
3394
|
},
|
|
3395
|
+
onShapeDeleteRequested: (s) => {
|
|
3396
|
+
this.#e.onShapeDeleteRequested?.(s);
|
|
3397
|
+
},
|
|
3283
3398
|
onToolChange: (s) => {
|
|
3284
3399
|
this.#e.onActiveShapeToolChange?.(s);
|
|
3285
3400
|
}
|
|
3286
3401
|
});
|
|
3287
|
-
const i = this.#
|
|
3288
|
-
i && (this.#g = new
|
|
3402
|
+
const i = this.#s.shapesCanvas.getContext("2d");
|
|
3403
|
+
i && (this.#g = new _t({
|
|
3289
3404
|
ctx: i,
|
|
3290
3405
|
config: this.#r.shapes.previousDayHighLow ?? null
|
|
3291
|
-
}), this.#g.setPreviousDay(this.#e.previousDay)), this.#n = new
|
|
3292
|
-
canvas: this.#
|
|
3406
|
+
}), this.#g.setPreviousDay(this.#e.previousDay)), this.#n = new Qt({ canvas: this.#s.tradesCanvas }), this.#n.setCandles(e), this.#n.setClosedTrades(this.#e.closedTrades ?? []), this.#M(), this.#a = new Vt({
|
|
3407
|
+
canvas: this.#s.axisXCanvas,
|
|
3293
3408
|
candles: e
|
|
3294
|
-
}), this.#d = new
|
|
3295
|
-
canvas: this.#
|
|
3409
|
+
}), this.#d = new Et({ canvas: this.#s.axisYCanvas }), this.#o = new ee({
|
|
3410
|
+
canvas: this.#s.tradesCanvas,
|
|
3296
3411
|
getHandleHitboxes: () => this.#p() ? [] : this.#n?.handleHitboxes ?? [],
|
|
3297
|
-
getCurrentPrice: () => this.#
|
|
3298
|
-
onDrag: (s) => this.#
|
|
3299
|
-
onMissingProtectionDrag: (s) => this.#
|
|
3300
|
-
onMissingProtectionDragEnd: (s) => this.#
|
|
3301
|
-
onMissingProtectionDragCancel: () => this.#
|
|
3302
|
-
onTradeModified: (s) => this.#
|
|
3412
|
+
getCurrentPrice: () => this.#i?.liveCandle?.close ?? 0,
|
|
3413
|
+
onDrag: (s) => this.#K(s),
|
|
3414
|
+
onMissingProtectionDrag: (s) => this.#J(s),
|
|
3415
|
+
onMissingProtectionDragEnd: (s) => this.#j(s),
|
|
3416
|
+
onMissingProtectionDragCancel: () => this.#Z(),
|
|
3417
|
+
onTradeModified: (s) => this.#W(s),
|
|
3303
3418
|
onTradeCloseClicked: (s) => this.#e.onTradeClose?.(s)
|
|
3304
|
-
}), this.#
|
|
3419
|
+
}), this.#C = !0, this.#c();
|
|
3305
3420
|
}
|
|
3306
|
-
#
|
|
3307
|
-
if (!this.#
|
|
3308
|
-
this.#
|
|
3309
|
-
const { signal: t } = this.#
|
|
3310
|
-
e.addEventListener("pointerdown", (i) => this.#
|
|
3421
|
+
#z() {
|
|
3422
|
+
if (!this.#s) return;
|
|
3423
|
+
this.#T = new AbortController();
|
|
3424
|
+
const { signal: t } = this.#T, e = this.#s.interactionTarget;
|
|
3425
|
+
e.addEventListener("pointerdown", (i) => this.#et(i), { signal: t }), e.addEventListener("pointerup", (i) => this.#st(i), { signal: t }), e.addEventListener("pointermove", (i) => this.#it(i), { signal: t }), e.addEventListener("pointerenter", (i) => this.#rt(i), { signal: t }), e.addEventListener("pointerleave", () => this.#nt(), { signal: t }), e.addEventListener("contextmenu", (i) => this.#at(i), { signal: t }), e.addEventListener("dblclick", (i) => this.#ot(i), { signal: t }), e.addEventListener("wheel", (i) => this.#Q(i), {
|
|
3311
3426
|
passive: !1,
|
|
3312
3427
|
signal: t
|
|
3313
|
-
}), this.#
|
|
3428
|
+
}), this.#s.axisXCanvas.addEventListener("pointerenter", (i) => this.#V(i), { signal: t }), this.#s.axisXCanvas.addEventListener("pointerdown", (i) => this.#Y(i, "x"), { signal: t }), this.#s.axisXCanvas.addEventListener("pointermove", (i) => this.#E(i), { signal: t }), this.#s.axisXCanvas.addEventListener("pointerup", (i) => this.#k(i), { signal: t }), this.#s.axisXCanvas.addEventListener("pointercancel", (i) => this.#k(i), { signal: t }), this.#s.axisYCanvas.addEventListener("pointerenter", (i) => this.#V(i), { signal: t }), this.#s.axisYCanvas.addEventListener("pointerdown", (i) => this.#Y(i, "y"), { signal: t }), this.#s.axisYCanvas.addEventListener("pointermove", (i) => this.#E(i), { signal: t }), this.#s.axisYCanvas.addEventListener("pointerup", (i) => this.#k(i), { signal: t }), this.#s.axisYCanvas.addEventListener("pointercancel", (i) => this.#k(i), { signal: t }), this.#s.axisYCanvas.addEventListener("wheel", (i) => this.#tt(i), {
|
|
3314
3429
|
passive: !1,
|
|
3315
3430
|
signal: t
|
|
3316
|
-
}), document.addEventListener("keydown", (i) => this.#
|
|
3431
|
+
}), document.addEventListener("keydown", (i) => this.#lt(i), { signal: t });
|
|
3317
3432
|
}
|
|
3318
|
-
#
|
|
3319
|
-
this.#
|
|
3320
|
-
this.#
|
|
3321
|
-
}), this.#
|
|
3433
|
+
#N() {
|
|
3434
|
+
this.#S = new ResizeObserver(() => {
|
|
3435
|
+
this.#B(), this.#c(), this.#m();
|
|
3436
|
+
}), this.#S.observe(this.#t);
|
|
3322
3437
|
}
|
|
3323
|
-
#
|
|
3438
|
+
#_() {
|
|
3324
3439
|
const t = this.#r.axis.axisY.width, e = this.#r.axis.axisX.height, i = this.#t.clientWidth, s = this.#t.clientHeight;
|
|
3325
3440
|
return {
|
|
3326
3441
|
axisYWidth: t,
|
|
@@ -3329,55 +3444,73 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3329
3444
|
plotHeight: Math.max(0, s - e)
|
|
3330
3445
|
};
|
|
3331
3446
|
}
|
|
3332
|
-
#
|
|
3447
|
+
#w(t, e, i) {
|
|
3333
3448
|
t.width = e, t.height = i;
|
|
3334
3449
|
}
|
|
3335
|
-
#
|
|
3336
|
-
if (!this.#
|
|
3337
|
-
const { plotWidth: t, plotHeight: e, axisYWidth: i, axisXHeight: s } = this.#
|
|
3338
|
-
if (this.#
|
|
3339
|
-
const r = t - this.#
|
|
3340
|
-
this.#
|
|
3450
|
+
#B() {
|
|
3451
|
+
if (!this.#s) return;
|
|
3452
|
+
const { plotWidth: t, plotHeight: e, axisYWidth: i, axisXHeight: s } = this.#_();
|
|
3453
|
+
if (this.#i && this.#P > 0 && t !== this.#P) {
|
|
3454
|
+
const r = t - this.#P;
|
|
3455
|
+
this.#i.panHorizontally(r);
|
|
3341
3456
|
}
|
|
3342
|
-
this.#
|
|
3457
|
+
this.#P = t, this.#w(this.#s.volumeCanvas, t, e), this.#w(this.#s.candleCanvas, t, e), this.#w(this.#s.shapesCanvas, t, e), this.#w(this.#s.overlayCanvas, t, e), this.#w(this.#s.tradesCanvas, t, e), this.#w(this.#s.axisXCanvas, t, s), this.#w(this.#s.axisYCanvas, i, e);
|
|
3343
3458
|
}
|
|
3344
|
-
#
|
|
3345
|
-
this.#
|
|
3459
|
+
#L() {
|
|
3460
|
+
this.#i && (this.#a?.setCandles(this.#i.candles), this.#a?.setViewport(this.#i.viewport), this.#a?.render(), this.#d?.setViewport(this.#i.viewport), this.#d?.render());
|
|
3346
3461
|
}
|
|
3347
3462
|
#c() {
|
|
3348
|
-
this.#
|
|
3463
|
+
this.#i && (this.#u?.setCandles(this.#i.candles), this.#u?.setLiveCandle(this.#i.liveCandle), this.#u?.setViewport(this.#i.viewport), this.#u?.render(), this.#i.render(), this.#h?.setCandles(this.#i.candles), this.#h?.setViewport(this.#i.viewport), this.#h?.render(), this.#g?.setViewport(this.#i.viewport), this.#g?.render(), this.#n?.setCandles(this.#i.candles), this.#n?.setViewport(this.#i.viewport), this.#n?.isDragging ? this.#n.renderLiveFeed() : this.#n?.render(), this.#L(), this.#l?.render());
|
|
3349
3464
|
}
|
|
3350
3465
|
#p() {
|
|
3351
3466
|
return this.#e.activeShapeTool !== null;
|
|
3352
3467
|
}
|
|
3353
|
-
#
|
|
3354
|
-
|
|
3468
|
+
#m() {
|
|
3469
|
+
if (this.#X) return;
|
|
3470
|
+
const t = this.#i?.getViewState() ?? null;
|
|
3471
|
+
!t || this.#G(this.#I, t) || (this.#I = t, this.#e.onViewChange?.(t));
|
|
3355
3472
|
}
|
|
3356
|
-
#
|
|
3473
|
+
#H(t) {
|
|
3474
|
+
if (!this.#b) {
|
|
3475
|
+
if (!t) {
|
|
3476
|
+
if (this.#y === null) return;
|
|
3477
|
+
this.#y = null, this.#e.onCursorMove?.(null);
|
|
3478
|
+
return;
|
|
3479
|
+
}
|
|
3480
|
+
this.#y !== null && this.#y.time === t.time && this.#y.price === t.price || (this.#y = t, this.#e.onCursorMove?.(t));
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
#G(t, e) {
|
|
3484
|
+
return t !== null && Math.abs(t.rightmostVisibleTime - e.rightmostVisibleTime) < 0.5 && Math.abs(t.rightmostVisibleX - e.rightmostVisibleX) < 1e-4 && Math.abs(t.rightEdgeTime - e.rightEdgeTime) < 0.5 && Math.abs(t.visibleDurationMs - e.visibleDurationMs) < 0.5;
|
|
3485
|
+
}
|
|
3486
|
+
#U(t) {
|
|
3487
|
+
t !== null && (this.#x = !1, this.#n?.setIsDragging(!1), this.#o?.cancelActiveInteraction()), this.#h?.setActiveTool(t);
|
|
3488
|
+
}
|
|
3489
|
+
#$() {
|
|
3357
3490
|
const t = this.#e.openTrades ?? [];
|
|
3358
|
-
return this.#
|
|
3491
|
+
return this.#v ? t.map((e) => e.ticket !== this.#v?.ticket ? e : {
|
|
3359
3492
|
...e,
|
|
3360
|
-
...this.#
|
|
3361
|
-
...this.#
|
|
3493
|
+
...this.#v.sl !== void 0 ? { sl: this.#v.sl } : {},
|
|
3494
|
+
...this.#v.tp !== void 0 ? { tp: this.#v.tp } : {}
|
|
3362
3495
|
}) : t;
|
|
3363
3496
|
}
|
|
3364
|
-
#
|
|
3365
|
-
this.#n?.setTrades(this
|
|
3497
|
+
#M() {
|
|
3498
|
+
this.#n?.setTrades(this.#$());
|
|
3366
3499
|
}
|
|
3367
|
-
#
|
|
3500
|
+
#q() {
|
|
3368
3501
|
const t = this.#e.liveCandle;
|
|
3369
|
-
if (!t || !this.#
|
|
3502
|
+
if (!t || !this.#i) return;
|
|
3370
3503
|
const e = pt(t, this.#e.brokerTimezoneOffsetMs);
|
|
3371
|
-
this.#
|
|
3504
|
+
this.#i.updateLiveCandle(e), this.#n?.setLiveCandle(this.#i.liveCandle), this.#n?.setCandles(this.#i.candles);
|
|
3372
3505
|
}
|
|
3373
|
-
#
|
|
3374
|
-
this.#n && (this.#n.setIsDragging(!0), this.#
|
|
3506
|
+
#K({ trade: t, type: e, price: i }) {
|
|
3507
|
+
this.#n && (this.#n.setIsDragging(!0), this.#v = {
|
|
3375
3508
|
ticket: t.ticket,
|
|
3376
3509
|
...e === "stopLoss" ? { sl: i } : {},
|
|
3377
3510
|
...e === "takeProfit" ? { tp: i } : {}
|
|
3378
|
-
}, this.#
|
|
3511
|
+
}, this.#M(), this.#n.render());
|
|
3379
3512
|
}
|
|
3380
|
-
#
|
|
3513
|
+
#J({ trade: t, type: e, price: i }) {
|
|
3381
3514
|
this.#n?.viewport && (this.#n.setIsDragging(!0), this.#n.setTemporaryProtectionDrag({
|
|
3382
3515
|
visible: !0,
|
|
3383
3516
|
trade: t,
|
|
@@ -3386,133 +3519,156 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3386
3519
|
viewport: this.#n.viewport
|
|
3387
3520
|
}), this.#n.render());
|
|
3388
3521
|
}
|
|
3389
|
-
#
|
|
3390
|
-
this.#n?.setIsDragging(!1), this.#
|
|
3522
|
+
#j({ trade: t, type: e, price: i }) {
|
|
3523
|
+
this.#n?.setIsDragging(!1), this.#W({
|
|
3391
3524
|
ticket: t.ticket,
|
|
3392
3525
|
...e === "stopLoss" ? { sl: i } : {},
|
|
3393
3526
|
...e === "takeProfit" ? { tp: i } : {}
|
|
3394
3527
|
});
|
|
3395
3528
|
}
|
|
3396
|
-
#
|
|
3529
|
+
#Z() {
|
|
3397
3530
|
this.#n?.setIsDragging(!1), this.#n?.clearTemporaryProtectionDrag(), this.#n?.render();
|
|
3398
3531
|
}
|
|
3399
|
-
#
|
|
3400
|
-
this.#n?.setIsDragging(!1), this.#
|
|
3401
|
-
}
|
|
3402
|
-
#
|
|
3403
|
-
if (!this.#
|
|
3404
|
-
if (!this.#
|
|
3405
|
-
this.#
|
|
3406
|
-
|
|
3407
|
-
}
|
|
3408
|
-
const
|
|
3409
|
-
this.#
|
|
3410
|
-
const n = this.#s.getPriceAtY(this.#h.mouseY);
|
|
3411
|
-
this.#d?.setCrosshair({
|
|
3532
|
+
#W(t) {
|
|
3533
|
+
this.#n?.setIsDragging(!1), this.#v = null, this.#n?.clearTemporaryProtectionDrag(), this.#e.onTradeModify?.(t), this.#M(), this.#n?.render();
|
|
3534
|
+
}
|
|
3535
|
+
#A(t) {
|
|
3536
|
+
if (!this.#l || !this.#s) return null;
|
|
3537
|
+
if (!this.#i)
|
|
3538
|
+
return this.#l.updateMousePosition(t.clientX, t.clientY), this.#l.render(), null;
|
|
3539
|
+
const e = vt(this.#s.overlayCanvas, t), i = this.#i.getNearestCandleIndexByX(e.x), s = i === null ? null : this.#i.candles[i] ?? null, r = i === null ? e.x : this.#i.getRawCandleSnapX(e.x);
|
|
3540
|
+
this.#l.updateMousePosition(t.clientX, t.clientY, { snapX: r });
|
|
3541
|
+
const n = this.#i.getPriceAtY(this.#l.mouseY);
|
|
3542
|
+
return this.#d?.setCrosshair({
|
|
3412
3543
|
visible: !0,
|
|
3413
|
-
y: this.#
|
|
3544
|
+
y: this.#l.mouseY,
|
|
3414
3545
|
price: n
|
|
3415
|
-
}), this.#
|
|
3546
|
+
}), this.#a?.setCrosshair({
|
|
3416
3547
|
visible: !0,
|
|
3417
|
-
x: this.#
|
|
3548
|
+
x: this.#l.mouseX,
|
|
3418
3549
|
candle: s
|
|
3419
|
-
}), this.#
|
|
3550
|
+
}), this.#L(), this.#l.render(), s ? {
|
|
3551
|
+
time: s.time,
|
|
3552
|
+
price: n
|
|
3553
|
+
} : null;
|
|
3420
3554
|
}
|
|
3421
|
-
#
|
|
3422
|
-
this.#
|
|
3555
|
+
#F() {
|
|
3556
|
+
this.#l?.hide(), this.#a?.hideCrosshair(), this.#d?.hideCrosshair(), this.#L(), this.#l?.render();
|
|
3423
3557
|
}
|
|
3424
|
-
#
|
|
3425
|
-
if (!this.#
|
|
3426
|
-
this.#p() || this.#
|
|
3558
|
+
#Q(t) {
|
|
3559
|
+
if (!this.#i || !this.#n) return;
|
|
3560
|
+
this.#p() || this.#o?.handlePointerEvent(t), t.preventDefault();
|
|
3427
3561
|
const e = t.deltaY < 0 ? 1 : -1;
|
|
3428
|
-
t.ctrlKey || t.metaKey ? this.#
|
|
3562
|
+
t.ctrlKey || t.metaKey ? this.#i.zoomVertically(e) : this.#i.zoomHorizontally(e), this.#c(), this.#m();
|
|
3429
3563
|
}
|
|
3430
|
-
|
|
3431
|
-
if (!this.#
|
|
3564
|
+
#tt(t) {
|
|
3565
|
+
if (!this.#i) return;
|
|
3432
3566
|
t.preventDefault(), t.stopPropagation();
|
|
3433
3567
|
const e = t.deltaY < 0 ? 1 : -1;
|
|
3434
|
-
this.#
|
|
3568
|
+
this.#i.zoomVertically(e), this.#c(), this.#m();
|
|
3435
3569
|
}
|
|
3436
|
-
#
|
|
3570
|
+
#V(t) {
|
|
3437
3571
|
const e = t.currentTarget;
|
|
3438
|
-
e.style.cursor = e === this.#
|
|
3572
|
+
e.style.cursor = e === this.#s?.axisXCanvas ? "ew-resize" : "ns-resize";
|
|
3439
3573
|
}
|
|
3440
|
-
#
|
|
3574
|
+
#Y(t, e) {
|
|
3441
3575
|
t.stopPropagation(), t.button === 0 && (t.currentTarget.setPointerCapture(t.pointerId), this.#f = {
|
|
3442
3576
|
axis: e,
|
|
3443
3577
|
lastClientPosition: e === "x" ? t.clientX : t.clientY,
|
|
3444
3578
|
pointerId: t.pointerId
|
|
3445
3579
|
}, t.preventDefault());
|
|
3446
3580
|
}
|
|
3447
|
-
#
|
|
3581
|
+
#E(t) {
|
|
3448
3582
|
t.stopPropagation();
|
|
3449
|
-
const e = t.currentTarget, i = e === this.#
|
|
3583
|
+
const e = t.currentTarget, i = e === this.#s?.axisXCanvas ? "x" : "y";
|
|
3450
3584
|
if (e.style.cursor = i === "x" ? "ew-resize" : "ns-resize", !this.#f || this.#f.pointerId !== t.pointerId || this.#f.axis !== i) return;
|
|
3451
3585
|
const s = i === "x" ? t.clientX : t.clientY, r = s - this.#f.lastClientPosition;
|
|
3452
|
-
if (this.#f.lastClientPosition = s, !this.#
|
|
3453
|
-
const n = -r /
|
|
3454
|
-
i === "x" ? this.#
|
|
3586
|
+
if (this.#f.lastClientPosition = s, !this.#i || r === 0) return;
|
|
3587
|
+
const n = -r / re;
|
|
3588
|
+
i === "x" ? this.#i.zoomHorizontally(n) : this.#i.zoomVertically(n), t.preventDefault(), this.#c(), this.#m();
|
|
3455
3589
|
}
|
|
3456
|
-
#
|
|
3590
|
+
#k(t) {
|
|
3457
3591
|
if (t.stopPropagation(), this.#f?.pointerId !== t.pointerId) return;
|
|
3458
3592
|
const e = t.currentTarget;
|
|
3459
3593
|
e.hasPointerCapture(t.pointerId) && e.releasePointerCapture(t.pointerId), this.#f = null, t.preventDefault();
|
|
3460
3594
|
}
|
|
3461
|
-
#
|
|
3462
|
-
if (!(!this.#p() && this.#
|
|
3463
|
-
if (this.#
|
|
3595
|
+
#et(t) {
|
|
3596
|
+
if (!(!this.#p() && this.#o?.handlePointerEvent(t))) {
|
|
3597
|
+
if (this.#h?.handlePointerEvent(t) ?? !1) {
|
|
3464
3598
|
this.#c();
|
|
3465
3599
|
return;
|
|
3466
3600
|
}
|
|
3467
|
-
this.#p() || (this.#
|
|
3601
|
+
this.#p() || (this.#x = !0, this.#R = t.clientX, this.#D = t.clientY);
|
|
3468
3602
|
}
|
|
3469
3603
|
}
|
|
3470
|
-
#
|
|
3471
|
-
const e = this.#
|
|
3472
|
-
|
|
3473
|
-
|
|
3604
|
+
#it(t) {
|
|
3605
|
+
const e = this.#h?.handlePointerEvent(t) ?? !1;
|
|
3606
|
+
this.#p() || this.#o?.handlePointerEvent(t);
|
|
3607
|
+
let i = this.#A(t);
|
|
3608
|
+
if (e) {
|
|
3609
|
+
this.#c(), i = this.#A(t), this.#H(i);
|
|
3474
3610
|
return;
|
|
3475
3611
|
}
|
|
3476
|
-
if (!this.#
|
|
3477
|
-
|
|
3478
|
-
|
|
3612
|
+
if (!this.#x || !this.#i || this.#p()) {
|
|
3613
|
+
this.#H(i);
|
|
3614
|
+
return;
|
|
3615
|
+
}
|
|
3616
|
+
const s = t.clientX - this.#R, r = t.clientY - this.#D;
|
|
3617
|
+
this.#R = t.clientX, this.#D = t.clientY, this.#i.panHorizontally(s), this.#i.panVertically(r), this.#c(), i = this.#A(t), this.#H(i), this.#m();
|
|
3479
3618
|
}
|
|
3480
|
-
#
|
|
3481
|
-
if (this.#
|
|
3482
|
-
this.#c();
|
|
3619
|
+
#st(t) {
|
|
3620
|
+
if (this.#x = !1, this.#h?.handlePointerEvent(t) ?? !1) {
|
|
3621
|
+
this.#c(), this.#m();
|
|
3483
3622
|
return;
|
|
3484
3623
|
}
|
|
3485
|
-
this.#p() || this.#
|
|
3624
|
+
this.#p() || this.#o?.handlePointerEvent(t), this.#m();
|
|
3486
3625
|
}
|
|
3487
|
-
#
|
|
3488
|
-
document.body.style.cursor = "crosshair", this.#
|
|
3626
|
+
#rt(t) {
|
|
3627
|
+
document.body.style.cursor = "crosshair", this.#h?.handlePointerEvent(t), this.#p() || this.#o?.handlePointerEvent(t);
|
|
3489
3628
|
}
|
|
3490
|
-
#
|
|
3491
|
-
this.#
|
|
3629
|
+
#nt() {
|
|
3630
|
+
this.#h?.clearHoverState(), document.body.style.cursor = "", this.#F(), this.#H(null);
|
|
3492
3631
|
}
|
|
3493
|
-
#
|
|
3494
|
-
((this.#
|
|
3632
|
+
#at(t) {
|
|
3633
|
+
((this.#h?.handlePointerEvent(t) ?? !1) || this.#p()) && (t.preventDefault(), t.stopPropagation(), this.#c());
|
|
3495
3634
|
}
|
|
3496
|
-
#
|
|
3497
|
-
this.#
|
|
3635
|
+
#ot(t) {
|
|
3636
|
+
this.#h?.handlePointerEvent(t);
|
|
3498
3637
|
}
|
|
3499
|
-
#
|
|
3500
|
-
(this.#
|
|
3501
|
-
}
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3638
|
+
#lt(t) {
|
|
3639
|
+
this.#ht(t.target) || (this.#h?.handleKeyboardEvent(t) ?? !1) && (t.preventDefault(), this.#c());
|
|
3640
|
+
}
|
|
3641
|
+
#ht(t) {
|
|
3642
|
+
return t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement || t instanceof HTMLElement && t.isContentEditable;
|
|
3643
|
+
}
|
|
3644
|
+
}, le = kt(({ className: t, style: e, ...i }, s) => {
|
|
3645
|
+
const r = _(null), n = _(null), a = _(i);
|
|
3646
|
+
return a.current = i, Rt(s, () => ({
|
|
3647
|
+
resetChartView() {
|
|
3648
|
+
n.current?.resetChartView();
|
|
3649
|
+
},
|
|
3650
|
+
getView() {
|
|
3651
|
+
return n.current?.getView() ?? null;
|
|
3652
|
+
},
|
|
3653
|
+
setView(o) {
|
|
3654
|
+
n.current?.setView(o);
|
|
3655
|
+
},
|
|
3656
|
+
setCursor(o) {
|
|
3657
|
+
n.current?.setCursor(o);
|
|
3658
|
+
},
|
|
3659
|
+
hideCursor() {
|
|
3660
|
+
n.current?.hideCursor();
|
|
3661
|
+
}
|
|
3662
|
+
})), st(() => {
|
|
3663
|
+
const o = r.current;
|
|
3664
|
+
if (!o) return;
|
|
3665
|
+
const l = new ne(o, a.current);
|
|
3510
3666
|
return n.current = l, () => {
|
|
3511
3667
|
l.destroy(), n.current = null;
|
|
3512
3668
|
};
|
|
3513
3669
|
}, []), st(() => {
|
|
3514
|
-
n.current?.updateProps(
|
|
3515
|
-
}, [i]), /* @__PURE__ */
|
|
3670
|
+
n.current?.updateProps(a.current);
|
|
3671
|
+
}, [i]), /* @__PURE__ */ Dt("div", {
|
|
3516
3672
|
ref: r,
|
|
3517
3673
|
className: t,
|
|
3518
3674
|
style: {
|
|
@@ -3524,5 +3680,5 @@ var U = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3524
3680
|
});
|
|
3525
3681
|
export {
|
|
3526
3682
|
c as CHART_CONFIG,
|
|
3527
|
-
|
|
3683
|
+
le as TradingReload
|
|
3528
3684
|
};
|