hyperprop-charting-library 0.1.63 → 0.1.65
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/hyperprop-charting-library.cjs +59 -3
- package/dist/hyperprop-charting-library.js +59 -3
- package/dist/index.cjs +59 -3
- package/dist/index.js +59 -3
- package/package.json +1 -1
|
@@ -1065,6 +1065,10 @@ function createChart(element, options = {}) {
|
|
|
1065
1065
|
}
|
|
1066
1066
|
canvas.style.display = "block";
|
|
1067
1067
|
canvas.style.touchAction = "none";
|
|
1068
|
+
canvas.style.userSelect = "none";
|
|
1069
|
+
canvas.style.setProperty("-webkit-user-select", "none");
|
|
1070
|
+
canvas.style.setProperty("-webkit-touch-callout", "none");
|
|
1071
|
+
canvas.setAttribute("draggable", "false");
|
|
1068
1072
|
element.innerHTML = "";
|
|
1069
1073
|
element.appendChild(canvas);
|
|
1070
1074
|
const margin = { top: 16, right: 72, bottom: 34, left: 12 };
|
|
@@ -3518,10 +3522,15 @@ function createChart(element, options = {}) {
|
|
|
3518
3522
|
}
|
|
3519
3523
|
const midpoint = getMidpoint(first, second);
|
|
3520
3524
|
const anchorRatio = clamp((midpoint.x - drawState.chartLeft) / drawState.chartWidth, 0, 1);
|
|
3525
|
+
const startYMin = yMinOverride ?? drawState.yMin;
|
|
3526
|
+
const startYMax = yMaxOverride ?? drawState.yMax;
|
|
3521
3527
|
pinchZoomState = {
|
|
3522
3528
|
startDistance: Math.max(1, getPointerDistance(first, second)),
|
|
3523
3529
|
startSpan: xSpan,
|
|
3524
|
-
anchorIndex: drawState.xStart + anchorRatio * xSpan
|
|
3530
|
+
anchorIndex: drawState.xStart + anchorRatio * xSpan,
|
|
3531
|
+
startMidpoint: midpoint,
|
|
3532
|
+
startYMin,
|
|
3533
|
+
startYMax
|
|
3525
3534
|
};
|
|
3526
3535
|
isDragging = false;
|
|
3527
3536
|
dragMode = null;
|
|
@@ -3550,11 +3559,19 @@ function createChart(element, options = {}) {
|
|
|
3550
3559
|
xSpan = nextSpan;
|
|
3551
3560
|
xCenter = nextStart + nextSpan / 2;
|
|
3552
3561
|
clampXViewport();
|
|
3562
|
+
const startYRange = pinchZoomState.startYMax - pinchZoomState.startYMin || 1;
|
|
3563
|
+
const priceShift = (midpoint.y - pinchZoomState.startMidpoint.y) / drawState.chartHeight * startYRange;
|
|
3564
|
+
const clampedY = clampYRange(pinchZoomState.startYMin + priceShift, pinchZoomState.startYMax + priceShift);
|
|
3565
|
+
yMinOverride = clampedY.min;
|
|
3566
|
+
yMaxOverride = clampedY.max;
|
|
3553
3567
|
updateFollowLatest(false);
|
|
3554
3568
|
emitViewportChange();
|
|
3555
3569
|
draw();
|
|
3556
3570
|
};
|
|
3557
3571
|
const onPointerDown = (event) => {
|
|
3572
|
+
if (event.pointerType === "touch" || event.pointerType === "pen") {
|
|
3573
|
+
event.preventDefault();
|
|
3574
|
+
}
|
|
3558
3575
|
const point = getCanvasPoint(event);
|
|
3559
3576
|
if (event.pointerType === "touch") {
|
|
3560
3577
|
touchPointers.set(event.pointerId, point);
|
|
@@ -3653,12 +3670,29 @@ function createChart(element, options = {}) {
|
|
|
3653
3670
|
isDragging = true;
|
|
3654
3671
|
dragMode = region;
|
|
3655
3672
|
activePointerId = event.pointerId;
|
|
3656
|
-
|
|
3673
|
+
const crosshairDrag = (event.pointerType === "touch" || event.pointerType === "pen") && region === "plot";
|
|
3674
|
+
pointerDownInfo = {
|
|
3675
|
+
pointerId: event.pointerId,
|
|
3676
|
+
pointerType: event.pointerType,
|
|
3677
|
+
x: point.x,
|
|
3678
|
+
y: point.y,
|
|
3679
|
+
region,
|
|
3680
|
+
moved: false,
|
|
3681
|
+
crosshairDrag
|
|
3682
|
+
};
|
|
3657
3683
|
lastPointerX = point.x;
|
|
3658
3684
|
lastPointerY = point.y;
|
|
3659
3685
|
canvas.setPointerCapture(event.pointerId);
|
|
3686
|
+
if (crosshairDrag) {
|
|
3687
|
+
canvas.style.cursor = "crosshair";
|
|
3688
|
+
setCrosshairPoint(point);
|
|
3689
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3690
|
+
}
|
|
3660
3691
|
};
|
|
3661
3692
|
const onPointerMove = (event) => {
|
|
3693
|
+
if (event.pointerType === "touch" || event.pointerType === "pen") {
|
|
3694
|
+
event.preventDefault();
|
|
3695
|
+
}
|
|
3662
3696
|
const point = getCanvasPoint(event);
|
|
3663
3697
|
if (event.pointerType === "touch" && touchPointers.has(event.pointerId)) {
|
|
3664
3698
|
touchPointers.set(event.pointerId, point);
|
|
@@ -3681,6 +3715,16 @@ function createChart(element, options = {}) {
|
|
|
3681
3715
|
pointerDownInfo.moved = true;
|
|
3682
3716
|
}
|
|
3683
3717
|
}
|
|
3718
|
+
if (pointerDownInfo?.crosshairDrag && pointerDownInfo.pointerId === event.pointerId) {
|
|
3719
|
+
if (getHitRegion(point.x, point.y) === "plot") {
|
|
3720
|
+
canvas.style.cursor = "crosshair";
|
|
3721
|
+
setCrosshairPoint(point);
|
|
3722
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3723
|
+
lastPointerX = point.x;
|
|
3724
|
+
lastPointerY = point.y;
|
|
3725
|
+
}
|
|
3726
|
+
return;
|
|
3727
|
+
}
|
|
3684
3728
|
if (drawingDragState) {
|
|
3685
3729
|
if (activePointerId !== null && event.pointerId !== activePointerId) {
|
|
3686
3730
|
return;
|
|
@@ -3894,7 +3938,13 @@ function createChart(element, options = {}) {
|
|
|
3894
3938
|
activePointerId = null;
|
|
3895
3939
|
canvas.style.cursor = "default";
|
|
3896
3940
|
if (event && pointerDownInfo && event.pointerId === pointerDownInfo.pointerId) {
|
|
3897
|
-
if (
|
|
3941
|
+
if (pointerDownInfo.crosshairDrag) {
|
|
3942
|
+
const point = getCanvasPoint(event);
|
|
3943
|
+
if (getHitRegion(point.x, point.y) === "plot") {
|
|
3944
|
+
setCrosshairPoint(point);
|
|
3945
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3946
|
+
}
|
|
3947
|
+
} else if (!pointerDownInfo.moved) {
|
|
3898
3948
|
const clickPrice = pointerDownInfo.region === "plot" ? roundToPricePrecision(priceFromCanvasY(pointerDownInfo.y)) : void 0;
|
|
3899
3949
|
chartClickHandler?.({
|
|
3900
3950
|
x: pointerDownInfo.x,
|
|
@@ -3941,6 +3991,7 @@ function createChart(element, options = {}) {
|
|
|
3941
3991
|
zoomX(factor, point.x);
|
|
3942
3992
|
};
|
|
3943
3993
|
const onDoubleClick = (event) => {
|
|
3994
|
+
event.preventDefault();
|
|
3944
3995
|
if (!doubleClickEnabled) {
|
|
3945
3996
|
return;
|
|
3946
3997
|
}
|
|
@@ -3966,6 +4017,9 @@ function createChart(element, options = {}) {
|
|
|
3966
4017
|
}
|
|
3967
4018
|
resetViewport();
|
|
3968
4019
|
};
|
|
4020
|
+
const onContextMenu = (event) => {
|
|
4021
|
+
event.preventDefault();
|
|
4022
|
+
};
|
|
3969
4023
|
canvas.addEventListener("pointerdown", onPointerDown);
|
|
3970
4024
|
canvas.addEventListener("pointermove", onPointerMove);
|
|
3971
4025
|
canvas.addEventListener("pointerup", endPointerDrag);
|
|
@@ -3973,6 +4027,7 @@ function createChart(element, options = {}) {
|
|
|
3973
4027
|
canvas.addEventListener("pointerleave", endPointerDrag);
|
|
3974
4028
|
canvas.addEventListener("wheel", onWheel, { passive: false });
|
|
3975
4029
|
canvas.addEventListener("dblclick", onDoubleClick);
|
|
4030
|
+
canvas.addEventListener("contextmenu", onContextMenu);
|
|
3976
4031
|
const updateOptions = (nextOptions) => {
|
|
3977
4032
|
const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
|
|
3978
4033
|
const previousWidth = width;
|
|
@@ -4270,6 +4325,7 @@ function createChart(element, options = {}) {
|
|
|
4270
4325
|
canvas.removeEventListener("pointerleave", endPointerDrag);
|
|
4271
4326
|
canvas.removeEventListener("wheel", onWheel);
|
|
4272
4327
|
canvas.removeEventListener("dblclick", onDoubleClick);
|
|
4328
|
+
canvas.removeEventListener("contextmenu", onContextMenu);
|
|
4273
4329
|
element.innerHTML = "";
|
|
4274
4330
|
};
|
|
4275
4331
|
draw();
|
|
@@ -1041,6 +1041,10 @@ function createChart(element, options = {}) {
|
|
|
1041
1041
|
}
|
|
1042
1042
|
canvas.style.display = "block";
|
|
1043
1043
|
canvas.style.touchAction = "none";
|
|
1044
|
+
canvas.style.userSelect = "none";
|
|
1045
|
+
canvas.style.setProperty("-webkit-user-select", "none");
|
|
1046
|
+
canvas.style.setProperty("-webkit-touch-callout", "none");
|
|
1047
|
+
canvas.setAttribute("draggable", "false");
|
|
1044
1048
|
element.innerHTML = "";
|
|
1045
1049
|
element.appendChild(canvas);
|
|
1046
1050
|
const margin = { top: 16, right: 72, bottom: 34, left: 12 };
|
|
@@ -3494,10 +3498,15 @@ function createChart(element, options = {}) {
|
|
|
3494
3498
|
}
|
|
3495
3499
|
const midpoint = getMidpoint(first, second);
|
|
3496
3500
|
const anchorRatio = clamp((midpoint.x - drawState.chartLeft) / drawState.chartWidth, 0, 1);
|
|
3501
|
+
const startYMin = yMinOverride ?? drawState.yMin;
|
|
3502
|
+
const startYMax = yMaxOverride ?? drawState.yMax;
|
|
3497
3503
|
pinchZoomState = {
|
|
3498
3504
|
startDistance: Math.max(1, getPointerDistance(first, second)),
|
|
3499
3505
|
startSpan: xSpan,
|
|
3500
|
-
anchorIndex: drawState.xStart + anchorRatio * xSpan
|
|
3506
|
+
anchorIndex: drawState.xStart + anchorRatio * xSpan,
|
|
3507
|
+
startMidpoint: midpoint,
|
|
3508
|
+
startYMin,
|
|
3509
|
+
startYMax
|
|
3501
3510
|
};
|
|
3502
3511
|
isDragging = false;
|
|
3503
3512
|
dragMode = null;
|
|
@@ -3526,11 +3535,19 @@ function createChart(element, options = {}) {
|
|
|
3526
3535
|
xSpan = nextSpan;
|
|
3527
3536
|
xCenter = nextStart + nextSpan / 2;
|
|
3528
3537
|
clampXViewport();
|
|
3538
|
+
const startYRange = pinchZoomState.startYMax - pinchZoomState.startYMin || 1;
|
|
3539
|
+
const priceShift = (midpoint.y - pinchZoomState.startMidpoint.y) / drawState.chartHeight * startYRange;
|
|
3540
|
+
const clampedY = clampYRange(pinchZoomState.startYMin + priceShift, pinchZoomState.startYMax + priceShift);
|
|
3541
|
+
yMinOverride = clampedY.min;
|
|
3542
|
+
yMaxOverride = clampedY.max;
|
|
3529
3543
|
updateFollowLatest(false);
|
|
3530
3544
|
emitViewportChange();
|
|
3531
3545
|
draw();
|
|
3532
3546
|
};
|
|
3533
3547
|
const onPointerDown = (event) => {
|
|
3548
|
+
if (event.pointerType === "touch" || event.pointerType === "pen") {
|
|
3549
|
+
event.preventDefault();
|
|
3550
|
+
}
|
|
3534
3551
|
const point = getCanvasPoint(event);
|
|
3535
3552
|
if (event.pointerType === "touch") {
|
|
3536
3553
|
touchPointers.set(event.pointerId, point);
|
|
@@ -3629,12 +3646,29 @@ function createChart(element, options = {}) {
|
|
|
3629
3646
|
isDragging = true;
|
|
3630
3647
|
dragMode = region;
|
|
3631
3648
|
activePointerId = event.pointerId;
|
|
3632
|
-
|
|
3649
|
+
const crosshairDrag = (event.pointerType === "touch" || event.pointerType === "pen") && region === "plot";
|
|
3650
|
+
pointerDownInfo = {
|
|
3651
|
+
pointerId: event.pointerId,
|
|
3652
|
+
pointerType: event.pointerType,
|
|
3653
|
+
x: point.x,
|
|
3654
|
+
y: point.y,
|
|
3655
|
+
region,
|
|
3656
|
+
moved: false,
|
|
3657
|
+
crosshairDrag
|
|
3658
|
+
};
|
|
3633
3659
|
lastPointerX = point.x;
|
|
3634
3660
|
lastPointerY = point.y;
|
|
3635
3661
|
canvas.setPointerCapture(event.pointerId);
|
|
3662
|
+
if (crosshairDrag) {
|
|
3663
|
+
canvas.style.cursor = "crosshair";
|
|
3664
|
+
setCrosshairPoint(point);
|
|
3665
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3666
|
+
}
|
|
3636
3667
|
};
|
|
3637
3668
|
const onPointerMove = (event) => {
|
|
3669
|
+
if (event.pointerType === "touch" || event.pointerType === "pen") {
|
|
3670
|
+
event.preventDefault();
|
|
3671
|
+
}
|
|
3638
3672
|
const point = getCanvasPoint(event);
|
|
3639
3673
|
if (event.pointerType === "touch" && touchPointers.has(event.pointerId)) {
|
|
3640
3674
|
touchPointers.set(event.pointerId, point);
|
|
@@ -3657,6 +3691,16 @@ function createChart(element, options = {}) {
|
|
|
3657
3691
|
pointerDownInfo.moved = true;
|
|
3658
3692
|
}
|
|
3659
3693
|
}
|
|
3694
|
+
if (pointerDownInfo?.crosshairDrag && pointerDownInfo.pointerId === event.pointerId) {
|
|
3695
|
+
if (getHitRegion(point.x, point.y) === "plot") {
|
|
3696
|
+
canvas.style.cursor = "crosshair";
|
|
3697
|
+
setCrosshairPoint(point);
|
|
3698
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3699
|
+
lastPointerX = point.x;
|
|
3700
|
+
lastPointerY = point.y;
|
|
3701
|
+
}
|
|
3702
|
+
return;
|
|
3703
|
+
}
|
|
3660
3704
|
if (drawingDragState) {
|
|
3661
3705
|
if (activePointerId !== null && event.pointerId !== activePointerId) {
|
|
3662
3706
|
return;
|
|
@@ -3870,7 +3914,13 @@ function createChart(element, options = {}) {
|
|
|
3870
3914
|
activePointerId = null;
|
|
3871
3915
|
canvas.style.cursor = "default";
|
|
3872
3916
|
if (event && pointerDownInfo && event.pointerId === pointerDownInfo.pointerId) {
|
|
3873
|
-
if (
|
|
3917
|
+
if (pointerDownInfo.crosshairDrag) {
|
|
3918
|
+
const point = getCanvasPoint(event);
|
|
3919
|
+
if (getHitRegion(point.x, point.y) === "plot") {
|
|
3920
|
+
setCrosshairPoint(point);
|
|
3921
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3922
|
+
}
|
|
3923
|
+
} else if (!pointerDownInfo.moved) {
|
|
3874
3924
|
const clickPrice = pointerDownInfo.region === "plot" ? roundToPricePrecision(priceFromCanvasY(pointerDownInfo.y)) : void 0;
|
|
3875
3925
|
chartClickHandler?.({
|
|
3876
3926
|
x: pointerDownInfo.x,
|
|
@@ -3917,6 +3967,7 @@ function createChart(element, options = {}) {
|
|
|
3917
3967
|
zoomX(factor, point.x);
|
|
3918
3968
|
};
|
|
3919
3969
|
const onDoubleClick = (event) => {
|
|
3970
|
+
event.preventDefault();
|
|
3920
3971
|
if (!doubleClickEnabled) {
|
|
3921
3972
|
return;
|
|
3922
3973
|
}
|
|
@@ -3942,6 +3993,9 @@ function createChart(element, options = {}) {
|
|
|
3942
3993
|
}
|
|
3943
3994
|
resetViewport();
|
|
3944
3995
|
};
|
|
3996
|
+
const onContextMenu = (event) => {
|
|
3997
|
+
event.preventDefault();
|
|
3998
|
+
};
|
|
3945
3999
|
canvas.addEventListener("pointerdown", onPointerDown);
|
|
3946
4000
|
canvas.addEventListener("pointermove", onPointerMove);
|
|
3947
4001
|
canvas.addEventListener("pointerup", endPointerDrag);
|
|
@@ -3949,6 +4003,7 @@ function createChart(element, options = {}) {
|
|
|
3949
4003
|
canvas.addEventListener("pointerleave", endPointerDrag);
|
|
3950
4004
|
canvas.addEventListener("wheel", onWheel, { passive: false });
|
|
3951
4005
|
canvas.addEventListener("dblclick", onDoubleClick);
|
|
4006
|
+
canvas.addEventListener("contextmenu", onContextMenu);
|
|
3952
4007
|
const updateOptions = (nextOptions) => {
|
|
3953
4008
|
const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
|
|
3954
4009
|
const previousWidth = width;
|
|
@@ -4246,6 +4301,7 @@ function createChart(element, options = {}) {
|
|
|
4246
4301
|
canvas.removeEventListener("pointerleave", endPointerDrag);
|
|
4247
4302
|
canvas.removeEventListener("wheel", onWheel);
|
|
4248
4303
|
canvas.removeEventListener("dblclick", onDoubleClick);
|
|
4304
|
+
canvas.removeEventListener("contextmenu", onContextMenu);
|
|
4249
4305
|
element.innerHTML = "";
|
|
4250
4306
|
};
|
|
4251
4307
|
draw();
|
package/dist/index.cjs
CHANGED
|
@@ -1065,6 +1065,10 @@ function createChart(element, options = {}) {
|
|
|
1065
1065
|
}
|
|
1066
1066
|
canvas.style.display = "block";
|
|
1067
1067
|
canvas.style.touchAction = "none";
|
|
1068
|
+
canvas.style.userSelect = "none";
|
|
1069
|
+
canvas.style.setProperty("-webkit-user-select", "none");
|
|
1070
|
+
canvas.style.setProperty("-webkit-touch-callout", "none");
|
|
1071
|
+
canvas.setAttribute("draggable", "false");
|
|
1068
1072
|
element.innerHTML = "";
|
|
1069
1073
|
element.appendChild(canvas);
|
|
1070
1074
|
const margin = { top: 16, right: 72, bottom: 34, left: 12 };
|
|
@@ -3518,10 +3522,15 @@ function createChart(element, options = {}) {
|
|
|
3518
3522
|
}
|
|
3519
3523
|
const midpoint = getMidpoint(first, second);
|
|
3520
3524
|
const anchorRatio = clamp((midpoint.x - drawState.chartLeft) / drawState.chartWidth, 0, 1);
|
|
3525
|
+
const startYMin = yMinOverride ?? drawState.yMin;
|
|
3526
|
+
const startYMax = yMaxOverride ?? drawState.yMax;
|
|
3521
3527
|
pinchZoomState = {
|
|
3522
3528
|
startDistance: Math.max(1, getPointerDistance(first, second)),
|
|
3523
3529
|
startSpan: xSpan,
|
|
3524
|
-
anchorIndex: drawState.xStart + anchorRatio * xSpan
|
|
3530
|
+
anchorIndex: drawState.xStart + anchorRatio * xSpan,
|
|
3531
|
+
startMidpoint: midpoint,
|
|
3532
|
+
startYMin,
|
|
3533
|
+
startYMax
|
|
3525
3534
|
};
|
|
3526
3535
|
isDragging = false;
|
|
3527
3536
|
dragMode = null;
|
|
@@ -3550,11 +3559,19 @@ function createChart(element, options = {}) {
|
|
|
3550
3559
|
xSpan = nextSpan;
|
|
3551
3560
|
xCenter = nextStart + nextSpan / 2;
|
|
3552
3561
|
clampXViewport();
|
|
3562
|
+
const startYRange = pinchZoomState.startYMax - pinchZoomState.startYMin || 1;
|
|
3563
|
+
const priceShift = (midpoint.y - pinchZoomState.startMidpoint.y) / drawState.chartHeight * startYRange;
|
|
3564
|
+
const clampedY = clampYRange(pinchZoomState.startYMin + priceShift, pinchZoomState.startYMax + priceShift);
|
|
3565
|
+
yMinOverride = clampedY.min;
|
|
3566
|
+
yMaxOverride = clampedY.max;
|
|
3553
3567
|
updateFollowLatest(false);
|
|
3554
3568
|
emitViewportChange();
|
|
3555
3569
|
draw();
|
|
3556
3570
|
};
|
|
3557
3571
|
const onPointerDown = (event) => {
|
|
3572
|
+
if (event.pointerType === "touch" || event.pointerType === "pen") {
|
|
3573
|
+
event.preventDefault();
|
|
3574
|
+
}
|
|
3558
3575
|
const point = getCanvasPoint(event);
|
|
3559
3576
|
if (event.pointerType === "touch") {
|
|
3560
3577
|
touchPointers.set(event.pointerId, point);
|
|
@@ -3653,12 +3670,29 @@ function createChart(element, options = {}) {
|
|
|
3653
3670
|
isDragging = true;
|
|
3654
3671
|
dragMode = region;
|
|
3655
3672
|
activePointerId = event.pointerId;
|
|
3656
|
-
|
|
3673
|
+
const crosshairDrag = (event.pointerType === "touch" || event.pointerType === "pen") && region === "plot";
|
|
3674
|
+
pointerDownInfo = {
|
|
3675
|
+
pointerId: event.pointerId,
|
|
3676
|
+
pointerType: event.pointerType,
|
|
3677
|
+
x: point.x,
|
|
3678
|
+
y: point.y,
|
|
3679
|
+
region,
|
|
3680
|
+
moved: false,
|
|
3681
|
+
crosshairDrag
|
|
3682
|
+
};
|
|
3657
3683
|
lastPointerX = point.x;
|
|
3658
3684
|
lastPointerY = point.y;
|
|
3659
3685
|
canvas.setPointerCapture(event.pointerId);
|
|
3686
|
+
if (crosshairDrag) {
|
|
3687
|
+
canvas.style.cursor = "crosshair";
|
|
3688
|
+
setCrosshairPoint(point);
|
|
3689
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3690
|
+
}
|
|
3660
3691
|
};
|
|
3661
3692
|
const onPointerMove = (event) => {
|
|
3693
|
+
if (event.pointerType === "touch" || event.pointerType === "pen") {
|
|
3694
|
+
event.preventDefault();
|
|
3695
|
+
}
|
|
3662
3696
|
const point = getCanvasPoint(event);
|
|
3663
3697
|
if (event.pointerType === "touch" && touchPointers.has(event.pointerId)) {
|
|
3664
3698
|
touchPointers.set(event.pointerId, point);
|
|
@@ -3681,6 +3715,16 @@ function createChart(element, options = {}) {
|
|
|
3681
3715
|
pointerDownInfo.moved = true;
|
|
3682
3716
|
}
|
|
3683
3717
|
}
|
|
3718
|
+
if (pointerDownInfo?.crosshairDrag && pointerDownInfo.pointerId === event.pointerId) {
|
|
3719
|
+
if (getHitRegion(point.x, point.y) === "plot") {
|
|
3720
|
+
canvas.style.cursor = "crosshair";
|
|
3721
|
+
setCrosshairPoint(point);
|
|
3722
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3723
|
+
lastPointerX = point.x;
|
|
3724
|
+
lastPointerY = point.y;
|
|
3725
|
+
}
|
|
3726
|
+
return;
|
|
3727
|
+
}
|
|
3684
3728
|
if (drawingDragState) {
|
|
3685
3729
|
if (activePointerId !== null && event.pointerId !== activePointerId) {
|
|
3686
3730
|
return;
|
|
@@ -3894,7 +3938,13 @@ function createChart(element, options = {}) {
|
|
|
3894
3938
|
activePointerId = null;
|
|
3895
3939
|
canvas.style.cursor = "default";
|
|
3896
3940
|
if (event && pointerDownInfo && event.pointerId === pointerDownInfo.pointerId) {
|
|
3897
|
-
if (
|
|
3941
|
+
if (pointerDownInfo.crosshairDrag) {
|
|
3942
|
+
const point = getCanvasPoint(event);
|
|
3943
|
+
if (getHitRegion(point.x, point.y) === "plot") {
|
|
3944
|
+
setCrosshairPoint(point);
|
|
3945
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3946
|
+
}
|
|
3947
|
+
} else if (!pointerDownInfo.moved) {
|
|
3898
3948
|
const clickPrice = pointerDownInfo.region === "plot" ? roundToPricePrecision(priceFromCanvasY(pointerDownInfo.y)) : void 0;
|
|
3899
3949
|
chartClickHandler?.({
|
|
3900
3950
|
x: pointerDownInfo.x,
|
|
@@ -3941,6 +3991,7 @@ function createChart(element, options = {}) {
|
|
|
3941
3991
|
zoomX(factor, point.x);
|
|
3942
3992
|
};
|
|
3943
3993
|
const onDoubleClick = (event) => {
|
|
3994
|
+
event.preventDefault();
|
|
3944
3995
|
if (!doubleClickEnabled) {
|
|
3945
3996
|
return;
|
|
3946
3997
|
}
|
|
@@ -3966,6 +4017,9 @@ function createChart(element, options = {}) {
|
|
|
3966
4017
|
}
|
|
3967
4018
|
resetViewport();
|
|
3968
4019
|
};
|
|
4020
|
+
const onContextMenu = (event) => {
|
|
4021
|
+
event.preventDefault();
|
|
4022
|
+
};
|
|
3969
4023
|
canvas.addEventListener("pointerdown", onPointerDown);
|
|
3970
4024
|
canvas.addEventListener("pointermove", onPointerMove);
|
|
3971
4025
|
canvas.addEventListener("pointerup", endPointerDrag);
|
|
@@ -3973,6 +4027,7 @@ function createChart(element, options = {}) {
|
|
|
3973
4027
|
canvas.addEventListener("pointerleave", endPointerDrag);
|
|
3974
4028
|
canvas.addEventListener("wheel", onWheel, { passive: false });
|
|
3975
4029
|
canvas.addEventListener("dblclick", onDoubleClick);
|
|
4030
|
+
canvas.addEventListener("contextmenu", onContextMenu);
|
|
3976
4031
|
const updateOptions = (nextOptions) => {
|
|
3977
4032
|
const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
|
|
3978
4033
|
const previousWidth = width;
|
|
@@ -4270,6 +4325,7 @@ function createChart(element, options = {}) {
|
|
|
4270
4325
|
canvas.removeEventListener("pointerleave", endPointerDrag);
|
|
4271
4326
|
canvas.removeEventListener("wheel", onWheel);
|
|
4272
4327
|
canvas.removeEventListener("dblclick", onDoubleClick);
|
|
4328
|
+
canvas.removeEventListener("contextmenu", onContextMenu);
|
|
4273
4329
|
element.innerHTML = "";
|
|
4274
4330
|
};
|
|
4275
4331
|
draw();
|
package/dist/index.js
CHANGED
|
@@ -1041,6 +1041,10 @@ function createChart(element, options = {}) {
|
|
|
1041
1041
|
}
|
|
1042
1042
|
canvas.style.display = "block";
|
|
1043
1043
|
canvas.style.touchAction = "none";
|
|
1044
|
+
canvas.style.userSelect = "none";
|
|
1045
|
+
canvas.style.setProperty("-webkit-user-select", "none");
|
|
1046
|
+
canvas.style.setProperty("-webkit-touch-callout", "none");
|
|
1047
|
+
canvas.setAttribute("draggable", "false");
|
|
1044
1048
|
element.innerHTML = "";
|
|
1045
1049
|
element.appendChild(canvas);
|
|
1046
1050
|
const margin = { top: 16, right: 72, bottom: 34, left: 12 };
|
|
@@ -3494,10 +3498,15 @@ function createChart(element, options = {}) {
|
|
|
3494
3498
|
}
|
|
3495
3499
|
const midpoint = getMidpoint(first, second);
|
|
3496
3500
|
const anchorRatio = clamp((midpoint.x - drawState.chartLeft) / drawState.chartWidth, 0, 1);
|
|
3501
|
+
const startYMin = yMinOverride ?? drawState.yMin;
|
|
3502
|
+
const startYMax = yMaxOverride ?? drawState.yMax;
|
|
3497
3503
|
pinchZoomState = {
|
|
3498
3504
|
startDistance: Math.max(1, getPointerDistance(first, second)),
|
|
3499
3505
|
startSpan: xSpan,
|
|
3500
|
-
anchorIndex: drawState.xStart + anchorRatio * xSpan
|
|
3506
|
+
anchorIndex: drawState.xStart + anchorRatio * xSpan,
|
|
3507
|
+
startMidpoint: midpoint,
|
|
3508
|
+
startYMin,
|
|
3509
|
+
startYMax
|
|
3501
3510
|
};
|
|
3502
3511
|
isDragging = false;
|
|
3503
3512
|
dragMode = null;
|
|
@@ -3526,11 +3535,19 @@ function createChart(element, options = {}) {
|
|
|
3526
3535
|
xSpan = nextSpan;
|
|
3527
3536
|
xCenter = nextStart + nextSpan / 2;
|
|
3528
3537
|
clampXViewport();
|
|
3538
|
+
const startYRange = pinchZoomState.startYMax - pinchZoomState.startYMin || 1;
|
|
3539
|
+
const priceShift = (midpoint.y - pinchZoomState.startMidpoint.y) / drawState.chartHeight * startYRange;
|
|
3540
|
+
const clampedY = clampYRange(pinchZoomState.startYMin + priceShift, pinchZoomState.startYMax + priceShift);
|
|
3541
|
+
yMinOverride = clampedY.min;
|
|
3542
|
+
yMaxOverride = clampedY.max;
|
|
3529
3543
|
updateFollowLatest(false);
|
|
3530
3544
|
emitViewportChange();
|
|
3531
3545
|
draw();
|
|
3532
3546
|
};
|
|
3533
3547
|
const onPointerDown = (event) => {
|
|
3548
|
+
if (event.pointerType === "touch" || event.pointerType === "pen") {
|
|
3549
|
+
event.preventDefault();
|
|
3550
|
+
}
|
|
3534
3551
|
const point = getCanvasPoint(event);
|
|
3535
3552
|
if (event.pointerType === "touch") {
|
|
3536
3553
|
touchPointers.set(event.pointerId, point);
|
|
@@ -3629,12 +3646,29 @@ function createChart(element, options = {}) {
|
|
|
3629
3646
|
isDragging = true;
|
|
3630
3647
|
dragMode = region;
|
|
3631
3648
|
activePointerId = event.pointerId;
|
|
3632
|
-
|
|
3649
|
+
const crosshairDrag = (event.pointerType === "touch" || event.pointerType === "pen") && region === "plot";
|
|
3650
|
+
pointerDownInfo = {
|
|
3651
|
+
pointerId: event.pointerId,
|
|
3652
|
+
pointerType: event.pointerType,
|
|
3653
|
+
x: point.x,
|
|
3654
|
+
y: point.y,
|
|
3655
|
+
region,
|
|
3656
|
+
moved: false,
|
|
3657
|
+
crosshairDrag
|
|
3658
|
+
};
|
|
3633
3659
|
lastPointerX = point.x;
|
|
3634
3660
|
lastPointerY = point.y;
|
|
3635
3661
|
canvas.setPointerCapture(event.pointerId);
|
|
3662
|
+
if (crosshairDrag) {
|
|
3663
|
+
canvas.style.cursor = "crosshair";
|
|
3664
|
+
setCrosshairPoint(point);
|
|
3665
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3666
|
+
}
|
|
3636
3667
|
};
|
|
3637
3668
|
const onPointerMove = (event) => {
|
|
3669
|
+
if (event.pointerType === "touch" || event.pointerType === "pen") {
|
|
3670
|
+
event.preventDefault();
|
|
3671
|
+
}
|
|
3638
3672
|
const point = getCanvasPoint(event);
|
|
3639
3673
|
if (event.pointerType === "touch" && touchPointers.has(event.pointerId)) {
|
|
3640
3674
|
touchPointers.set(event.pointerId, point);
|
|
@@ -3657,6 +3691,16 @@ function createChart(element, options = {}) {
|
|
|
3657
3691
|
pointerDownInfo.moved = true;
|
|
3658
3692
|
}
|
|
3659
3693
|
}
|
|
3694
|
+
if (pointerDownInfo?.crosshairDrag && pointerDownInfo.pointerId === event.pointerId) {
|
|
3695
|
+
if (getHitRegion(point.x, point.y) === "plot") {
|
|
3696
|
+
canvas.style.cursor = "crosshair";
|
|
3697
|
+
setCrosshairPoint(point);
|
|
3698
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3699
|
+
lastPointerX = point.x;
|
|
3700
|
+
lastPointerY = point.y;
|
|
3701
|
+
}
|
|
3702
|
+
return;
|
|
3703
|
+
}
|
|
3660
3704
|
if (drawingDragState) {
|
|
3661
3705
|
if (activePointerId !== null && event.pointerId !== activePointerId) {
|
|
3662
3706
|
return;
|
|
@@ -3870,7 +3914,13 @@ function createChart(element, options = {}) {
|
|
|
3870
3914
|
activePointerId = null;
|
|
3871
3915
|
canvas.style.cursor = "default";
|
|
3872
3916
|
if (event && pointerDownInfo && event.pointerId === pointerDownInfo.pointerId) {
|
|
3873
|
-
if (
|
|
3917
|
+
if (pointerDownInfo.crosshairDrag) {
|
|
3918
|
+
const point = getCanvasPoint(event);
|
|
3919
|
+
if (getHitRegion(point.x, point.y) === "plot") {
|
|
3920
|
+
setCrosshairPoint(point);
|
|
3921
|
+
emitCrosshairMove(point.x, point.y, "plot");
|
|
3922
|
+
}
|
|
3923
|
+
} else if (!pointerDownInfo.moved) {
|
|
3874
3924
|
const clickPrice = pointerDownInfo.region === "plot" ? roundToPricePrecision(priceFromCanvasY(pointerDownInfo.y)) : void 0;
|
|
3875
3925
|
chartClickHandler?.({
|
|
3876
3926
|
x: pointerDownInfo.x,
|
|
@@ -3917,6 +3967,7 @@ function createChart(element, options = {}) {
|
|
|
3917
3967
|
zoomX(factor, point.x);
|
|
3918
3968
|
};
|
|
3919
3969
|
const onDoubleClick = (event) => {
|
|
3970
|
+
event.preventDefault();
|
|
3920
3971
|
if (!doubleClickEnabled) {
|
|
3921
3972
|
return;
|
|
3922
3973
|
}
|
|
@@ -3942,6 +3993,9 @@ function createChart(element, options = {}) {
|
|
|
3942
3993
|
}
|
|
3943
3994
|
resetViewport();
|
|
3944
3995
|
};
|
|
3996
|
+
const onContextMenu = (event) => {
|
|
3997
|
+
event.preventDefault();
|
|
3998
|
+
};
|
|
3945
3999
|
canvas.addEventListener("pointerdown", onPointerDown);
|
|
3946
4000
|
canvas.addEventListener("pointermove", onPointerMove);
|
|
3947
4001
|
canvas.addEventListener("pointerup", endPointerDrag);
|
|
@@ -3949,6 +4003,7 @@ function createChart(element, options = {}) {
|
|
|
3949
4003
|
canvas.addEventListener("pointerleave", endPointerDrag);
|
|
3950
4004
|
canvas.addEventListener("wheel", onWheel, { passive: false });
|
|
3951
4005
|
canvas.addEventListener("dblclick", onDoubleClick);
|
|
4006
|
+
canvas.addEventListener("contextmenu", onContextMenu);
|
|
3952
4007
|
const updateOptions = (nextOptions) => {
|
|
3953
4008
|
const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
|
|
3954
4009
|
const previousWidth = width;
|
|
@@ -4246,6 +4301,7 @@ function createChart(element, options = {}) {
|
|
|
4246
4301
|
canvas.removeEventListener("pointerleave", endPointerDrag);
|
|
4247
4302
|
canvas.removeEventListener("wheel", onWheel);
|
|
4248
4303
|
canvas.removeEventListener("dblclick", onDoubleClick);
|
|
4304
|
+
canvas.removeEventListener("contextmenu", onContextMenu);
|
|
4249
4305
|
element.innerHTML = "";
|
|
4250
4306
|
};
|
|
4251
4307
|
draw();
|