@pradeepjadhav/trading-reload-chart 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -2
- package/dist/canvas/layers/CrosshairLayer.d.ts +1 -0
- package/dist/canvas/layers/ExistingCandlesLayer.d.ts +37 -0
- package/dist/canvas/layers/ShapesLayer/LineShape.d.ts +1 -1
- package/dist/canvas/layers/ShapesLayer/PathShape.d.ts +1 -1
- package/dist/canvas/layers/ShapesLayer/RectangleShape.d.ts +1 -1
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.helpers.d.ts +1 -1
- package/dist/canvas/layers/TradeLayer/TradeLayer.types.d.ts +1 -1
- package/dist/canvas/layers/WatermarkLayer/WatermarkLayer.d.ts +40 -0
- package/dist/canvas/layers/WatermarkLayer/WatermarkLayer.helpers.d.ts +27 -0
- package/dist/canvas/layers/WatermarkLayer/WatermarkLayer.types.d.ts +66 -0
- package/dist/chart/ChartController.d.ts +5 -0
- package/dist/chart/ChartController.types.d.ts +10 -0
- package/dist/chart/createChartDom.types.d.ts +1 -0
- package/dist/chart/utils/resolveWheelZoomAxis.d.ts +7 -0
- package/dist/chart/utils/resolveWheelZoomAxis.types.d.ts +1 -0
- package/dist/config/chartConfig.types.d.ts +41 -0
- package/dist/index.d.ts +2 -1
- package/dist/models/Candle.types.d.ts +4 -1
- package/dist/models/ChartSync.types.d.ts +16 -0
- package/dist/react/TradingReload.types.d.ts +40 -0
- package/dist/trading-reload-chart.css +1 -1
- package/dist/trading-reload-chart.js +725 -487
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef as
|
|
1
|
+
import { forwardRef as kt, useEffect as st, useImperativeHandle as Rt, useRef as _ } from "react";
|
|
2
2
|
import { jsx as Dt } from "react/jsx-runtime";
|
|
3
3
|
var h = {
|
|
4
4
|
primary: "#7959F7",
|
|
@@ -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,
|
|
@@ -173,7 +173,7 @@ var h = {
|
|
|
173
173
|
textColor: h.white,
|
|
174
174
|
textOpacity: 0.6,
|
|
175
175
|
font: X.default
|
|
176
|
-
},
|
|
176
|
+
}, ot = {
|
|
177
177
|
height: 22,
|
|
178
178
|
widthPNL: 80,
|
|
179
179
|
position: {
|
|
@@ -240,6 +240,16 @@ var h = {
|
|
|
240
240
|
thickness: 1,
|
|
241
241
|
style: "dashed"
|
|
242
242
|
},
|
|
243
|
+
watermark: {
|
|
244
|
+
text: "",
|
|
245
|
+
position: "center",
|
|
246
|
+
fontSize: 48,
|
|
247
|
+
fontWeight: 700,
|
|
248
|
+
fontFamily: "Inter, system-ui, -apple-system, sans-serif",
|
|
249
|
+
color: h.white,
|
|
250
|
+
opacity: 0.25,
|
|
251
|
+
padding: 16
|
|
252
|
+
},
|
|
243
253
|
axis: {
|
|
244
254
|
axisX: {
|
|
245
255
|
height: 30,
|
|
@@ -338,25 +348,25 @@ var h = {
|
|
|
338
348
|
visible: !0,
|
|
339
349
|
dragActivationThresholdPx: 2,
|
|
340
350
|
slHandle: {
|
|
341
|
-
...
|
|
351
|
+
...at,
|
|
342
352
|
borderColor: h.red,
|
|
343
353
|
backgroundColor: h.slBackground,
|
|
344
354
|
textColor: h.red
|
|
345
355
|
},
|
|
346
356
|
tpHandle: {
|
|
347
|
-
...
|
|
357
|
+
...at,
|
|
348
358
|
borderColor: h.green,
|
|
349
359
|
backgroundColor: h.tpBackground,
|
|
350
360
|
textColor: h.green
|
|
351
361
|
},
|
|
352
362
|
temporarySlHandle: {
|
|
353
|
-
...
|
|
363
|
+
...ot,
|
|
354
364
|
borderColor: h.red,
|
|
355
365
|
backgroundColor: h.slBackground,
|
|
356
366
|
textColor: h.red
|
|
357
367
|
},
|
|
358
368
|
temporaryTpHandle: {
|
|
359
|
-
...
|
|
369
|
+
...ot,
|
|
360
370
|
borderColor: h.green,
|
|
361
371
|
backgroundColor: h.tpBackground,
|
|
362
372
|
textColor: h.green
|
|
@@ -416,9 +426,9 @@ var h = {
|
|
|
416
426
|
}, It = ({ candleSpacing: t, candleTimeframeMs: e, labelWidth: i, minLabelGap: s }) => {
|
|
417
427
|
if (t <= 0 || e <= 0) return lt[0];
|
|
418
428
|
const r = i + s;
|
|
419
|
-
for (const
|
|
420
|
-
const n = 1440 * 60 * 1e3,
|
|
421
|
-
return n * Math.ceil(r /
|
|
429
|
+
for (const o of lt) if (o / e * t >= r) return o;
|
|
430
|
+
const n = 1440 * 60 * 1e3, a = n / e * t;
|
|
431
|
+
return n * Math.ceil(r / a);
|
|
422
432
|
}, Bt = (t, e) => {
|
|
423
433
|
const i = new Date(t), s = (i.getHours() * 60 + i.getMinutes()) * 60 * 1e3 + i.getSeconds() * 1e3 + i.getMilliseconds();
|
|
424
434
|
return e >= 1440 * 60 * 1e3 ? s === 0 : s % e === 0;
|
|
@@ -428,7 +438,7 @@ var h = {
|
|
|
428
438
|
}, Ft = (t) => {
|
|
429
439
|
const e = new Date(t), i = e.toLocaleDateString("en-US", { weekday: "short" }), s = e.toLocaleDateString("en-US", { month: "short" });
|
|
430
440
|
return `${i} ${e.getDate()} ${s} ${e.getHours().toString().padStart(2, "0")}.${e.getMinutes().toString().padStart(2, "0")}`;
|
|
431
|
-
},
|
|
441
|
+
}, Vt = class {
|
|
432
442
|
#t;
|
|
433
443
|
#e;
|
|
434
444
|
candles;
|
|
@@ -463,8 +473,8 @@ var h = {
|
|
|
463
473
|
if (!this.crosshair.visible || !this.crosshair.candle) return;
|
|
464
474
|
const t = this.#e, e = this.#t.width, i = this.#t.height, s = c.axis.axisX.crosshairLabel, r = Ft(this.crosshair.candle.time);
|
|
465
475
|
t.save(), t.font = s.font;
|
|
466
|
-
const n = t.measureText(r).width + s.paddingX * 2,
|
|
467
|
-
t.fillStyle = s.backgroundColor, t.fillRect(
|
|
476
|
+
const n = t.measureText(r).width + s.paddingX * 2, a = s.height, o = this.getCrosshairLabelX(n, e), l = Math.max(0, (i - a) / 2);
|
|
477
|
+
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
478
|
}
|
|
469
479
|
clearCanvas() {
|
|
470
480
|
this.#e.clearRect(0, 0, this.#t.width, this.#t.height);
|
|
@@ -486,12 +496,12 @@ var h = {
|
|
|
486
496
|
candleTimeframeMs: s,
|
|
487
497
|
labelWidth: r,
|
|
488
498
|
minLabelGap: e.minLabelGap
|
|
489
|
-
}), { startIndex:
|
|
490
|
-
for (let l =
|
|
499
|
+
}), { startIndex: a, endIndex: o } = this.getVisibleCandleIndexRange(i);
|
|
500
|
+
for (let l = a; l <= o; l += 1) {
|
|
491
501
|
const d = this.getSlotTime(l, s);
|
|
492
502
|
if (d === null || !Bt(d, n)) continue;
|
|
493
|
-
const u = this.getCandleCenterX(l), g = Wt(d),
|
|
494
|
-
this.isLabelOutsideCanvas(u,
|
|
503
|
+
const u = this.getCandleCenterX(l), g = Wt(d), p = t.measureText(g).width;
|
|
504
|
+
this.isLabelOutsideCanvas(u, p, i) || (this.drawTick(u), this.drawLabel(g, u));
|
|
495
505
|
}
|
|
496
506
|
t.restore();
|
|
497
507
|
}
|
|
@@ -535,7 +545,7 @@ var h = {
|
|
|
535
545
|
getCrosshairLabelX(t, e) {
|
|
536
546
|
return Math.max(120, Math.min(e - t, this.crosshair.x - t / 2));
|
|
537
547
|
}
|
|
538
|
-
},
|
|
548
|
+
}, m = (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
549
|
const i = t / (e / c.axis.axisY.tickGap), s = 10 ** Math.floor(Math.log10(i));
|
|
540
550
|
for (const r of [
|
|
541
551
|
1,
|
|
@@ -547,7 +557,7 @@ var h = {
|
|
|
547
557
|
if (n >= i) return n;
|
|
548
558
|
}
|
|
549
559
|
return 10 * s;
|
|
550
|
-
},
|
|
560
|
+
}, Et = class {
|
|
551
561
|
#t;
|
|
552
562
|
#e;
|
|
553
563
|
viewport = null;
|
|
@@ -576,8 +586,8 @@ var h = {
|
|
|
576
586
|
}
|
|
577
587
|
drawCrosshairPriceLabel() {
|
|
578
588
|
if (!this.crosshair.visible) return;
|
|
579
|
-
const t = this.#e, e = this.#t.width, i = this.#t.height, s = c.axis.axisY.crosshairLabel, r =
|
|
580
|
-
t.save(), t.fillStyle = s.backgroundColor, t.fillRect(0,
|
|
589
|
+
const t = this.#e, e = this.#t.width, i = this.#t.height, s = c.axis.axisY.crosshairLabel, r = m(this.crosshair.price).toFixed(5), n = s.height, a = this.getCrosshairLabelY(n, i);
|
|
590
|
+
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
591
|
}
|
|
582
592
|
clearCanvas() {
|
|
583
593
|
this.#e.clearRect(0, 0, this.#t.width, this.#t.height);
|
|
@@ -592,15 +602,15 @@ var h = {
|
|
|
592
602
|
}
|
|
593
603
|
drawPriceLabels() {
|
|
594
604
|
if (!this.viewport) return;
|
|
595
|
-
const t = this.#e, e = this.#t.height, i = c.axis.axisY, s =
|
|
605
|
+
const t = this.#e, e = this.#t.height, i = c.axis.axisY, s = Yt({
|
|
596
606
|
priceRange: this.viewport.priceRange,
|
|
597
607
|
canvasHeight: e
|
|
598
608
|
});
|
|
599
609
|
t.save(), t.font = i.font, t.fillStyle = i.textColor, t.textAlign = i.textAlign, t.textBaseline = "middle";
|
|
600
610
|
const { startPrice: r, endPrice: n } = this.getVisiblePriceRange(s);
|
|
601
|
-
for (let
|
|
602
|
-
const
|
|
603
|
-
this.isPriceOutsideCanvas(
|
|
611
|
+
for (let a = r; a <= n; a += s) {
|
|
612
|
+
const o = this.getPriceY(a, e);
|
|
613
|
+
this.isPriceOutsideCanvas(o, e) || (this.drawTick(o), this.drawPriceLabel(a, o));
|
|
604
614
|
}
|
|
605
615
|
t.restore();
|
|
606
616
|
}
|
|
@@ -614,7 +624,7 @@ var h = {
|
|
|
614
624
|
};
|
|
615
625
|
}
|
|
616
626
|
getPriceY(t, e) {
|
|
617
|
-
return this.viewport ?
|
|
627
|
+
return this.viewport ? Y({
|
|
618
628
|
price: t,
|
|
619
629
|
minPrice: this.viewport.minPrice,
|
|
620
630
|
priceRange: this.viewport.priceRange,
|
|
@@ -630,12 +640,12 @@ var h = {
|
|
|
630
640
|
}
|
|
631
641
|
drawPriceLabel(t, e) {
|
|
632
642
|
const i = this.#e, s = c.axis.axisY;
|
|
633
|
-
i.fillStyle = s.textColor, i.fillText(
|
|
643
|
+
i.fillStyle = s.textColor, i.fillText(m(t).toFixed(5), s.labelOffsetX, e);
|
|
634
644
|
}
|
|
635
645
|
getCrosshairLabelY(t, e) {
|
|
636
646
|
return Math.max(0, Math.min(e - t, this.crosshair.y - t / 2));
|
|
637
647
|
}
|
|
638
|
-
},
|
|
648
|
+
}, Ot = class {
|
|
639
649
|
#t;
|
|
640
650
|
#e;
|
|
641
651
|
mouseX = 0;
|
|
@@ -654,6 +664,9 @@ var h = {
|
|
|
654
664
|
const s = this.getLocalCanvasPoint(t, e), r = i.snapX ?? s.x;
|
|
655
665
|
this.mouseX = this.clampX(r), this.mouseY = this.clampY(s.y), this.visible = !0;
|
|
656
666
|
}
|
|
667
|
+
setPosition(t, e) {
|
|
668
|
+
this.mouseX = this.clampX(t), this.mouseY = this.clampY(e), this.visible = !0;
|
|
669
|
+
}
|
|
657
670
|
hide() {
|
|
658
671
|
this.visible = !1;
|
|
659
672
|
}
|
|
@@ -712,7 +725,7 @@ var h = {
|
|
|
712
725
|
drawLine({ ctx: t, fromX: e, fromY: i, toX: s, toY: r }) {
|
|
713
726
|
t.beginPath(), t.moveTo(e, i), t.lineTo(s, r), t.stroke();
|
|
714
727
|
}
|
|
715
|
-
}, F = 60 * 1e3, Ct = 60 * F,
|
|
728
|
+
}, F = 60 * 1e3, Ct = 60 * F, zt = 24 * Ct, Nt = class {
|
|
716
729
|
#t;
|
|
717
730
|
#e;
|
|
718
731
|
candles;
|
|
@@ -790,6 +803,31 @@ var h = {
|
|
|
790
803
|
endIndex: Math.min(this.candles.length - 1, Math.ceil((t - this.offsetX) / this.candleSpacing))
|
|
791
804
|
};
|
|
792
805
|
}
|
|
806
|
+
getViewState() {
|
|
807
|
+
return this.candles.length === 0 || this.candleSpacing <= 0 || this.#t.width <= 0 ? null : {
|
|
808
|
+
rightmostVisibleTime: this.getRightmostVisibleTime(),
|
|
809
|
+
rightmostVisibleX: this.getRightmostVisibleX(),
|
|
810
|
+
rightEdgeTime: this.getRightEdgeTime(),
|
|
811
|
+
visibleDurationMs: this.getVisibleDurationMs()
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
setViewState(t) {
|
|
815
|
+
if (this.candles.length === 0 || this.#t.width <= 0 || !this.hasUsableTimeframe()) return;
|
|
816
|
+
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;
|
|
817
|
+
if (!Number.isFinite(e) || i <= 0) return;
|
|
818
|
+
const r = this.detectCandleTimeframeMs(), n = this.baseCandleWidth + this.baseCandleGap, a = this.#t.width * r / i, o = n > 0 ? a / n : this.zoomX;
|
|
819
|
+
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();
|
|
820
|
+
}
|
|
821
|
+
setCursorState(t) {
|
|
822
|
+
if (this.candles.length === 0 || !Number.isFinite(t.time) || !Number.isFinite(t.price)) return null;
|
|
823
|
+
const e = this.getCandleIndexByTime(t.time), i = this.candles[e];
|
|
824
|
+
return i ? {
|
|
825
|
+
candle: i,
|
|
826
|
+
candleIndex: e,
|
|
827
|
+
x: this.getCandleCenterX(e),
|
|
828
|
+
y: this.getPriceY(t.price, this.#t.height)
|
|
829
|
+
} : null;
|
|
830
|
+
}
|
|
793
831
|
getCandleX(t) {
|
|
794
832
|
return t * this.candleSpacing + this.offsetX;
|
|
795
833
|
}
|
|
@@ -806,7 +844,7 @@ var h = {
|
|
|
806
844
|
return this.getCandleCenterX(e);
|
|
807
845
|
}
|
|
808
846
|
getPriceAtY(t) {
|
|
809
|
-
return
|
|
847
|
+
return m(mt({
|
|
810
848
|
y: t,
|
|
811
849
|
minPrice: this.minPrice,
|
|
812
850
|
priceRange: this.priceRange,
|
|
@@ -840,34 +878,34 @@ var h = {
|
|
|
840
878
|
startIndex: s,
|
|
841
879
|
chartHeight: i
|
|
842
880
|
});
|
|
843
|
-
const
|
|
881
|
+
const a = {
|
|
844
882
|
ctx: t,
|
|
845
883
|
chartWidth: e,
|
|
846
884
|
chartHeight: i
|
|
847
885
|
};
|
|
848
|
-
this.drawAskPriceLine(
|
|
886
|
+
this.drawAskPriceLine(a), this.drawBidPriceLine(a);
|
|
849
887
|
}
|
|
850
888
|
drawCandles({ ctx: t, candles: e, startIndex: i, chartHeight: s }) {
|
|
851
889
|
e.forEach((r, n) => {
|
|
852
|
-
const
|
|
890
|
+
const a = i + n, o = this.getCandleX(a), l = this.getCandleColor(r), d = this.getCandleYCoordinates(r, s);
|
|
853
891
|
this.drawSingleCandle({
|
|
854
892
|
ctx: t,
|
|
855
|
-
candleX:
|
|
893
|
+
candleX: o,
|
|
856
894
|
candleColor: l,
|
|
857
895
|
...d
|
|
858
896
|
});
|
|
859
897
|
});
|
|
860
898
|
}
|
|
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(
|
|
899
|
+
drawSingleCandle({ ctx: t, candleX: e, openY: i, closeY: s, highY: r, lowY: n, candleColor: a }) {
|
|
900
|
+
t.strokeStyle = a, t.fillStyle = a;
|
|
901
|
+
const o = e + this.candleWidth / 2;
|
|
902
|
+
t.beginPath(), t.moveTo(o, r), t.lineTo(o, n), t.stroke();
|
|
865
903
|
const l = Math.min(i, s), d = Math.max(Math.abs(s - i), c.candles.minBodyHeight);
|
|
866
904
|
t.fillRect(e, l, this.candleWidth, d);
|
|
867
905
|
}
|
|
868
|
-
drawPriceLine({ ctx: t, chartWidth: e, chartHeight: i, price: s, color: r, opacity: n, lineWidth:
|
|
869
|
-
const l = this.getPriceY(
|
|
870
|
-
t.save(), t.globalAlpha = n, t.strokeStyle = r, t.lineWidth =
|
|
906
|
+
drawPriceLine({ ctx: t, chartWidth: e, chartHeight: i, price: s, color: r, opacity: n, lineWidth: a, dash: o }) {
|
|
907
|
+
const l = this.getPriceY(m(s), i);
|
|
908
|
+
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
909
|
}
|
|
872
910
|
drawBidPriceLine({ ctx: t, chartWidth: e, chartHeight: i }) {
|
|
873
911
|
const s = this.candles.at(-1);
|
|
@@ -884,11 +922,11 @@ var h = {
|
|
|
884
922
|
}
|
|
885
923
|
drawAskPriceLine({ ctx: t, chartWidth: e, chartHeight: i }) {
|
|
886
924
|
const s = this.candles.at(-1);
|
|
887
|
-
!s || !c.candles.liveAskPriceLine.visible ||
|
|
925
|
+
!s || !c.candles.liveAskPriceLine.visible || this.drawPriceLine({
|
|
888
926
|
ctx: t,
|
|
889
927
|
chartWidth: e,
|
|
890
928
|
chartHeight: i,
|
|
891
|
-
price: s.ask,
|
|
929
|
+
price: s.ask ?? s.close,
|
|
892
930
|
color: this.getAskPriceLineColor(s),
|
|
893
931
|
opacity: c.candles.liveAskPriceLine.opacity,
|
|
894
932
|
lineWidth: c.candles.liveAskPriceLine.width,
|
|
@@ -925,12 +963,12 @@ var h = {
|
|
|
925
963
|
};
|
|
926
964
|
}
|
|
927
965
|
getInitialPriceRange(t, e) {
|
|
928
|
-
const i = this.getInitialFallbackPercent(), s =
|
|
966
|
+
const i = this.getInitialFallbackPercent(), s = m(e - t), r = Math.max(Math.abs((t + e) / 2) * i, 1e-5), n = Math.max(s, r);
|
|
929
967
|
return n + n * 0.2;
|
|
930
968
|
}
|
|
931
969
|
getInitialFallbackPercent() {
|
|
932
970
|
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 <
|
|
971
|
+
return t <= F ? 25e-4 : t <= 5 * F ? 35e-4 : t <= 15 * F ? 5e-3 : t <= Ct ? 75e-4 : (t < zt, 0.01);
|
|
934
972
|
}
|
|
935
973
|
detectCandleTimeframeMs() {
|
|
936
974
|
if (this.candles.length < 2) return 15 * F;
|
|
@@ -938,6 +976,9 @@ var h = {
|
|
|
938
976
|
for (let e = 1; e < Math.min(this.candles.length, 10); e++) t.push(this.candles[e].time - this.candles[e - 1].time);
|
|
939
977
|
return t.sort((e, i) => e - i), t[Math.floor(t.length / 2)];
|
|
940
978
|
}
|
|
979
|
+
hasUsableTimeframe() {
|
|
980
|
+
return this.detectCandleTimeframeMs() > 0;
|
|
981
|
+
}
|
|
941
982
|
applyManualViewportOverrides(t) {
|
|
942
983
|
t.priceCenter !== void 0 && (this.priceCenter = t.priceCenter), t.priceRange !== void 0 && (this.priceRange = t.priceRange, this.initialPriceRange = t.priceRange);
|
|
943
984
|
}
|
|
@@ -956,13 +997,58 @@ var h = {
|
|
|
956
997
|
getRightEdgeCandleIndex() {
|
|
957
998
|
return (this.#t.width - this.offsetX) / this.candleSpacing;
|
|
958
999
|
}
|
|
1000
|
+
getRightmostVisibleTime() {
|
|
1001
|
+
const t = this.getRightmostVisibleIndex();
|
|
1002
|
+
return this.candles[t]?.time ?? 0;
|
|
1003
|
+
}
|
|
1004
|
+
getRightmostVisibleX() {
|
|
1005
|
+
const t = this.getRightmostVisibleIndex();
|
|
1006
|
+
if (this.#t.width <= 0) return 1;
|
|
1007
|
+
const e = this.getCandleCenterX(t) / this.#t.width;
|
|
1008
|
+
return Math.max(0, Math.min(e, 1));
|
|
1009
|
+
}
|
|
1010
|
+
getRightmostVisibleIndex() {
|
|
1011
|
+
return this.candles.length === 0 ? 0 : this.clampCandleIndex(Math.round((this.#t.width - this.offsetX - this.candleWidth) / this.candleSpacing));
|
|
1012
|
+
}
|
|
1013
|
+
getRightEdgeTime() {
|
|
1014
|
+
const t = this.candles.at(-1), e = this.detectCandleTimeframeMs();
|
|
1015
|
+
if (!t || e <= 0) return 0;
|
|
1016
|
+
const i = this.getRightEdgeCandleIndex() - (this.candles.length - 1);
|
|
1017
|
+
return t.time + i * e;
|
|
1018
|
+
}
|
|
1019
|
+
getVisibleDurationMs() {
|
|
1020
|
+
const t = this.detectCandleTimeframeMs();
|
|
1021
|
+
return t <= 0 || this.candleSpacing <= 0 ? 0 : this.#t.width * t / this.candleSpacing;
|
|
1022
|
+
}
|
|
1023
|
+
getTimeDeltaInCandleSlots(t) {
|
|
1024
|
+
const e = this.candles[0];
|
|
1025
|
+
return !e || this.detectCandleTimeframeMs() <= 0 ? 0 : (t - e.time) / this.detectCandleTimeframeMs();
|
|
1026
|
+
}
|
|
1027
|
+
getCandleIndexByTime(t) {
|
|
1028
|
+
if (this.candles.length === 0 || !Number.isFinite(t)) return 0;
|
|
1029
|
+
const e = this.candles.length - 1, i = this.candles[0]?.time ?? 0, s = this.candles[e]?.time ?? 0, r = this.detectCandleTimeframeMs();
|
|
1030
|
+
if (t <= i) return 0;
|
|
1031
|
+
if (t >= s + Math.max(r, 0)) return e;
|
|
1032
|
+
const n = this.findCandleIndexAtOrAfter(t);
|
|
1033
|
+
if (this.candles[n]?.time === t) return n;
|
|
1034
|
+
const a = Math.max(0, n - 1), o = this.candles[a]?.time ?? 0, l = this.candles[n]?.time ?? 0;
|
|
1035
|
+
return t < o + r || t - o <= l - t ? a : n;
|
|
1036
|
+
}
|
|
1037
|
+
findCandleIndexAtOrAfter(t) {
|
|
1038
|
+
let e = 0, i = this.candles.length - 1;
|
|
1039
|
+
for (; e < i; ) {
|
|
1040
|
+
const s = Math.floor((e + i) / 2);
|
|
1041
|
+
(this.candles[s]?.time ?? 0) < t ? e = s + 1 : i = s;
|
|
1042
|
+
}
|
|
1043
|
+
return e;
|
|
1044
|
+
}
|
|
959
1045
|
getNextHorizontalZoom(t) {
|
|
960
1046
|
const { speed: e, min: i, max: s } = c.zoom.x, r = this.zoomX + t * e;
|
|
961
1047
|
return Math.max(i, Math.min(r, s));
|
|
962
1048
|
}
|
|
963
1049
|
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(
|
|
1050
|
+
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);
|
|
1051
|
+
return Math.max(a, Math.min(n, o));
|
|
966
1052
|
}
|
|
967
1053
|
clearCanvas(t, e, i) {
|
|
968
1054
|
t.clearRect(0, 0, e, i);
|
|
@@ -979,7 +1065,7 @@ var h = {
|
|
|
979
1065
|
};
|
|
980
1066
|
}
|
|
981
1067
|
getPriceY(t, e) {
|
|
982
|
-
return
|
|
1068
|
+
return Y({
|
|
983
1069
|
price: t,
|
|
984
1070
|
minPrice: this.minPrice,
|
|
985
1071
|
priceRange: this.priceRange,
|
|
@@ -995,13 +1081,13 @@ var h = {
|
|
|
995
1081
|
}, _t = class {
|
|
996
1082
|
#t;
|
|
997
1083
|
#e;
|
|
998
|
-
#
|
|
1084
|
+
#n = null;
|
|
999
1085
|
#i = null;
|
|
1000
1086
|
constructor({ ctx: t, config: e }) {
|
|
1001
1087
|
this.#t = t, this.#e = e;
|
|
1002
1088
|
}
|
|
1003
1089
|
setViewport(t) {
|
|
1004
|
-
this.#
|
|
1090
|
+
this.#n = t;
|
|
1005
1091
|
}
|
|
1006
1092
|
setConfig(t) {
|
|
1007
1093
|
this.#e = t;
|
|
@@ -1010,24 +1096,29 @@ var h = {
|
|
|
1010
1096
|
this.#i = t ?? null;
|
|
1011
1097
|
}
|
|
1012
1098
|
render() {
|
|
1013
|
-
if (!this.#
|
|
1099
|
+
if (!this.#n || !this.#i) return;
|
|
1014
1100
|
const { high: t, low: e } = this.#i;
|
|
1015
|
-
Number.isFinite(t) && t > 0 && this.#
|
|
1101
|
+
Number.isFinite(t) && t > 0 && this.#h(t, "PDH"), Number.isFinite(e) && e > 0 && this.#h(e, "PDL");
|
|
1016
1102
|
}
|
|
1017
|
-
#
|
|
1018
|
-
if (!this.#
|
|
1019
|
-
const i = this.#t, s = i.canvas, r =
|
|
1103
|
+
#h(t, e) {
|
|
1104
|
+
if (!this.#n || !this.#e) return;
|
|
1105
|
+
const i = this.#t, s = i.canvas, r = Y({
|
|
1020
1106
|
price: t,
|
|
1021
|
-
minPrice: this.#
|
|
1022
|
-
priceRange: this.#
|
|
1107
|
+
minPrice: this.#n.minPrice,
|
|
1108
|
+
priceRange: this.#n.priceRange,
|
|
1023
1109
|
chartHeight: s.height
|
|
1024
1110
|
});
|
|
1025
1111
|
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(
|
|
1112
|
+
const { line: n, text: a } = this.#e, o = s.width;
|
|
1113
|
+
i.save(), i.font = a.font;
|
|
1114
|
+
const l = i.measureText(e).width, d = o / 2, u = l / 2 + a.paddingX;
|
|
1115
|
+
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
1116
|
}
|
|
1117
|
+
}, f = {
|
|
1118
|
+
handleColor: h.background,
|
|
1119
|
+
handleBorderColor: h.blue,
|
|
1120
|
+
handleBorderThickness: 1.5,
|
|
1121
|
+
handleRadius: 5
|
|
1031
1122
|
}, vt = (t, e) => {
|
|
1032
1123
|
const i = t.getBoundingClientRect(), s = t.width / i.width, r = t.height / i.height;
|
|
1033
1124
|
return {
|
|
@@ -1038,7 +1129,7 @@ var h = {
|
|
|
1038
1129
|
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
1130
|
time: e.getNearestCandleTimeForX(t.x),
|
|
1040
1131
|
price: e.getPriceForY(t.y)
|
|
1041
|
-
}),
|
|
1132
|
+
}), v = (t, e) => ({
|
|
1042
1133
|
x: e.getXForTime(t.time),
|
|
1043
1134
|
y: e.getYForPrice(t.price)
|
|
1044
1135
|
}), Gt = (t, e) => {
|
|
@@ -1051,22 +1142,22 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1051
1142
|
width: s - i,
|
|
1052
1143
|
height: n - r
|
|
1053
1144
|
};
|
|
1054
|
-
}, K = (t, e, i) => Gt(
|
|
1145
|
+
}, K = (t, e, i) => Gt(v(t, i), v(e, i)), J = (t, e) => {
|
|
1055
1146
|
const i = t.x - e.x, s = t.y - e.y;
|
|
1056
1147
|
return Math.sqrt(i * i + s * s);
|
|
1057
1148
|
}, yt = (t, e, i) => {
|
|
1058
1149
|
const s = i.x - e.x, r = i.y - e.y, n = s * s + r * r;
|
|
1059
1150
|
if (n === 0) return J(t, e);
|
|
1060
|
-
const
|
|
1151
|
+
const a = Math.max(0, Math.min(1, ((t.x - e.x) * s + (t.y - e.y) * r) / n));
|
|
1061
1152
|
return J(t, {
|
|
1062
|
-
x: e.x +
|
|
1063
|
-
y: e.y +
|
|
1153
|
+
x: e.x + a * s,
|
|
1154
|
+
y: e.y + a * r
|
|
1064
1155
|
});
|
|
1065
1156
|
}, 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
1157
|
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 ||
|
|
1069
|
-
},
|
|
1158
|
+
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;
|
|
1159
|
+
return (s || r) && l || (n || a) && o;
|
|
1160
|
+
}, P = ({ shapeId: t, type: e, point: i, radius: s = 5, cursor: r, index: n }) => ({
|
|
1070
1161
|
shapeId: t,
|
|
1071
1162
|
type: e,
|
|
1072
1163
|
x: i.x,
|
|
@@ -1074,9 +1165,9 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1074
1165
|
radius: s,
|
|
1075
1166
|
cursor: r,
|
|
1076
1167
|
index: n
|
|
1077
|
-
}), j = (t, e) => J(t, e) <= e.radius + 2,
|
|
1078
|
-
t.strokeStyle =
|
|
1079
|
-
},
|
|
1168
|
+
}), 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) => {
|
|
1169
|
+
t.strokeStyle = x(e.lineColor, e.lineOpacity), t.lineWidth = i ?? e.lineWidth, t.setLineDash(z(e.lineStyle, t.lineWidth));
|
|
1170
|
+
}, bt = (t, e, i) => !e || i === void 0 || i <= 0 ? !1 : (t.fillStyle = x(e, i), !0), E = (t) => {
|
|
1080
1171
|
t.setLineDash([]);
|
|
1081
1172
|
}, $t = (t, e, i = {
|
|
1082
1173
|
fillColor: "#ffffff",
|
|
@@ -1084,11 +1175,11 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1084
1175
|
borderThickness: 3
|
|
1085
1176
|
}) => {
|
|
1086
1177
|
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
|
-
},
|
|
1178
|
+
}, O = (t, e, i) => {
|
|
1088
1179
|
e.forEach((s) => {
|
|
1089
1180
|
$t(t, s, i);
|
|
1090
1181
|
});
|
|
1091
|
-
},
|
|
1182
|
+
}, x = (t, e) => {
|
|
1092
1183
|
const i = Kt(e, 0, 1);
|
|
1093
1184
|
return t.startsWith("rgba(") ? t : t.startsWith("rgb(") ? t.replace("rgb(", "rgba(").replace(")", `, ${i})`) : t.startsWith("#") ? qt(t, i) : t;
|
|
1094
1185
|
}, qt = (t, e) => {
|
|
@@ -1113,12 +1204,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1113
1204
|
}, Jt = (t, e, i) => {
|
|
1114
1205
|
const s = Z(t, e), r = s + i;
|
|
1115
1206
|
return s >= 0 && r >= 0 && r < t.length ? t[r].time : e + Q(t) * i;
|
|
1116
|
-
}, ct = (t) => t instanceof MouseEvent && t.type === "contextmenu" ? !1 : "button" in t && t.type === "pointerdown" ? t.button === 0 : !0,
|
|
1117
|
-
handleColor: h.background,
|
|
1118
|
-
handleBorderColor: h.blue,
|
|
1119
|
-
handleBorderThickness: 1.5,
|
|
1120
|
-
handleRadius: 5
|
|
1121
|
-
}, L = class I {
|
|
1207
|
+
}, ct = (t) => t instanceof MouseEvent && t.type === "contextmenu" ? !1 : "button" in t && t.type === "pointerdown" ? t.button === 0 : !0, L = class I {
|
|
1122
1208
|
static defaultConfig = {
|
|
1123
1209
|
levels: [
|
|
1124
1210
|
{
|
|
@@ -1165,14 +1251,14 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1165
1251
|
fillColor: "#808080",
|
|
1166
1252
|
fillOpacity: 0.04
|
|
1167
1253
|
};
|
|
1168
|
-
static draw({ ctx: e, shape: i, converter: s, config: r = I.defaultConfig, selected: n = !1, hovered:
|
|
1169
|
-
const [
|
|
1170
|
-
e.save(),
|
|
1171
|
-
for (const
|
|
1172
|
-
const S = dt(
|
|
1173
|
-
e.beginPath(), e.strokeStyle =
|
|
1254
|
+
static draw({ ctx: e, shape: i, converter: s, config: r = I.defaultConfig, selected: n = !1, hovered: a = !1 }) {
|
|
1255
|
+
const [o, l] = i.vertices, d = v(o, s), u = v(l, s), g = K(o, l, s), p = Math.min(d.x, u.x), w = Math.max(d.x, u.x);
|
|
1256
|
+
e.save(), bt(e, r.fillColor, r.fillOpacity) && e.fillRect(g.left, g.top, g.width, g.height);
|
|
1257
|
+
for (const C of r.levels) {
|
|
1258
|
+
const S = dt(o.price, l.price, C.level), T = s.getYForPrice(S), k = C.lineWidth;
|
|
1259
|
+
e.beginPath(), e.strokeStyle = x(C.color, C.opacity), e.lineWidth = k, e.setLineDash(z(C.lineStyle, k)), e.moveTo(p, T), e.lineTo(w, T), e.stroke(), C.label && (e.setLineDash([]), e.fillStyle = x(C.color, C.opacity), e.font = "11px sans-serif", e.textBaseline = "middle", e.fillText(Number(C.label).toFixed(2).toString(), w + 12, T));
|
|
1174
1260
|
}
|
|
1175
|
-
|
|
1261
|
+
E(e), (n || a) && O(e, I.getHandles(i, s), {
|
|
1176
1262
|
fillColor: f.handleColor,
|
|
1177
1263
|
borderColor: f.handleBorderColor,
|
|
1178
1264
|
borderThickness: f.handleBorderThickness
|
|
@@ -1192,27 +1278,27 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1192
1278
|
});
|
|
1193
1279
|
}
|
|
1194
1280
|
static getHandles(e, i) {
|
|
1195
|
-
const [s, r] = e.vertices, n =
|
|
1196
|
-
return [
|
|
1281
|
+
const [s, r] = e.vertices, n = v(s, i), a = v(r, i);
|
|
1282
|
+
return [P({
|
|
1197
1283
|
shapeId: e.id,
|
|
1198
1284
|
type: "start",
|
|
1199
1285
|
point: n,
|
|
1200
1286
|
radius: f.handleRadius,
|
|
1201
1287
|
cursor: "grab"
|
|
1202
|
-
}),
|
|
1288
|
+
}), P({
|
|
1203
1289
|
shapeId: e.id,
|
|
1204
1290
|
type: "end",
|
|
1205
|
-
point:
|
|
1291
|
+
point: a,
|
|
1206
1292
|
radius: f.handleRadius,
|
|
1207
1293
|
cursor: "grab"
|
|
1208
1294
|
})];
|
|
1209
1295
|
}
|
|
1210
1296
|
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8, config: n = I.defaultConfig }) {
|
|
1211
|
-
const [
|
|
1297
|
+
const [a, o] = i.vertices, l = v(a, s), d = v(o, s), u = Math.min(l.x, d.x), g = Math.max(l.x, d.x);
|
|
1212
1298
|
if (e.x < u - r || e.x > g + r) return !1;
|
|
1213
|
-
for (const
|
|
1214
|
-
const w = dt(
|
|
1215
|
-
if (Math.abs(e.y -
|
|
1299
|
+
for (const p of n.levels) {
|
|
1300
|
+
const w = dt(a.price, o.price, p.level), C = s.getYForPrice(w);
|
|
1301
|
+
if (Math.abs(e.y - C) <= r) return !0;
|
|
1216
1302
|
}
|
|
1217
1303
|
return !1;
|
|
1218
1304
|
}
|
|
@@ -1237,23 +1323,23 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1237
1323
|
vertices: [e.vertices[0], s]
|
|
1238
1324
|
} : e;
|
|
1239
1325
|
}
|
|
1240
|
-
},
|
|
1326
|
+
}, R = class V {
|
|
1241
1327
|
static defaultConfig = {
|
|
1242
1328
|
lineWidth: 2,
|
|
1243
1329
|
lineColor: "#2962ff",
|
|
1244
1330
|
lineOpacity: 1,
|
|
1245
1331
|
lineStyle: "solid"
|
|
1246
1332
|
};
|
|
1247
|
-
static draw({ ctx: e, shape: i, converter: s, config: r =
|
|
1248
|
-
const [
|
|
1249
|
-
e.save(), tt(e, r), e.beginPath(), e.moveTo(d.x, d.y), e.lineTo(u.x, u.y), e.stroke(),
|
|
1333
|
+
static draw({ ctx: e, shape: i, converter: s, config: r = V.defaultConfig, selected: n = !1, hovered: a = !1 }) {
|
|
1334
|
+
const [o, l] = i.vertices, d = v(o, s), u = v(l, s);
|
|
1335
|
+
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
1336
|
fillColor: f.handleColor,
|
|
1251
1337
|
borderColor: f.handleBorderColor,
|
|
1252
1338
|
borderThickness: f.handleBorderThickness
|
|
1253
1339
|
}), e.restore();
|
|
1254
1340
|
}
|
|
1255
|
-
static drawDraft({ ctx: e, vertices: i, converter: s, config: r =
|
|
1256
|
-
|
|
1341
|
+
static drawDraft({ ctx: e, vertices: i, converter: s, config: r = V.defaultConfig }) {
|
|
1342
|
+
V.draw({
|
|
1257
1343
|
ctx: e,
|
|
1258
1344
|
shape: {
|
|
1259
1345
|
id: "__draft_trendline__",
|
|
@@ -1266,24 +1352,24 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1266
1352
|
});
|
|
1267
1353
|
}
|
|
1268
1354
|
static getHandles(e, i) {
|
|
1269
|
-
const [s, r] = e.vertices, n =
|
|
1270
|
-
return [
|
|
1355
|
+
const [s, r] = e.vertices, n = v(s, i), a = v(r, i);
|
|
1356
|
+
return [P({
|
|
1271
1357
|
shapeId: e.id,
|
|
1272
1358
|
type: "start",
|
|
1273
1359
|
point: n,
|
|
1274
1360
|
radius: f.handleRadius,
|
|
1275
1361
|
cursor: "grab"
|
|
1276
|
-
}),
|
|
1362
|
+
}), P({
|
|
1277
1363
|
shapeId: e.id,
|
|
1278
1364
|
type: "end",
|
|
1279
|
-
point:
|
|
1365
|
+
point: a,
|
|
1280
1366
|
radius: f.handleRadius,
|
|
1281
1367
|
cursor: "grab"
|
|
1282
1368
|
})];
|
|
1283
1369
|
}
|
|
1284
1370
|
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8 }) {
|
|
1285
|
-
const [n,
|
|
1286
|
-
return yt(e,
|
|
1371
|
+
const [n, a] = i.vertices;
|
|
1372
|
+
return yt(e, v(n, s), v(a, s)) <= r;
|
|
1287
1373
|
}
|
|
1288
1374
|
static move(e, i) {
|
|
1289
1375
|
return {
|
|
@@ -1306,7 +1392,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1306
1392
|
vertices: [e.vertices[0], s]
|
|
1307
1393
|
} : e;
|
|
1308
1394
|
}
|
|
1309
|
-
},
|
|
1395
|
+
}, D = class B {
|
|
1310
1396
|
static defaultConfig = {
|
|
1311
1397
|
lineWidth: 2,
|
|
1312
1398
|
lineColor: "#2962ff",
|
|
@@ -1315,19 +1401,19 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1315
1401
|
fillColor: "#2962ff",
|
|
1316
1402
|
fillOpacity: 0
|
|
1317
1403
|
};
|
|
1318
|
-
static draw({ ctx: e, shape: i, converter: s, config: r = B.defaultConfig, selected: n = !1, hovered:
|
|
1319
|
-
const
|
|
1320
|
-
if (
|
|
1321
|
-
e.save(), tt(e, r), e.beginPath(), e.moveTo(
|
|
1322
|
-
for (let l = 1; l <
|
|
1323
|
-
e.stroke(),
|
|
1404
|
+
static draw({ ctx: e, shape: i, converter: s, config: r = B.defaultConfig, selected: n = !1, hovered: a = !1 }) {
|
|
1405
|
+
const o = i.vertices.map((l) => v(l, s));
|
|
1406
|
+
if (o.length !== 0) {
|
|
1407
|
+
e.save(), tt(e, r), e.beginPath(), e.moveTo(o[0].x, o[0].y);
|
|
1408
|
+
for (let l = 1; l < o.length; l += 1) e.lineTo(o[l].x, o[l].y);
|
|
1409
|
+
e.stroke(), E(e), o.length >= 2 && B.drawEndArrow({
|
|
1324
1410
|
ctx: e,
|
|
1325
|
-
previousPoint:
|
|
1326
|
-
endPoint:
|
|
1411
|
+
previousPoint: o[o.length - 2],
|
|
1412
|
+
endPoint: o[o.length - 1],
|
|
1327
1413
|
color: r.lineColor,
|
|
1328
1414
|
opacity: r.lineOpacity,
|
|
1329
1415
|
lineWidth: r.lineWidth
|
|
1330
|
-
}), (n ||
|
|
1416
|
+
}), (n || a) && O(e, B.getHandles(i, s), {
|
|
1331
1417
|
fillColor: f.handleColor,
|
|
1332
1418
|
borderColor: f.handleBorderColor,
|
|
1333
1419
|
borderThickness: f.handleBorderThickness
|
|
@@ -1335,13 +1421,13 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1335
1421
|
}
|
|
1336
1422
|
}
|
|
1337
1423
|
static drawDraft({ ctx: e, vertices: i, previewVertex: s, converter: r, config: n = B.defaultConfig }) {
|
|
1338
|
-
const
|
|
1424
|
+
const a = s ? [...i, s] : i;
|
|
1339
1425
|
B.draw({
|
|
1340
1426
|
ctx: e,
|
|
1341
1427
|
shape: {
|
|
1342
1428
|
id: "__draft_path__",
|
|
1343
1429
|
type: "path",
|
|
1344
|
-
vertices:
|
|
1430
|
+
vertices: a
|
|
1345
1431
|
},
|
|
1346
1432
|
converter: r,
|
|
1347
1433
|
config: n,
|
|
@@ -1349,22 +1435,22 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1349
1435
|
});
|
|
1350
1436
|
}
|
|
1351
1437
|
static getHandles(e, i) {
|
|
1352
|
-
return e.vertices.map((s, r) =>
|
|
1438
|
+
return e.vertices.map((s, r) => P({
|
|
1353
1439
|
shapeId: e.id,
|
|
1354
1440
|
type: r === 0 ? "start" : r === e.vertices.length - 1 ? "end" : "move",
|
|
1355
|
-
point:
|
|
1441
|
+
point: v(s, i),
|
|
1356
1442
|
radius: f.handleRadius,
|
|
1357
1443
|
cursor: "grab",
|
|
1358
1444
|
index: r
|
|
1359
1445
|
}));
|
|
1360
1446
|
}
|
|
1361
1447
|
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8 }) {
|
|
1362
|
-
const n = i.vertices.map((
|
|
1448
|
+
const n = i.vertices.map((a) => v(a, s));
|
|
1363
1449
|
if (n.length === 1) {
|
|
1364
|
-
const
|
|
1365
|
-
return Math.sqrt(
|
|
1450
|
+
const a = n[0], o = e.x - a.x, l = e.y - a.y;
|
|
1451
|
+
return Math.sqrt(o * o + l * l) <= r;
|
|
1366
1452
|
}
|
|
1367
|
-
for (let
|
|
1453
|
+
for (let a = 1; a < n.length; a += 1) if (yt(e, n[a - 1], n[a]) <= r) return !0;
|
|
1368
1454
|
return !1;
|
|
1369
1455
|
}
|
|
1370
1456
|
static move(e, i) {
|
|
@@ -1382,11 +1468,11 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1382
1468
|
vertices: e.vertices.map((r, n) => n === i ? s : r)
|
|
1383
1469
|
};
|
|
1384
1470
|
}
|
|
1385
|
-
static drawEndArrow({ ctx: e, previousPoint: i, endPoint: s, color: r, opacity: n, lineWidth:
|
|
1386
|
-
const
|
|
1387
|
-
e.save(), e.beginPath(), e.strokeStyle =
|
|
1471
|
+
static drawEndArrow({ ctx: e, previousPoint: i, endPoint: s, color: r, opacity: n, lineWidth: a }) {
|
|
1472
|
+
const o = Math.atan2(s.y - i.y, s.x - i.x), l = 12, d = Math.PI / 7;
|
|
1473
|
+
e.save(), e.beginPath(), e.strokeStyle = x(r, n), e.fillStyle = x(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
1474
|
}
|
|
1389
|
-
},
|
|
1475
|
+
}, A = class W {
|
|
1390
1476
|
static defaultConfig = {
|
|
1391
1477
|
lineWidth: 2,
|
|
1392
1478
|
lineColor: "#2962ff",
|
|
@@ -1399,9 +1485,9 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1399
1485
|
textFontFamily: "Arial",
|
|
1400
1486
|
textFontSize: 20
|
|
1401
1487
|
};
|
|
1402
|
-
static draw({ ctx: e, shape: i, converter: s, config: r = W.defaultConfig, selected: n = !1, hovered:
|
|
1403
|
-
const [
|
|
1404
|
-
e.save(),
|
|
1488
|
+
static draw({ ctx: e, shape: i, converter: s, config: r = W.defaultConfig, selected: n = !1, hovered: a = !1 }) {
|
|
1489
|
+
const [o, l] = i.vertices, d = K(o, l, s);
|
|
1490
|
+
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
1491
|
fillColor: f.handleColor,
|
|
1406
1492
|
borderColor: f.handleBorderColor,
|
|
1407
1493
|
borderThickness: f.handleBorderThickness
|
|
@@ -1421,24 +1507,24 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1421
1507
|
});
|
|
1422
1508
|
}
|
|
1423
1509
|
static getHandles(e, i) {
|
|
1424
|
-
const [s, r] = e.vertices, n =
|
|
1425
|
-
return [
|
|
1510
|
+
const [s, r] = e.vertices, n = v(s, i), a = v(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";
|
|
1511
|
+
return [P({
|
|
1426
1512
|
shapeId: e.id,
|
|
1427
1513
|
type: "start",
|
|
1428
1514
|
point: n,
|
|
1429
1515
|
radius: f.handleRadius,
|
|
1430
1516
|
cursor: d
|
|
1431
|
-
}),
|
|
1517
|
+
}), P({
|
|
1432
1518
|
shapeId: e.id,
|
|
1433
1519
|
type: "end",
|
|
1434
|
-
point:
|
|
1520
|
+
point: a,
|
|
1435
1521
|
radius: f.handleRadius,
|
|
1436
1522
|
cursor: u
|
|
1437
1523
|
})];
|
|
1438
1524
|
}
|
|
1439
1525
|
static hitTest({ point: e, shape: i, converter: s, tolerance: r = 8 }) {
|
|
1440
|
-
const [n,
|
|
1441
|
-
return Ut(e, K(n,
|
|
1526
|
+
const [n, a] = i.vertices;
|
|
1527
|
+
return Ut(e, K(n, a, s), r);
|
|
1442
1528
|
}
|
|
1443
1529
|
static move(e, i) {
|
|
1444
1530
|
return {
|
|
@@ -1465,22 +1551,22 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1465
1551
|
const n = s?.trim();
|
|
1466
1552
|
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
1553
|
}
|
|
1468
|
-
},
|
|
1554
|
+
}, xt = [
|
|
1469
1555
|
"USDJPY",
|
|
1470
1556
|
"GBPJPY",
|
|
1471
1557
|
"AUDJPY",
|
|
1472
1558
|
"EURJPY",
|
|
1473
1559
|
"NZDJPY",
|
|
1474
1560
|
"CADJPY"
|
|
1475
|
-
],
|
|
1561
|
+
], Pt = ["BTCUSD", "ETHUSD"], St = [
|
|
1476
1562
|
"XAUUSD",
|
|
1477
1563
|
"USOIL",
|
|
1478
1564
|
"UKOIL",
|
|
1479
1565
|
"XAGUSD"
|
|
1480
|
-
], Tt = (t) =>
|
|
1481
|
-
const n = r.split(".")[0],
|
|
1482
|
-
return (t === "buy" ? i - e : e - i) /
|
|
1483
|
-
}, H = class
|
|
1566
|
+
], Tt = (t) => xt.some((e) => t.includes(e.slice(3))) ? 0.01 : Pt.includes(t) ? 1 : St.includes(t) ? 0.01 : 1e-4, jt = (t, e) => xt.includes(t) ? e * 6.33806 : Pt.includes(t) ? e * 1 : (St.includes(t), e * 10), ut = (t, e, i, s, r) => {
|
|
1567
|
+
const n = r.split(".")[0], a = Tt(n), o = jt(n, s);
|
|
1568
|
+
return (t === "buy" ? i - e : e - i) / a * o;
|
|
1569
|
+
}, H = class b {
|
|
1484
1570
|
static defaultLongConfig = {
|
|
1485
1571
|
defaultWidthCandles: 10,
|
|
1486
1572
|
defaultStopLossPercent: 0.25,
|
|
@@ -1498,48 +1584,48 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1498
1584
|
midLineWidth: 1,
|
|
1499
1585
|
midLineStyle: "dashed"
|
|
1500
1586
|
};
|
|
1501
|
-
static defaultShortConfig = { ...
|
|
1502
|
-
static draw({ ctx: e, activeSymbol: i, shape: s, converter: r, config: n = s.type === "longPosition" ?
|
|
1503
|
-
const l =
|
|
1504
|
-
e.save(), e.fillStyle =
|
|
1587
|
+
static defaultShortConfig = { ...b.defaultLongConfig };
|
|
1588
|
+
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 }) {
|
|
1589
|
+
const l = b.getGeometry(s, r);
|
|
1590
|
+
e.save(), e.fillStyle = x(n.profitFillColor, n.profitFillOpacity), e.fillRect(l.profitBox.left, l.profitBox.top, l.profitBox.width, l.profitBox.height), e.fillStyle = x(n.lossFillColor, n.lossFillOpacity), e.fillRect(l.lossBox.left, l.lossBox.top, l.lossBox.width, l.lossBox.height);
|
|
1505
1591
|
const d = n.borderWidth;
|
|
1506
|
-
e.strokeStyle =
|
|
1592
|
+
e.strokeStyle = x(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 = x(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
1593
|
ctx: e,
|
|
1508
1594
|
activeSymbol: i,
|
|
1509
1595
|
shape: s,
|
|
1510
1596
|
geometry: l,
|
|
1511
1597
|
config: n
|
|
1512
|
-
}), (
|
|
1598
|
+
}), (a || o) && O(e, b.getHandles(s, r), {
|
|
1513
1599
|
fillColor: f.handleColor,
|
|
1514
1600
|
borderColor: f.handleBorderColor,
|
|
1515
1601
|
borderThickness: f.handleBorderThickness
|
|
1516
1602
|
}), e.restore();
|
|
1517
1603
|
}
|
|
1518
|
-
static createFromVertex({ id: e, type: i, entry: s, converter: r, config: n = i === "longPosition" ?
|
|
1519
|
-
const
|
|
1604
|
+
static createFromVertex({ id: e, type: i, entry: s, converter: r, config: n = i === "longPosition" ? b.defaultLongConfig : b.defaultShortConfig }) {
|
|
1605
|
+
const a = r.getTimeForX(r.getXForTime(s.time) + r.getCandleWidth() * n.defaultWidthCandles), o = n.defaultStopLossPercent;
|
|
1520
1606
|
return {
|
|
1521
1607
|
id: e,
|
|
1522
1608
|
type: i,
|
|
1523
1609
|
entry: s,
|
|
1524
|
-
endTime:
|
|
1525
|
-
stopLossPercent:
|
|
1526
|
-
takeProfitPercent:
|
|
1610
|
+
endTime: a,
|
|
1611
|
+
stopLossPercent: o,
|
|
1612
|
+
takeProfitPercent: o * n.defaultRiskRewardRatio
|
|
1527
1613
|
};
|
|
1528
1614
|
}
|
|
1529
1615
|
static getGeometry(e, i) {
|
|
1530
|
-
const s =
|
|
1616
|
+
const s = v(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), p = i.getYForPrice(u), w = i.getYForPrice(g), C = Math.min(p, w, s.y), S = Math.max(p, w, s.y), T = {
|
|
1531
1617
|
left: n,
|
|
1532
|
-
top:
|
|
1533
|
-
right:
|
|
1618
|
+
top: C,
|
|
1619
|
+
right: a,
|
|
1534
1620
|
bottom: s.y,
|
|
1535
|
-
width:
|
|
1536
|
-
height: Math.abs(s.y -
|
|
1621
|
+
width: a - n,
|
|
1622
|
+
height: Math.abs(s.y - C)
|
|
1537
1623
|
}, k = {
|
|
1538
1624
|
left: n,
|
|
1539
1625
|
top: s.y,
|
|
1540
|
-
right:
|
|
1626
|
+
right: a,
|
|
1541
1627
|
bottom: S,
|
|
1542
|
-
width:
|
|
1628
|
+
width: a - n,
|
|
1543
1629
|
height: Math.abs(S - s.y)
|
|
1544
1630
|
};
|
|
1545
1631
|
return {
|
|
@@ -1550,20 +1636,20 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1550
1636
|
lowerPrice: g,
|
|
1551
1637
|
box: {
|
|
1552
1638
|
left: n,
|
|
1553
|
-
top:
|
|
1554
|
-
right:
|
|
1639
|
+
top: C,
|
|
1640
|
+
right: a,
|
|
1555
1641
|
bottom: S,
|
|
1556
|
-
width:
|
|
1557
|
-
height: S -
|
|
1642
|
+
width: a - n,
|
|
1643
|
+
height: S - C
|
|
1558
1644
|
},
|
|
1559
|
-
profitBox:
|
|
1560
|
-
lossBox:
|
|
1645
|
+
profitBox: o ? T : k,
|
|
1646
|
+
lossBox: o ? k : T
|
|
1561
1647
|
};
|
|
1562
1648
|
}
|
|
1563
1649
|
static getHandles(e, i) {
|
|
1564
|
-
const s =
|
|
1650
|
+
const s = b.getGeometry(e, i);
|
|
1565
1651
|
return [
|
|
1566
|
-
|
|
1652
|
+
P({
|
|
1567
1653
|
shapeId: e.id,
|
|
1568
1654
|
type: "upperHeight",
|
|
1569
1655
|
point: {
|
|
@@ -1573,7 +1659,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1573
1659
|
radius: f.handleRadius,
|
|
1574
1660
|
cursor: "ns-resize"
|
|
1575
1661
|
}),
|
|
1576
|
-
|
|
1662
|
+
P({
|
|
1577
1663
|
shapeId: e.id,
|
|
1578
1664
|
type: "lowerHeight",
|
|
1579
1665
|
point: {
|
|
@@ -1583,7 +1669,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1583
1669
|
radius: f.handleRadius,
|
|
1584
1670
|
cursor: "ns-resize"
|
|
1585
1671
|
}),
|
|
1586
|
-
|
|
1672
|
+
P({
|
|
1587
1673
|
shapeId: e.id,
|
|
1588
1674
|
type: "start",
|
|
1589
1675
|
point: {
|
|
@@ -1593,7 +1679,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1593
1679
|
radius: f.handleRadius,
|
|
1594
1680
|
cursor: "ns-resize"
|
|
1595
1681
|
}),
|
|
1596
|
-
|
|
1682
|
+
P({
|
|
1597
1683
|
shapeId: e.id,
|
|
1598
1684
|
type: "end",
|
|
1599
1685
|
point: {
|
|
@@ -1606,7 +1692,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1606
1692
|
];
|
|
1607
1693
|
}
|
|
1608
1694
|
static hitTest({ point: e, shape: i, converter: s }) {
|
|
1609
|
-
return
|
|
1695
|
+
return b.getHandles(i, s).some((r) => j(e, r)) ? !0 : wt(e, b.getGeometry(i, s).box);
|
|
1610
1696
|
}
|
|
1611
1697
|
static move(e, i) {
|
|
1612
1698
|
return {
|
|
@@ -1628,7 +1714,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1628
1714
|
} : i === "end" ? {
|
|
1629
1715
|
...e,
|
|
1630
1716
|
endTime: s.time
|
|
1631
|
-
} : i === "upperHeight" ?
|
|
1717
|
+
} : i === "upperHeight" ? b.resizeUpperHeight(e, s.price) : i === "lowerHeight" ? b.resizeLowerHeight(e, s.price) : {
|
|
1632
1718
|
...e,
|
|
1633
1719
|
endTime: r.getTimeForX(r.getXForTime(e.endTime))
|
|
1634
1720
|
};
|
|
@@ -1655,11 +1741,11 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1655
1741
|
}
|
|
1656
1742
|
static drawLabels({ ctx: e, activeSymbol: i, shape: s, geometry: r, config: n }) {
|
|
1657
1743
|
e.save(), e.font = "11px sans-serif", e.textBaseline = "middle";
|
|
1658
|
-
const
|
|
1659
|
-
e.fillStyle =
|
|
1660
|
-
const
|
|
1661
|
-
e.fillText(`${l.toFixed(2)} (${g.toFixed(2)})`, u,
|
|
1662
|
-
const w =
|
|
1744
|
+
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;
|
|
1745
|
+
e.fillStyle = x(n.profitFillColor, 0.95);
|
|
1746
|
+
const p = a === "longPosition" ? r.profitBox.top + r.profitBox.height / 10 : r.profitBox.bottom - r.profitBox.height / 10;
|
|
1747
|
+
e.fillText(`${l.toFixed(2)} (${g.toFixed(2)})`, u, p), e.fillStyle = x(n.lossFillColor, 0.95);
|
|
1748
|
+
const w = a === "shortPosition" ? r.lossBox.top + r.lossBox.height / 10 : r.lossBox.bottom - r.lossBox.height / 10;
|
|
1663
1749
|
e.fillText(d.toFixed(1), u, w);
|
|
1664
1750
|
}
|
|
1665
1751
|
}, Zt = class {
|
|
@@ -1769,7 +1855,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1769
1855
|
if (!ct(t)) return !1;
|
|
1770
1856
|
const s = this.findHandleAtPoint(e);
|
|
1771
1857
|
if (s) {
|
|
1772
|
-
const n = this.shapes.find((
|
|
1858
|
+
const n = this.shapes.find((a) => a.id === s.shapeId);
|
|
1773
1859
|
return n ? (this.setSelectedShapeId(n.id), this.checkTouchDoubleTap(n, t), this.dragState = {
|
|
1774
1860
|
edit: {
|
|
1775
1861
|
mode: "resize",
|
|
@@ -1953,10 +2039,10 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1953
2039
|
return this.resizeShape(e.shape, e.handleType, t, e.handleIndex);
|
|
1954
2040
|
}
|
|
1955
2041
|
moveShape(t, e) {
|
|
1956
|
-
return t.type === "trendline" ?
|
|
2042
|
+
return t.type === "trendline" ? R.move(t, e) : t.type === "rectangle" ? A.move(t, e) : t.type === "path" ? D.move(t, e) : t.type === "fibRetracement" ? L.move(t, e) : H.move(t, e);
|
|
1957
2043
|
}
|
|
1958
2044
|
resizeShape(t, e, i, s) {
|
|
1959
|
-
return t.type === "trendline" ?
|
|
2045
|
+
return t.type === "trendline" ? R.resize(t, e, i) : t.type === "rectangle" ? A.resize(t, e, i) : t.type === "fibRetracement" ? L.resize(t, e, i) : t.type === "path" ? D.resize(t, s ?? -1, i) : H.resize({
|
|
1960
2046
|
shape: t,
|
|
1961
2047
|
handleType: e,
|
|
1962
2048
|
vertex: i,
|
|
@@ -1966,7 +2052,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1966
2052
|
drawShape({ shape: t, converter: e, selected: i, hovered: s }) {
|
|
1967
2053
|
if (t.type === "trendline") {
|
|
1968
2054
|
const n = this.getTrendlineConfig(t);
|
|
1969
|
-
|
|
2055
|
+
R.draw({
|
|
1970
2056
|
ctx: this.ctx,
|
|
1971
2057
|
shape: t,
|
|
1972
2058
|
converter: e,
|
|
@@ -1978,7 +2064,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1978
2064
|
}
|
|
1979
2065
|
if (t.type === "rectangle") {
|
|
1980
2066
|
const n = this.getRectangleConfig(t);
|
|
1981
|
-
|
|
2067
|
+
A.draw({
|
|
1982
2068
|
ctx: this.ctx,
|
|
1983
2069
|
shape: t,
|
|
1984
2070
|
converter: e,
|
|
@@ -1990,7 +2076,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
1990
2076
|
}
|
|
1991
2077
|
if (t.type === "path") {
|
|
1992
2078
|
const n = this.getPathConfig(t);
|
|
1993
|
-
|
|
2079
|
+
D.draw({
|
|
1994
2080
|
ctx: this.ctx,
|
|
1995
2081
|
shape: t,
|
|
1996
2082
|
converter: e,
|
|
@@ -2026,7 +2112,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2026
2112
|
drawDraft(t) {
|
|
2027
2113
|
if (this.draft) {
|
|
2028
2114
|
if (this.draft.type === "trendline") {
|
|
2029
|
-
|
|
2115
|
+
R.drawDraft({
|
|
2030
2116
|
ctx: this.ctx,
|
|
2031
2117
|
vertices: this.draft.vertices,
|
|
2032
2118
|
converter: t,
|
|
@@ -2035,7 +2121,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2035
2121
|
return;
|
|
2036
2122
|
}
|
|
2037
2123
|
if (this.draft.type === "rectangle") {
|
|
2038
|
-
|
|
2124
|
+
A.drawDraft({
|
|
2039
2125
|
ctx: this.ctx,
|
|
2040
2126
|
vertices: this.draft.vertices,
|
|
2041
2127
|
converter: t,
|
|
@@ -2052,7 +2138,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2052
2138
|
});
|
|
2053
2139
|
return;
|
|
2054
2140
|
}
|
|
2055
|
-
this.draft.type === "path" &&
|
|
2141
|
+
this.draft.type === "path" && D.drawDraft({
|
|
2056
2142
|
ctx: this.ctx,
|
|
2057
2143
|
vertices: this.draft.vertices,
|
|
2058
2144
|
previewVertex: this.draft.previewVertex,
|
|
@@ -2070,7 +2156,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2070
2156
|
i && e.push(i), s && e.push(s), this.handleHitboxes = e.flatMap((r) => this.getShapeHandles(r, t));
|
|
2071
2157
|
}
|
|
2072
2158
|
getShapeHandles(t, e) {
|
|
2073
|
-
return t.type === "trendline" ?
|
|
2159
|
+
return t.type === "trendline" ? R.getHandles(t, e) : t.type === "rectangle" ? A.getHandles(t, e) : t.type === "path" ? D.getHandles(t, e) : t.type === "fibRetracement" ? L.getHandles(t, e) : H.getHandles(t, e);
|
|
2074
2160
|
}
|
|
2075
2161
|
findHandleAtPoint(t) {
|
|
2076
2162
|
for (let e = this.handleHitboxes.length - 1; e >= 0; e -= 1) {
|
|
@@ -2093,15 +2179,15 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2093
2179
|
return null;
|
|
2094
2180
|
}
|
|
2095
2181
|
isShapeHit(t, e, i) {
|
|
2096
|
-
return t.type === "trendline" ?
|
|
2182
|
+
return t.type === "trendline" ? R.hitTest({
|
|
2097
2183
|
point: e,
|
|
2098
2184
|
shape: t,
|
|
2099
2185
|
converter: i
|
|
2100
|
-
}) : t.type === "rectangle" ?
|
|
2186
|
+
}) : t.type === "rectangle" ? A.hitTest({
|
|
2101
2187
|
point: e,
|
|
2102
2188
|
shape: t,
|
|
2103
2189
|
converter: i
|
|
2104
|
-
}) : t.type === "path" ?
|
|
2190
|
+
}) : t.type === "path" ? D.hitTest({
|
|
2105
2191
|
point: e,
|
|
2106
2192
|
shape: t,
|
|
2107
2193
|
converter: i
|
|
@@ -2219,7 +2305,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2219
2305
|
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);
|
|
2220
2306
|
}
|
|
2221
2307
|
getYForPrice(t) {
|
|
2222
|
-
return this.viewport ?
|
|
2308
|
+
return this.viewport ? Y({
|
|
2223
2309
|
price: t,
|
|
2224
2310
|
minPrice: this.viewport.minPrice,
|
|
2225
2311
|
priceRange: this.viewport.priceRange,
|
|
@@ -2240,15 +2326,15 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2240
2326
|
mergeConfig(t) {
|
|
2241
2327
|
return {
|
|
2242
2328
|
trendline: {
|
|
2243
|
-
...
|
|
2329
|
+
...R.defaultConfig,
|
|
2244
2330
|
...t?.trendline ?? {}
|
|
2245
2331
|
},
|
|
2246
2332
|
rectangle: {
|
|
2247
|
-
...
|
|
2333
|
+
...A.defaultConfig,
|
|
2248
2334
|
...t?.rectangle ?? {}
|
|
2249
2335
|
},
|
|
2250
2336
|
path: {
|
|
2251
|
-
...
|
|
2337
|
+
...D.defaultConfig,
|
|
2252
2338
|
...t?.path ?? {}
|
|
2253
2339
|
},
|
|
2254
2340
|
fibRetracement: {
|
|
@@ -2315,53 +2401,53 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2315
2401
|
for (const t of this.trades) this.drawTrade({ trade: t });
|
|
2316
2402
|
this.drawTemporaryProtectionDrag();
|
|
2317
2403
|
}
|
|
2318
|
-
createHitBox = ({ price: t, trade: e, type: i, x: s, y: r, width: n, height:
|
|
2319
|
-
const { showCloseSection: l, widthClose: d } = this.getHandleStyleConfig(i).handle, u = l ? d : 0, g = n - u,
|
|
2404
|
+
createHitBox = ({ price: t, trade: e, type: i, x: s, y: r, width: n, height: a, viewport: o }) => {
|
|
2405
|
+
const { showCloseSection: l, widthClose: d } = this.getHandleStyleConfig(i).handle, u = l ? d : 0, g = n - u, p = s + n - u;
|
|
2320
2406
|
return {
|
|
2321
2407
|
kind: "existingHandle",
|
|
2322
|
-
price:
|
|
2408
|
+
price: m(t),
|
|
2323
2409
|
trade: e,
|
|
2324
2410
|
type: i,
|
|
2325
2411
|
x: s,
|
|
2326
2412
|
y: r,
|
|
2327
2413
|
width: n,
|
|
2328
|
-
height:
|
|
2329
|
-
viewport:
|
|
2414
|
+
height: a,
|
|
2415
|
+
viewport: o,
|
|
2330
2416
|
labelArea: {
|
|
2331
2417
|
x: s,
|
|
2332
2418
|
y: r,
|
|
2333
2419
|
width: g,
|
|
2334
|
-
height:
|
|
2420
|
+
height: a
|
|
2335
2421
|
},
|
|
2336
2422
|
closeButtonArea: {
|
|
2337
|
-
x:
|
|
2423
|
+
x: p,
|
|
2338
2424
|
y: r,
|
|
2339
2425
|
width: u,
|
|
2340
|
-
height:
|
|
2426
|
+
height: a
|
|
2341
2427
|
}
|
|
2342
2428
|
};
|
|
2343
2429
|
};
|
|
2344
|
-
createMissingProtectionHitBox = ({ price: t, trade: e, type: i, x: s, y: r, width: n, height:
|
|
2430
|
+
createMissingProtectionHitBox = ({ price: t, trade: e, type: i, x: s, y: r, width: n, height: a, viewport: o }) => ({
|
|
2345
2431
|
kind: "missingProtectionHandle",
|
|
2346
|
-
price:
|
|
2432
|
+
price: m(t),
|
|
2347
2433
|
trade: e,
|
|
2348
2434
|
type: i,
|
|
2349
2435
|
x: s,
|
|
2350
2436
|
y: r,
|
|
2351
2437
|
width: n,
|
|
2352
|
-
height:
|
|
2353
|
-
viewport:
|
|
2438
|
+
height: a,
|
|
2439
|
+
viewport: o,
|
|
2354
2440
|
labelArea: {
|
|
2355
2441
|
x: s,
|
|
2356
2442
|
y: r,
|
|
2357
2443
|
width: n,
|
|
2358
|
-
height:
|
|
2444
|
+
height: a
|
|
2359
2445
|
},
|
|
2360
2446
|
closeButtonArea: {
|
|
2361
2447
|
x: s + n,
|
|
2362
2448
|
y: r,
|
|
2363
2449
|
width: 0,
|
|
2364
|
-
height:
|
|
2450
|
+
height: a
|
|
2365
2451
|
}
|
|
2366
2452
|
});
|
|
2367
2453
|
drawTrade({ trade: t }) {
|
|
@@ -2442,20 +2528,20 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2442
2528
|
padding: Math.max(1, s.borderWidth)
|
|
2443
2529
|
}), 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();
|
|
2444
2530
|
}
|
|
2445
|
-
drawHandleSections({ handleType: t, handleX: e, handleY: i, handleWidth: s, handleHeight: r, handleConfig: n, trade:
|
|
2531
|
+
drawHandleSections({ handleType: t, handleX: e, handleY: i, handleWidth: s, handleHeight: r, handleConfig: n, trade: a, y: o }) {
|
|
2446
2532
|
const l = this.#e, d = c.tradeHandles, u = this.getHandleSections({
|
|
2447
2533
|
handleType: t,
|
|
2448
2534
|
handleConfig: n,
|
|
2449
|
-
trade:
|
|
2535
|
+
trade: a
|
|
2450
2536
|
});
|
|
2451
2537
|
let g = e;
|
|
2452
2538
|
l.save(), l.font = d.font, l.textBaseline = "middle", l.globalAlpha = d.textOpacity;
|
|
2453
|
-
for (const
|
|
2454
|
-
|
|
2455
|
-
section:
|
|
2539
|
+
for (const p of u)
|
|
2540
|
+
p.visible && (this.drawHandleSectionLabel({
|
|
2541
|
+
section: p,
|
|
2456
2542
|
currentX: g,
|
|
2457
|
-
y:
|
|
2458
|
-
}), g +=
|
|
2543
|
+
y: o
|
|
2544
|
+
}), g += p.width, g < e + s && this.drawHandleSectionDivider({
|
|
2459
2545
|
x: g,
|
|
2460
2546
|
y1: i + 4,
|
|
2461
2547
|
y2: i + r - 4,
|
|
@@ -2504,7 +2590,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2504
2590
|
return this.getProtectionDirection({
|
|
2505
2591
|
trade: e,
|
|
2506
2592
|
type: i
|
|
2507
|
-
}) > 0 ?
|
|
2593
|
+
}) > 0 ? m(Math.max(t, e.openPrice)) : m(Math.min(t, e.openPrice));
|
|
2508
2594
|
}
|
|
2509
2595
|
clearCanvas() {
|
|
2510
2596
|
this.#e.clearRect(0, 0, this.#t.width, this.#t.height);
|
|
@@ -2523,7 +2609,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2523
2609
|
if (!this.viewport) return null;
|
|
2524
2610
|
const e = this.getTimeX(t.openTime), i = this.getTimeX(t.closeTime);
|
|
2525
2611
|
if (e === null || i === null) return null;
|
|
2526
|
-
const s = this.getPriceY(t.openPrice, this.viewport), r = this.getPriceY(t.closePrice, this.viewport), n = c.closedTradeIndicators.arrow,
|
|
2612
|
+
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;
|
|
2527
2613
|
return {
|
|
2528
2614
|
trade: t,
|
|
2529
2615
|
start: {
|
|
@@ -2538,8 +2624,8 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2538
2624
|
time: t.closeTime,
|
|
2539
2625
|
price: t.closePrice
|
|
2540
2626
|
},
|
|
2541
|
-
arrowWidth:
|
|
2542
|
-
arrowHeight:
|
|
2627
|
+
arrowWidth: a,
|
|
2628
|
+
arrowHeight: o
|
|
2543
2629
|
};
|
|
2544
2630
|
}
|
|
2545
2631
|
drawClosedTradeConnector({ start: t, close: e }) {
|
|
@@ -2555,7 +2641,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2555
2641
|
drawClosedTradeArrows({ trade: t, start: e, close: i, arrowWidth: s, arrowHeight: r }) {
|
|
2556
2642
|
const n = c.closedTradeIndicators.arrow;
|
|
2557
2643
|
if (!n.visible) return;
|
|
2558
|
-
const
|
|
2644
|
+
const a = t.type === "buy" ? "sell" : "buy";
|
|
2559
2645
|
this.drawClosedTradeArrow({
|
|
2560
2646
|
x: e.x,
|
|
2561
2647
|
y: e.y,
|
|
@@ -2566,7 +2652,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2566
2652
|
}), this.drawClosedTradeArrow({
|
|
2567
2653
|
x: i.x,
|
|
2568
2654
|
y: i.y,
|
|
2569
|
-
type:
|
|
2655
|
+
type: a,
|
|
2570
2656
|
width: s,
|
|
2571
2657
|
height: r,
|
|
2572
2658
|
config: n
|
|
@@ -2574,10 +2660,10 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2574
2660
|
}
|
|
2575
2661
|
drawClosedTradeArrow({ x: t, y: e, type: i, width: s, height: r, config: n }) {
|
|
2576
2662
|
if (s <= 0 || r <= 0) return;
|
|
2577
|
-
const
|
|
2578
|
-
|
|
2663
|
+
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), p = g + n.borderWidth * 2, w = t, C = e + u * (p / 2), S = t, T = C + u * r, k = r * n.headHeightRatio, et = s / 2, Ht = w - et, Mt = w + et, N = C + u * k, it = () => {
|
|
2664
|
+
a.beginPath(), a.moveTo(S, T), a.lineTo(w, N), a.moveTo(w, C), a.lineTo(Ht, N), a.moveTo(w, C), a.lineTo(Mt, N), a.stroke();
|
|
2579
2665
|
};
|
|
2580
|
-
|
|
2666
|
+
a.save(), a.globalAlpha = n.opacity, a.lineCap = "round", a.lineJoin = "round", a.strokeStyle = d, a.lineWidth = p, it(), a.strokeStyle = l, a.lineWidth = g, it(), a.restore();
|
|
2581
2667
|
}
|
|
2582
2668
|
getTimeX(t) {
|
|
2583
2669
|
if (!this.viewport || this.candles.length === 0 || !Number.isFinite(t)) return null;
|
|
@@ -2592,9 +2678,9 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2592
2678
|
const d = this.candles.length - 1, u = this.getCandleTimeInterval(d), g = (e - s.time) / u;
|
|
2593
2679
|
return this.getCandleCenterX(d) + g * this.viewport.candleSpacing;
|
|
2594
2680
|
}
|
|
2595
|
-
const r = this.getFirstCandleIndexAtOrAfterTime(e), n = Math.max(0, r - 1),
|
|
2596
|
-
if (!
|
|
2597
|
-
const l = (e -
|
|
2681
|
+
const r = this.getFirstCandleIndexAtOrAfterTime(e), n = Math.max(0, r - 1), a = this.candles[n], o = this.candles[r];
|
|
2682
|
+
if (!a || !o || o.time === a.time) return this.getCandleCenterX(n);
|
|
2683
|
+
const l = (e - a.time) / (o.time - a.time);
|
|
2598
2684
|
return this.getCandleCenterX(n) + l * this.viewport.candleSpacing;
|
|
2599
2685
|
}
|
|
2600
2686
|
normalizeTimestamp(t) {
|
|
@@ -2617,7 +2703,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2617
2703
|
}
|
|
2618
2704
|
getTradeHandleRenderState({ price: t, type: e, trade: i }) {
|
|
2619
2705
|
if (!this.viewport) return null;
|
|
2620
|
-
const s = this.viewport, r = this.getPriceY(t, s), n = this.getHandleStyleConfig(e),
|
|
2706
|
+
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;
|
|
2621
2707
|
return {
|
|
2622
2708
|
price: t,
|
|
2623
2709
|
type: e,
|
|
@@ -2625,11 +2711,11 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2625
2711
|
viewport: s,
|
|
2626
2712
|
y: r,
|
|
2627
2713
|
handleStyleConfig: n,
|
|
2628
|
-
handleConfig:
|
|
2629
|
-
lineConfig:
|
|
2714
|
+
handleConfig: a,
|
|
2715
|
+
lineConfig: o,
|
|
2630
2716
|
handleX: this.getHandleX({
|
|
2631
2717
|
handleWidth: l,
|
|
2632
|
-
config:
|
|
2718
|
+
config: a
|
|
2633
2719
|
}),
|
|
2634
2720
|
handleY: r - d / 2,
|
|
2635
2721
|
handleWidth: l,
|
|
@@ -2637,7 +2723,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2637
2723
|
};
|
|
2638
2724
|
}
|
|
2639
2725
|
getPriceY(t, e) {
|
|
2640
|
-
return
|
|
2726
|
+
return Y({
|
|
2641
2727
|
price: t,
|
|
2642
2728
|
minPrice: e.minPrice,
|
|
2643
2729
|
priceRange: e.priceRange,
|
|
@@ -2781,12 +2867,12 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2781
2867
|
return t.sl || e.push("stopLoss"), t.tp || e.push("takeProfit"), e;
|
|
2782
2868
|
}
|
|
2783
2869
|
getMissingProtectionHandleRenderState({ type: t, trade: e, startPriceRenderState: i, visibleTypes: s }) {
|
|
2784
|
-
const r = this.getMissingProtectionHandleConfig(t), n = r.width,
|
|
2870
|
+
const r = this.getMissingProtectionHandleConfig(t), n = r.width, a = r.height, o = this.getMissingProtectionHandleX({
|
|
2785
2871
|
type: t,
|
|
2786
2872
|
config: r,
|
|
2787
2873
|
startPriceRenderState: i,
|
|
2788
2874
|
visibleTypes: s
|
|
2789
|
-
}), l = i.y -
|
|
2875
|
+
}), l = i.y - a / 2;
|
|
2790
2876
|
return {
|
|
2791
2877
|
price: e.openPrice,
|
|
2792
2878
|
type: t,
|
|
@@ -2794,10 +2880,10 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2794
2880
|
viewport: i.viewport,
|
|
2795
2881
|
y: i.y,
|
|
2796
2882
|
config: r,
|
|
2797
|
-
handleX:
|
|
2883
|
+
handleX: o,
|
|
2798
2884
|
handleY: l,
|
|
2799
2885
|
handleWidth: n,
|
|
2800
|
-
handleHeight:
|
|
2886
|
+
handleHeight: a
|
|
2801
2887
|
};
|
|
2802
2888
|
}
|
|
2803
2889
|
getMissingProtectionHandleX({ type: t, config: e, startPriceRenderState: i, visibleTypes: s }) {
|
|
@@ -2825,8 +2911,8 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2825
2911
|
}), 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();
|
|
2826
2912
|
}
|
|
2827
2913
|
drawMissingProtectionHandleLabel({ type: t, handleX: e, y: i, handleWidth: s, config: r }) {
|
|
2828
|
-
const n = this.#e,
|
|
2829
|
-
n.save(), n.font = r.font, n.textBaseline = "middle", n.globalAlpha = r.textOpacity, n.fillStyle = r.textColor, n.fillText(
|
|
2914
|
+
const n = this.#e, a = t === "stopLoss" ? "SL" : "TP", o = e + s / 2;
|
|
2915
|
+
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();
|
|
2830
2916
|
}
|
|
2831
2917
|
drawTemporaryProtectionDrag() {
|
|
2832
2918
|
const t = this.getTemporaryProtectionRenderState();
|
|
@@ -2839,7 +2925,7 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2839
2925
|
}
|
|
2840
2926
|
getTemporaryProtectionRenderState() {
|
|
2841
2927
|
if (!this.temporaryProtectionDrag) return null;
|
|
2842
|
-
const { trade: t, type: e, viewport: i } = this.temporaryProtectionDrag, s =
|
|
2928
|
+
const { trade: t, type: e, viewport: i } = this.temporaryProtectionDrag, s = m(this.temporaryProtectionDrag.price), r = this.getPriceY(s, i), n = this.getTemporaryProtectionHandleConfig(e), a = this.getTemporaryProtectionLineConfig(e), o = n.widthPNL, l = n.height;
|
|
2843
2929
|
return {
|
|
2844
2930
|
price: s,
|
|
2845
2931
|
type: e,
|
|
@@ -2847,13 +2933,13 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2847
2933
|
viewport: i,
|
|
2848
2934
|
y: r,
|
|
2849
2935
|
handleConfig: n,
|
|
2850
|
-
lineConfig:
|
|
2936
|
+
lineConfig: a,
|
|
2851
2937
|
handleX: this.getTemporaryProtectionHandleX({
|
|
2852
|
-
handleWidth:
|
|
2938
|
+
handleWidth: o,
|
|
2853
2939
|
config: n
|
|
2854
2940
|
}),
|
|
2855
2941
|
handleY: r - l / 2,
|
|
2856
|
-
handleWidth:
|
|
2942
|
+
handleWidth: o,
|
|
2857
2943
|
handleHeight: l
|
|
2858
2944
|
};
|
|
2859
2945
|
}
|
|
@@ -2875,9 +2961,9 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2875
2961
|
padding: Math.max(1, s.borderWidth)
|
|
2876
2962
|
}), 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();
|
|
2877
2963
|
}
|
|
2878
|
-
drawTemporaryProtectionPnLLabel({ trade: t, type: e, price: i, handleX: s, y: r, handleWidth: n, handleConfig:
|
|
2879
|
-
const
|
|
2880
|
-
|
|
2964
|
+
drawTemporaryProtectionPnLLabel({ trade: t, type: e, price: i, handleX: s, y: r, handleWidth: n, handleConfig: a }) {
|
|
2965
|
+
const o = this.#e, l = ut(t.type, t.openPrice, i, t.volume, t.symbol), d = this.formatPnlLabel(l), u = s + n / 2;
|
|
2966
|
+
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();
|
|
2881
2967
|
}
|
|
2882
2968
|
clearRectArea({ x: t, y: e, width: i, height: s, padding: r = 0 }) {
|
|
2883
2969
|
this.#e.clearRect(t - r, e - r, i + r * 2, s + r * 2);
|
|
@@ -2912,31 +2998,31 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2912
2998
|
], ee = class {
|
|
2913
2999
|
#t;
|
|
2914
3000
|
#e;
|
|
2915
|
-
#
|
|
3001
|
+
#n;
|
|
2916
3002
|
#i;
|
|
2917
|
-
#
|
|
2918
|
-
#s;
|
|
2919
|
-
#l;
|
|
3003
|
+
#h;
|
|
2920
3004
|
#g;
|
|
2921
|
-
#
|
|
3005
|
+
#s;
|
|
3006
|
+
#o;
|
|
3007
|
+
#f;
|
|
3008
|
+
#r = null;
|
|
2922
3009
|
#a = null;
|
|
2923
|
-
#o = null;
|
|
2924
3010
|
#d = !1;
|
|
2925
|
-
#
|
|
2926
|
-
#
|
|
3011
|
+
#u = 0;
|
|
3012
|
+
#l = 0;
|
|
2927
3013
|
constructor(t) {
|
|
2928
|
-
this.#t = t.canvas, this.#e = t.getHandleHitboxes, this.#
|
|
3014
|
+
this.#t = t.canvas, this.#e = t.getHandleHitboxes, this.#n = t.getCurrentPrice, this.#i = t.onDrag, this.#h = t.onMissingProtectionDrag, this.#g = t.onMissingProtectionDragEnd, this.#s = t.onMissingProtectionDragCancel, this.#o = t.onTradeModified, this.#f = t.onTradeCloseClicked;
|
|
2929
3015
|
}
|
|
2930
3016
|
cancelActiveInteraction() {
|
|
2931
|
-
this.#
|
|
3017
|
+
this.#a && this.#s?.(), this.#r = null, this.#a = null, this.#d = !1, this.#u = 0, this.#l = 0;
|
|
2932
3018
|
}
|
|
2933
3019
|
handlePointerEvent(t) {
|
|
2934
3020
|
if (!this.isSupportedEventType(t.type)) return !1;
|
|
2935
3021
|
const e = this.getCanvasMousePoint(t);
|
|
2936
|
-
if (t.type === "pointermove" && this.#
|
|
2937
|
-
if (t.type === "pointermove" && this.#
|
|
3022
|
+
if (t.type === "pointermove" && this.#a) return this.handleActiveMissingProtectionDrag(t, e);
|
|
3023
|
+
if (t.type === "pointermove" && this.#r) return this.handleActiveDrag(t, e);
|
|
2938
3024
|
if (t.type === "pointerup")
|
|
2939
|
-
return this.#
|
|
3025
|
+
return this.#a ? this.handleMissingProtectionDragEnd() : this.handleDragEnd();
|
|
2940
3026
|
const i = this.getHoveredHitbox(e);
|
|
2941
3027
|
return i ? this.handleHoveredHitbox(t, i, e) : (this.resetCursorIfIdle(), !1);
|
|
2942
3028
|
}
|
|
@@ -2951,67 +3037,67 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
2951
3037
|
};
|
|
2952
3038
|
}
|
|
2953
3039
|
handleActiveDrag(t, e) {
|
|
2954
|
-
if (!this.#
|
|
3040
|
+
if (!this.#r) return !1;
|
|
2955
3041
|
const i = this.getNextDragPrice(e.y);
|
|
2956
|
-
return this.#
|
|
2957
|
-
trade: this.#
|
|
2958
|
-
type: this.#
|
|
3042
|
+
return this.#r.price = i, this.#i?.({
|
|
3043
|
+
trade: this.#r.trade,
|
|
3044
|
+
type: this.#r.type,
|
|
2959
3045
|
price: i
|
|
2960
3046
|
}), this.consumeEvent(t), !0;
|
|
2961
3047
|
}
|
|
2962
3048
|
handleActiveMissingProtectionDrag(t, e) {
|
|
2963
|
-
if (!this.#
|
|
2964
|
-
const i = e.y - this.#
|
|
3049
|
+
if (!this.#a || !this.isProtectionHandleType(this.#a.type)) return !1;
|
|
3050
|
+
const i = e.y - this.#u, s = c.tradeHandles.missingProtectionHandles.dragActivationThresholdPx;
|
|
2965
3051
|
if (!this.#d && Math.abs(i) < s)
|
|
2966
3052
|
return this.consumeEvent(t), !0;
|
|
2967
3053
|
this.#d = !0;
|
|
2968
3054
|
const r = this.getNextMissingProtectionPrice(e.y);
|
|
2969
|
-
return this.#
|
|
2970
|
-
trade: this.#
|
|
2971
|
-
type: this.#
|
|
3055
|
+
return this.#a.price = r, this.#h?.({
|
|
3056
|
+
trade: this.#a.trade,
|
|
3057
|
+
type: this.#a.type,
|
|
2972
3058
|
price: r
|
|
2973
3059
|
}), this.consumeEvent(t), !0;
|
|
2974
3060
|
}
|
|
2975
3061
|
getNextDragPrice(t) {
|
|
2976
|
-
if (!this.#
|
|
2977
|
-
const e = t - this.#
|
|
2978
|
-
return this.isProtectionHandleType(this.#
|
|
3062
|
+
if (!this.#r) return 0;
|
|
3063
|
+
const e = t - this.#u, i = this.#r.viewport.priceRange / this.#t.height, s = m(this.#l - e * i);
|
|
3064
|
+
return this.isProtectionHandleType(this.#r.type) ? this.constrainExistingProtectionPrice({
|
|
2979
3065
|
price: s,
|
|
2980
|
-
hitbox: this.#
|
|
2981
|
-
type: this.#
|
|
3066
|
+
hitbox: this.#r,
|
|
3067
|
+
type: this.#r.type
|
|
2982
3068
|
}) : s;
|
|
2983
3069
|
}
|
|
2984
3070
|
getNextMissingProtectionPrice(t) {
|
|
2985
|
-
if (!this.#
|
|
2986
|
-
const e =
|
|
3071
|
+
if (!this.#a || !this.isProtectionHandleType(this.#a.type)) return 0;
|
|
3072
|
+
const e = m(this.#a.viewport.minPrice + (this.#t.height - t) / this.#t.height * this.#a.viewport.priceRange);
|
|
2987
3073
|
return this.constrainProtectionPrice({
|
|
2988
3074
|
price: e,
|
|
2989
|
-
hitbox: this.#
|
|
2990
|
-
type: this.#
|
|
3075
|
+
hitbox: this.#a,
|
|
3076
|
+
type: this.#a.type
|
|
2991
3077
|
});
|
|
2992
3078
|
}
|
|
2993
3079
|
handleDragEnd() {
|
|
2994
|
-
return this.#
|
|
3080
|
+
return this.#r && this.modifyActiveDragTrade(), this.#r = null, !1;
|
|
2995
3081
|
}
|
|
2996
3082
|
handleMissingProtectionDragEnd() {
|
|
2997
|
-
return this.#
|
|
2998
|
-
trade: this.#
|
|
2999
|
-
type: this.#
|
|
3000
|
-
price:
|
|
3001
|
-
}) : this.#
|
|
3083
|
+
return this.#a && this.#d && this.isProtectionHandleType(this.#a.type) ? this.#g?.({
|
|
3084
|
+
trade: this.#a.trade,
|
|
3085
|
+
type: this.#a.type,
|
|
3086
|
+
price: m(this.#a.price)
|
|
3087
|
+
}) : this.#s?.(), this.#a = null, this.#d = !1, !1;
|
|
3002
3088
|
}
|
|
3003
3089
|
modifyActiveDragTrade() {
|
|
3004
|
-
if (!this.#
|
|
3005
|
-
const t =
|
|
3006
|
-
if (this.#
|
|
3007
|
-
this.#
|
|
3008
|
-
ticket: this.#
|
|
3090
|
+
if (!this.#r) return;
|
|
3091
|
+
const t = m(this.#r.price);
|
|
3092
|
+
if (this.#r.type === "stopLoss") {
|
|
3093
|
+
this.#o?.({
|
|
3094
|
+
ticket: this.#r.trade.ticket,
|
|
3009
3095
|
sl: t
|
|
3010
3096
|
});
|
|
3011
3097
|
return;
|
|
3012
3098
|
}
|
|
3013
|
-
this.#
|
|
3014
|
-
ticket: this.#
|
|
3099
|
+
this.#o?.({
|
|
3100
|
+
ticket: this.#r.trade.ticket,
|
|
3015
3101
|
tp: t
|
|
3016
3102
|
});
|
|
3017
3103
|
}
|
|
@@ -3031,10 +3117,10 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3031
3117
|
}
|
|
3032
3118
|
handleCloseButtonClick(t) {
|
|
3033
3119
|
if (t.type === "startPrice") {
|
|
3034
|
-
this.#
|
|
3120
|
+
this.#f?.({ ticket: t.trade.ticket });
|
|
3035
3121
|
return;
|
|
3036
3122
|
}
|
|
3037
|
-
this.#
|
|
3123
|
+
this.#o?.({
|
|
3038
3124
|
ticket: t.trade.ticket,
|
|
3039
3125
|
...t.type === "stopLoss" ? { sl: null } : {},
|
|
3040
3126
|
...t.type === "takeProfit" ? { tp: null } : {}
|
|
@@ -3044,13 +3130,13 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3044
3130
|
document.body.style.cursor = t.type === "startPrice" ? "crosshair" : "ns-resize";
|
|
3045
3131
|
}
|
|
3046
3132
|
startDrag(t, e) {
|
|
3047
|
-
this.#
|
|
3133
|
+
this.#r = t, this.#u = e, this.#l = t.price;
|
|
3048
3134
|
}
|
|
3049
3135
|
startMissingProtectionDrag(t, e) {
|
|
3050
|
-
this.#
|
|
3136
|
+
this.#a = t, this.#u = e, this.#d = !1;
|
|
3051
3137
|
}
|
|
3052
3138
|
resetCursorIfIdle() {
|
|
3053
|
-
!this.#
|
|
3139
|
+
!this.#r && !this.#a && (document.body.style.cursor = "crosshair");
|
|
3054
3140
|
}
|
|
3055
3141
|
isPointInsideArea(t, e) {
|
|
3056
3142
|
const i = t.x >= e.x && t.x <= e.x + e.width, s = t.y >= e.y && t.y <= e.y + e.height;
|
|
@@ -3060,12 +3146,12 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3060
3146
|
return t === "stopLoss" || t === "takeProfit";
|
|
3061
3147
|
}
|
|
3062
3148
|
constrainExistingProtectionPrice({ price: t, hitbox: e, type: i }) {
|
|
3063
|
-
const s = this.isBuyTrade(e), r = e.trade.openPrice, n = this.#
|
|
3064
|
-
return
|
|
3149
|
+
const s = this.isBuyTrade(e), r = e.trade.openPrice, n = this.#n?.() ?? 0;
|
|
3150
|
+
return m(i === "takeProfit" ? s ? Math.max(t, r, n) : Math.min(t, r, n) : s ? Math.min(t, n) : Math.max(t, n));
|
|
3065
3151
|
}
|
|
3066
3152
|
constrainProtectionPrice({ price: t, hitbox: e, type: i }) {
|
|
3067
|
-
const s = this.isBuyTrade(e), r = e.trade.openPrice, n = this.#
|
|
3068
|
-
return
|
|
3153
|
+
const s = this.isBuyTrade(e), r = e.trade.openPrice, n = this.#n?.() ?? 0;
|
|
3154
|
+
return m(i === "takeProfit" ? s ? Math.max(t, r, n) : Math.min(t, r, n) : s ? Math.min(t, n) : Math.max(t, n));
|
|
3069
3155
|
}
|
|
3070
3156
|
isBuyTrade(t) {
|
|
3071
3157
|
return String(t.trade.type).toLowerCase().includes("buy");
|
|
@@ -3102,18 +3188,18 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3102
3188
|
if (this.clearCanvas(), !c.volume.visible || !this.viewport || this.candles.length === 0) return;
|
|
3103
3189
|
const t = this.#e, e = this.#t.width, i = this.#t.height, { startIndex: s, endIndex: r } = this.getVisibleRange(e);
|
|
3104
3190
|
if (r < s) return;
|
|
3105
|
-
const n = this.candles.slice(s, r + 1),
|
|
3106
|
-
|
|
3191
|
+
const n = this.candles.slice(s, r + 1), a = this.getMaxVolume(n);
|
|
3192
|
+
a <= 0 || this.drawVolumeBars({
|
|
3107
3193
|
ctx: t,
|
|
3108
3194
|
candles: n,
|
|
3109
3195
|
startIndex: s,
|
|
3110
|
-
maxVolume:
|
|
3196
|
+
maxVolume: a,
|
|
3111
3197
|
chartHeight: i
|
|
3112
3198
|
});
|
|
3113
3199
|
}
|
|
3114
3200
|
drawVolumeBars({ ctx: t, candles: e, startIndex: i, maxVolume: s, chartHeight: r }) {
|
|
3115
|
-
t.save(), t.globalAlpha = this.opacity, e.forEach((n,
|
|
3116
|
-
const
|
|
3201
|
+
t.save(), t.globalAlpha = this.opacity, e.forEach((n, a) => {
|
|
3202
|
+
const o = i + a, l = this.getCandleX(o);
|
|
3117
3203
|
this.drawSingleVolumeBar({
|
|
3118
3204
|
ctx: t,
|
|
3119
3205
|
candle: n,
|
|
@@ -3127,8 +3213,8 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3127
3213
|
if (!this.viewport || e.volume <= 0) return;
|
|
3128
3214
|
const n = this.getVolumeAreaHeight(r);
|
|
3129
3215
|
if (n <= 0) return;
|
|
3130
|
-
const
|
|
3131
|
-
t.fillStyle = this.getVolumeBarColor(e), t.fillRect(i, l, d,
|
|
3216
|
+
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);
|
|
3217
|
+
t.fillStyle = this.getVolumeBarColor(e), t.fillRect(i, l, d, o);
|
|
3132
3218
|
}
|
|
3133
3219
|
getVisibleRange(t) {
|
|
3134
3220
|
if (!this.viewport) return {
|
|
@@ -3159,30 +3245,107 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3159
3245
|
clearCanvas() {
|
|
3160
3246
|
this.#e.clearRect(0, 0, this.#t.width, this.#t.height);
|
|
3161
3247
|
}
|
|
3162
|
-
},
|
|
3248
|
+
}, se = {
|
|
3249
|
+
center: {
|
|
3250
|
+
textAlign: "center",
|
|
3251
|
+
textBaseline: "middle"
|
|
3252
|
+
},
|
|
3253
|
+
"top-center": {
|
|
3254
|
+
textAlign: "center",
|
|
3255
|
+
textBaseline: "top"
|
|
3256
|
+
},
|
|
3257
|
+
"bottom-center": {
|
|
3258
|
+
textAlign: "center",
|
|
3259
|
+
textBaseline: "bottom"
|
|
3260
|
+
},
|
|
3261
|
+
"left-center": {
|
|
3262
|
+
textAlign: "left",
|
|
3263
|
+
textBaseline: "middle"
|
|
3264
|
+
},
|
|
3265
|
+
"right-center": {
|
|
3266
|
+
textAlign: "right",
|
|
3267
|
+
textBaseline: "middle"
|
|
3268
|
+
}
|
|
3269
|
+
}, re = ({ position: t, width: e, padding: i }) => {
|
|
3270
|
+
switch (t) {
|
|
3271
|
+
case "left-center":
|
|
3272
|
+
return i;
|
|
3273
|
+
case "right-center":
|
|
3274
|
+
return e - i;
|
|
3275
|
+
default:
|
|
3276
|
+
return e / 2;
|
|
3277
|
+
}
|
|
3278
|
+
}, ne = ({ position: t, height: e, padding: i }) => {
|
|
3279
|
+
switch (t) {
|
|
3280
|
+
case "top-center":
|
|
3281
|
+
return i;
|
|
3282
|
+
case "bottom-center":
|
|
3283
|
+
return e - i;
|
|
3284
|
+
default:
|
|
3285
|
+
return e / 2;
|
|
3286
|
+
}
|
|
3287
|
+
}, ae = (t) => ({
|
|
3288
|
+
...se[t.position],
|
|
3289
|
+
x: re(t),
|
|
3290
|
+
y: ne(t)
|
|
3291
|
+
}), oe = (t) => Number.isFinite(t) ? Math.min(Math.max(t, 0), 1) : 1, le = class {
|
|
3292
|
+
#t;
|
|
3293
|
+
#e;
|
|
3294
|
+
#n;
|
|
3295
|
+
#i = 0;
|
|
3296
|
+
#h = 0;
|
|
3297
|
+
constructor(t) {
|
|
3298
|
+
this.#t = t.canvas, this.#n = t.config;
|
|
3299
|
+
const e = this.#t.getContext("2d");
|
|
3300
|
+
if (!e) throw new Error("Canvas 2D context not supported");
|
|
3301
|
+
this.#e = e;
|
|
3302
|
+
}
|
|
3303
|
+
setConfig(t) {
|
|
3304
|
+
this.#n = t;
|
|
3305
|
+
}
|
|
3306
|
+
resize(t, e) {
|
|
3307
|
+
this.#i = t, this.#h = e;
|
|
3308
|
+
}
|
|
3309
|
+
render() {
|
|
3310
|
+
const t = this.#e, { text: e } = this.#n;
|
|
3311
|
+
if (t.setTransform(1, 0, 0, 1, 0, 0), t.clearRect(0, 0, this.#t.width, this.#t.height), !e || this.#i <= 0 || this.#h <= 0) return;
|
|
3312
|
+
const { x: i, y: s, textAlign: r, textBaseline: n } = ae({
|
|
3313
|
+
position: this.#n.position,
|
|
3314
|
+
width: this.#i,
|
|
3315
|
+
height: this.#h,
|
|
3316
|
+
padding: this.#n.padding
|
|
3317
|
+
});
|
|
3318
|
+
t.save(), t.font = this.#g(), t.textAlign = r, t.textBaseline = n, t.fillStyle = this.#n.color, t.globalAlpha = oe(this.#n.opacity), t.fillText(e, i, s), t.restore();
|
|
3319
|
+
}
|
|
3320
|
+
#g() {
|
|
3321
|
+
const { fontSize: t, fontWeight: e, fontFamily: i } = this.#n;
|
|
3322
|
+
return `${e} ${t}px ${i}`;
|
|
3323
|
+
}
|
|
3324
|
+
}, M = (t) => {
|
|
3163
3325
|
const e = document.createElement("canvas");
|
|
3164
3326
|
return e.className = t, e;
|
|
3165
|
-
},
|
|
3327
|
+
}, he = (t, e) => {
|
|
3166
3328
|
const i = document.createElement("div");
|
|
3167
3329
|
i.className = "trading-reload-chart", i.style.backgroundColor = e, i.tabIndex = 0;
|
|
3168
3330
|
const s = document.createElement("div");
|
|
3169
3331
|
s.className = "trading-reload-chart__layout";
|
|
3170
3332
|
const r = document.createElement("div");
|
|
3171
3333
|
r.className = "trading-reload-chart__stack";
|
|
3172
|
-
const n =
|
|
3173
|
-
r.append(n,
|
|
3174
|
-
const
|
|
3175
|
-
return s.append(r,
|
|
3334
|
+
const n = M("trading-reload-chart__volume"), a = M("trading-reload-chart__watermark"), o = M("trading-reload-chart__plot"), l = M("trading-reload-chart__shapes"), d = M("trading-reload-chart__trades"), u = M("trading-reload-chart__overlay"), g = M("trading-reload-chart__axis-x");
|
|
3335
|
+
r.append(n, a, o, l, d, u, g);
|
|
3336
|
+
const p = M("trading-reload-chart__axis-y");
|
|
3337
|
+
return s.append(r, p), i.append(s), t.append(i), {
|
|
3176
3338
|
root: i,
|
|
3177
3339
|
layout: s,
|
|
3178
3340
|
stack: r,
|
|
3179
3341
|
volumeCanvas: n,
|
|
3342
|
+
watermarkCanvas: a,
|
|
3180
3343
|
candleCanvas: o,
|
|
3181
|
-
shapesCanvas:
|
|
3182
|
-
tradesCanvas:
|
|
3183
|
-
overlayCanvas:
|
|
3184
|
-
axisXCanvas:
|
|
3185
|
-
axisYCanvas:
|
|
3344
|
+
shapesCanvas: l,
|
|
3345
|
+
tradesCanvas: d,
|
|
3346
|
+
overlayCanvas: u,
|
|
3347
|
+
axisXCanvas: g,
|
|
3348
|
+
axisYCanvas: p,
|
|
3186
3349
|
interactionTarget: s
|
|
3187
3350
|
};
|
|
3188
3351
|
}, gt = (t) => typeof t == "object" && t !== null && !Array.isArray(t), Lt = (t, e) => {
|
|
@@ -3201,76 +3364,113 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3201
3364
|
}, ft = (t) => Lt(c, t ?? {}), pt = (t, e) => e === void 0 || t.time >= 1e12 ? t : {
|
|
3202
3365
|
...t,
|
|
3203
3366
|
time: t.time * 1e3 - e
|
|
3204
|
-
},
|
|
3367
|
+
}, de = 0, ce = 50, ue = (t) => !t.ctrlKey && !t.metaKey || t.deltaMode === de && Math.abs(t.deltaY) < ce ? "x" : "y", ge = 12, fe = class {
|
|
3205
3368
|
#t;
|
|
3206
3369
|
#e;
|
|
3207
|
-
#
|
|
3370
|
+
#n;
|
|
3208
3371
|
#i = null;
|
|
3209
|
-
#
|
|
3210
|
-
#s = null;
|
|
3211
|
-
#l = null;
|
|
3372
|
+
#h = null;
|
|
3212
3373
|
#g = null;
|
|
3213
|
-
#
|
|
3214
|
-
#a = null;
|
|
3374
|
+
#s = null;
|
|
3215
3375
|
#o = null;
|
|
3216
|
-
#d = null;
|
|
3217
|
-
#h = null;
|
|
3218
|
-
#m = !1;
|
|
3219
|
-
#y = 0;
|
|
3220
|
-
#w = !1;
|
|
3221
|
-
#T = 0;
|
|
3222
|
-
#L = 0;
|
|
3223
3376
|
#f = null;
|
|
3224
|
-
#
|
|
3225
|
-
#
|
|
3226
|
-
#
|
|
3377
|
+
#r = null;
|
|
3378
|
+
#a = null;
|
|
3379
|
+
#d = null;
|
|
3380
|
+
#u = null;
|
|
3381
|
+
#l = null;
|
|
3382
|
+
#x = !1;
|
|
3383
|
+
#P = 0;
|
|
3384
|
+
#S = !1;
|
|
3385
|
+
#D = 0;
|
|
3386
|
+
#A = 0;
|
|
3387
|
+
#p = null;
|
|
3388
|
+
#v = null;
|
|
3389
|
+
#T = null;
|
|
3390
|
+
#L = null;
|
|
3391
|
+
#X = !1;
|
|
3392
|
+
#b = !1;
|
|
3393
|
+
#I = null;
|
|
3394
|
+
#y = null;
|
|
3227
3395
|
constructor(t, e) {
|
|
3228
|
-
this.#t = t, this.#e = e, this.#
|
|
3396
|
+
this.#t = t, this.#e = e, this.#n = ft(e.config), this.#i = he(t, this.#n.colors.background), this.#l = new Ot({
|
|
3229
3397
|
canvas: this.#i.overlayCanvas,
|
|
3230
|
-
crosshairColor: this.#
|
|
3231
|
-
crosshairThickness: this.#
|
|
3232
|
-
crosshairStyle: this.#
|
|
3233
|
-
}), this.#
|
|
3398
|
+
crosshairColor: this.#n.crosshair.color,
|
|
3399
|
+
crosshairThickness: this.#n.crosshair.thickness,
|
|
3400
|
+
crosshairStyle: this.#n.crosshair.style
|
|
3401
|
+
}), this.#g = new le({
|
|
3402
|
+
canvas: this.#i.watermarkCanvas,
|
|
3403
|
+
config: this.#n.watermark
|
|
3404
|
+
}), this.#N(), this.#_(), this.#W(), this.updateProps(e);
|
|
3234
3405
|
}
|
|
3235
3406
|
updateProps(t) {
|
|
3236
3407
|
const e = this.#e.activeShapeTool;
|
|
3237
|
-
this.#e = t, this.#
|
|
3408
|
+
this.#e = t, this.#n = ft(t.config), this.#i && (this.#i.root.style.backgroundColor = this.#n.colors.background, this.#i.layout.style.setProperty("--axis-x-height", `${this.#n.axis.axisX.height}px`)), !this.#x && t.candles.length > 0 && this.#z(t.candles), this.#s && (t.activeShapeTool !== e && this.#$(t.activeShapeTool), this.#o?.setConfig(this.#n.shapes), this.#o?.setShapes(t.shapes), this.#o?.setActiveTool(t.activeShapeTool), this.#g?.setConfig(this.#n.watermark), this.#f?.setConfig(this.#n.shapes.previousDayHighLow ?? null), this.#f?.setPreviousDay(t.previousDay), this.#r?.setClosedTrades(t.closedTrades ?? []), this.#k(), this.#K(), this.#c(), this.#C());
|
|
3238
3409
|
}
|
|
3239
3410
|
resetChartView() {
|
|
3240
|
-
this.#s?.resetView(), this.#c();
|
|
3411
|
+
this.#s?.resetView(), this.#c(), this.#C();
|
|
3412
|
+
}
|
|
3413
|
+
setView(t) {
|
|
3414
|
+
this.#s && (this.#X = !0, this.#s.setViewState(t), this.#X = !1, this.#I = this.#s.getViewState(), this.#c());
|
|
3415
|
+
}
|
|
3416
|
+
getView() {
|
|
3417
|
+
return this.#s?.getViewState() ?? null;
|
|
3418
|
+
}
|
|
3419
|
+
setCursor(t) {
|
|
3420
|
+
if (!t) {
|
|
3421
|
+
this.#b = !0, this.#V(), this.#b = !1, this.#y = null;
|
|
3422
|
+
return;
|
|
3423
|
+
}
|
|
3424
|
+
if (!this.#s || !this.#l || !this.#i) return;
|
|
3425
|
+
const e = this.#s.setCursorState(t);
|
|
3426
|
+
e && (this.#b = !0, this.#l.setPosition(e.x, e.y), this.#d?.setCrosshair({
|
|
3427
|
+
visible: !0,
|
|
3428
|
+
x: e.x,
|
|
3429
|
+
candle: e.candle
|
|
3430
|
+
}), this.#u?.setCrosshair({
|
|
3431
|
+
visible: !0,
|
|
3432
|
+
y: e.y,
|
|
3433
|
+
price: t.price
|
|
3434
|
+
}), this.#H(), this.#l.render(), this.#b = !1, this.#y = {
|
|
3435
|
+
...t,
|
|
3436
|
+
time: e.candle.time
|
|
3437
|
+
});
|
|
3438
|
+
}
|
|
3439
|
+
hideCursor() {
|
|
3440
|
+
this.setCursor(null);
|
|
3241
3441
|
}
|
|
3242
3442
|
destroy() {
|
|
3243
|
-
this.#
|
|
3443
|
+
this.#L?.abort(), this.#L = null, this.#T?.disconnect(), this.#T = null, this.#i?.root.remove(), this.#i = null, this.#h = null, this.#g = null, this.#s = null, this.#o = null, this.#f = null, this.#r = null, this.#a = null, this.#d = null, this.#u = null, this.#l = null, this.#p = null, this.#x = !1;
|
|
3244
3444
|
}
|
|
3245
|
-
#
|
|
3246
|
-
if (!this.#i || this.#
|
|
3445
|
+
#z(t) {
|
|
3446
|
+
if (!this.#i || this.#x) return;
|
|
3247
3447
|
const e = t.map((s) => pt(s, this.#e.brokerTimezoneOffsetMs));
|
|
3248
|
-
this.#
|
|
3448
|
+
this.#h = new ie({
|
|
3249
3449
|
canvas: this.#i.volumeCanvas,
|
|
3250
3450
|
candles: e,
|
|
3251
|
-
bullishColor: this.#
|
|
3252
|
-
bearishColor: this.#
|
|
3253
|
-
opacity: this.#
|
|
3254
|
-
height: this.#
|
|
3255
|
-
bottomOffset: this.#
|
|
3256
|
-
minBarHeight: this.#
|
|
3451
|
+
bullishColor: this.#n.volume.bullishColor,
|
|
3452
|
+
bearishColor: this.#n.volume.bearishColor,
|
|
3453
|
+
opacity: this.#n.volume.opacity,
|
|
3454
|
+
height: this.#n.volume.height,
|
|
3455
|
+
bottomOffset: this.#n.volume.bottomOffset,
|
|
3456
|
+
minBarHeight: this.#n.volume.minBarHeight
|
|
3257
3457
|
}), this.#s = new Nt({
|
|
3258
3458
|
canvas: this.#i.candleCanvas,
|
|
3259
3459
|
candles: e,
|
|
3260
|
-
baseCandleWidth: this.#
|
|
3261
|
-
baseCandleGap: this.#
|
|
3262
|
-
bullishColor: this.#
|
|
3263
|
-
bearishColor: this.#
|
|
3264
|
-
autoFollowLatestCandle: this.#
|
|
3265
|
-
autoFollowThresholdCandles: this.#
|
|
3266
|
-
rightOffsetCandles: this.#
|
|
3267
|
-
}), this.#
|
|
3460
|
+
baseCandleWidth: this.#n.candles.defaultWidth,
|
|
3461
|
+
baseCandleGap: this.#n.candles.defaultGap,
|
|
3462
|
+
bullishColor: this.#n.colors.bullish,
|
|
3463
|
+
bearishColor: this.#n.colors.bearish,
|
|
3464
|
+
autoFollowLatestCandle: this.#n.candles.autoFollowLatestCandle,
|
|
3465
|
+
autoFollowThresholdCandles: this.#n.candles.autoFollowThresholdCandles,
|
|
3466
|
+
rightOffsetCandles: this.#n.candles.rightOffsetCandles
|
|
3467
|
+
}), this.#o = new Zt({
|
|
3268
3468
|
canvas: this.#i.shapesCanvas,
|
|
3269
3469
|
activeSymbol: this.#e.activeSymbol,
|
|
3270
3470
|
candles: e,
|
|
3271
3471
|
shapes: this.#e.shapes,
|
|
3272
3472
|
activeTool: this.#e.activeShapeTool,
|
|
3273
|
-
config: this.#
|
|
3473
|
+
config: this.#n.shapes,
|
|
3274
3474
|
onShapeAdded: (s) => {
|
|
3275
3475
|
this.#e.onShapeAdded?.(s);
|
|
3276
3476
|
},
|
|
@@ -3291,43 +3491,43 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3291
3491
|
}
|
|
3292
3492
|
});
|
|
3293
3493
|
const i = this.#i.shapesCanvas.getContext("2d");
|
|
3294
|
-
i && (this.#
|
|
3494
|
+
i && (this.#f = new _t({
|
|
3295
3495
|
ctx: i,
|
|
3296
|
-
config: this.#
|
|
3297
|
-
}), this.#
|
|
3496
|
+
config: this.#n.shapes.previousDayHighLow ?? null
|
|
3497
|
+
}), this.#f.setPreviousDay(this.#e.previousDay)), this.#r = new Qt({ canvas: this.#i.tradesCanvas }), this.#r.setCandles(e), this.#r.setClosedTrades(this.#e.closedTrades ?? []), this.#k(), this.#d = new Vt({
|
|
3298
3498
|
canvas: this.#i.axisXCanvas,
|
|
3299
3499
|
candles: e
|
|
3300
|
-
}), this.#
|
|
3500
|
+
}), this.#u = new Et({ canvas: this.#i.axisYCanvas }), this.#a = new ee({
|
|
3301
3501
|
canvas: this.#i.tradesCanvas,
|
|
3302
|
-
getHandleHitboxes: () => this.#
|
|
3502
|
+
getHandleHitboxes: () => this.#m() ? [] : this.#r?.handleHitboxes ?? [],
|
|
3303
3503
|
getCurrentPrice: () => this.#s?.liveCandle?.close ?? 0,
|
|
3304
|
-
onDrag: (s) => this.#
|
|
3305
|
-
onMissingProtectionDrag: (s) => this.#
|
|
3306
|
-
onMissingProtectionDragEnd: (s) => this.#
|
|
3307
|
-
onMissingProtectionDragCancel: () => this.#
|
|
3308
|
-
onTradeModified: (s) => this.#
|
|
3504
|
+
onDrag: (s) => this.#J(s),
|
|
3505
|
+
onMissingProtectionDrag: (s) => this.#j(s),
|
|
3506
|
+
onMissingProtectionDragEnd: (s) => this.#Z(s),
|
|
3507
|
+
onMissingProtectionDragCancel: () => this.#Q(),
|
|
3508
|
+
onTradeModified: (s) => this.#F(s),
|
|
3309
3509
|
onTradeCloseClicked: (s) => this.#e.onTradeClose?.(s)
|
|
3310
|
-
}), this.#
|
|
3510
|
+
}), this.#x = !0, this.#c();
|
|
3311
3511
|
}
|
|
3312
|
-
#
|
|
3512
|
+
#N() {
|
|
3313
3513
|
if (!this.#i) return;
|
|
3314
|
-
this.#
|
|
3315
|
-
const { signal: t } = this.#
|
|
3316
|
-
e.addEventListener("pointerdown", (i) => this.#
|
|
3514
|
+
this.#L = new AbortController();
|
|
3515
|
+
const { signal: t } = this.#L, e = this.#i.interactionTarget;
|
|
3516
|
+
e.addEventListener("pointerdown", (i) => this.#it(i), { signal: t }), e.addEventListener("pointerup", (i) => this.#rt(i), { signal: t }), e.addEventListener("pointermove", (i) => this.#st(i), { signal: t }), e.addEventListener("pointerenter", (i) => this.#nt(i), { signal: t }), e.addEventListener("pointerleave", () => this.#at(), { signal: t }), e.addEventListener("contextmenu", (i) => this.#ot(i), { signal: t }), e.addEventListener("dblclick", (i) => this.#lt(i), { signal: t }), e.addEventListener("wheel", (i) => this.#tt(i), {
|
|
3317
3517
|
passive: !1,
|
|
3318
3518
|
signal: t
|
|
3319
|
-
}), this.#i.axisXCanvas.addEventListener("pointerenter", (i) => this.#
|
|
3519
|
+
}), this.#i.axisXCanvas.addEventListener("pointerenter", (i) => this.#Y(i), { signal: t }), this.#i.axisXCanvas.addEventListener("pointerdown", (i) => this.#E(i, "x"), { signal: t }), this.#i.axisXCanvas.addEventListener("pointermove", (i) => this.#O(i), { signal: t }), this.#i.axisXCanvas.addEventListener("pointerup", (i) => this.#R(i), { signal: t }), this.#i.axisXCanvas.addEventListener("pointercancel", (i) => this.#R(i), { signal: t }), this.#i.axisYCanvas.addEventListener("pointerenter", (i) => this.#Y(i), { signal: t }), this.#i.axisYCanvas.addEventListener("pointerdown", (i) => this.#E(i, "y"), { signal: t }), this.#i.axisYCanvas.addEventListener("pointermove", (i) => this.#O(i), { signal: t }), this.#i.axisYCanvas.addEventListener("pointerup", (i) => this.#R(i), { signal: t }), this.#i.axisYCanvas.addEventListener("pointercancel", (i) => this.#R(i), { signal: t }), this.#i.axisYCanvas.addEventListener("wheel", (i) => this.#et(i), {
|
|
3320
3520
|
passive: !1,
|
|
3321
3521
|
signal: t
|
|
3322
|
-
}), document.addEventListener("keydown", (i) => this.#
|
|
3522
|
+
}), document.addEventListener("keydown", (i) => this.#ht(i), { signal: t });
|
|
3323
3523
|
}
|
|
3324
|
-
#
|
|
3325
|
-
this.#
|
|
3326
|
-
this.#
|
|
3327
|
-
}), this.#
|
|
3524
|
+
#_() {
|
|
3525
|
+
this.#T = new ResizeObserver(() => {
|
|
3526
|
+
this.#W(), this.#c(), this.#C();
|
|
3527
|
+
}), this.#T.observe(this.#t);
|
|
3328
3528
|
}
|
|
3329
|
-
#
|
|
3330
|
-
const t = this.#
|
|
3529
|
+
#G() {
|
|
3530
|
+
const t = this.#n.axis.axisY.width, e = this.#n.axis.axisX.height, i = this.#t.clientWidth, s = this.#t.clientHeight;
|
|
3331
3531
|
return {
|
|
3332
3532
|
axisYWidth: t,
|
|
3333
3533
|
axisXHeight: e,
|
|
@@ -3335,192 +3535,230 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3335
3535
|
plotHeight: Math.max(0, s - e)
|
|
3336
3536
|
};
|
|
3337
3537
|
}
|
|
3338
|
-
#
|
|
3538
|
+
#w(t, e, i) {
|
|
3339
3539
|
t.width = e, t.height = i;
|
|
3340
3540
|
}
|
|
3341
|
-
#
|
|
3541
|
+
#W() {
|
|
3342
3542
|
if (!this.#i) return;
|
|
3343
|
-
const { plotWidth: t, plotHeight: e, axisYWidth: i, axisXHeight: s } = this.#
|
|
3344
|
-
if (this.#s && this.#
|
|
3345
|
-
const r = t - this.#
|
|
3543
|
+
const { plotWidth: t, plotHeight: e, axisYWidth: i, axisXHeight: s } = this.#G();
|
|
3544
|
+
if (this.#s && this.#P > 0 && t !== this.#P) {
|
|
3545
|
+
const r = t - this.#P;
|
|
3346
3546
|
this.#s.panHorizontally(r);
|
|
3347
3547
|
}
|
|
3348
|
-
this.#
|
|
3548
|
+
this.#P = t, this.#w(this.#i.volumeCanvas, t, e), this.#w(this.#i.watermarkCanvas, t, e), this.#w(this.#i.candleCanvas, t, e), this.#w(this.#i.shapesCanvas, t, e), this.#w(this.#i.overlayCanvas, t, e), this.#w(this.#i.tradesCanvas, t, e), this.#w(this.#i.axisXCanvas, t, s), this.#w(this.#i.axisYCanvas, i, e), this.#g?.resize(t, e);
|
|
3349
3549
|
}
|
|
3350
3550
|
#H() {
|
|
3351
|
-
this.#s && (this.#
|
|
3551
|
+
this.#s && (this.#d?.setCandles(this.#s.candles), this.#d?.setViewport(this.#s.viewport), this.#d?.render(), this.#u?.setViewport(this.#s.viewport), this.#u?.render());
|
|
3352
3552
|
}
|
|
3353
3553
|
#c() {
|
|
3354
|
-
this.#s && (this.#
|
|
3554
|
+
this.#s && (this.#h?.setCandles(this.#s.candles), this.#h?.setLiveCandle(this.#s.liveCandle), this.#h?.setViewport(this.#s.viewport), this.#h?.render(), this.#g?.render(), this.#s.render(), this.#o?.setCandles(this.#s.candles), this.#o?.setViewport(this.#s.viewport), this.#o?.render(), this.#f?.setViewport(this.#s.viewport), this.#f?.render(), this.#r?.setCandles(this.#s.candles), this.#r?.setViewport(this.#s.viewport), this.#r?.isDragging ? this.#r.renderLiveFeed() : this.#r?.render(), this.#H(), this.#l?.render());
|
|
3355
3555
|
}
|
|
3356
|
-
#
|
|
3556
|
+
#m() {
|
|
3357
3557
|
return this.#e.activeShapeTool !== null;
|
|
3358
3558
|
}
|
|
3359
|
-
#
|
|
3360
|
-
|
|
3559
|
+
#C() {
|
|
3560
|
+
if (this.#X) return;
|
|
3561
|
+
const t = this.#s?.getViewState() ?? null;
|
|
3562
|
+
!t || this.#U(this.#I, t) || (this.#I = t, this.#e.onViewChange?.(t));
|
|
3361
3563
|
}
|
|
3362
|
-
#
|
|
3564
|
+
#M(t) {
|
|
3565
|
+
if (!this.#b) {
|
|
3566
|
+
if (!t) {
|
|
3567
|
+
if (this.#y === null) return;
|
|
3568
|
+
this.#y = null, this.#e.onCursorMove?.(null);
|
|
3569
|
+
return;
|
|
3570
|
+
}
|
|
3571
|
+
this.#y !== null && this.#y.time === t.time && this.#y.price === t.price || (this.#y = t, this.#e.onCursorMove?.(t));
|
|
3572
|
+
}
|
|
3573
|
+
}
|
|
3574
|
+
#U(t, e) {
|
|
3575
|
+
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;
|
|
3576
|
+
}
|
|
3577
|
+
#$(t) {
|
|
3578
|
+
t !== null && (this.#S = !1, this.#r?.setIsDragging(!1), this.#a?.cancelActiveInteraction()), this.#o?.setActiveTool(t);
|
|
3579
|
+
}
|
|
3580
|
+
#q() {
|
|
3363
3581
|
const t = this.#e.openTrades ?? [];
|
|
3364
|
-
return this.#
|
|
3582
|
+
return this.#v ? t.map((e) => e.ticket !== this.#v?.ticket ? e : {
|
|
3365
3583
|
...e,
|
|
3366
|
-
...this.#
|
|
3367
|
-
...this.#
|
|
3584
|
+
...this.#v.sl !== void 0 ? { sl: this.#v.sl } : {},
|
|
3585
|
+
...this.#v.tp !== void 0 ? { tp: this.#v.tp } : {}
|
|
3368
3586
|
}) : t;
|
|
3369
3587
|
}
|
|
3370
|
-
#
|
|
3371
|
-
this.#
|
|
3588
|
+
#k() {
|
|
3589
|
+
this.#r?.setTrades(this.#q());
|
|
3372
3590
|
}
|
|
3373
|
-
#
|
|
3591
|
+
#K() {
|
|
3374
3592
|
const t = this.#e.liveCandle;
|
|
3375
3593
|
if (!t || !this.#s) return;
|
|
3376
3594
|
const e = pt(t, this.#e.brokerTimezoneOffsetMs);
|
|
3377
|
-
this.#s.updateLiveCandle(e), this.#
|
|
3595
|
+
this.#s.updateLiveCandle(e), this.#r?.setLiveCandle(this.#s.liveCandle), this.#r?.setCandles(this.#s.candles);
|
|
3378
3596
|
}
|
|
3379
|
-
#
|
|
3380
|
-
this.#
|
|
3597
|
+
#J({ trade: t, type: e, price: i }) {
|
|
3598
|
+
this.#r && (this.#r.setIsDragging(!0), this.#v = {
|
|
3381
3599
|
ticket: t.ticket,
|
|
3382
3600
|
...e === "stopLoss" ? { sl: i } : {},
|
|
3383
3601
|
...e === "takeProfit" ? { tp: i } : {}
|
|
3384
|
-
}, this.#
|
|
3602
|
+
}, this.#k(), this.#r.render());
|
|
3385
3603
|
}
|
|
3386
|
-
#
|
|
3387
|
-
this.#
|
|
3604
|
+
#j({ trade: t, type: e, price: i }) {
|
|
3605
|
+
this.#r?.viewport && (this.#r.setIsDragging(!0), this.#r.setTemporaryProtectionDrag({
|
|
3388
3606
|
visible: !0,
|
|
3389
3607
|
trade: t,
|
|
3390
3608
|
type: e,
|
|
3391
3609
|
price: i,
|
|
3392
|
-
viewport: this.#
|
|
3393
|
-
}), this.#
|
|
3610
|
+
viewport: this.#r.viewport
|
|
3611
|
+
}), this.#r.render());
|
|
3394
3612
|
}
|
|
3395
|
-
#
|
|
3396
|
-
this.#
|
|
3613
|
+
#Z({ trade: t, type: e, price: i }) {
|
|
3614
|
+
this.#r?.setIsDragging(!1), this.#F({
|
|
3397
3615
|
ticket: t.ticket,
|
|
3398
3616
|
...e === "stopLoss" ? { sl: i } : {},
|
|
3399
3617
|
...e === "takeProfit" ? { tp: i } : {}
|
|
3400
3618
|
});
|
|
3401
3619
|
}
|
|
3402
|
-
#
|
|
3403
|
-
this.#
|
|
3620
|
+
#Q() {
|
|
3621
|
+
this.#r?.setIsDragging(!1), this.#r?.clearTemporaryProtectionDrag(), this.#r?.render();
|
|
3404
3622
|
}
|
|
3405
|
-
#
|
|
3406
|
-
this.#
|
|
3623
|
+
#F(t) {
|
|
3624
|
+
this.#r?.setIsDragging(!1), this.#v = null, this.#r?.clearTemporaryProtectionDrag(), this.#e.onTradeModify?.(t), this.#k(), this.#r?.render();
|
|
3407
3625
|
}
|
|
3408
|
-
#
|
|
3409
|
-
if (!this.#
|
|
3410
|
-
if (!this.#s)
|
|
3411
|
-
this.#
|
|
3412
|
-
return;
|
|
3413
|
-
}
|
|
3626
|
+
#B(t) {
|
|
3627
|
+
if (!this.#l || !this.#i) return null;
|
|
3628
|
+
if (!this.#s)
|
|
3629
|
+
return this.#l.updateMousePosition(t.clientX, t.clientY), this.#l.render(), null;
|
|
3414
3630
|
const e = vt(this.#i.overlayCanvas, t), i = this.#s.getNearestCandleIndexByX(e.x), s = i === null ? null : this.#s.candles[i] ?? null, r = i === null ? e.x : this.#s.getRawCandleSnapX(e.x);
|
|
3415
|
-
this.#
|
|
3416
|
-
const n = this.#s.getPriceAtY(this.#
|
|
3417
|
-
this.#
|
|
3631
|
+
this.#l.updateMousePosition(t.clientX, t.clientY, { snapX: r });
|
|
3632
|
+
const n = this.#s.getPriceAtY(this.#l.mouseY);
|
|
3633
|
+
return this.#u?.setCrosshair({
|
|
3418
3634
|
visible: !0,
|
|
3419
|
-
y: this.#
|
|
3635
|
+
y: this.#l.mouseY,
|
|
3420
3636
|
price: n
|
|
3421
|
-
}), this.#
|
|
3637
|
+
}), this.#d?.setCrosshair({
|
|
3422
3638
|
visible: !0,
|
|
3423
|
-
x: this.#
|
|
3639
|
+
x: this.#l.mouseX,
|
|
3424
3640
|
candle: s
|
|
3425
|
-
}), this.#H(), this.#
|
|
3641
|
+
}), this.#H(), this.#l.render(), s ? {
|
|
3642
|
+
time: s.time,
|
|
3643
|
+
price: n
|
|
3644
|
+
} : null;
|
|
3426
3645
|
}
|
|
3427
|
-
#
|
|
3428
|
-
this.#
|
|
3646
|
+
#V() {
|
|
3647
|
+
this.#l?.hide(), this.#d?.hideCrosshair(), this.#u?.hideCrosshair(), this.#H(), this.#l?.render();
|
|
3429
3648
|
}
|
|
3430
|
-
#
|
|
3431
|
-
if (!this.#s || !this.#
|
|
3432
|
-
this.#
|
|
3649
|
+
#tt(t) {
|
|
3650
|
+
if (!this.#s || !this.#r) return;
|
|
3651
|
+
this.#m() || this.#a?.handlePointerEvent(t), t.preventDefault();
|
|
3433
3652
|
const e = t.deltaY < 0 ? 1 : -1;
|
|
3434
|
-
t
|
|
3653
|
+
ue(t) === "y" ? this.#s.zoomVertically(e) : this.#s.zoomHorizontally(e), this.#c(), this.#C();
|
|
3435
3654
|
}
|
|
3436
|
-
|
|
3655
|
+
#et(t) {
|
|
3437
3656
|
if (!this.#s) return;
|
|
3438
3657
|
t.preventDefault(), t.stopPropagation();
|
|
3439
3658
|
const e = t.deltaY < 0 ? 1 : -1;
|
|
3440
|
-
this.#s.zoomVertically(e), this.#c();
|
|
3659
|
+
this.#s.zoomVertically(e), this.#c(), this.#C();
|
|
3441
3660
|
}
|
|
3442
|
-
#
|
|
3661
|
+
#Y(t) {
|
|
3443
3662
|
const e = t.currentTarget;
|
|
3444
3663
|
e.style.cursor = e === this.#i?.axisXCanvas ? "ew-resize" : "ns-resize";
|
|
3445
3664
|
}
|
|
3446
|
-
#
|
|
3447
|
-
t.stopPropagation(), t.button === 0 && (t.currentTarget.setPointerCapture(t.pointerId), this.#
|
|
3665
|
+
#E(t, e) {
|
|
3666
|
+
t.stopPropagation(), t.button === 0 && (t.currentTarget.setPointerCapture(t.pointerId), this.#p = {
|
|
3448
3667
|
axis: e,
|
|
3449
3668
|
lastClientPosition: e === "x" ? t.clientX : t.clientY,
|
|
3450
3669
|
pointerId: t.pointerId
|
|
3451
3670
|
}, t.preventDefault());
|
|
3452
3671
|
}
|
|
3453
|
-
#
|
|
3672
|
+
#O(t) {
|
|
3454
3673
|
t.stopPropagation();
|
|
3455
3674
|
const e = t.currentTarget, i = e === this.#i?.axisXCanvas ? "x" : "y";
|
|
3456
|
-
if (e.style.cursor = i === "x" ? "ew-resize" : "ns-resize", !this.#
|
|
3457
|
-
const s = i === "x" ? t.clientX : t.clientY, r = s - this.#
|
|
3458
|
-
if (this.#
|
|
3459
|
-
const n = -r /
|
|
3460
|
-
i === "x" ? this.#s.zoomHorizontally(n) : this.#s.zoomVertically(n), t.preventDefault(), this.#c();
|
|
3461
|
-
}
|
|
3462
|
-
#
|
|
3463
|
-
if (t.stopPropagation(), this.#
|
|
3675
|
+
if (e.style.cursor = i === "x" ? "ew-resize" : "ns-resize", !this.#p || this.#p.pointerId !== t.pointerId || this.#p.axis !== i) return;
|
|
3676
|
+
const s = i === "x" ? t.clientX : t.clientY, r = s - this.#p.lastClientPosition;
|
|
3677
|
+
if (this.#p.lastClientPosition = s, !this.#s || r === 0) return;
|
|
3678
|
+
const n = -r / ge;
|
|
3679
|
+
i === "x" ? this.#s.zoomHorizontally(n) : this.#s.zoomVertically(n), t.preventDefault(), this.#c(), this.#C();
|
|
3680
|
+
}
|
|
3681
|
+
#R(t) {
|
|
3682
|
+
if (t.stopPropagation(), this.#p?.pointerId !== t.pointerId) return;
|
|
3464
3683
|
const e = t.currentTarget;
|
|
3465
|
-
e.hasPointerCapture(t.pointerId) && e.releasePointerCapture(t.pointerId), this.#
|
|
3684
|
+
e.hasPointerCapture(t.pointerId) && e.releasePointerCapture(t.pointerId), this.#p = null, t.preventDefault();
|
|
3466
3685
|
}
|
|
3467
|
-
#
|
|
3468
|
-
if (!(!this.#
|
|
3469
|
-
if (this.#
|
|
3686
|
+
#it(t) {
|
|
3687
|
+
if (!(!this.#m() && this.#a?.handlePointerEvent(t))) {
|
|
3688
|
+
if (this.#o?.handlePointerEvent(t) ?? !1) {
|
|
3470
3689
|
this.#c();
|
|
3471
3690
|
return;
|
|
3472
3691
|
}
|
|
3473
|
-
this.#
|
|
3692
|
+
this.#m() || (this.#S = !0, this.#D = t.clientX, this.#A = t.clientY);
|
|
3474
3693
|
}
|
|
3475
3694
|
}
|
|
3476
|
-
#
|
|
3477
|
-
const e = this.#
|
|
3478
|
-
|
|
3479
|
-
|
|
3695
|
+
#st(t) {
|
|
3696
|
+
const e = this.#o?.handlePointerEvent(t) ?? !1;
|
|
3697
|
+
this.#m() || this.#a?.handlePointerEvent(t);
|
|
3698
|
+
let i = this.#B(t);
|
|
3699
|
+
if (e) {
|
|
3700
|
+
this.#c(), i = this.#B(t), this.#M(i);
|
|
3480
3701
|
return;
|
|
3481
3702
|
}
|
|
3482
|
-
if (!this.#
|
|
3483
|
-
|
|
3484
|
-
|
|
3703
|
+
if (!this.#S || !this.#s || this.#m()) {
|
|
3704
|
+
this.#M(i);
|
|
3705
|
+
return;
|
|
3706
|
+
}
|
|
3707
|
+
const s = t.clientX - this.#D, r = t.clientY - this.#A;
|
|
3708
|
+
this.#D = t.clientX, this.#A = t.clientY, this.#s.panHorizontally(s), this.#s.panVertically(r), this.#c(), i = this.#B(t), this.#M(i), this.#C();
|
|
3485
3709
|
}
|
|
3486
|
-
#
|
|
3487
|
-
if (this.#
|
|
3488
|
-
this.#c();
|
|
3710
|
+
#rt(t) {
|
|
3711
|
+
if (this.#S = !1, this.#o?.handlePointerEvent(t) ?? !1) {
|
|
3712
|
+
this.#c(), this.#C();
|
|
3489
3713
|
return;
|
|
3490
3714
|
}
|
|
3491
|
-
this.#
|
|
3715
|
+
this.#m() || this.#a?.handlePointerEvent(t), this.#C();
|
|
3492
3716
|
}
|
|
3493
|
-
#
|
|
3494
|
-
document.body.style.cursor = "crosshair", this.#
|
|
3717
|
+
#nt(t) {
|
|
3718
|
+
document.body.style.cursor = "crosshair", this.#o?.handlePointerEvent(t), this.#m() || this.#a?.handlePointerEvent(t);
|
|
3495
3719
|
}
|
|
3496
|
-
#
|
|
3497
|
-
this.#
|
|
3720
|
+
#at() {
|
|
3721
|
+
this.#o?.clearHoverState(), document.body.style.cursor = "", this.#V(), this.#M(null);
|
|
3498
3722
|
}
|
|
3499
|
-
#
|
|
3500
|
-
((this.#
|
|
3723
|
+
#ot(t) {
|
|
3724
|
+
((this.#o?.handlePointerEvent(t) ?? !1) || this.#m()) && (t.preventDefault(), t.stopPropagation(), this.#c());
|
|
3501
3725
|
}
|
|
3502
|
-
#
|
|
3503
|
-
this.#
|
|
3726
|
+
#lt(t) {
|
|
3727
|
+
this.#o?.handlePointerEvent(t);
|
|
3504
3728
|
}
|
|
3505
|
-
#
|
|
3506
|
-
this.#
|
|
3729
|
+
#ht(t) {
|
|
3730
|
+
this.#dt(t.target) || (this.#o?.handleKeyboardEvent(t) ?? !1) && (t.preventDefault(), this.#c());
|
|
3507
3731
|
}
|
|
3508
|
-
#
|
|
3732
|
+
#dt(t) {
|
|
3509
3733
|
return t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement || t instanceof HTMLElement && t.isContentEditable;
|
|
3510
3734
|
}
|
|
3511
|
-
},
|
|
3512
|
-
const r = _(null), n = _(null),
|
|
3513
|
-
return
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3735
|
+
}, Ce = kt(({ className: t, style: e, ...i }, s) => {
|
|
3736
|
+
const r = _(null), n = _(null), a = _(i);
|
|
3737
|
+
return a.current = i, Rt(s, () => ({
|
|
3738
|
+
resetChartView() {
|
|
3739
|
+
n.current?.resetChartView();
|
|
3740
|
+
},
|
|
3741
|
+
getView() {
|
|
3742
|
+
return n.current?.getView() ?? null;
|
|
3743
|
+
},
|
|
3744
|
+
setView(o) {
|
|
3745
|
+
n.current?.setView(o);
|
|
3746
|
+
},
|
|
3747
|
+
setCursor(o) {
|
|
3748
|
+
n.current?.setCursor(o);
|
|
3749
|
+
},
|
|
3750
|
+
hideCursor() {
|
|
3751
|
+
n.current?.hideCursor();
|
|
3752
|
+
}
|
|
3753
|
+
})), st(() => {
|
|
3754
|
+
const o = r.current;
|
|
3755
|
+
if (!o) return;
|
|
3756
|
+
const l = new fe(o, a.current);
|
|
3519
3757
|
return n.current = l, () => {
|
|
3520
3758
|
l.destroy(), n.current = null;
|
|
3521
3759
|
};
|
|
3522
3760
|
}, []), st(() => {
|
|
3523
|
-
n.current?.updateProps(
|
|
3761
|
+
n.current?.updateProps(a.current);
|
|
3524
3762
|
}, [i]), /* @__PURE__ */ Dt("div", {
|
|
3525
3763
|
ref: r,
|
|
3526
3764
|
className: t,
|
|
@@ -3533,5 +3771,5 @@ var $ = () => typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID(
|
|
|
3533
3771
|
});
|
|
3534
3772
|
export {
|
|
3535
3773
|
c as CHART_CONFIG,
|
|
3536
|
-
|
|
3774
|
+
Ce as TradingReload
|
|
3537
3775
|
};
|