hyperprop-charting-library 0.1.85 → 0.1.86
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 +88 -2
- package/dist/hyperprop-charting-library.d.ts +4 -2
- package/dist/hyperprop-charting-library.js +88 -2
- package/dist/index.cjs +88 -2
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +88 -2
- package/docs/API.md +1 -0
- package/package.json +1 -1
|
@@ -968,6 +968,7 @@ function createChart(element, options = {}) {
|
|
|
968
968
|
leverage: Number(drawing.leverage) || 1,
|
|
969
969
|
pointValue: Number(drawing.pointValue) || 1,
|
|
970
970
|
qtyPrecision: Number.isFinite(drawing.qtyPrecision) ? Math.max(0, Math.floor(Number(drawing.qtyPrecision))) : 0,
|
|
971
|
+
fontSize: Math.max(6, Number(drawing.fontSize) || 14),
|
|
971
972
|
...drawing.label === void 0 ? {} : { label: drawing.label }
|
|
972
973
|
});
|
|
973
974
|
const serializeDrawing = (drawing) => ({
|
|
@@ -987,6 +988,7 @@ function createChart(element, options = {}) {
|
|
|
987
988
|
leverage: drawing.leverage,
|
|
988
989
|
pointValue: drawing.pointValue,
|
|
989
990
|
qtyPrecision: drawing.qtyPrecision,
|
|
991
|
+
fontSize: drawing.fontSize,
|
|
990
992
|
...drawing.label === void 0 ? {} : { label: drawing.label }
|
|
991
993
|
});
|
|
992
994
|
let indicators = (options.indicators ?? []).map((indicator) => normalizeIndicatorState(indicator));
|
|
@@ -997,6 +999,7 @@ function createChart(element, options = {}) {
|
|
|
997
999
|
let drawingsChangeHandler = null;
|
|
998
1000
|
let drawingSelectHandler = null;
|
|
999
1001
|
let drawingDoubleClickHandler = null;
|
|
1002
|
+
let drawingEditTextHandler = null;
|
|
1000
1003
|
let drawingHoverHandler = null;
|
|
1001
1004
|
let lastHoveredDrawingId = null;
|
|
1002
1005
|
let selectedDrawingId = null;
|
|
@@ -2635,6 +2638,41 @@ function createChart(element, options = {}) {
|
|
|
2635
2638
|
drawDrawingLabel(drawing.label, midX, topY - 4, drawing.color);
|
|
2636
2639
|
}
|
|
2637
2640
|
}
|
|
2641
|
+
} else if (drawing.type === "text" || drawing.type === "note") {
|
|
2642
|
+
const anchor = drawing.points[0];
|
|
2643
|
+
if (anchor) {
|
|
2644
|
+
const ax = xFromDrawingPoint(anchor);
|
|
2645
|
+
const ay = yFromPrice(anchor.price);
|
|
2646
|
+
const isNote = drawing.type === "note";
|
|
2647
|
+
const fontSize = Math.max(6, drawing.fontSize);
|
|
2648
|
+
const prevFont = ctx.font;
|
|
2649
|
+
ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
|
|
2650
|
+
ctx.textAlign = "left";
|
|
2651
|
+
ctx.textBaseline = "top";
|
|
2652
|
+
const lines = (drawing.label ?? "").split("\n");
|
|
2653
|
+
const lineH = Math.round(fontSize * 1.35);
|
|
2654
|
+
const textW = Math.max(1, ...lines.map((line) => ctx.measureText(line).width));
|
|
2655
|
+
const padX = isNote ? 8 : 2;
|
|
2656
|
+
const padY = isNote ? 6 : 1;
|
|
2657
|
+
const blockW = textW + padX * 2;
|
|
2658
|
+
const blockH = lines.length * lineH + padY * 2;
|
|
2659
|
+
ctx.save();
|
|
2660
|
+
ctx.globalAlpha = draft ? 0.7 : 1;
|
|
2661
|
+
if (isNote) {
|
|
2662
|
+
ctx.fillStyle = hexToRgba(drawing.color, 0.14);
|
|
2663
|
+
fillRoundedRect(ax, ay, blockW, blockH, 4);
|
|
2664
|
+
ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
|
|
2665
|
+
ctx.lineWidth = 1;
|
|
2666
|
+
strokeRoundedRect(ax, ay, blockW, blockH, 4);
|
|
2667
|
+
}
|
|
2668
|
+
ctx.fillStyle = drawing.color;
|
|
2669
|
+
lines.forEach((line, lineIndex) => ctx.fillText(line, ax + padX, ay + padY + lineIndex * lineH));
|
|
2670
|
+
ctx.restore();
|
|
2671
|
+
ctx.font = prevFont;
|
|
2672
|
+
if (isSelected) {
|
|
2673
|
+
drawDrawingHandle(ax, ay, drawing.color);
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2638
2676
|
}
|
|
2639
2677
|
ctx.restore();
|
|
2640
2678
|
};
|
|
@@ -3883,6 +3921,27 @@ function createChart(element, options = {}) {
|
|
|
3883
3921
|
if (x >= Math.min(px0, px1) && x <= Math.max(px0, px1) && y >= Math.min(y0, y1) && y <= Math.max(y0, y1)) {
|
|
3884
3922
|
return { drawing, target: "line" };
|
|
3885
3923
|
}
|
|
3924
|
+
} else if (drawing.type === "text" || drawing.type === "note") {
|
|
3925
|
+
const anchor = drawing.points[0];
|
|
3926
|
+
if (!anchor) continue;
|
|
3927
|
+
const ax = canvasXFromDrawingPoint(anchor);
|
|
3928
|
+
const ay = canvasYFromDrawingPrice(anchor.price);
|
|
3929
|
+
if (Math.hypot(x - ax, y - ay) <= 9) return { drawing, target: "handle", pointIndex: 0 };
|
|
3930
|
+
const fontSize = Math.max(6, drawing.fontSize);
|
|
3931
|
+
const prevFont = ctx.font;
|
|
3932
|
+
ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
|
|
3933
|
+
const lines = (drawing.label ?? "").split("\n");
|
|
3934
|
+
const textW = Math.max(1, ...lines.map((line) => ctx.measureText(line).width));
|
|
3935
|
+
ctx.font = prevFont;
|
|
3936
|
+
const isNote = drawing.type === "note";
|
|
3937
|
+
const padX = isNote ? 8 : 2;
|
|
3938
|
+
const padY = isNote ? 6 : 1;
|
|
3939
|
+
const lineH = Math.round(fontSize * 1.35);
|
|
3940
|
+
const blockW = textW + padX * 2;
|
|
3941
|
+
const blockH = lines.length * lineH + padY * 2;
|
|
3942
|
+
if (x >= ax && x <= ax + blockW && y >= ay && y <= ay + blockH) {
|
|
3943
|
+
return { drawing, target: "line" };
|
|
3944
|
+
}
|
|
3886
3945
|
}
|
|
3887
3946
|
}
|
|
3888
3947
|
return null;
|
|
@@ -4083,6 +4142,24 @@ function createChart(element, options = {}) {
|
|
|
4083
4142
|
draw();
|
|
4084
4143
|
return true;
|
|
4085
4144
|
}
|
|
4145
|
+
if (activeDrawingTool === "text" || activeDrawingTool === "note") {
|
|
4146
|
+
const defaults = getDrawingToolDefaults(activeDrawingTool);
|
|
4147
|
+
const created = normalizeDrawingState({
|
|
4148
|
+
type: activeDrawingTool,
|
|
4149
|
+
points: [point],
|
|
4150
|
+
color: defaults.color ?? "#e2e8f0",
|
|
4151
|
+
style: defaults.style ?? "solid",
|
|
4152
|
+
width: defaults.width ?? 1,
|
|
4153
|
+
...defaults.fontSize === void 0 ? {} : { fontSize: defaults.fontSize },
|
|
4154
|
+
label: ""
|
|
4155
|
+
});
|
|
4156
|
+
drawings.push(created);
|
|
4157
|
+
selectedDrawingId = created.id;
|
|
4158
|
+
emitDrawingsChange();
|
|
4159
|
+
draw();
|
|
4160
|
+
drawingEditTextHandler?.({ drawing: serializeDrawing(created), target: "line", x, y });
|
|
4161
|
+
return true;
|
|
4162
|
+
}
|
|
4086
4163
|
if (activeDrawingTool === "price-range") {
|
|
4087
4164
|
const tick = getConfiguredTickSize();
|
|
4088
4165
|
const visibleRange = drawState.yMax - drawState.yMin;
|
|
@@ -4705,13 +4782,18 @@ function createChart(element, options = {}) {
|
|
|
4705
4782
|
const drawingHit = getDrawingHit(point.x, point.y);
|
|
4706
4783
|
if (drawingHit) {
|
|
4707
4784
|
selectedDrawingId = drawingHit.drawing.id;
|
|
4708
|
-
|
|
4785
|
+
const payload = {
|
|
4709
4786
|
drawing: serializeDrawing(drawingHit.drawing),
|
|
4710
4787
|
target: drawingHit.target,
|
|
4711
4788
|
...drawingHit.pointIndex === void 0 ? {} : { pointIndex: drawingHit.pointIndex },
|
|
4712
4789
|
x: point.x,
|
|
4713
4790
|
y: point.y
|
|
4714
|
-
}
|
|
4791
|
+
};
|
|
4792
|
+
if (drawingHit.drawing.type === "text" || drawingHit.drawing.type === "note") {
|
|
4793
|
+
drawingEditTextHandler?.(payload);
|
|
4794
|
+
} else {
|
|
4795
|
+
drawingDoubleClickHandler?.(payload);
|
|
4796
|
+
}
|
|
4715
4797
|
return;
|
|
4716
4798
|
}
|
|
4717
4799
|
}
|
|
@@ -5028,6 +5110,9 @@ function createChart(element, options = {}) {
|
|
|
5028
5110
|
const onDrawingDoubleClick = (handler) => {
|
|
5029
5111
|
drawingDoubleClickHandler = handler;
|
|
5030
5112
|
};
|
|
5113
|
+
const onDrawingEditText = (handler) => {
|
|
5114
|
+
drawingEditTextHandler = handler;
|
|
5115
|
+
};
|
|
5031
5116
|
const onDrawingHover = (handler) => {
|
|
5032
5117
|
drawingHoverHandler = handler;
|
|
5033
5118
|
};
|
|
@@ -5086,6 +5171,7 @@ function createChart(element, options = {}) {
|
|
|
5086
5171
|
onDrawingsChange,
|
|
5087
5172
|
onDrawingSelect,
|
|
5088
5173
|
onDrawingDoubleClick,
|
|
5174
|
+
onDrawingEditText,
|
|
5089
5175
|
setSelectedDrawing,
|
|
5090
5176
|
onDrawingHover,
|
|
5091
5177
|
setDrawingDefaults,
|
|
@@ -44,7 +44,7 @@ interface ChartOptions {
|
|
|
44
44
|
drawings?: DrawingObjectOptions[];
|
|
45
45
|
}
|
|
46
46
|
type IndicatorPane = "overlay" | "separate";
|
|
47
|
-
type DrawingToolType = "horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range";
|
|
47
|
+
type DrawingToolType = "horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "text" | "note";
|
|
48
48
|
interface DrawingPoint {
|
|
49
49
|
index: number;
|
|
50
50
|
price: number;
|
|
@@ -73,6 +73,7 @@ interface DrawingObjectOptions {
|
|
|
73
73
|
leverage?: number;
|
|
74
74
|
pointValue?: number;
|
|
75
75
|
qtyPrecision?: number;
|
|
76
|
+
fontSize?: number;
|
|
76
77
|
}
|
|
77
78
|
/** Default colors for position tools: [profit, loss, label text]. */
|
|
78
79
|
declare const POSITION_DEFAULT_COLORS: string[];
|
|
@@ -91,7 +92,7 @@ interface DrawingHoverEvent {
|
|
|
91
92
|
x: number;
|
|
92
93
|
y: number;
|
|
93
94
|
}
|
|
94
|
-
type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width" | "accountSize" | "lotSize" | "risk" | "riskMode" | "leverage" | "pointValue" | "qtyPrecision">>;
|
|
95
|
+
type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width" | "accountSize" | "lotSize" | "risk" | "riskMode" | "leverage" | "pointValue" | "qtyPrecision" | "fontSize">>;
|
|
95
96
|
interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
|
|
96
97
|
id?: string;
|
|
97
98
|
type: string;
|
|
@@ -428,6 +429,7 @@ interface ChartInstance {
|
|
|
428
429
|
onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
|
|
429
430
|
onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
430
431
|
onDrawingDoubleClick: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
432
|
+
onDrawingEditText: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
431
433
|
onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
|
|
432
434
|
setDrawingDefaults: (tool: DrawingToolType, defaults: DrawingDefaults | null) => void;
|
|
433
435
|
setSelectedDrawing: (id: string | null) => void;
|
|
@@ -942,6 +942,7 @@ function createChart(element, options = {}) {
|
|
|
942
942
|
leverage: Number(drawing.leverage) || 1,
|
|
943
943
|
pointValue: Number(drawing.pointValue) || 1,
|
|
944
944
|
qtyPrecision: Number.isFinite(drawing.qtyPrecision) ? Math.max(0, Math.floor(Number(drawing.qtyPrecision))) : 0,
|
|
945
|
+
fontSize: Math.max(6, Number(drawing.fontSize) || 14),
|
|
945
946
|
...drawing.label === void 0 ? {} : { label: drawing.label }
|
|
946
947
|
});
|
|
947
948
|
const serializeDrawing = (drawing) => ({
|
|
@@ -961,6 +962,7 @@ function createChart(element, options = {}) {
|
|
|
961
962
|
leverage: drawing.leverage,
|
|
962
963
|
pointValue: drawing.pointValue,
|
|
963
964
|
qtyPrecision: drawing.qtyPrecision,
|
|
965
|
+
fontSize: drawing.fontSize,
|
|
964
966
|
...drawing.label === void 0 ? {} : { label: drawing.label }
|
|
965
967
|
});
|
|
966
968
|
let indicators = (options.indicators ?? []).map((indicator) => normalizeIndicatorState(indicator));
|
|
@@ -971,6 +973,7 @@ function createChart(element, options = {}) {
|
|
|
971
973
|
let drawingsChangeHandler = null;
|
|
972
974
|
let drawingSelectHandler = null;
|
|
973
975
|
let drawingDoubleClickHandler = null;
|
|
976
|
+
let drawingEditTextHandler = null;
|
|
974
977
|
let drawingHoverHandler = null;
|
|
975
978
|
let lastHoveredDrawingId = null;
|
|
976
979
|
let selectedDrawingId = null;
|
|
@@ -2609,6 +2612,41 @@ function createChart(element, options = {}) {
|
|
|
2609
2612
|
drawDrawingLabel(drawing.label, midX, topY - 4, drawing.color);
|
|
2610
2613
|
}
|
|
2611
2614
|
}
|
|
2615
|
+
} else if (drawing.type === "text" || drawing.type === "note") {
|
|
2616
|
+
const anchor = drawing.points[0];
|
|
2617
|
+
if (anchor) {
|
|
2618
|
+
const ax = xFromDrawingPoint(anchor);
|
|
2619
|
+
const ay = yFromPrice(anchor.price);
|
|
2620
|
+
const isNote = drawing.type === "note";
|
|
2621
|
+
const fontSize = Math.max(6, drawing.fontSize);
|
|
2622
|
+
const prevFont = ctx.font;
|
|
2623
|
+
ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
|
|
2624
|
+
ctx.textAlign = "left";
|
|
2625
|
+
ctx.textBaseline = "top";
|
|
2626
|
+
const lines = (drawing.label ?? "").split("\n");
|
|
2627
|
+
const lineH = Math.round(fontSize * 1.35);
|
|
2628
|
+
const textW = Math.max(1, ...lines.map((line) => ctx.measureText(line).width));
|
|
2629
|
+
const padX = isNote ? 8 : 2;
|
|
2630
|
+
const padY = isNote ? 6 : 1;
|
|
2631
|
+
const blockW = textW + padX * 2;
|
|
2632
|
+
const blockH = lines.length * lineH + padY * 2;
|
|
2633
|
+
ctx.save();
|
|
2634
|
+
ctx.globalAlpha = draft ? 0.7 : 1;
|
|
2635
|
+
if (isNote) {
|
|
2636
|
+
ctx.fillStyle = hexToRgba(drawing.color, 0.14);
|
|
2637
|
+
fillRoundedRect(ax, ay, blockW, blockH, 4);
|
|
2638
|
+
ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
|
|
2639
|
+
ctx.lineWidth = 1;
|
|
2640
|
+
strokeRoundedRect(ax, ay, blockW, blockH, 4);
|
|
2641
|
+
}
|
|
2642
|
+
ctx.fillStyle = drawing.color;
|
|
2643
|
+
lines.forEach((line, lineIndex) => ctx.fillText(line, ax + padX, ay + padY + lineIndex * lineH));
|
|
2644
|
+
ctx.restore();
|
|
2645
|
+
ctx.font = prevFont;
|
|
2646
|
+
if (isSelected) {
|
|
2647
|
+
drawDrawingHandle(ax, ay, drawing.color);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2612
2650
|
}
|
|
2613
2651
|
ctx.restore();
|
|
2614
2652
|
};
|
|
@@ -3857,6 +3895,27 @@ function createChart(element, options = {}) {
|
|
|
3857
3895
|
if (x >= Math.min(px0, px1) && x <= Math.max(px0, px1) && y >= Math.min(y0, y1) && y <= Math.max(y0, y1)) {
|
|
3858
3896
|
return { drawing, target: "line" };
|
|
3859
3897
|
}
|
|
3898
|
+
} else if (drawing.type === "text" || drawing.type === "note") {
|
|
3899
|
+
const anchor = drawing.points[0];
|
|
3900
|
+
if (!anchor) continue;
|
|
3901
|
+
const ax = canvasXFromDrawingPoint(anchor);
|
|
3902
|
+
const ay = canvasYFromDrawingPrice(anchor.price);
|
|
3903
|
+
if (Math.hypot(x - ax, y - ay) <= 9) return { drawing, target: "handle", pointIndex: 0 };
|
|
3904
|
+
const fontSize = Math.max(6, drawing.fontSize);
|
|
3905
|
+
const prevFont = ctx.font;
|
|
3906
|
+
ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
|
|
3907
|
+
const lines = (drawing.label ?? "").split("\n");
|
|
3908
|
+
const textW = Math.max(1, ...lines.map((line) => ctx.measureText(line).width));
|
|
3909
|
+
ctx.font = prevFont;
|
|
3910
|
+
const isNote = drawing.type === "note";
|
|
3911
|
+
const padX = isNote ? 8 : 2;
|
|
3912
|
+
const padY = isNote ? 6 : 1;
|
|
3913
|
+
const lineH = Math.round(fontSize * 1.35);
|
|
3914
|
+
const blockW = textW + padX * 2;
|
|
3915
|
+
const blockH = lines.length * lineH + padY * 2;
|
|
3916
|
+
if (x >= ax && x <= ax + blockW && y >= ay && y <= ay + blockH) {
|
|
3917
|
+
return { drawing, target: "line" };
|
|
3918
|
+
}
|
|
3860
3919
|
}
|
|
3861
3920
|
}
|
|
3862
3921
|
return null;
|
|
@@ -4057,6 +4116,24 @@ function createChart(element, options = {}) {
|
|
|
4057
4116
|
draw();
|
|
4058
4117
|
return true;
|
|
4059
4118
|
}
|
|
4119
|
+
if (activeDrawingTool === "text" || activeDrawingTool === "note") {
|
|
4120
|
+
const defaults = getDrawingToolDefaults(activeDrawingTool);
|
|
4121
|
+
const created = normalizeDrawingState({
|
|
4122
|
+
type: activeDrawingTool,
|
|
4123
|
+
points: [point],
|
|
4124
|
+
color: defaults.color ?? "#e2e8f0",
|
|
4125
|
+
style: defaults.style ?? "solid",
|
|
4126
|
+
width: defaults.width ?? 1,
|
|
4127
|
+
...defaults.fontSize === void 0 ? {} : { fontSize: defaults.fontSize },
|
|
4128
|
+
label: ""
|
|
4129
|
+
});
|
|
4130
|
+
drawings.push(created);
|
|
4131
|
+
selectedDrawingId = created.id;
|
|
4132
|
+
emitDrawingsChange();
|
|
4133
|
+
draw();
|
|
4134
|
+
drawingEditTextHandler?.({ drawing: serializeDrawing(created), target: "line", x, y });
|
|
4135
|
+
return true;
|
|
4136
|
+
}
|
|
4060
4137
|
if (activeDrawingTool === "price-range") {
|
|
4061
4138
|
const tick = getConfiguredTickSize();
|
|
4062
4139
|
const visibleRange = drawState.yMax - drawState.yMin;
|
|
@@ -4679,13 +4756,18 @@ function createChart(element, options = {}) {
|
|
|
4679
4756
|
const drawingHit = getDrawingHit(point.x, point.y);
|
|
4680
4757
|
if (drawingHit) {
|
|
4681
4758
|
selectedDrawingId = drawingHit.drawing.id;
|
|
4682
|
-
|
|
4759
|
+
const payload = {
|
|
4683
4760
|
drawing: serializeDrawing(drawingHit.drawing),
|
|
4684
4761
|
target: drawingHit.target,
|
|
4685
4762
|
...drawingHit.pointIndex === void 0 ? {} : { pointIndex: drawingHit.pointIndex },
|
|
4686
4763
|
x: point.x,
|
|
4687
4764
|
y: point.y
|
|
4688
|
-
}
|
|
4765
|
+
};
|
|
4766
|
+
if (drawingHit.drawing.type === "text" || drawingHit.drawing.type === "note") {
|
|
4767
|
+
drawingEditTextHandler?.(payload);
|
|
4768
|
+
} else {
|
|
4769
|
+
drawingDoubleClickHandler?.(payload);
|
|
4770
|
+
}
|
|
4689
4771
|
return;
|
|
4690
4772
|
}
|
|
4691
4773
|
}
|
|
@@ -5002,6 +5084,9 @@ function createChart(element, options = {}) {
|
|
|
5002
5084
|
const onDrawingDoubleClick = (handler) => {
|
|
5003
5085
|
drawingDoubleClickHandler = handler;
|
|
5004
5086
|
};
|
|
5087
|
+
const onDrawingEditText = (handler) => {
|
|
5088
|
+
drawingEditTextHandler = handler;
|
|
5089
|
+
};
|
|
5005
5090
|
const onDrawingHover = (handler) => {
|
|
5006
5091
|
drawingHoverHandler = handler;
|
|
5007
5092
|
};
|
|
@@ -5060,6 +5145,7 @@ function createChart(element, options = {}) {
|
|
|
5060
5145
|
onDrawingsChange,
|
|
5061
5146
|
onDrawingSelect,
|
|
5062
5147
|
onDrawingDoubleClick,
|
|
5148
|
+
onDrawingEditText,
|
|
5063
5149
|
setSelectedDrawing,
|
|
5064
5150
|
onDrawingHover,
|
|
5065
5151
|
setDrawingDefaults,
|
package/dist/index.cjs
CHANGED
|
@@ -968,6 +968,7 @@ function createChart(element, options = {}) {
|
|
|
968
968
|
leverage: Number(drawing.leverage) || 1,
|
|
969
969
|
pointValue: Number(drawing.pointValue) || 1,
|
|
970
970
|
qtyPrecision: Number.isFinite(drawing.qtyPrecision) ? Math.max(0, Math.floor(Number(drawing.qtyPrecision))) : 0,
|
|
971
|
+
fontSize: Math.max(6, Number(drawing.fontSize) || 14),
|
|
971
972
|
...drawing.label === void 0 ? {} : { label: drawing.label }
|
|
972
973
|
});
|
|
973
974
|
const serializeDrawing = (drawing) => ({
|
|
@@ -987,6 +988,7 @@ function createChart(element, options = {}) {
|
|
|
987
988
|
leverage: drawing.leverage,
|
|
988
989
|
pointValue: drawing.pointValue,
|
|
989
990
|
qtyPrecision: drawing.qtyPrecision,
|
|
991
|
+
fontSize: drawing.fontSize,
|
|
990
992
|
...drawing.label === void 0 ? {} : { label: drawing.label }
|
|
991
993
|
});
|
|
992
994
|
let indicators = (options.indicators ?? []).map((indicator) => normalizeIndicatorState(indicator));
|
|
@@ -997,6 +999,7 @@ function createChart(element, options = {}) {
|
|
|
997
999
|
let drawingsChangeHandler = null;
|
|
998
1000
|
let drawingSelectHandler = null;
|
|
999
1001
|
let drawingDoubleClickHandler = null;
|
|
1002
|
+
let drawingEditTextHandler = null;
|
|
1000
1003
|
let drawingHoverHandler = null;
|
|
1001
1004
|
let lastHoveredDrawingId = null;
|
|
1002
1005
|
let selectedDrawingId = null;
|
|
@@ -2635,6 +2638,41 @@ function createChart(element, options = {}) {
|
|
|
2635
2638
|
drawDrawingLabel(drawing.label, midX, topY - 4, drawing.color);
|
|
2636
2639
|
}
|
|
2637
2640
|
}
|
|
2641
|
+
} else if (drawing.type === "text" || drawing.type === "note") {
|
|
2642
|
+
const anchor = drawing.points[0];
|
|
2643
|
+
if (anchor) {
|
|
2644
|
+
const ax = xFromDrawingPoint(anchor);
|
|
2645
|
+
const ay = yFromPrice(anchor.price);
|
|
2646
|
+
const isNote = drawing.type === "note";
|
|
2647
|
+
const fontSize = Math.max(6, drawing.fontSize);
|
|
2648
|
+
const prevFont = ctx.font;
|
|
2649
|
+
ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
|
|
2650
|
+
ctx.textAlign = "left";
|
|
2651
|
+
ctx.textBaseline = "top";
|
|
2652
|
+
const lines = (drawing.label ?? "").split("\n");
|
|
2653
|
+
const lineH = Math.round(fontSize * 1.35);
|
|
2654
|
+
const textW = Math.max(1, ...lines.map((line) => ctx.measureText(line).width));
|
|
2655
|
+
const padX = isNote ? 8 : 2;
|
|
2656
|
+
const padY = isNote ? 6 : 1;
|
|
2657
|
+
const blockW = textW + padX * 2;
|
|
2658
|
+
const blockH = lines.length * lineH + padY * 2;
|
|
2659
|
+
ctx.save();
|
|
2660
|
+
ctx.globalAlpha = draft ? 0.7 : 1;
|
|
2661
|
+
if (isNote) {
|
|
2662
|
+
ctx.fillStyle = hexToRgba(drawing.color, 0.14);
|
|
2663
|
+
fillRoundedRect(ax, ay, blockW, blockH, 4);
|
|
2664
|
+
ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
|
|
2665
|
+
ctx.lineWidth = 1;
|
|
2666
|
+
strokeRoundedRect(ax, ay, blockW, blockH, 4);
|
|
2667
|
+
}
|
|
2668
|
+
ctx.fillStyle = drawing.color;
|
|
2669
|
+
lines.forEach((line, lineIndex) => ctx.fillText(line, ax + padX, ay + padY + lineIndex * lineH));
|
|
2670
|
+
ctx.restore();
|
|
2671
|
+
ctx.font = prevFont;
|
|
2672
|
+
if (isSelected) {
|
|
2673
|
+
drawDrawingHandle(ax, ay, drawing.color);
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2638
2676
|
}
|
|
2639
2677
|
ctx.restore();
|
|
2640
2678
|
};
|
|
@@ -3883,6 +3921,27 @@ function createChart(element, options = {}) {
|
|
|
3883
3921
|
if (x >= Math.min(px0, px1) && x <= Math.max(px0, px1) && y >= Math.min(y0, y1) && y <= Math.max(y0, y1)) {
|
|
3884
3922
|
return { drawing, target: "line" };
|
|
3885
3923
|
}
|
|
3924
|
+
} else if (drawing.type === "text" || drawing.type === "note") {
|
|
3925
|
+
const anchor = drawing.points[0];
|
|
3926
|
+
if (!anchor) continue;
|
|
3927
|
+
const ax = canvasXFromDrawingPoint(anchor);
|
|
3928
|
+
const ay = canvasYFromDrawingPrice(anchor.price);
|
|
3929
|
+
if (Math.hypot(x - ax, y - ay) <= 9) return { drawing, target: "handle", pointIndex: 0 };
|
|
3930
|
+
const fontSize = Math.max(6, drawing.fontSize);
|
|
3931
|
+
const prevFont = ctx.font;
|
|
3932
|
+
ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
|
|
3933
|
+
const lines = (drawing.label ?? "").split("\n");
|
|
3934
|
+
const textW = Math.max(1, ...lines.map((line) => ctx.measureText(line).width));
|
|
3935
|
+
ctx.font = prevFont;
|
|
3936
|
+
const isNote = drawing.type === "note";
|
|
3937
|
+
const padX = isNote ? 8 : 2;
|
|
3938
|
+
const padY = isNote ? 6 : 1;
|
|
3939
|
+
const lineH = Math.round(fontSize * 1.35);
|
|
3940
|
+
const blockW = textW + padX * 2;
|
|
3941
|
+
const blockH = lines.length * lineH + padY * 2;
|
|
3942
|
+
if (x >= ax && x <= ax + blockW && y >= ay && y <= ay + blockH) {
|
|
3943
|
+
return { drawing, target: "line" };
|
|
3944
|
+
}
|
|
3886
3945
|
}
|
|
3887
3946
|
}
|
|
3888
3947
|
return null;
|
|
@@ -4083,6 +4142,24 @@ function createChart(element, options = {}) {
|
|
|
4083
4142
|
draw();
|
|
4084
4143
|
return true;
|
|
4085
4144
|
}
|
|
4145
|
+
if (activeDrawingTool === "text" || activeDrawingTool === "note") {
|
|
4146
|
+
const defaults = getDrawingToolDefaults(activeDrawingTool);
|
|
4147
|
+
const created = normalizeDrawingState({
|
|
4148
|
+
type: activeDrawingTool,
|
|
4149
|
+
points: [point],
|
|
4150
|
+
color: defaults.color ?? "#e2e8f0",
|
|
4151
|
+
style: defaults.style ?? "solid",
|
|
4152
|
+
width: defaults.width ?? 1,
|
|
4153
|
+
...defaults.fontSize === void 0 ? {} : { fontSize: defaults.fontSize },
|
|
4154
|
+
label: ""
|
|
4155
|
+
});
|
|
4156
|
+
drawings.push(created);
|
|
4157
|
+
selectedDrawingId = created.id;
|
|
4158
|
+
emitDrawingsChange();
|
|
4159
|
+
draw();
|
|
4160
|
+
drawingEditTextHandler?.({ drawing: serializeDrawing(created), target: "line", x, y });
|
|
4161
|
+
return true;
|
|
4162
|
+
}
|
|
4086
4163
|
if (activeDrawingTool === "price-range") {
|
|
4087
4164
|
const tick = getConfiguredTickSize();
|
|
4088
4165
|
const visibleRange = drawState.yMax - drawState.yMin;
|
|
@@ -4705,13 +4782,18 @@ function createChart(element, options = {}) {
|
|
|
4705
4782
|
const drawingHit = getDrawingHit(point.x, point.y);
|
|
4706
4783
|
if (drawingHit) {
|
|
4707
4784
|
selectedDrawingId = drawingHit.drawing.id;
|
|
4708
|
-
|
|
4785
|
+
const payload = {
|
|
4709
4786
|
drawing: serializeDrawing(drawingHit.drawing),
|
|
4710
4787
|
target: drawingHit.target,
|
|
4711
4788
|
...drawingHit.pointIndex === void 0 ? {} : { pointIndex: drawingHit.pointIndex },
|
|
4712
4789
|
x: point.x,
|
|
4713
4790
|
y: point.y
|
|
4714
|
-
}
|
|
4791
|
+
};
|
|
4792
|
+
if (drawingHit.drawing.type === "text" || drawingHit.drawing.type === "note") {
|
|
4793
|
+
drawingEditTextHandler?.(payload);
|
|
4794
|
+
} else {
|
|
4795
|
+
drawingDoubleClickHandler?.(payload);
|
|
4796
|
+
}
|
|
4715
4797
|
return;
|
|
4716
4798
|
}
|
|
4717
4799
|
}
|
|
@@ -5028,6 +5110,9 @@ function createChart(element, options = {}) {
|
|
|
5028
5110
|
const onDrawingDoubleClick = (handler) => {
|
|
5029
5111
|
drawingDoubleClickHandler = handler;
|
|
5030
5112
|
};
|
|
5113
|
+
const onDrawingEditText = (handler) => {
|
|
5114
|
+
drawingEditTextHandler = handler;
|
|
5115
|
+
};
|
|
5031
5116
|
const onDrawingHover = (handler) => {
|
|
5032
5117
|
drawingHoverHandler = handler;
|
|
5033
5118
|
};
|
|
@@ -5086,6 +5171,7 @@ function createChart(element, options = {}) {
|
|
|
5086
5171
|
onDrawingsChange,
|
|
5087
5172
|
onDrawingSelect,
|
|
5088
5173
|
onDrawingDoubleClick,
|
|
5174
|
+
onDrawingEditText,
|
|
5089
5175
|
setSelectedDrawing,
|
|
5090
5176
|
onDrawingHover,
|
|
5091
5177
|
setDrawingDefaults,
|
package/dist/index.d.cts
CHANGED
|
@@ -44,7 +44,7 @@ interface ChartOptions {
|
|
|
44
44
|
drawings?: DrawingObjectOptions[];
|
|
45
45
|
}
|
|
46
46
|
type IndicatorPane = "overlay" | "separate";
|
|
47
|
-
type DrawingToolType = "horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range";
|
|
47
|
+
type DrawingToolType = "horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "text" | "note";
|
|
48
48
|
interface DrawingPoint {
|
|
49
49
|
index: number;
|
|
50
50
|
price: number;
|
|
@@ -73,6 +73,7 @@ interface DrawingObjectOptions {
|
|
|
73
73
|
leverage?: number;
|
|
74
74
|
pointValue?: number;
|
|
75
75
|
qtyPrecision?: number;
|
|
76
|
+
fontSize?: number;
|
|
76
77
|
}
|
|
77
78
|
/** Default colors for position tools: [profit, loss, label text]. */
|
|
78
79
|
declare const POSITION_DEFAULT_COLORS: string[];
|
|
@@ -91,7 +92,7 @@ interface DrawingHoverEvent {
|
|
|
91
92
|
x: number;
|
|
92
93
|
y: number;
|
|
93
94
|
}
|
|
94
|
-
type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width" | "accountSize" | "lotSize" | "risk" | "riskMode" | "leverage" | "pointValue" | "qtyPrecision">>;
|
|
95
|
+
type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width" | "accountSize" | "lotSize" | "risk" | "riskMode" | "leverage" | "pointValue" | "qtyPrecision" | "fontSize">>;
|
|
95
96
|
interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
|
|
96
97
|
id?: string;
|
|
97
98
|
type: string;
|
|
@@ -428,6 +429,7 @@ interface ChartInstance {
|
|
|
428
429
|
onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
|
|
429
430
|
onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
430
431
|
onDrawingDoubleClick: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
432
|
+
onDrawingEditText: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
431
433
|
onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
|
|
432
434
|
setDrawingDefaults: (tool: DrawingToolType, defaults: DrawingDefaults | null) => void;
|
|
433
435
|
setSelectedDrawing: (id: string | null) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ interface ChartOptions {
|
|
|
44
44
|
drawings?: DrawingObjectOptions[];
|
|
45
45
|
}
|
|
46
46
|
type IndicatorPane = "overlay" | "separate";
|
|
47
|
-
type DrawingToolType = "horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range";
|
|
47
|
+
type DrawingToolType = "horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "text" | "note";
|
|
48
48
|
interface DrawingPoint {
|
|
49
49
|
index: number;
|
|
50
50
|
price: number;
|
|
@@ -73,6 +73,7 @@ interface DrawingObjectOptions {
|
|
|
73
73
|
leverage?: number;
|
|
74
74
|
pointValue?: number;
|
|
75
75
|
qtyPrecision?: number;
|
|
76
|
+
fontSize?: number;
|
|
76
77
|
}
|
|
77
78
|
/** Default colors for position tools: [profit, loss, label text]. */
|
|
78
79
|
declare const POSITION_DEFAULT_COLORS: string[];
|
|
@@ -91,7 +92,7 @@ interface DrawingHoverEvent {
|
|
|
91
92
|
x: number;
|
|
92
93
|
y: number;
|
|
93
94
|
}
|
|
94
|
-
type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width" | "accountSize" | "lotSize" | "risk" | "riskMode" | "leverage" | "pointValue" | "qtyPrecision">>;
|
|
95
|
+
type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width" | "accountSize" | "lotSize" | "risk" | "riskMode" | "leverage" | "pointValue" | "qtyPrecision" | "fontSize">>;
|
|
95
96
|
interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
|
|
96
97
|
id?: string;
|
|
97
98
|
type: string;
|
|
@@ -428,6 +429,7 @@ interface ChartInstance {
|
|
|
428
429
|
onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
|
|
429
430
|
onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
430
431
|
onDrawingDoubleClick: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
432
|
+
onDrawingEditText: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
431
433
|
onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
|
|
432
434
|
setDrawingDefaults: (tool: DrawingToolType, defaults: DrawingDefaults | null) => void;
|
|
433
435
|
setSelectedDrawing: (id: string | null) => void;
|
package/dist/index.js
CHANGED
|
@@ -942,6 +942,7 @@ function createChart(element, options = {}) {
|
|
|
942
942
|
leverage: Number(drawing.leverage) || 1,
|
|
943
943
|
pointValue: Number(drawing.pointValue) || 1,
|
|
944
944
|
qtyPrecision: Number.isFinite(drawing.qtyPrecision) ? Math.max(0, Math.floor(Number(drawing.qtyPrecision))) : 0,
|
|
945
|
+
fontSize: Math.max(6, Number(drawing.fontSize) || 14),
|
|
945
946
|
...drawing.label === void 0 ? {} : { label: drawing.label }
|
|
946
947
|
});
|
|
947
948
|
const serializeDrawing = (drawing) => ({
|
|
@@ -961,6 +962,7 @@ function createChart(element, options = {}) {
|
|
|
961
962
|
leverage: drawing.leverage,
|
|
962
963
|
pointValue: drawing.pointValue,
|
|
963
964
|
qtyPrecision: drawing.qtyPrecision,
|
|
965
|
+
fontSize: drawing.fontSize,
|
|
964
966
|
...drawing.label === void 0 ? {} : { label: drawing.label }
|
|
965
967
|
});
|
|
966
968
|
let indicators = (options.indicators ?? []).map((indicator) => normalizeIndicatorState(indicator));
|
|
@@ -971,6 +973,7 @@ function createChart(element, options = {}) {
|
|
|
971
973
|
let drawingsChangeHandler = null;
|
|
972
974
|
let drawingSelectHandler = null;
|
|
973
975
|
let drawingDoubleClickHandler = null;
|
|
976
|
+
let drawingEditTextHandler = null;
|
|
974
977
|
let drawingHoverHandler = null;
|
|
975
978
|
let lastHoveredDrawingId = null;
|
|
976
979
|
let selectedDrawingId = null;
|
|
@@ -2609,6 +2612,41 @@ function createChart(element, options = {}) {
|
|
|
2609
2612
|
drawDrawingLabel(drawing.label, midX, topY - 4, drawing.color);
|
|
2610
2613
|
}
|
|
2611
2614
|
}
|
|
2615
|
+
} else if (drawing.type === "text" || drawing.type === "note") {
|
|
2616
|
+
const anchor = drawing.points[0];
|
|
2617
|
+
if (anchor) {
|
|
2618
|
+
const ax = xFromDrawingPoint(anchor);
|
|
2619
|
+
const ay = yFromPrice(anchor.price);
|
|
2620
|
+
const isNote = drawing.type === "note";
|
|
2621
|
+
const fontSize = Math.max(6, drawing.fontSize);
|
|
2622
|
+
const prevFont = ctx.font;
|
|
2623
|
+
ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
|
|
2624
|
+
ctx.textAlign = "left";
|
|
2625
|
+
ctx.textBaseline = "top";
|
|
2626
|
+
const lines = (drawing.label ?? "").split("\n");
|
|
2627
|
+
const lineH = Math.round(fontSize * 1.35);
|
|
2628
|
+
const textW = Math.max(1, ...lines.map((line) => ctx.measureText(line).width));
|
|
2629
|
+
const padX = isNote ? 8 : 2;
|
|
2630
|
+
const padY = isNote ? 6 : 1;
|
|
2631
|
+
const blockW = textW + padX * 2;
|
|
2632
|
+
const blockH = lines.length * lineH + padY * 2;
|
|
2633
|
+
ctx.save();
|
|
2634
|
+
ctx.globalAlpha = draft ? 0.7 : 1;
|
|
2635
|
+
if (isNote) {
|
|
2636
|
+
ctx.fillStyle = hexToRgba(drawing.color, 0.14);
|
|
2637
|
+
fillRoundedRect(ax, ay, blockW, blockH, 4);
|
|
2638
|
+
ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
|
|
2639
|
+
ctx.lineWidth = 1;
|
|
2640
|
+
strokeRoundedRect(ax, ay, blockW, blockH, 4);
|
|
2641
|
+
}
|
|
2642
|
+
ctx.fillStyle = drawing.color;
|
|
2643
|
+
lines.forEach((line, lineIndex) => ctx.fillText(line, ax + padX, ay + padY + lineIndex * lineH));
|
|
2644
|
+
ctx.restore();
|
|
2645
|
+
ctx.font = prevFont;
|
|
2646
|
+
if (isSelected) {
|
|
2647
|
+
drawDrawingHandle(ax, ay, drawing.color);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2612
2650
|
}
|
|
2613
2651
|
ctx.restore();
|
|
2614
2652
|
};
|
|
@@ -3857,6 +3895,27 @@ function createChart(element, options = {}) {
|
|
|
3857
3895
|
if (x >= Math.min(px0, px1) && x <= Math.max(px0, px1) && y >= Math.min(y0, y1) && y <= Math.max(y0, y1)) {
|
|
3858
3896
|
return { drawing, target: "line" };
|
|
3859
3897
|
}
|
|
3898
|
+
} else if (drawing.type === "text" || drawing.type === "note") {
|
|
3899
|
+
const anchor = drawing.points[0];
|
|
3900
|
+
if (!anchor) continue;
|
|
3901
|
+
const ax = canvasXFromDrawingPoint(anchor);
|
|
3902
|
+
const ay = canvasYFromDrawingPrice(anchor.price);
|
|
3903
|
+
if (Math.hypot(x - ax, y - ay) <= 9) return { drawing, target: "handle", pointIndex: 0 };
|
|
3904
|
+
const fontSize = Math.max(6, drawing.fontSize);
|
|
3905
|
+
const prevFont = ctx.font;
|
|
3906
|
+
ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
|
|
3907
|
+
const lines = (drawing.label ?? "").split("\n");
|
|
3908
|
+
const textW = Math.max(1, ...lines.map((line) => ctx.measureText(line).width));
|
|
3909
|
+
ctx.font = prevFont;
|
|
3910
|
+
const isNote = drawing.type === "note";
|
|
3911
|
+
const padX = isNote ? 8 : 2;
|
|
3912
|
+
const padY = isNote ? 6 : 1;
|
|
3913
|
+
const lineH = Math.round(fontSize * 1.35);
|
|
3914
|
+
const blockW = textW + padX * 2;
|
|
3915
|
+
const blockH = lines.length * lineH + padY * 2;
|
|
3916
|
+
if (x >= ax && x <= ax + blockW && y >= ay && y <= ay + blockH) {
|
|
3917
|
+
return { drawing, target: "line" };
|
|
3918
|
+
}
|
|
3860
3919
|
}
|
|
3861
3920
|
}
|
|
3862
3921
|
return null;
|
|
@@ -4057,6 +4116,24 @@ function createChart(element, options = {}) {
|
|
|
4057
4116
|
draw();
|
|
4058
4117
|
return true;
|
|
4059
4118
|
}
|
|
4119
|
+
if (activeDrawingTool === "text" || activeDrawingTool === "note") {
|
|
4120
|
+
const defaults = getDrawingToolDefaults(activeDrawingTool);
|
|
4121
|
+
const created = normalizeDrawingState({
|
|
4122
|
+
type: activeDrawingTool,
|
|
4123
|
+
points: [point],
|
|
4124
|
+
color: defaults.color ?? "#e2e8f0",
|
|
4125
|
+
style: defaults.style ?? "solid",
|
|
4126
|
+
width: defaults.width ?? 1,
|
|
4127
|
+
...defaults.fontSize === void 0 ? {} : { fontSize: defaults.fontSize },
|
|
4128
|
+
label: ""
|
|
4129
|
+
});
|
|
4130
|
+
drawings.push(created);
|
|
4131
|
+
selectedDrawingId = created.id;
|
|
4132
|
+
emitDrawingsChange();
|
|
4133
|
+
draw();
|
|
4134
|
+
drawingEditTextHandler?.({ drawing: serializeDrawing(created), target: "line", x, y });
|
|
4135
|
+
return true;
|
|
4136
|
+
}
|
|
4060
4137
|
if (activeDrawingTool === "price-range") {
|
|
4061
4138
|
const tick = getConfiguredTickSize();
|
|
4062
4139
|
const visibleRange = drawState.yMax - drawState.yMin;
|
|
@@ -4679,13 +4756,18 @@ function createChart(element, options = {}) {
|
|
|
4679
4756
|
const drawingHit = getDrawingHit(point.x, point.y);
|
|
4680
4757
|
if (drawingHit) {
|
|
4681
4758
|
selectedDrawingId = drawingHit.drawing.id;
|
|
4682
|
-
|
|
4759
|
+
const payload = {
|
|
4683
4760
|
drawing: serializeDrawing(drawingHit.drawing),
|
|
4684
4761
|
target: drawingHit.target,
|
|
4685
4762
|
...drawingHit.pointIndex === void 0 ? {} : { pointIndex: drawingHit.pointIndex },
|
|
4686
4763
|
x: point.x,
|
|
4687
4764
|
y: point.y
|
|
4688
|
-
}
|
|
4765
|
+
};
|
|
4766
|
+
if (drawingHit.drawing.type === "text" || drawingHit.drawing.type === "note") {
|
|
4767
|
+
drawingEditTextHandler?.(payload);
|
|
4768
|
+
} else {
|
|
4769
|
+
drawingDoubleClickHandler?.(payload);
|
|
4770
|
+
}
|
|
4689
4771
|
return;
|
|
4690
4772
|
}
|
|
4691
4773
|
}
|
|
@@ -5002,6 +5084,9 @@ function createChart(element, options = {}) {
|
|
|
5002
5084
|
const onDrawingDoubleClick = (handler) => {
|
|
5003
5085
|
drawingDoubleClickHandler = handler;
|
|
5004
5086
|
};
|
|
5087
|
+
const onDrawingEditText = (handler) => {
|
|
5088
|
+
drawingEditTextHandler = handler;
|
|
5089
|
+
};
|
|
5005
5090
|
const onDrawingHover = (handler) => {
|
|
5006
5091
|
drawingHoverHandler = handler;
|
|
5007
5092
|
};
|
|
@@ -5060,6 +5145,7 @@ function createChart(element, options = {}) {
|
|
|
5060
5145
|
onDrawingsChange,
|
|
5061
5146
|
onDrawingSelect,
|
|
5062
5147
|
onDrawingDoubleClick,
|
|
5148
|
+
onDrawingEditText,
|
|
5063
5149
|
setSelectedDrawing,
|
|
5064
5150
|
onDrawingHover,
|
|
5065
5151
|
setDrawingDefaults,
|
package/docs/API.md
CHANGED
|
@@ -483,6 +483,7 @@ Use `getDrawings()` / `setDrawings()` for persistence.
|
|
|
483
483
|
- `resetViewport(): void` (fit x + reset y auto-scale)
|
|
484
484
|
- `setSelectedDrawing(id: string | null): void` (marks a drawing selected; only the selected/drafted drawing renders its handles, and position tools render their lines/labels only while selected)
|
|
485
485
|
- `onDrawingDoubleClick(handler): void` (fires when a drawing is double-clicked; use it to open a settings dialog, e.g. for position tools)
|
|
486
|
+
- `onDrawingEditText(handler): void` (fires when a `text`/`note` tool is placed or double-clicked; use it to show an inline text editor at `{x, y}` and write the result back via `updateDrawing(id, { label })`). `text`/`note` drawings store their content in `label` and size in `fontSize`.
|
|
486
487
|
- `setActiveDrawingTool(tool: DrawingToolType | null): void` (`DrawingToolType` = `"horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement"`)
|
|
487
488
|
- `getActiveDrawingTool(): DrawingToolType | null`
|
|
488
489
|
- `setDrawings(drawings: DrawingObjectOptions[]): void`
|