hyperprop-charting-library 0.1.57 → 0.1.58
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.
|
@@ -962,6 +962,8 @@ function createChart(element, options = {}) {
|
|
|
962
962
|
let drawingDragState = null;
|
|
963
963
|
let drawingsChangeHandler = null;
|
|
964
964
|
let drawingSelectHandler = null;
|
|
965
|
+
let drawingHoverHandler = null;
|
|
966
|
+
let lastHoveredDrawingId = null;
|
|
965
967
|
const emitDrawingsChange = () => {
|
|
966
968
|
drawingsChangeHandler?.(drawings.map((drawing) => serializeDrawing(drawing)));
|
|
967
969
|
};
|
|
@@ -2031,6 +2033,29 @@ function createChart(element, options = {}) {
|
|
|
2031
2033
|
ctx.stroke();
|
|
2032
2034
|
ctx.restore();
|
|
2033
2035
|
};
|
|
2036
|
+
const drawDrawingLabel = (labelText, anchorX, anchorY, color, angle) => {
|
|
2037
|
+
if (!labelText) return;
|
|
2038
|
+
ctx.save();
|
|
2039
|
+
ctx.translate(anchorX, anchorY);
|
|
2040
|
+
ctx.rotate(angle);
|
|
2041
|
+
ctx.translate(0, -8);
|
|
2042
|
+
const prevFont = ctx.font;
|
|
2043
|
+
ctx.font = `500 12px ${mergedOptions.fontFamily}`;
|
|
2044
|
+
const textWidth = ctx.measureText(labelText).width;
|
|
2045
|
+
const paddingX = 6;
|
|
2046
|
+
const paddingY = 3;
|
|
2047
|
+
const bgWidth = textWidth + paddingX * 2;
|
|
2048
|
+
const bgHeight = 18;
|
|
2049
|
+
ctx.fillStyle = `${color}1f`;
|
|
2050
|
+
fillRoundedRect(-bgWidth / 2, -bgHeight, bgWidth, bgHeight, 4);
|
|
2051
|
+
ctx.fillStyle = color;
|
|
2052
|
+
ctx.textAlign = "center";
|
|
2053
|
+
ctx.textBaseline = "middle";
|
|
2054
|
+
ctx.fillText(labelText, 0, -bgHeight / 2);
|
|
2055
|
+
ctx.font = prevFont;
|
|
2056
|
+
void paddingY;
|
|
2057
|
+
ctx.restore();
|
|
2058
|
+
};
|
|
2034
2059
|
const drawDrawing = (drawing, draft = false) => {
|
|
2035
2060
|
if (!drawing.visible) {
|
|
2036
2061
|
return;
|
|
@@ -2050,6 +2075,9 @@ function createChart(element, options = {}) {
|
|
|
2050
2075
|
ctx.lineTo(crisp(chartRight), crisp(y));
|
|
2051
2076
|
ctx.stroke();
|
|
2052
2077
|
drawDrawingHandle(handleX, y, drawing.color);
|
|
2078
|
+
if (drawing.label) {
|
|
2079
|
+
drawDrawingLabel(drawing.label, chartLeft + 60, y, drawing.color, 0);
|
|
2080
|
+
}
|
|
2053
2081
|
}
|
|
2054
2082
|
} else if (drawing.type === "trendline") {
|
|
2055
2083
|
const first = drawing.points[0];
|
|
@@ -2065,6 +2093,12 @@ function createChart(element, options = {}) {
|
|
|
2065
2093
|
ctx.stroke();
|
|
2066
2094
|
drawDrawingHandle(firstX, firstY, drawing.color);
|
|
2067
2095
|
drawDrawingHandle(secondX, secondY, drawing.color);
|
|
2096
|
+
if (drawing.label) {
|
|
2097
|
+
const midX = (firstX + secondX) / 2;
|
|
2098
|
+
const midY = (firstY + secondY) / 2;
|
|
2099
|
+
const angle = Math.atan2(secondY - firstY, secondX - firstX);
|
|
2100
|
+
drawDrawingLabel(drawing.label, midX, midY, drawing.color, angle);
|
|
2101
|
+
}
|
|
2068
2102
|
}
|
|
2069
2103
|
}
|
|
2070
2104
|
ctx.restore();
|
|
@@ -3574,8 +3608,23 @@ function createChart(element, options = {}) {
|
|
|
3574
3608
|
const drawingHit = getDrawingHit(point.x, point.y);
|
|
3575
3609
|
canvas.style.cursor = drawingHit?.drawing.locked ? "pointer" : drawingHit?.target === "handle" ? "grab" : "move";
|
|
3576
3610
|
setCrosshairPoint(null);
|
|
3611
|
+
if (drawingHit && drawingHoverHandler) {
|
|
3612
|
+
if (lastHoveredDrawingId !== drawingHit.drawing.id) {
|
|
3613
|
+
lastHoveredDrawingId = drawingHit.drawing.id;
|
|
3614
|
+
}
|
|
3615
|
+
drawingHoverHandler({
|
|
3616
|
+
drawing: serializeDrawing(drawingHit.drawing),
|
|
3617
|
+
target: drawingHit.target,
|
|
3618
|
+
x: point.x,
|
|
3619
|
+
y: point.y
|
|
3620
|
+
});
|
|
3621
|
+
}
|
|
3577
3622
|
return;
|
|
3578
3623
|
}
|
|
3624
|
+
if (lastHoveredDrawingId !== null) {
|
|
3625
|
+
lastHoveredDrawingId = null;
|
|
3626
|
+
drawingHoverHandler?.({ drawing: null, target: null, x: point.x, y: point.y });
|
|
3627
|
+
}
|
|
3579
3628
|
const hoverRegion = getHitRegion(point.x, point.y);
|
|
3580
3629
|
if (hoverRegion === "plot") {
|
|
3581
3630
|
canvas.style.cursor = activeDrawingTool ? "crosshair" : doubleClickEnabled ? "default" : "crosshair";
|
|
@@ -4031,6 +4080,9 @@ function createChart(element, options = {}) {
|
|
|
4031
4080
|
const onDrawingSelect = (handler) => {
|
|
4032
4081
|
drawingSelectHandler = handler;
|
|
4033
4082
|
};
|
|
4083
|
+
const onDrawingHover = (handler) => {
|
|
4084
|
+
drawingHoverHandler = handler;
|
|
4085
|
+
};
|
|
4034
4086
|
const destroy = () => {
|
|
4035
4087
|
if (smoothingRafId !== null) {
|
|
4036
4088
|
cancelAnimationFrame(smoothingRafId);
|
|
@@ -4084,6 +4136,7 @@ function createChart(element, options = {}) {
|
|
|
4084
4136
|
clearDrawings,
|
|
4085
4137
|
onDrawingsChange,
|
|
4086
4138
|
onDrawingSelect,
|
|
4139
|
+
onDrawingHover,
|
|
4087
4140
|
setDoubleClickEnabled,
|
|
4088
4141
|
setDoubleClickAction,
|
|
4089
4142
|
registerIndicator,
|
|
@@ -67,6 +67,12 @@ interface DrawingSelectEvent {
|
|
|
67
67
|
x: number;
|
|
68
68
|
y: number;
|
|
69
69
|
}
|
|
70
|
+
interface DrawingHoverEvent {
|
|
71
|
+
drawing: DrawingObjectOptions | null;
|
|
72
|
+
target: "line" | "handle" | null;
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
}
|
|
70
76
|
interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
|
|
71
77
|
id?: string;
|
|
72
78
|
type: string;
|
|
@@ -398,6 +404,7 @@ interface ChartInstance {
|
|
|
398
404
|
clearDrawings: () => void;
|
|
399
405
|
onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
|
|
400
406
|
onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
407
|
+
onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
|
|
401
408
|
setDoubleClickEnabled: (enabled: boolean) => void;
|
|
402
409
|
setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
|
|
403
410
|
registerIndicator: (plugin: IndicatorPlugin<any>) => void;
|
|
@@ -433,4 +440,4 @@ interface ViewportState {
|
|
|
433
440
|
}
|
|
434
441
|
declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
|
|
435
442
|
|
|
436
|
-
export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
|
|
443
|
+
export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
|
|
@@ -938,6 +938,8 @@ function createChart(element, options = {}) {
|
|
|
938
938
|
let drawingDragState = null;
|
|
939
939
|
let drawingsChangeHandler = null;
|
|
940
940
|
let drawingSelectHandler = null;
|
|
941
|
+
let drawingHoverHandler = null;
|
|
942
|
+
let lastHoveredDrawingId = null;
|
|
941
943
|
const emitDrawingsChange = () => {
|
|
942
944
|
drawingsChangeHandler?.(drawings.map((drawing) => serializeDrawing(drawing)));
|
|
943
945
|
};
|
|
@@ -2007,6 +2009,29 @@ function createChart(element, options = {}) {
|
|
|
2007
2009
|
ctx.stroke();
|
|
2008
2010
|
ctx.restore();
|
|
2009
2011
|
};
|
|
2012
|
+
const drawDrawingLabel = (labelText, anchorX, anchorY, color, angle) => {
|
|
2013
|
+
if (!labelText) return;
|
|
2014
|
+
ctx.save();
|
|
2015
|
+
ctx.translate(anchorX, anchorY);
|
|
2016
|
+
ctx.rotate(angle);
|
|
2017
|
+
ctx.translate(0, -8);
|
|
2018
|
+
const prevFont = ctx.font;
|
|
2019
|
+
ctx.font = `500 12px ${mergedOptions.fontFamily}`;
|
|
2020
|
+
const textWidth = ctx.measureText(labelText).width;
|
|
2021
|
+
const paddingX = 6;
|
|
2022
|
+
const paddingY = 3;
|
|
2023
|
+
const bgWidth = textWidth + paddingX * 2;
|
|
2024
|
+
const bgHeight = 18;
|
|
2025
|
+
ctx.fillStyle = `${color}1f`;
|
|
2026
|
+
fillRoundedRect(-bgWidth / 2, -bgHeight, bgWidth, bgHeight, 4);
|
|
2027
|
+
ctx.fillStyle = color;
|
|
2028
|
+
ctx.textAlign = "center";
|
|
2029
|
+
ctx.textBaseline = "middle";
|
|
2030
|
+
ctx.fillText(labelText, 0, -bgHeight / 2);
|
|
2031
|
+
ctx.font = prevFont;
|
|
2032
|
+
void paddingY;
|
|
2033
|
+
ctx.restore();
|
|
2034
|
+
};
|
|
2010
2035
|
const drawDrawing = (drawing, draft = false) => {
|
|
2011
2036
|
if (!drawing.visible) {
|
|
2012
2037
|
return;
|
|
@@ -2026,6 +2051,9 @@ function createChart(element, options = {}) {
|
|
|
2026
2051
|
ctx.lineTo(crisp(chartRight), crisp(y));
|
|
2027
2052
|
ctx.stroke();
|
|
2028
2053
|
drawDrawingHandle(handleX, y, drawing.color);
|
|
2054
|
+
if (drawing.label) {
|
|
2055
|
+
drawDrawingLabel(drawing.label, chartLeft + 60, y, drawing.color, 0);
|
|
2056
|
+
}
|
|
2029
2057
|
}
|
|
2030
2058
|
} else if (drawing.type === "trendline") {
|
|
2031
2059
|
const first = drawing.points[0];
|
|
@@ -2041,6 +2069,12 @@ function createChart(element, options = {}) {
|
|
|
2041
2069
|
ctx.stroke();
|
|
2042
2070
|
drawDrawingHandle(firstX, firstY, drawing.color);
|
|
2043
2071
|
drawDrawingHandle(secondX, secondY, drawing.color);
|
|
2072
|
+
if (drawing.label) {
|
|
2073
|
+
const midX = (firstX + secondX) / 2;
|
|
2074
|
+
const midY = (firstY + secondY) / 2;
|
|
2075
|
+
const angle = Math.atan2(secondY - firstY, secondX - firstX);
|
|
2076
|
+
drawDrawingLabel(drawing.label, midX, midY, drawing.color, angle);
|
|
2077
|
+
}
|
|
2044
2078
|
}
|
|
2045
2079
|
}
|
|
2046
2080
|
ctx.restore();
|
|
@@ -3550,8 +3584,23 @@ function createChart(element, options = {}) {
|
|
|
3550
3584
|
const drawingHit = getDrawingHit(point.x, point.y);
|
|
3551
3585
|
canvas.style.cursor = drawingHit?.drawing.locked ? "pointer" : drawingHit?.target === "handle" ? "grab" : "move";
|
|
3552
3586
|
setCrosshairPoint(null);
|
|
3587
|
+
if (drawingHit && drawingHoverHandler) {
|
|
3588
|
+
if (lastHoveredDrawingId !== drawingHit.drawing.id) {
|
|
3589
|
+
lastHoveredDrawingId = drawingHit.drawing.id;
|
|
3590
|
+
}
|
|
3591
|
+
drawingHoverHandler({
|
|
3592
|
+
drawing: serializeDrawing(drawingHit.drawing),
|
|
3593
|
+
target: drawingHit.target,
|
|
3594
|
+
x: point.x,
|
|
3595
|
+
y: point.y
|
|
3596
|
+
});
|
|
3597
|
+
}
|
|
3553
3598
|
return;
|
|
3554
3599
|
}
|
|
3600
|
+
if (lastHoveredDrawingId !== null) {
|
|
3601
|
+
lastHoveredDrawingId = null;
|
|
3602
|
+
drawingHoverHandler?.({ drawing: null, target: null, x: point.x, y: point.y });
|
|
3603
|
+
}
|
|
3555
3604
|
const hoverRegion = getHitRegion(point.x, point.y);
|
|
3556
3605
|
if (hoverRegion === "plot") {
|
|
3557
3606
|
canvas.style.cursor = activeDrawingTool ? "crosshair" : doubleClickEnabled ? "default" : "crosshair";
|
|
@@ -4007,6 +4056,9 @@ function createChart(element, options = {}) {
|
|
|
4007
4056
|
const onDrawingSelect = (handler) => {
|
|
4008
4057
|
drawingSelectHandler = handler;
|
|
4009
4058
|
};
|
|
4059
|
+
const onDrawingHover = (handler) => {
|
|
4060
|
+
drawingHoverHandler = handler;
|
|
4061
|
+
};
|
|
4010
4062
|
const destroy = () => {
|
|
4011
4063
|
if (smoothingRafId !== null) {
|
|
4012
4064
|
cancelAnimationFrame(smoothingRafId);
|
|
@@ -4060,6 +4112,7 @@ function createChart(element, options = {}) {
|
|
|
4060
4112
|
clearDrawings,
|
|
4061
4113
|
onDrawingsChange,
|
|
4062
4114
|
onDrawingSelect,
|
|
4115
|
+
onDrawingHover,
|
|
4063
4116
|
setDoubleClickEnabled,
|
|
4064
4117
|
setDoubleClickAction,
|
|
4065
4118
|
registerIndicator,
|
package/dist/index.cjs
CHANGED
|
@@ -962,6 +962,8 @@ function createChart(element, options = {}) {
|
|
|
962
962
|
let drawingDragState = null;
|
|
963
963
|
let drawingsChangeHandler = null;
|
|
964
964
|
let drawingSelectHandler = null;
|
|
965
|
+
let drawingHoverHandler = null;
|
|
966
|
+
let lastHoveredDrawingId = null;
|
|
965
967
|
const emitDrawingsChange = () => {
|
|
966
968
|
drawingsChangeHandler?.(drawings.map((drawing) => serializeDrawing(drawing)));
|
|
967
969
|
};
|
|
@@ -2031,6 +2033,29 @@ function createChart(element, options = {}) {
|
|
|
2031
2033
|
ctx.stroke();
|
|
2032
2034
|
ctx.restore();
|
|
2033
2035
|
};
|
|
2036
|
+
const drawDrawingLabel = (labelText, anchorX, anchorY, color, angle) => {
|
|
2037
|
+
if (!labelText) return;
|
|
2038
|
+
ctx.save();
|
|
2039
|
+
ctx.translate(anchorX, anchorY);
|
|
2040
|
+
ctx.rotate(angle);
|
|
2041
|
+
ctx.translate(0, -8);
|
|
2042
|
+
const prevFont = ctx.font;
|
|
2043
|
+
ctx.font = `500 12px ${mergedOptions.fontFamily}`;
|
|
2044
|
+
const textWidth = ctx.measureText(labelText).width;
|
|
2045
|
+
const paddingX = 6;
|
|
2046
|
+
const paddingY = 3;
|
|
2047
|
+
const bgWidth = textWidth + paddingX * 2;
|
|
2048
|
+
const bgHeight = 18;
|
|
2049
|
+
ctx.fillStyle = `${color}1f`;
|
|
2050
|
+
fillRoundedRect(-bgWidth / 2, -bgHeight, bgWidth, bgHeight, 4);
|
|
2051
|
+
ctx.fillStyle = color;
|
|
2052
|
+
ctx.textAlign = "center";
|
|
2053
|
+
ctx.textBaseline = "middle";
|
|
2054
|
+
ctx.fillText(labelText, 0, -bgHeight / 2);
|
|
2055
|
+
ctx.font = prevFont;
|
|
2056
|
+
void paddingY;
|
|
2057
|
+
ctx.restore();
|
|
2058
|
+
};
|
|
2034
2059
|
const drawDrawing = (drawing, draft = false) => {
|
|
2035
2060
|
if (!drawing.visible) {
|
|
2036
2061
|
return;
|
|
@@ -2050,6 +2075,9 @@ function createChart(element, options = {}) {
|
|
|
2050
2075
|
ctx.lineTo(crisp(chartRight), crisp(y));
|
|
2051
2076
|
ctx.stroke();
|
|
2052
2077
|
drawDrawingHandle(handleX, y, drawing.color);
|
|
2078
|
+
if (drawing.label) {
|
|
2079
|
+
drawDrawingLabel(drawing.label, chartLeft + 60, y, drawing.color, 0);
|
|
2080
|
+
}
|
|
2053
2081
|
}
|
|
2054
2082
|
} else if (drawing.type === "trendline") {
|
|
2055
2083
|
const first = drawing.points[0];
|
|
@@ -2065,6 +2093,12 @@ function createChart(element, options = {}) {
|
|
|
2065
2093
|
ctx.stroke();
|
|
2066
2094
|
drawDrawingHandle(firstX, firstY, drawing.color);
|
|
2067
2095
|
drawDrawingHandle(secondX, secondY, drawing.color);
|
|
2096
|
+
if (drawing.label) {
|
|
2097
|
+
const midX = (firstX + secondX) / 2;
|
|
2098
|
+
const midY = (firstY + secondY) / 2;
|
|
2099
|
+
const angle = Math.atan2(secondY - firstY, secondX - firstX);
|
|
2100
|
+
drawDrawingLabel(drawing.label, midX, midY, drawing.color, angle);
|
|
2101
|
+
}
|
|
2068
2102
|
}
|
|
2069
2103
|
}
|
|
2070
2104
|
ctx.restore();
|
|
@@ -3574,8 +3608,23 @@ function createChart(element, options = {}) {
|
|
|
3574
3608
|
const drawingHit = getDrawingHit(point.x, point.y);
|
|
3575
3609
|
canvas.style.cursor = drawingHit?.drawing.locked ? "pointer" : drawingHit?.target === "handle" ? "grab" : "move";
|
|
3576
3610
|
setCrosshairPoint(null);
|
|
3611
|
+
if (drawingHit && drawingHoverHandler) {
|
|
3612
|
+
if (lastHoveredDrawingId !== drawingHit.drawing.id) {
|
|
3613
|
+
lastHoveredDrawingId = drawingHit.drawing.id;
|
|
3614
|
+
}
|
|
3615
|
+
drawingHoverHandler({
|
|
3616
|
+
drawing: serializeDrawing(drawingHit.drawing),
|
|
3617
|
+
target: drawingHit.target,
|
|
3618
|
+
x: point.x,
|
|
3619
|
+
y: point.y
|
|
3620
|
+
});
|
|
3621
|
+
}
|
|
3577
3622
|
return;
|
|
3578
3623
|
}
|
|
3624
|
+
if (lastHoveredDrawingId !== null) {
|
|
3625
|
+
lastHoveredDrawingId = null;
|
|
3626
|
+
drawingHoverHandler?.({ drawing: null, target: null, x: point.x, y: point.y });
|
|
3627
|
+
}
|
|
3579
3628
|
const hoverRegion = getHitRegion(point.x, point.y);
|
|
3580
3629
|
if (hoverRegion === "plot") {
|
|
3581
3630
|
canvas.style.cursor = activeDrawingTool ? "crosshair" : doubleClickEnabled ? "default" : "crosshair";
|
|
@@ -4031,6 +4080,9 @@ function createChart(element, options = {}) {
|
|
|
4031
4080
|
const onDrawingSelect = (handler) => {
|
|
4032
4081
|
drawingSelectHandler = handler;
|
|
4033
4082
|
};
|
|
4083
|
+
const onDrawingHover = (handler) => {
|
|
4084
|
+
drawingHoverHandler = handler;
|
|
4085
|
+
};
|
|
4034
4086
|
const destroy = () => {
|
|
4035
4087
|
if (smoothingRafId !== null) {
|
|
4036
4088
|
cancelAnimationFrame(smoothingRafId);
|
|
@@ -4084,6 +4136,7 @@ function createChart(element, options = {}) {
|
|
|
4084
4136
|
clearDrawings,
|
|
4085
4137
|
onDrawingsChange,
|
|
4086
4138
|
onDrawingSelect,
|
|
4139
|
+
onDrawingHover,
|
|
4087
4140
|
setDoubleClickEnabled,
|
|
4088
4141
|
setDoubleClickAction,
|
|
4089
4142
|
registerIndicator,
|
package/dist/index.d.cts
CHANGED
|
@@ -67,6 +67,12 @@ interface DrawingSelectEvent {
|
|
|
67
67
|
x: number;
|
|
68
68
|
y: number;
|
|
69
69
|
}
|
|
70
|
+
interface DrawingHoverEvent {
|
|
71
|
+
drawing: DrawingObjectOptions | null;
|
|
72
|
+
target: "line" | "handle" | null;
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
}
|
|
70
76
|
interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
|
|
71
77
|
id?: string;
|
|
72
78
|
type: string;
|
|
@@ -398,6 +404,7 @@ interface ChartInstance {
|
|
|
398
404
|
clearDrawings: () => void;
|
|
399
405
|
onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
|
|
400
406
|
onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
407
|
+
onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
|
|
401
408
|
setDoubleClickEnabled: (enabled: boolean) => void;
|
|
402
409
|
setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
|
|
403
410
|
registerIndicator: (plugin: IndicatorPlugin<any>) => void;
|
|
@@ -433,4 +440,4 @@ interface ViewportState {
|
|
|
433
440
|
}
|
|
434
441
|
declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
|
|
435
442
|
|
|
436
|
-
export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
|
|
443
|
+
export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
|
package/dist/index.d.ts
CHANGED
|
@@ -67,6 +67,12 @@ interface DrawingSelectEvent {
|
|
|
67
67
|
x: number;
|
|
68
68
|
y: number;
|
|
69
69
|
}
|
|
70
|
+
interface DrawingHoverEvent {
|
|
71
|
+
drawing: DrawingObjectOptions | null;
|
|
72
|
+
target: "line" | "handle" | null;
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
}
|
|
70
76
|
interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
|
|
71
77
|
id?: string;
|
|
72
78
|
type: string;
|
|
@@ -398,6 +404,7 @@ interface ChartInstance {
|
|
|
398
404
|
clearDrawings: () => void;
|
|
399
405
|
onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
|
|
400
406
|
onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
|
|
407
|
+
onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
|
|
401
408
|
setDoubleClickEnabled: (enabled: boolean) => void;
|
|
402
409
|
setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
|
|
403
410
|
registerIndicator: (plugin: IndicatorPlugin<any>) => void;
|
|
@@ -433,4 +440,4 @@ interface ViewportState {
|
|
|
433
440
|
}
|
|
434
441
|
declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
|
|
435
442
|
|
|
436
|
-
export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
|
|
443
|
+
export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
|
package/dist/index.js
CHANGED
|
@@ -938,6 +938,8 @@ function createChart(element, options = {}) {
|
|
|
938
938
|
let drawingDragState = null;
|
|
939
939
|
let drawingsChangeHandler = null;
|
|
940
940
|
let drawingSelectHandler = null;
|
|
941
|
+
let drawingHoverHandler = null;
|
|
942
|
+
let lastHoveredDrawingId = null;
|
|
941
943
|
const emitDrawingsChange = () => {
|
|
942
944
|
drawingsChangeHandler?.(drawings.map((drawing) => serializeDrawing(drawing)));
|
|
943
945
|
};
|
|
@@ -2007,6 +2009,29 @@ function createChart(element, options = {}) {
|
|
|
2007
2009
|
ctx.stroke();
|
|
2008
2010
|
ctx.restore();
|
|
2009
2011
|
};
|
|
2012
|
+
const drawDrawingLabel = (labelText, anchorX, anchorY, color, angle) => {
|
|
2013
|
+
if (!labelText) return;
|
|
2014
|
+
ctx.save();
|
|
2015
|
+
ctx.translate(anchorX, anchorY);
|
|
2016
|
+
ctx.rotate(angle);
|
|
2017
|
+
ctx.translate(0, -8);
|
|
2018
|
+
const prevFont = ctx.font;
|
|
2019
|
+
ctx.font = `500 12px ${mergedOptions.fontFamily}`;
|
|
2020
|
+
const textWidth = ctx.measureText(labelText).width;
|
|
2021
|
+
const paddingX = 6;
|
|
2022
|
+
const paddingY = 3;
|
|
2023
|
+
const bgWidth = textWidth + paddingX * 2;
|
|
2024
|
+
const bgHeight = 18;
|
|
2025
|
+
ctx.fillStyle = `${color}1f`;
|
|
2026
|
+
fillRoundedRect(-bgWidth / 2, -bgHeight, bgWidth, bgHeight, 4);
|
|
2027
|
+
ctx.fillStyle = color;
|
|
2028
|
+
ctx.textAlign = "center";
|
|
2029
|
+
ctx.textBaseline = "middle";
|
|
2030
|
+
ctx.fillText(labelText, 0, -bgHeight / 2);
|
|
2031
|
+
ctx.font = prevFont;
|
|
2032
|
+
void paddingY;
|
|
2033
|
+
ctx.restore();
|
|
2034
|
+
};
|
|
2010
2035
|
const drawDrawing = (drawing, draft = false) => {
|
|
2011
2036
|
if (!drawing.visible) {
|
|
2012
2037
|
return;
|
|
@@ -2026,6 +2051,9 @@ function createChart(element, options = {}) {
|
|
|
2026
2051
|
ctx.lineTo(crisp(chartRight), crisp(y));
|
|
2027
2052
|
ctx.stroke();
|
|
2028
2053
|
drawDrawingHandle(handleX, y, drawing.color);
|
|
2054
|
+
if (drawing.label) {
|
|
2055
|
+
drawDrawingLabel(drawing.label, chartLeft + 60, y, drawing.color, 0);
|
|
2056
|
+
}
|
|
2029
2057
|
}
|
|
2030
2058
|
} else if (drawing.type === "trendline") {
|
|
2031
2059
|
const first = drawing.points[0];
|
|
@@ -2041,6 +2069,12 @@ function createChart(element, options = {}) {
|
|
|
2041
2069
|
ctx.stroke();
|
|
2042
2070
|
drawDrawingHandle(firstX, firstY, drawing.color);
|
|
2043
2071
|
drawDrawingHandle(secondX, secondY, drawing.color);
|
|
2072
|
+
if (drawing.label) {
|
|
2073
|
+
const midX = (firstX + secondX) / 2;
|
|
2074
|
+
const midY = (firstY + secondY) / 2;
|
|
2075
|
+
const angle = Math.atan2(secondY - firstY, secondX - firstX);
|
|
2076
|
+
drawDrawingLabel(drawing.label, midX, midY, drawing.color, angle);
|
|
2077
|
+
}
|
|
2044
2078
|
}
|
|
2045
2079
|
}
|
|
2046
2080
|
ctx.restore();
|
|
@@ -3550,8 +3584,23 @@ function createChart(element, options = {}) {
|
|
|
3550
3584
|
const drawingHit = getDrawingHit(point.x, point.y);
|
|
3551
3585
|
canvas.style.cursor = drawingHit?.drawing.locked ? "pointer" : drawingHit?.target === "handle" ? "grab" : "move";
|
|
3552
3586
|
setCrosshairPoint(null);
|
|
3587
|
+
if (drawingHit && drawingHoverHandler) {
|
|
3588
|
+
if (lastHoveredDrawingId !== drawingHit.drawing.id) {
|
|
3589
|
+
lastHoveredDrawingId = drawingHit.drawing.id;
|
|
3590
|
+
}
|
|
3591
|
+
drawingHoverHandler({
|
|
3592
|
+
drawing: serializeDrawing(drawingHit.drawing),
|
|
3593
|
+
target: drawingHit.target,
|
|
3594
|
+
x: point.x,
|
|
3595
|
+
y: point.y
|
|
3596
|
+
});
|
|
3597
|
+
}
|
|
3553
3598
|
return;
|
|
3554
3599
|
}
|
|
3600
|
+
if (lastHoveredDrawingId !== null) {
|
|
3601
|
+
lastHoveredDrawingId = null;
|
|
3602
|
+
drawingHoverHandler?.({ drawing: null, target: null, x: point.x, y: point.y });
|
|
3603
|
+
}
|
|
3555
3604
|
const hoverRegion = getHitRegion(point.x, point.y);
|
|
3556
3605
|
if (hoverRegion === "plot") {
|
|
3557
3606
|
canvas.style.cursor = activeDrawingTool ? "crosshair" : doubleClickEnabled ? "default" : "crosshair";
|
|
@@ -4007,6 +4056,9 @@ function createChart(element, options = {}) {
|
|
|
4007
4056
|
const onDrawingSelect = (handler) => {
|
|
4008
4057
|
drawingSelectHandler = handler;
|
|
4009
4058
|
};
|
|
4059
|
+
const onDrawingHover = (handler) => {
|
|
4060
|
+
drawingHoverHandler = handler;
|
|
4061
|
+
};
|
|
4010
4062
|
const destroy = () => {
|
|
4011
4063
|
if (smoothingRafId !== null) {
|
|
4012
4064
|
cancelAnimationFrame(smoothingRafId);
|
|
@@ -4060,6 +4112,7 @@ function createChart(element, options = {}) {
|
|
|
4060
4112
|
clearDrawings,
|
|
4061
4113
|
onDrawingsChange,
|
|
4062
4114
|
onDrawingSelect,
|
|
4115
|
+
onDrawingHover,
|
|
4063
4116
|
setDoubleClickEnabled,
|
|
4064
4117
|
setDoubleClickAction,
|
|
4065
4118
|
registerIndicator,
|