@pipsend/charts 2.3.10 → 2.3.12
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/pipsend-charts.development.mjs +133 -14
- package/dist/pipsend-charts.production.mjs +2 -2
- package/dist/pipsend-charts.standalone.development.js +133 -14
- package/dist/pipsend-charts.standalone.development.mjs +133 -14
- package/dist/pipsend-charts.standalone.production.js +2 -2
- package/dist/pipsend-charts.standalone.production.mjs +2 -2
- package/dist/typings.d.ts +19 -8
- package/package.json +83 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @license
|
|
3
|
-
* Pipsend Charts v2.3.
|
|
3
|
+
* Pipsend Charts v2.3.12
|
|
4
4
|
* Copyright (c) 2026 Pipsend
|
|
5
5
|
* Licensed under MIT License
|
|
6
6
|
* Built on TradingView Lightweight Charts™ (Apache 2.0)
|
|
@@ -19705,6 +19705,12 @@
|
|
|
19705
19705
|
}
|
|
19706
19706
|
|
|
19707
19707
|
const CLICK_TOLERANCE_PX = 4;
|
|
19708
|
+
/**
|
|
19709
|
+
* A fingertip never holds still: every tap travels further than a pointer
|
|
19710
|
+
* does, and judging it by the mouse's few pixels turned each one into a tiny
|
|
19711
|
+
* drag, so the tap never arrived.
|
|
19712
|
+
*/
|
|
19713
|
+
const TOUCH_CLICK_TOLERANCE_PX = 12;
|
|
19708
19714
|
/**
|
|
19709
19715
|
* Single input owner for every trading line on a chart.
|
|
19710
19716
|
*
|
|
@@ -19723,6 +19729,8 @@
|
|
|
19723
19729
|
this._private__pointerId = null;
|
|
19724
19730
|
this._private__pressOrigin = null;
|
|
19725
19731
|
this._private__pressedLine = null;
|
|
19732
|
+
/** Whether the gesture in flight came from a finger rather than a mouse. */
|
|
19733
|
+
this._private__pressWasTouch = false;
|
|
19726
19734
|
/** Distance from the pointer to the dragged line when the press landed. */
|
|
19727
19735
|
this._private__grabOffset = 0;
|
|
19728
19736
|
/** Latest pointer position in pane coordinates, or null when off the panes. */
|
|
@@ -19787,8 +19795,18 @@
|
|
|
19787
19795
|
this._private__applyCursor();
|
|
19788
19796
|
}
|
|
19789
19797
|
_private__onPointerDown(event) {
|
|
19790
|
-
|
|
19798
|
+
// Hover belongs to the mouse. Touch leaves whatever the last press marked
|
|
19799
|
+
// still marked, so trusting it here grabbed that line again wherever the
|
|
19800
|
+
// next tap landed: every press resolves itself instead.
|
|
19801
|
+
this._private__pressWasTouch = event.pointerType !== 'mouse';
|
|
19802
|
+
let line = this._private__pressWasTouch || this._private__hoveredId === null
|
|
19803
|
+
? null
|
|
19804
|
+
: this._private__lines.get(this._private__hoveredId) ?? null;
|
|
19805
|
+
if (line === null) {
|
|
19806
|
+
line = this._private__resolveHitAt(event);
|
|
19807
|
+
}
|
|
19791
19808
|
if (!line) {
|
|
19809
|
+
this._private__clearTouchHover();
|
|
19792
19810
|
return;
|
|
19793
19811
|
}
|
|
19794
19812
|
this._private__pressOrigin = { _internal_x: event.clientX, _internal_y: event.clientY };
|
|
@@ -19827,14 +19845,16 @@
|
|
|
19827
19845
|
}
|
|
19828
19846
|
_private__onPointerUp(event) {
|
|
19829
19847
|
const dragged = this._private__dragging;
|
|
19848
|
+
const wasTouch = this._private__pressWasTouch;
|
|
19830
19849
|
const pressed = this._private__pressedLine;
|
|
19831
19850
|
const origin = this._private__pressOrigin;
|
|
19832
19851
|
this._private__releasePointer();
|
|
19833
19852
|
this._private__pressedLine = null;
|
|
19834
19853
|
this._private__pressOrigin = null;
|
|
19854
|
+
const tolerance = wasTouch ? TOUCH_CLICK_TOLERANCE_PX : CLICK_TOLERANCE_PX;
|
|
19835
19855
|
const moved = origin !== null &&
|
|
19836
|
-
(Math.abs(event.clientX - origin._internal_x) >
|
|
19837
|
-
Math.abs(event.clientY - origin._internal_y) >
|
|
19856
|
+
(Math.abs(event.clientX - origin._internal_x) > tolerance ||
|
|
19857
|
+
Math.abs(event.clientY - origin._internal_y) > tolerance);
|
|
19838
19858
|
if (dragged !== null) {
|
|
19839
19859
|
this._private__dragging = null;
|
|
19840
19860
|
this._private__grabOffset = 0;
|
|
@@ -19848,12 +19868,24 @@
|
|
|
19848
19868
|
dragged.click();
|
|
19849
19869
|
}
|
|
19850
19870
|
}
|
|
19871
|
+
this._private__clearTouchHover(wasTouch);
|
|
19851
19872
|
this._private__applyCursor();
|
|
19852
19873
|
return;
|
|
19853
19874
|
}
|
|
19854
19875
|
if (pressed !== null && !moved && pressed.isClickable()) {
|
|
19855
19876
|
pressed.click();
|
|
19856
19877
|
}
|
|
19878
|
+
this._private__clearTouchHover(wasTouch);
|
|
19879
|
+
}
|
|
19880
|
+
/** A finger leaves nothing hovered behind it, the way lifting a mouse does. */
|
|
19881
|
+
_private__clearTouchHover(wasTouch = this._private__pressWasTouch) {
|
|
19882
|
+
if (!wasTouch || this._private__hoveredId === null) {
|
|
19883
|
+
return;
|
|
19884
|
+
}
|
|
19885
|
+
const line = this._private__lines.get(this._private__hoveredId) ?? null;
|
|
19886
|
+
this._private__setHovered(null);
|
|
19887
|
+
this._private__setHoveredPart(line, null);
|
|
19888
|
+
this._private__applyCursor();
|
|
19857
19889
|
}
|
|
19858
19890
|
/**
|
|
19859
19891
|
* Abort an in-flight gesture: the line goes back to where it was and no
|
|
@@ -19899,9 +19931,38 @@
|
|
|
19899
19931
|
return paneY === null ? null : line.priceAt(paneY - this._private__grabOffset);
|
|
19900
19932
|
}
|
|
19901
19933
|
/** The pointer's position inside the line's pane, in pane coordinates. */
|
|
19902
|
-
|
|
19934
|
+
/**
|
|
19935
|
+
* The hovered id comes from the crosshair, which touch never moves before it
|
|
19936
|
+
* presses, so the press resolves the target itself.
|
|
19937
|
+
*/
|
|
19938
|
+
_private__resolveHitAt(event) {
|
|
19939
|
+
for (const line of this._private__lines.values()) {
|
|
19940
|
+
if (!line.hitTestAt) {
|
|
19941
|
+
continue;
|
|
19942
|
+
}
|
|
19943
|
+
const paneElement = this._private__paneElementOf(line);
|
|
19944
|
+
if (paneElement === null) {
|
|
19945
|
+
continue;
|
|
19946
|
+
}
|
|
19947
|
+
const rect = paneElement.getBoundingClientRect();
|
|
19948
|
+
// A fingertip is far coarser than a pointer, so its targets are widened.
|
|
19949
|
+
const slop = event.pointerType === 'mouse' ? 0 : 12 /* Constants.TouchSlopPx */;
|
|
19950
|
+
const hit = this._private__splitHit(line.hitTestAt(event.clientX - rect.left, event.clientY - rect.top, slop));
|
|
19951
|
+
if (hit === null) {
|
|
19952
|
+
continue;
|
|
19953
|
+
}
|
|
19954
|
+
this._private__setHovered(line.id());
|
|
19955
|
+
this._private__setHoveredPart(line, hit._internal_part);
|
|
19956
|
+
return line;
|
|
19957
|
+
}
|
|
19958
|
+
return null;
|
|
19959
|
+
}
|
|
19960
|
+
_private__paneElementOf(line) {
|
|
19903
19961
|
const pane = this._private__chart.panes()[line.paneIndex()];
|
|
19904
|
-
|
|
19962
|
+
return pane ? pane.getHTMLElement() : null;
|
|
19963
|
+
}
|
|
19964
|
+
_private__paneY(line, event) {
|
|
19965
|
+
const paneElement = this._private__paneElementOf(line);
|
|
19905
19966
|
if (paneElement) {
|
|
19906
19967
|
return event.clientY - paneElement.getBoundingClientRect().top;
|
|
19907
19968
|
}
|
|
@@ -20018,6 +20079,7 @@
|
|
|
20018
20079
|
* line. Hit testing comes from the engine — the line's id travels as the price
|
|
20019
20080
|
* line's `externalId` — so the hit area matches what is drawn.
|
|
20020
20081
|
*/
|
|
20082
|
+
const HIT_TOLERANCE_PX$1 = 8;
|
|
20021
20083
|
class DraggablePriceLine {
|
|
20022
20084
|
constructor(chart, series, options) {
|
|
20023
20085
|
this._private__priceLine = null;
|
|
@@ -20070,6 +20132,14 @@
|
|
|
20070
20132
|
color: hovered ? this._private__options.hoverColor : this._private__originalColor,
|
|
20071
20133
|
});
|
|
20072
20134
|
}
|
|
20135
|
+
/**
|
|
20136
|
+
* The engine draws this one, so there is no pane view to ask: a press within
|
|
20137
|
+
* the line's own grab strip counts as a hit.
|
|
20138
|
+
*/
|
|
20139
|
+
hitTestAt(x, y, slop = 0) {
|
|
20140
|
+
const coord = this._private__series.priceToCoordinate(this._private__options.price);
|
|
20141
|
+
return coord !== null && Math.abs(y - coord) <= HIT_TOLERANCE_PX$1 + slop ? this._private__id : null;
|
|
20142
|
+
}
|
|
20073
20143
|
priceAt(paneY) {
|
|
20074
20144
|
const price = this._private__series.coordinateToPrice(paneY);
|
|
20075
20145
|
return price === null ? null : price;
|
|
@@ -20612,22 +20682,27 @@
|
|
|
20612
20682
|
_internal_setData(data) {
|
|
20613
20683
|
this._private__data = data;
|
|
20614
20684
|
}
|
|
20615
|
-
|
|
20685
|
+
/**
|
|
20686
|
+
* `slop` widens every target by the same amount, for input coarser than a
|
|
20687
|
+
* mouse pointer.
|
|
20688
|
+
*/
|
|
20689
|
+
_internal_hitTest(x, y, slop = 0) {
|
|
20616
20690
|
// The close button sits on top of the label, which sits on top of the
|
|
20617
20691
|
// line, so the narrowest target is tested first.
|
|
20618
20692
|
for (const layout of this._private__layouts) {
|
|
20619
|
-
if (layout._internal_closable && x >= layout._internal_closeLeft && x <= layout._internal_closeRight &&
|
|
20620
|
-
Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2) {
|
|
20693
|
+
if (layout._internal_closable && x >= layout._internal_closeLeft - slop && x <= layout._internal_closeRight + slop &&
|
|
20694
|
+
Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2 + slop) {
|
|
20621
20695
|
return { _internal_level: layout._internal_level, _internal_part: 'close' };
|
|
20622
20696
|
}
|
|
20623
20697
|
}
|
|
20624
20698
|
for (const layout of this._private__layouts) {
|
|
20625
|
-
if (x >= layout._internal_pillLeft && x <= layout._internal_pillRight
|
|
20699
|
+
if (x >= layout._internal_pillLeft - slop && x <= layout._internal_pillRight + slop &&
|
|
20700
|
+
Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2 + slop) {
|
|
20626
20701
|
return { _internal_level: layout._internal_level, _internal_part: 'body' };
|
|
20627
20702
|
}
|
|
20628
20703
|
}
|
|
20629
20704
|
for (const layout of this._private__layouts) {
|
|
20630
|
-
if (Math.abs(y - layout._internal_y) <= 8 /* Constants.LineHitTolerance */) {
|
|
20705
|
+
if (Math.abs(y - layout._internal_y) <= 8 /* Constants.LineHitTolerance */ + slop) {
|
|
20631
20706
|
return { _internal_level: layout._internal_level, _internal_part: 'line' };
|
|
20632
20707
|
}
|
|
20633
20708
|
}
|
|
@@ -20864,8 +20939,8 @@
|
|
|
20864
20939
|
zOrder() {
|
|
20865
20940
|
return 'top';
|
|
20866
20941
|
}
|
|
20867
|
-
_internal_hitTest(x, y) {
|
|
20868
|
-
return this._private__data === null ? null : this._private__renderer._internal_hitTest(x, y);
|
|
20942
|
+
_internal_hitTest(x, y, slop = 0) {
|
|
20943
|
+
return this._private__data === null ? null : this._private__renderer._internal_hitTest(x, y, slop);
|
|
20869
20944
|
}
|
|
20870
20945
|
}
|
|
20871
20946
|
|
|
@@ -21016,6 +21091,13 @@
|
|
|
21016
21091
|
* of jumping to sit under it — which matters most when the label has been
|
|
21017
21092
|
* fanned away from its own line.
|
|
21018
21093
|
*/
|
|
21094
|
+
hitTestAt(x, y, slop = 0) {
|
|
21095
|
+
const hit = this._private__paneView._internal_hitTest(x, y, slop);
|
|
21096
|
+
if (hit === null) {
|
|
21097
|
+
return null;
|
|
21098
|
+
}
|
|
21099
|
+
return this._private__levelOptions(hit._internal_level) === null ? null : `${this._private__id}#${hit._internal_level}:${hit._internal_part}`;
|
|
21100
|
+
}
|
|
21019
21101
|
dragAnchorY() {
|
|
21020
21102
|
if (this._private__dragLevel === null) {
|
|
21021
21103
|
return null;
|
|
@@ -30086,6 +30168,7 @@
|
|
|
30086
30168
|
this._private__mouseMoveHandler = null;
|
|
30087
30169
|
this._private__pointerDownHandler = null;
|
|
30088
30170
|
this._private__pointerUpHandler = null;
|
|
30171
|
+
this._private__pointerMoveHandler = null;
|
|
30089
30172
|
this._private__pointerCancelHandler = null;
|
|
30090
30173
|
this._private__lostCaptureHandler = null;
|
|
30091
30174
|
this._private__windowPointerUpHandler = null;
|
|
@@ -30660,10 +30743,12 @@
|
|
|
30660
30743
|
if (chartElement) {
|
|
30661
30744
|
this._private__pointerDownHandler = (event) => this._private__handlePointerDown(event);
|
|
30662
30745
|
this._private__pointerUpHandler = (event) => this._private__handlePointerUp(event);
|
|
30746
|
+
this._private__pointerMoveHandler = (event) => this._private__handlePointerMove(event);
|
|
30663
30747
|
this._private__pointerCancelHandler = (event) => this._private__handlePointerUp(event);
|
|
30664
30748
|
this._private__lostCaptureHandler = (event) => this._private__handleLostPointerCapture(event);
|
|
30665
30749
|
chartElement.addEventListener('pointerdown', this._private__pointerDownHandler);
|
|
30666
30750
|
chartElement.addEventListener('pointerup', this._private__pointerUpHandler);
|
|
30751
|
+
chartElement.addEventListener('pointermove', this._private__pointerMoveHandler);
|
|
30667
30752
|
chartElement.addEventListener('pointercancel', this._private__pointerCancelHandler);
|
|
30668
30753
|
chartElement.addEventListener('lostpointercapture', this._private__lostCaptureHandler);
|
|
30669
30754
|
}
|
|
@@ -30698,6 +30783,10 @@
|
|
|
30698
30783
|
chartElement.removeEventListener('pointerup', this._private__pointerUpHandler);
|
|
30699
30784
|
this._private__pointerUpHandler = null;
|
|
30700
30785
|
}
|
|
30786
|
+
if (this._private__pointerMoveHandler) {
|
|
30787
|
+
chartElement.removeEventListener('pointermove', this._private__pointerMoveHandler);
|
|
30788
|
+
this._private__pointerMoveHandler = null;
|
|
30789
|
+
}
|
|
30701
30790
|
if (this._private__pointerCancelHandler) {
|
|
30702
30791
|
chartElement.removeEventListener('pointercancel', this._private__pointerCancelHandler);
|
|
30703
30792
|
this._private__pointerCancelHandler = null;
|
|
@@ -30847,6 +30936,36 @@
|
|
|
30847
30936
|
// mouse events, and those are what drive the crosshair the drag reads.
|
|
30848
30937
|
this._private__disableChartInteractions();
|
|
30849
30938
|
}
|
|
30939
|
+
/**
|
|
30940
|
+
* The drag reads the crosshair, which touch never moves: its move handler
|
|
30941
|
+
* only tries to pan, and the drag has just turned panning off. So touch is
|
|
30942
|
+
* driven straight from the pointer instead.
|
|
30943
|
+
*/
|
|
30944
|
+
_private__handlePointerMove(event) {
|
|
30945
|
+
if (!this._private__isDragging || this._private__draggedToolId === null || event.pointerType === 'mouse') {
|
|
30946
|
+
return;
|
|
30947
|
+
}
|
|
30948
|
+
if (this._private__pointerId !== null && event.pointerId !== this._private__pointerId) {
|
|
30949
|
+
return;
|
|
30950
|
+
}
|
|
30951
|
+
const tool = this._private__tools.get(this._private__draggedToolId);
|
|
30952
|
+
if (!tool) {
|
|
30953
|
+
return;
|
|
30954
|
+
}
|
|
30955
|
+
const paneElement = this._private__paneElementOf(tool);
|
|
30956
|
+
if (paneElement === null) {
|
|
30957
|
+
return;
|
|
30958
|
+
}
|
|
30959
|
+
const rect = paneElement.getBoundingClientRect();
|
|
30960
|
+
const series = tool.series();
|
|
30961
|
+
const price = series.coordinateToPrice((event.clientY - rect.top));
|
|
30962
|
+
const time = timeFromCoordinate(this._private__chart, series, event.clientX - rect.left);
|
|
30963
|
+
if (price === null || time === null) {
|
|
30964
|
+
return;
|
|
30965
|
+
}
|
|
30966
|
+
tool.updateDrag(time, price);
|
|
30967
|
+
event.preventDefault();
|
|
30968
|
+
}
|
|
30850
30969
|
_private__handlePointerUp(event) {
|
|
30851
30970
|
if (!this._private__isDragging || this._private__draggedToolId === null) {
|
|
30852
30971
|
return;
|
|
@@ -31020,7 +31139,7 @@
|
|
|
31020
31139
|
* Returns the current version as a string. For example `'1.0.0'`.
|
|
31021
31140
|
*/
|
|
31022
31141
|
function version() {
|
|
31023
|
-
return "2.3.
|
|
31142
|
+
return "2.3.12";
|
|
31024
31143
|
}
|
|
31025
31144
|
|
|
31026
31145
|
var PipsendChartsModule = /*#__PURE__*/Object.freeze({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @license
|
|
3
|
-
* Pipsend Charts v2.3.
|
|
3
|
+
* Pipsend Charts v2.3.12
|
|
4
4
|
* Copyright (c) 2026 Pipsend
|
|
5
5
|
* Licensed under MIT License
|
|
6
6
|
* Built on TradingView Lightweight Charts™ (Apache 2.0)
|
|
@@ -19702,6 +19702,12 @@ function setVolumeProfileData(indicator, data) {
|
|
|
19702
19702
|
}
|
|
19703
19703
|
|
|
19704
19704
|
const CLICK_TOLERANCE_PX = 4;
|
|
19705
|
+
/**
|
|
19706
|
+
* A fingertip never holds still: every tap travels further than a pointer
|
|
19707
|
+
* does, and judging it by the mouse's few pixels turned each one into a tiny
|
|
19708
|
+
* drag, so the tap never arrived.
|
|
19709
|
+
*/
|
|
19710
|
+
const TOUCH_CLICK_TOLERANCE_PX = 12;
|
|
19705
19711
|
/**
|
|
19706
19712
|
* Single input owner for every trading line on a chart.
|
|
19707
19713
|
*
|
|
@@ -19720,6 +19726,8 @@ class TradingLineController {
|
|
|
19720
19726
|
this._private__pointerId = null;
|
|
19721
19727
|
this._private__pressOrigin = null;
|
|
19722
19728
|
this._private__pressedLine = null;
|
|
19729
|
+
/** Whether the gesture in flight came from a finger rather than a mouse. */
|
|
19730
|
+
this._private__pressWasTouch = false;
|
|
19723
19731
|
/** Distance from the pointer to the dragged line when the press landed. */
|
|
19724
19732
|
this._private__grabOffset = 0;
|
|
19725
19733
|
/** Latest pointer position in pane coordinates, or null when off the panes. */
|
|
@@ -19784,8 +19792,18 @@ class TradingLineController {
|
|
|
19784
19792
|
this._private__applyCursor();
|
|
19785
19793
|
}
|
|
19786
19794
|
_private__onPointerDown(event) {
|
|
19787
|
-
|
|
19795
|
+
// Hover belongs to the mouse. Touch leaves whatever the last press marked
|
|
19796
|
+
// still marked, so trusting it here grabbed that line again wherever the
|
|
19797
|
+
// next tap landed: every press resolves itself instead.
|
|
19798
|
+
this._private__pressWasTouch = event.pointerType !== 'mouse';
|
|
19799
|
+
let line = this._private__pressWasTouch || this._private__hoveredId === null
|
|
19800
|
+
? null
|
|
19801
|
+
: this._private__lines.get(this._private__hoveredId) ?? null;
|
|
19802
|
+
if (line === null) {
|
|
19803
|
+
line = this._private__resolveHitAt(event);
|
|
19804
|
+
}
|
|
19788
19805
|
if (!line) {
|
|
19806
|
+
this._private__clearTouchHover();
|
|
19789
19807
|
return;
|
|
19790
19808
|
}
|
|
19791
19809
|
this._private__pressOrigin = { _internal_x: event.clientX, _internal_y: event.clientY };
|
|
@@ -19824,14 +19842,16 @@ class TradingLineController {
|
|
|
19824
19842
|
}
|
|
19825
19843
|
_private__onPointerUp(event) {
|
|
19826
19844
|
const dragged = this._private__dragging;
|
|
19845
|
+
const wasTouch = this._private__pressWasTouch;
|
|
19827
19846
|
const pressed = this._private__pressedLine;
|
|
19828
19847
|
const origin = this._private__pressOrigin;
|
|
19829
19848
|
this._private__releasePointer();
|
|
19830
19849
|
this._private__pressedLine = null;
|
|
19831
19850
|
this._private__pressOrigin = null;
|
|
19851
|
+
const tolerance = wasTouch ? TOUCH_CLICK_TOLERANCE_PX : CLICK_TOLERANCE_PX;
|
|
19832
19852
|
const moved = origin !== null &&
|
|
19833
|
-
(Math.abs(event.clientX - origin._internal_x) >
|
|
19834
|
-
Math.abs(event.clientY - origin._internal_y) >
|
|
19853
|
+
(Math.abs(event.clientX - origin._internal_x) > tolerance ||
|
|
19854
|
+
Math.abs(event.clientY - origin._internal_y) > tolerance);
|
|
19835
19855
|
if (dragged !== null) {
|
|
19836
19856
|
this._private__dragging = null;
|
|
19837
19857
|
this._private__grabOffset = 0;
|
|
@@ -19845,12 +19865,24 @@ class TradingLineController {
|
|
|
19845
19865
|
dragged.click();
|
|
19846
19866
|
}
|
|
19847
19867
|
}
|
|
19868
|
+
this._private__clearTouchHover(wasTouch);
|
|
19848
19869
|
this._private__applyCursor();
|
|
19849
19870
|
return;
|
|
19850
19871
|
}
|
|
19851
19872
|
if (pressed !== null && !moved && pressed.isClickable()) {
|
|
19852
19873
|
pressed.click();
|
|
19853
19874
|
}
|
|
19875
|
+
this._private__clearTouchHover(wasTouch);
|
|
19876
|
+
}
|
|
19877
|
+
/** A finger leaves nothing hovered behind it, the way lifting a mouse does. */
|
|
19878
|
+
_private__clearTouchHover(wasTouch = this._private__pressWasTouch) {
|
|
19879
|
+
if (!wasTouch || this._private__hoveredId === null) {
|
|
19880
|
+
return;
|
|
19881
|
+
}
|
|
19882
|
+
const line = this._private__lines.get(this._private__hoveredId) ?? null;
|
|
19883
|
+
this._private__setHovered(null);
|
|
19884
|
+
this._private__setHoveredPart(line, null);
|
|
19885
|
+
this._private__applyCursor();
|
|
19854
19886
|
}
|
|
19855
19887
|
/**
|
|
19856
19888
|
* Abort an in-flight gesture: the line goes back to where it was and no
|
|
@@ -19896,9 +19928,38 @@ class TradingLineController {
|
|
|
19896
19928
|
return paneY === null ? null : line.priceAt(paneY - this._private__grabOffset);
|
|
19897
19929
|
}
|
|
19898
19930
|
/** The pointer's position inside the line's pane, in pane coordinates. */
|
|
19899
|
-
|
|
19931
|
+
/**
|
|
19932
|
+
* The hovered id comes from the crosshair, which touch never moves before it
|
|
19933
|
+
* presses, so the press resolves the target itself.
|
|
19934
|
+
*/
|
|
19935
|
+
_private__resolveHitAt(event) {
|
|
19936
|
+
for (const line of this._private__lines.values()) {
|
|
19937
|
+
if (!line.hitTestAt) {
|
|
19938
|
+
continue;
|
|
19939
|
+
}
|
|
19940
|
+
const paneElement = this._private__paneElementOf(line);
|
|
19941
|
+
if (paneElement === null) {
|
|
19942
|
+
continue;
|
|
19943
|
+
}
|
|
19944
|
+
const rect = paneElement.getBoundingClientRect();
|
|
19945
|
+
// A fingertip is far coarser than a pointer, so its targets are widened.
|
|
19946
|
+
const slop = event.pointerType === 'mouse' ? 0 : 12 /* Constants.TouchSlopPx */;
|
|
19947
|
+
const hit = this._private__splitHit(line.hitTestAt(event.clientX - rect.left, event.clientY - rect.top, slop));
|
|
19948
|
+
if (hit === null) {
|
|
19949
|
+
continue;
|
|
19950
|
+
}
|
|
19951
|
+
this._private__setHovered(line.id());
|
|
19952
|
+
this._private__setHoveredPart(line, hit._internal_part);
|
|
19953
|
+
return line;
|
|
19954
|
+
}
|
|
19955
|
+
return null;
|
|
19956
|
+
}
|
|
19957
|
+
_private__paneElementOf(line) {
|
|
19900
19958
|
const pane = this._private__chart.panes()[line.paneIndex()];
|
|
19901
|
-
|
|
19959
|
+
return pane ? pane.getHTMLElement() : null;
|
|
19960
|
+
}
|
|
19961
|
+
_private__paneY(line, event) {
|
|
19962
|
+
const paneElement = this._private__paneElementOf(line);
|
|
19902
19963
|
if (paneElement) {
|
|
19903
19964
|
return event.clientY - paneElement.getBoundingClientRect().top;
|
|
19904
19965
|
}
|
|
@@ -20015,6 +20076,7 @@ let nextLineId = 0;
|
|
|
20015
20076
|
* line. Hit testing comes from the engine — the line's id travels as the price
|
|
20016
20077
|
* line's `externalId` — so the hit area matches what is drawn.
|
|
20017
20078
|
*/
|
|
20079
|
+
const HIT_TOLERANCE_PX$1 = 8;
|
|
20018
20080
|
class DraggablePriceLine {
|
|
20019
20081
|
constructor(chart, series, options) {
|
|
20020
20082
|
this._private__priceLine = null;
|
|
@@ -20067,6 +20129,14 @@ class DraggablePriceLine {
|
|
|
20067
20129
|
color: hovered ? this._private__options.hoverColor : this._private__originalColor,
|
|
20068
20130
|
});
|
|
20069
20131
|
}
|
|
20132
|
+
/**
|
|
20133
|
+
* The engine draws this one, so there is no pane view to ask: a press within
|
|
20134
|
+
* the line's own grab strip counts as a hit.
|
|
20135
|
+
*/
|
|
20136
|
+
hitTestAt(x, y, slop = 0) {
|
|
20137
|
+
const coord = this._private__series.priceToCoordinate(this._private__options.price);
|
|
20138
|
+
return coord !== null && Math.abs(y - coord) <= HIT_TOLERANCE_PX$1 + slop ? this._private__id : null;
|
|
20139
|
+
}
|
|
20070
20140
|
priceAt(paneY) {
|
|
20071
20141
|
const price = this._private__series.coordinateToPrice(paneY);
|
|
20072
20142
|
return price === null ? null : price;
|
|
@@ -20609,22 +20679,27 @@ class PositionLineRenderer {
|
|
|
20609
20679
|
_internal_setData(data) {
|
|
20610
20680
|
this._private__data = data;
|
|
20611
20681
|
}
|
|
20612
|
-
|
|
20682
|
+
/**
|
|
20683
|
+
* `slop` widens every target by the same amount, for input coarser than a
|
|
20684
|
+
* mouse pointer.
|
|
20685
|
+
*/
|
|
20686
|
+
_internal_hitTest(x, y, slop = 0) {
|
|
20613
20687
|
// The close button sits on top of the label, which sits on top of the
|
|
20614
20688
|
// line, so the narrowest target is tested first.
|
|
20615
20689
|
for (const layout of this._private__layouts) {
|
|
20616
|
-
if (layout._internal_closable && x >= layout._internal_closeLeft && x <= layout._internal_closeRight &&
|
|
20617
|
-
Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2) {
|
|
20690
|
+
if (layout._internal_closable && x >= layout._internal_closeLeft - slop && x <= layout._internal_closeRight + slop &&
|
|
20691
|
+
Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2 + slop) {
|
|
20618
20692
|
return { _internal_level: layout._internal_level, _internal_part: 'close' };
|
|
20619
20693
|
}
|
|
20620
20694
|
}
|
|
20621
20695
|
for (const layout of this._private__layouts) {
|
|
20622
|
-
if (x >= layout._internal_pillLeft && x <= layout._internal_pillRight
|
|
20696
|
+
if (x >= layout._internal_pillLeft - slop && x <= layout._internal_pillRight + slop &&
|
|
20697
|
+
Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2 + slop) {
|
|
20623
20698
|
return { _internal_level: layout._internal_level, _internal_part: 'body' };
|
|
20624
20699
|
}
|
|
20625
20700
|
}
|
|
20626
20701
|
for (const layout of this._private__layouts) {
|
|
20627
|
-
if (Math.abs(y - layout._internal_y) <= 8 /* Constants.LineHitTolerance */) {
|
|
20702
|
+
if (Math.abs(y - layout._internal_y) <= 8 /* Constants.LineHitTolerance */ + slop) {
|
|
20628
20703
|
return { _internal_level: layout._internal_level, _internal_part: 'line' };
|
|
20629
20704
|
}
|
|
20630
20705
|
}
|
|
@@ -20861,8 +20936,8 @@ class PositionLinePaneView {
|
|
|
20861
20936
|
zOrder() {
|
|
20862
20937
|
return 'top';
|
|
20863
20938
|
}
|
|
20864
|
-
_internal_hitTest(x, y) {
|
|
20865
|
-
return this._private__data === null ? null : this._private__renderer._internal_hitTest(x, y);
|
|
20939
|
+
_internal_hitTest(x, y, slop = 0) {
|
|
20940
|
+
return this._private__data === null ? null : this._private__renderer._internal_hitTest(x, y, slop);
|
|
20866
20941
|
}
|
|
20867
20942
|
}
|
|
20868
20943
|
|
|
@@ -21013,6 +21088,13 @@ class PositionLine {
|
|
|
21013
21088
|
* of jumping to sit under it — which matters most when the label has been
|
|
21014
21089
|
* fanned away from its own line.
|
|
21015
21090
|
*/
|
|
21091
|
+
hitTestAt(x, y, slop = 0) {
|
|
21092
|
+
const hit = this._private__paneView._internal_hitTest(x, y, slop);
|
|
21093
|
+
if (hit === null) {
|
|
21094
|
+
return null;
|
|
21095
|
+
}
|
|
21096
|
+
return this._private__levelOptions(hit._internal_level) === null ? null : `${this._private__id}#${hit._internal_level}:${hit._internal_part}`;
|
|
21097
|
+
}
|
|
21016
21098
|
dragAnchorY() {
|
|
21017
21099
|
if (this._private__dragLevel === null) {
|
|
21018
21100
|
return null;
|
|
@@ -30083,6 +30165,7 @@ class DrawingToolsManager {
|
|
|
30083
30165
|
this._private__mouseMoveHandler = null;
|
|
30084
30166
|
this._private__pointerDownHandler = null;
|
|
30085
30167
|
this._private__pointerUpHandler = null;
|
|
30168
|
+
this._private__pointerMoveHandler = null;
|
|
30086
30169
|
this._private__pointerCancelHandler = null;
|
|
30087
30170
|
this._private__lostCaptureHandler = null;
|
|
30088
30171
|
this._private__windowPointerUpHandler = null;
|
|
@@ -30657,10 +30740,12 @@ class DrawingToolsManager {
|
|
|
30657
30740
|
if (chartElement) {
|
|
30658
30741
|
this._private__pointerDownHandler = (event) => this._private__handlePointerDown(event);
|
|
30659
30742
|
this._private__pointerUpHandler = (event) => this._private__handlePointerUp(event);
|
|
30743
|
+
this._private__pointerMoveHandler = (event) => this._private__handlePointerMove(event);
|
|
30660
30744
|
this._private__pointerCancelHandler = (event) => this._private__handlePointerUp(event);
|
|
30661
30745
|
this._private__lostCaptureHandler = (event) => this._private__handleLostPointerCapture(event);
|
|
30662
30746
|
chartElement.addEventListener('pointerdown', this._private__pointerDownHandler);
|
|
30663
30747
|
chartElement.addEventListener('pointerup', this._private__pointerUpHandler);
|
|
30748
|
+
chartElement.addEventListener('pointermove', this._private__pointerMoveHandler);
|
|
30664
30749
|
chartElement.addEventListener('pointercancel', this._private__pointerCancelHandler);
|
|
30665
30750
|
chartElement.addEventListener('lostpointercapture', this._private__lostCaptureHandler);
|
|
30666
30751
|
}
|
|
@@ -30695,6 +30780,10 @@ class DrawingToolsManager {
|
|
|
30695
30780
|
chartElement.removeEventListener('pointerup', this._private__pointerUpHandler);
|
|
30696
30781
|
this._private__pointerUpHandler = null;
|
|
30697
30782
|
}
|
|
30783
|
+
if (this._private__pointerMoveHandler) {
|
|
30784
|
+
chartElement.removeEventListener('pointermove', this._private__pointerMoveHandler);
|
|
30785
|
+
this._private__pointerMoveHandler = null;
|
|
30786
|
+
}
|
|
30698
30787
|
if (this._private__pointerCancelHandler) {
|
|
30699
30788
|
chartElement.removeEventListener('pointercancel', this._private__pointerCancelHandler);
|
|
30700
30789
|
this._private__pointerCancelHandler = null;
|
|
@@ -30844,6 +30933,36 @@ class DrawingToolsManager {
|
|
|
30844
30933
|
// mouse events, and those are what drive the crosshair the drag reads.
|
|
30845
30934
|
this._private__disableChartInteractions();
|
|
30846
30935
|
}
|
|
30936
|
+
/**
|
|
30937
|
+
* The drag reads the crosshair, which touch never moves: its move handler
|
|
30938
|
+
* only tries to pan, and the drag has just turned panning off. So touch is
|
|
30939
|
+
* driven straight from the pointer instead.
|
|
30940
|
+
*/
|
|
30941
|
+
_private__handlePointerMove(event) {
|
|
30942
|
+
if (!this._private__isDragging || this._private__draggedToolId === null || event.pointerType === 'mouse') {
|
|
30943
|
+
return;
|
|
30944
|
+
}
|
|
30945
|
+
if (this._private__pointerId !== null && event.pointerId !== this._private__pointerId) {
|
|
30946
|
+
return;
|
|
30947
|
+
}
|
|
30948
|
+
const tool = this._private__tools.get(this._private__draggedToolId);
|
|
30949
|
+
if (!tool) {
|
|
30950
|
+
return;
|
|
30951
|
+
}
|
|
30952
|
+
const paneElement = this._private__paneElementOf(tool);
|
|
30953
|
+
if (paneElement === null) {
|
|
30954
|
+
return;
|
|
30955
|
+
}
|
|
30956
|
+
const rect = paneElement.getBoundingClientRect();
|
|
30957
|
+
const series = tool.series();
|
|
30958
|
+
const price = series.coordinateToPrice((event.clientY - rect.top));
|
|
30959
|
+
const time = timeFromCoordinate(this._private__chart, series, event.clientX - rect.left);
|
|
30960
|
+
if (price === null || time === null) {
|
|
30961
|
+
return;
|
|
30962
|
+
}
|
|
30963
|
+
tool.updateDrag(time, price);
|
|
30964
|
+
event.preventDefault();
|
|
30965
|
+
}
|
|
30847
30966
|
_private__handlePointerUp(event) {
|
|
30848
30967
|
if (!this._private__isDragging || this._private__draggedToolId === null) {
|
|
30849
30968
|
return;
|
|
@@ -31017,7 +31136,7 @@ const customSeriesDefaultOptions = {
|
|
|
31017
31136
|
* Returns the current version as a string. For example `'1.0.0'`.
|
|
31018
31137
|
*/
|
|
31019
31138
|
function version() {
|
|
31020
|
-
return "2.3.
|
|
31139
|
+
return "2.3.12";
|
|
31021
31140
|
}
|
|
31022
31141
|
|
|
31023
31142
|
export { areaSeries as AreaSeries, ArrowTool, barSeries as BarSeries, baselineSeries as BaselineSeries, BrushTool, candlestickSeries as CandlestickSeries, CircleTool, ColorType, CrossLineTool, CrosshairMode, DEFAULT_SESSIONS, DraggablePriceLine, DrawingToolsManager, EXTENDED_FIBONACCI_RATIOS, FibonacciCalculator, FibonacciExtensionTool, FibonacciFanTool, FibonacciTool, GanttTool, histogramSeries as HistogramSeries, HorizontalLineTool, InteractiveLineManager, LastPriceAnimationMode, lineSeries as LineSeries, LineStyle, LineType, MismatchDirection, ParallelChannelTool, PitchforkTool, PolygonTool, PositionCalculator, PositionLine, PositionMarkersManager, PositionTool, PriceLineSource, PriceScaleMode, RectangleTool, RulerCalculator, RulerTool, STANDARD_FIBONACCI_RATIOS, TextTool, TickMarkType, TrackingModeExitMode, TradingSessionsIndicator, TrendLineTool, VerticalLineTool, VolumeProfileIndicator, applyADX, applyATR, applyBollingerBands, applyCCI, applyDonchianChannels, applyEMA, applyHeikinAshi, applyIchimoku, applyKeltnerChannels, applyMACD, applyMFI, applyOBV, applyParabolicSAR, applyPivotPoints, applyRSI, applySMA, applyStochastic, applySuperTrend, applyVWAP, applyVolume, applyWMA, applyWilliamsR, calculateHeikinAshi, calculatePipConfig, coordinateFromTime, createArrowTool, createBrushTool, createChart, createChartEx, createCircleTool, createCrossLineTool, createFibonacciExtensionTool, createFibonacciFanTool, createFibonacciTool, createGanttTool, createHorizontalLineTool, createImageWatermark, createInteractiveLineManager, createOptionsChart, createParallelChannelTool, createPitchforkTool, createPolygonTool, createPositionLine, createPositionMarkers, createPositionTool, createRectangleTool, createRulerTool, createSeriesMarkers, createTextTool, createTextWatermark, createTradingLine, createTradingSessionsIndicator, createTrendLineTool, createUpDownMarkers, createVerticalLineTool, createVolumeProfileIndicator, createYieldCurveChart, customSeriesDefaultOptions, defaultHorzScaleBehavior, getPipConfig, hideSeriesPaint, isBusinessDay, isUTCTimestamp, setSeriesVolumes, setVolumeProfileData, timeFromCoordinate, version };
|