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