hyperprop-charting-library 0.1.148 → 0.1.150
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 +28 -1
- package/dist/hyperprop-charting-library.d.ts +8 -0
- package/dist/hyperprop-charting-library.js +28 -1
- package/dist/index.cjs +28 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +28 -1
- package/docs/API.md +22 -0
- package/package.json +1 -1
|
@@ -4306,6 +4306,7 @@ function createChart(element, options = {}) {
|
|
|
4306
4306
|
let actionDragState = null;
|
|
4307
4307
|
let pointerDownInfo = null;
|
|
4308
4308
|
let crosshairPoint = null;
|
|
4309
|
+
let externalCrosshair = null;
|
|
4309
4310
|
let doubleClickEnabled = mergedOptions.doubleClickEnabled;
|
|
4310
4311
|
let doubleClickAction = mergedOptions.doubleClickAction;
|
|
4311
4312
|
setIndicatorLiveThrottleMs(mergedOptions.indicatorUpdate?.liveThrottleMs ?? 80);
|
|
@@ -8508,7 +8509,26 @@ function createChart(element, options = {}) {
|
|
|
8508
8509
|
crosshairPriceActionRegion = null;
|
|
8509
8510
|
const layout = overlayLayout;
|
|
8510
8511
|
const crosshair = resolvedCrosshair;
|
|
8511
|
-
if (!layout
|
|
8512
|
+
if (!layout) return;
|
|
8513
|
+
if (!crosshairPoint && externalCrosshair !== null && crosshair.visible) {
|
|
8514
|
+
const index = findNearestIndexForTimeMs(externalCrosshair.timeMs);
|
|
8515
|
+
if (index !== null) {
|
|
8516
|
+
const x = layout.chartLeft + (index + 0.5 - layout.xStart) / layout.xSpan * layout.chartWidth;
|
|
8517
|
+
if (x >= layout.chartLeft && x <= layout.chartRight) {
|
|
8518
|
+
ctx.save();
|
|
8519
|
+
ctx.globalAlpha = 0.55;
|
|
8520
|
+
ctx.strokeStyle = crosshair.color;
|
|
8521
|
+
ctx.lineWidth = Math.max(1, crosshair.width);
|
|
8522
|
+
applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
|
|
8523
|
+
ctx.beginPath();
|
|
8524
|
+
ctx.moveTo(crisp(x), crisp(layout.chartTop));
|
|
8525
|
+
ctx.lineTo(crisp(x), crisp(layout.fullChartBottom));
|
|
8526
|
+
ctx.stroke();
|
|
8527
|
+
ctx.restore();
|
|
8528
|
+
}
|
|
8529
|
+
}
|
|
8530
|
+
}
|
|
8531
|
+
if (!crosshair.visible || !crosshairPoint) {
|
|
8512
8532
|
return;
|
|
8513
8533
|
}
|
|
8514
8534
|
const { chartLeft, chartTop, chartRight, chartBottom, chartWidth, chartHeight, fullChartBottom, yMin, yRange, xStart, xSpan: xSpan2 } = layout;
|
|
@@ -11990,6 +12010,12 @@ function createChart(element, options = {}) {
|
|
|
11990
12010
|
const onAlertAction = (handler) => {
|
|
11991
12011
|
alertActionHandler = handler;
|
|
11992
12012
|
};
|
|
12013
|
+
const setExternalCrosshair = (point) => {
|
|
12014
|
+
const nextMs = point && Number.isFinite(point.timeMs) ? point.timeMs : null;
|
|
12015
|
+
if (nextMs === (externalCrosshair?.timeMs ?? null)) return;
|
|
12016
|
+
externalCrosshair = nextMs === null ? null : { timeMs: nextMs };
|
|
12017
|
+
scheduleDraw({ overlayOnly: true });
|
|
12018
|
+
};
|
|
11993
12019
|
const setTimezone = (timezone) => {
|
|
11994
12020
|
timezoneSetting = timezone || "local";
|
|
11995
12021
|
zoneClock = createZoneClock(timezoneSetting);
|
|
@@ -12300,6 +12326,7 @@ function createChart(element, options = {}) {
|
|
|
12300
12326
|
saveState,
|
|
12301
12327
|
loadState,
|
|
12302
12328
|
takeScreenshot,
|
|
12329
|
+
setExternalCrosshair,
|
|
12303
12330
|
setTimezone,
|
|
12304
12331
|
getTimezone,
|
|
12305
12332
|
setTimeFormat,
|
|
@@ -1030,6 +1030,14 @@ interface ChartInstance {
|
|
|
1030
1030
|
* the crosshair tag and day/session boundaries move. Unknown ids fall back
|
|
1031
1031
|
* to local time rather than throwing.
|
|
1032
1032
|
*/
|
|
1033
|
+
/**
|
|
1034
|
+
* Mirror a sibling chart's crosshair in a multi-chart layout. Matching is
|
|
1035
|
+
* by timestamp, so charts on different intervals or instruments still line
|
|
1036
|
+
* up. Pass null to clear.
|
|
1037
|
+
*/
|
|
1038
|
+
setExternalCrosshair: (point: {
|
|
1039
|
+
timeMs: number;
|
|
1040
|
+
} | null) => void;
|
|
1033
1041
|
setTimezone: (timezone: ChartTimezone) => void;
|
|
1034
1042
|
getTimezone: () => ChartTimezone;
|
|
1035
1043
|
/** Switch rendered clock times between 24-hour and 12-hour. */
|
|
@@ -4270,6 +4270,7 @@ function createChart(element, options = {}) {
|
|
|
4270
4270
|
let actionDragState = null;
|
|
4271
4271
|
let pointerDownInfo = null;
|
|
4272
4272
|
let crosshairPoint = null;
|
|
4273
|
+
let externalCrosshair = null;
|
|
4273
4274
|
let doubleClickEnabled = mergedOptions.doubleClickEnabled;
|
|
4274
4275
|
let doubleClickAction = mergedOptions.doubleClickAction;
|
|
4275
4276
|
setIndicatorLiveThrottleMs(mergedOptions.indicatorUpdate?.liveThrottleMs ?? 80);
|
|
@@ -8472,7 +8473,26 @@ function createChart(element, options = {}) {
|
|
|
8472
8473
|
crosshairPriceActionRegion = null;
|
|
8473
8474
|
const layout = overlayLayout;
|
|
8474
8475
|
const crosshair = resolvedCrosshair;
|
|
8475
|
-
if (!layout
|
|
8476
|
+
if (!layout) return;
|
|
8477
|
+
if (!crosshairPoint && externalCrosshair !== null && crosshair.visible) {
|
|
8478
|
+
const index = findNearestIndexForTimeMs(externalCrosshair.timeMs);
|
|
8479
|
+
if (index !== null) {
|
|
8480
|
+
const x = layout.chartLeft + (index + 0.5 - layout.xStart) / layout.xSpan * layout.chartWidth;
|
|
8481
|
+
if (x >= layout.chartLeft && x <= layout.chartRight) {
|
|
8482
|
+
ctx.save();
|
|
8483
|
+
ctx.globalAlpha = 0.55;
|
|
8484
|
+
ctx.strokeStyle = crosshair.color;
|
|
8485
|
+
ctx.lineWidth = Math.max(1, crosshair.width);
|
|
8486
|
+
applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
|
|
8487
|
+
ctx.beginPath();
|
|
8488
|
+
ctx.moveTo(crisp(x), crisp(layout.chartTop));
|
|
8489
|
+
ctx.lineTo(crisp(x), crisp(layout.fullChartBottom));
|
|
8490
|
+
ctx.stroke();
|
|
8491
|
+
ctx.restore();
|
|
8492
|
+
}
|
|
8493
|
+
}
|
|
8494
|
+
}
|
|
8495
|
+
if (!crosshair.visible || !crosshairPoint) {
|
|
8476
8496
|
return;
|
|
8477
8497
|
}
|
|
8478
8498
|
const { chartLeft, chartTop, chartRight, chartBottom, chartWidth, chartHeight, fullChartBottom, yMin, yRange, xStart, xSpan: xSpan2 } = layout;
|
|
@@ -11954,6 +11974,12 @@ function createChart(element, options = {}) {
|
|
|
11954
11974
|
const onAlertAction = (handler) => {
|
|
11955
11975
|
alertActionHandler = handler;
|
|
11956
11976
|
};
|
|
11977
|
+
const setExternalCrosshair = (point) => {
|
|
11978
|
+
const nextMs = point && Number.isFinite(point.timeMs) ? point.timeMs : null;
|
|
11979
|
+
if (nextMs === (externalCrosshair?.timeMs ?? null)) return;
|
|
11980
|
+
externalCrosshair = nextMs === null ? null : { timeMs: nextMs };
|
|
11981
|
+
scheduleDraw({ overlayOnly: true });
|
|
11982
|
+
};
|
|
11957
11983
|
const setTimezone = (timezone) => {
|
|
11958
11984
|
timezoneSetting = timezone || "local";
|
|
11959
11985
|
zoneClock = createZoneClock(timezoneSetting);
|
|
@@ -12264,6 +12290,7 @@ function createChart(element, options = {}) {
|
|
|
12264
12290
|
saveState,
|
|
12265
12291
|
loadState,
|
|
12266
12292
|
takeScreenshot,
|
|
12293
|
+
setExternalCrosshair,
|
|
12267
12294
|
setTimezone,
|
|
12268
12295
|
getTimezone,
|
|
12269
12296
|
setTimeFormat,
|
package/dist/index.cjs
CHANGED
|
@@ -4306,6 +4306,7 @@ function createChart(element, options = {}) {
|
|
|
4306
4306
|
let actionDragState = null;
|
|
4307
4307
|
let pointerDownInfo = null;
|
|
4308
4308
|
let crosshairPoint = null;
|
|
4309
|
+
let externalCrosshair = null;
|
|
4309
4310
|
let doubleClickEnabled = mergedOptions.doubleClickEnabled;
|
|
4310
4311
|
let doubleClickAction = mergedOptions.doubleClickAction;
|
|
4311
4312
|
setIndicatorLiveThrottleMs(mergedOptions.indicatorUpdate?.liveThrottleMs ?? 80);
|
|
@@ -8508,7 +8509,26 @@ function createChart(element, options = {}) {
|
|
|
8508
8509
|
crosshairPriceActionRegion = null;
|
|
8509
8510
|
const layout = overlayLayout;
|
|
8510
8511
|
const crosshair = resolvedCrosshair;
|
|
8511
|
-
if (!layout
|
|
8512
|
+
if (!layout) return;
|
|
8513
|
+
if (!crosshairPoint && externalCrosshair !== null && crosshair.visible) {
|
|
8514
|
+
const index = findNearestIndexForTimeMs(externalCrosshair.timeMs);
|
|
8515
|
+
if (index !== null) {
|
|
8516
|
+
const x = layout.chartLeft + (index + 0.5 - layout.xStart) / layout.xSpan * layout.chartWidth;
|
|
8517
|
+
if (x >= layout.chartLeft && x <= layout.chartRight) {
|
|
8518
|
+
ctx.save();
|
|
8519
|
+
ctx.globalAlpha = 0.55;
|
|
8520
|
+
ctx.strokeStyle = crosshair.color;
|
|
8521
|
+
ctx.lineWidth = Math.max(1, crosshair.width);
|
|
8522
|
+
applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
|
|
8523
|
+
ctx.beginPath();
|
|
8524
|
+
ctx.moveTo(crisp(x), crisp(layout.chartTop));
|
|
8525
|
+
ctx.lineTo(crisp(x), crisp(layout.fullChartBottom));
|
|
8526
|
+
ctx.stroke();
|
|
8527
|
+
ctx.restore();
|
|
8528
|
+
}
|
|
8529
|
+
}
|
|
8530
|
+
}
|
|
8531
|
+
if (!crosshair.visible || !crosshairPoint) {
|
|
8512
8532
|
return;
|
|
8513
8533
|
}
|
|
8514
8534
|
const { chartLeft, chartTop, chartRight, chartBottom, chartWidth, chartHeight, fullChartBottom, yMin, yRange, xStart, xSpan: xSpan2 } = layout;
|
|
@@ -11990,6 +12010,12 @@ function createChart(element, options = {}) {
|
|
|
11990
12010
|
const onAlertAction = (handler) => {
|
|
11991
12011
|
alertActionHandler = handler;
|
|
11992
12012
|
};
|
|
12013
|
+
const setExternalCrosshair = (point) => {
|
|
12014
|
+
const nextMs = point && Number.isFinite(point.timeMs) ? point.timeMs : null;
|
|
12015
|
+
if (nextMs === (externalCrosshair?.timeMs ?? null)) return;
|
|
12016
|
+
externalCrosshair = nextMs === null ? null : { timeMs: nextMs };
|
|
12017
|
+
scheduleDraw({ overlayOnly: true });
|
|
12018
|
+
};
|
|
11993
12019
|
const setTimezone = (timezone) => {
|
|
11994
12020
|
timezoneSetting = timezone || "local";
|
|
11995
12021
|
zoneClock = createZoneClock(timezoneSetting);
|
|
@@ -12300,6 +12326,7 @@ function createChart(element, options = {}) {
|
|
|
12300
12326
|
saveState,
|
|
12301
12327
|
loadState,
|
|
12302
12328
|
takeScreenshot,
|
|
12329
|
+
setExternalCrosshair,
|
|
12303
12330
|
setTimezone,
|
|
12304
12331
|
getTimezone,
|
|
12305
12332
|
setTimeFormat,
|
package/dist/index.d.cts
CHANGED
|
@@ -1030,6 +1030,14 @@ interface ChartInstance {
|
|
|
1030
1030
|
* the crosshair tag and day/session boundaries move. Unknown ids fall back
|
|
1031
1031
|
* to local time rather than throwing.
|
|
1032
1032
|
*/
|
|
1033
|
+
/**
|
|
1034
|
+
* Mirror a sibling chart's crosshair in a multi-chart layout. Matching is
|
|
1035
|
+
* by timestamp, so charts on different intervals or instruments still line
|
|
1036
|
+
* up. Pass null to clear.
|
|
1037
|
+
*/
|
|
1038
|
+
setExternalCrosshair: (point: {
|
|
1039
|
+
timeMs: number;
|
|
1040
|
+
} | null) => void;
|
|
1033
1041
|
setTimezone: (timezone: ChartTimezone) => void;
|
|
1034
1042
|
getTimezone: () => ChartTimezone;
|
|
1035
1043
|
/** Switch rendered clock times between 24-hour and 12-hour. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1030,6 +1030,14 @@ interface ChartInstance {
|
|
|
1030
1030
|
* the crosshair tag and day/session boundaries move. Unknown ids fall back
|
|
1031
1031
|
* to local time rather than throwing.
|
|
1032
1032
|
*/
|
|
1033
|
+
/**
|
|
1034
|
+
* Mirror a sibling chart's crosshair in a multi-chart layout. Matching is
|
|
1035
|
+
* by timestamp, so charts on different intervals or instruments still line
|
|
1036
|
+
* up. Pass null to clear.
|
|
1037
|
+
*/
|
|
1038
|
+
setExternalCrosshair: (point: {
|
|
1039
|
+
timeMs: number;
|
|
1040
|
+
} | null) => void;
|
|
1033
1041
|
setTimezone: (timezone: ChartTimezone) => void;
|
|
1034
1042
|
getTimezone: () => ChartTimezone;
|
|
1035
1043
|
/** Switch rendered clock times between 24-hour and 12-hour. */
|
package/dist/index.js
CHANGED
|
@@ -4270,6 +4270,7 @@ function createChart(element, options = {}) {
|
|
|
4270
4270
|
let actionDragState = null;
|
|
4271
4271
|
let pointerDownInfo = null;
|
|
4272
4272
|
let crosshairPoint = null;
|
|
4273
|
+
let externalCrosshair = null;
|
|
4273
4274
|
let doubleClickEnabled = mergedOptions.doubleClickEnabled;
|
|
4274
4275
|
let doubleClickAction = mergedOptions.doubleClickAction;
|
|
4275
4276
|
setIndicatorLiveThrottleMs(mergedOptions.indicatorUpdate?.liveThrottleMs ?? 80);
|
|
@@ -8472,7 +8473,26 @@ function createChart(element, options = {}) {
|
|
|
8472
8473
|
crosshairPriceActionRegion = null;
|
|
8473
8474
|
const layout = overlayLayout;
|
|
8474
8475
|
const crosshair = resolvedCrosshair;
|
|
8475
|
-
if (!layout
|
|
8476
|
+
if (!layout) return;
|
|
8477
|
+
if (!crosshairPoint && externalCrosshair !== null && crosshair.visible) {
|
|
8478
|
+
const index = findNearestIndexForTimeMs(externalCrosshair.timeMs);
|
|
8479
|
+
if (index !== null) {
|
|
8480
|
+
const x = layout.chartLeft + (index + 0.5 - layout.xStart) / layout.xSpan * layout.chartWidth;
|
|
8481
|
+
if (x >= layout.chartLeft && x <= layout.chartRight) {
|
|
8482
|
+
ctx.save();
|
|
8483
|
+
ctx.globalAlpha = 0.55;
|
|
8484
|
+
ctx.strokeStyle = crosshair.color;
|
|
8485
|
+
ctx.lineWidth = Math.max(1, crosshair.width);
|
|
8486
|
+
applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
|
|
8487
|
+
ctx.beginPath();
|
|
8488
|
+
ctx.moveTo(crisp(x), crisp(layout.chartTop));
|
|
8489
|
+
ctx.lineTo(crisp(x), crisp(layout.fullChartBottom));
|
|
8490
|
+
ctx.stroke();
|
|
8491
|
+
ctx.restore();
|
|
8492
|
+
}
|
|
8493
|
+
}
|
|
8494
|
+
}
|
|
8495
|
+
if (!crosshair.visible || !crosshairPoint) {
|
|
8476
8496
|
return;
|
|
8477
8497
|
}
|
|
8478
8498
|
const { chartLeft, chartTop, chartRight, chartBottom, chartWidth, chartHeight, fullChartBottom, yMin, yRange, xStart, xSpan: xSpan2 } = layout;
|
|
@@ -11954,6 +11974,12 @@ function createChart(element, options = {}) {
|
|
|
11954
11974
|
const onAlertAction = (handler) => {
|
|
11955
11975
|
alertActionHandler = handler;
|
|
11956
11976
|
};
|
|
11977
|
+
const setExternalCrosshair = (point) => {
|
|
11978
|
+
const nextMs = point && Number.isFinite(point.timeMs) ? point.timeMs : null;
|
|
11979
|
+
if (nextMs === (externalCrosshair?.timeMs ?? null)) return;
|
|
11980
|
+
externalCrosshair = nextMs === null ? null : { timeMs: nextMs };
|
|
11981
|
+
scheduleDraw({ overlayOnly: true });
|
|
11982
|
+
};
|
|
11957
11983
|
const setTimezone = (timezone) => {
|
|
11958
11984
|
timezoneSetting = timezone || "local";
|
|
11959
11985
|
zoneClock = createZoneClock(timezoneSetting);
|
|
@@ -12264,6 +12290,7 @@ function createChart(element, options = {}) {
|
|
|
12264
12290
|
saveState,
|
|
12265
12291
|
loadState,
|
|
12266
12292
|
takeScreenshot,
|
|
12293
|
+
setExternalCrosshair,
|
|
12267
12294
|
setTimezone,
|
|
12268
12295
|
getTimezone,
|
|
12269
12296
|
setTimeFormat,
|
package/docs/API.md
CHANGED
|
@@ -881,6 +881,28 @@ they are not part of `saveState()`.
|
|
|
881
881
|
|
|
882
882
|
---
|
|
883
883
|
|
|
884
|
+
## Overlay indicator legend
|
|
885
|
+
|
|
886
|
+
With `labels.showIndicatorNames` / `showIndicatorValues`, overlay indicators
|
|
887
|
+
are listed top-left, one row each. Hovering a row reveals the same four
|
|
888
|
+
controls the separate panes have — eye, gear, `{}`, X — and they emit the same
|
|
889
|
+
`onIndicatorPaneAction` event, so a host that already handles pane actions gets
|
|
890
|
+
the overlay legend for free:
|
|
891
|
+
|
|
892
|
+
```ts
|
|
893
|
+
chart.updateOptions({ labels: { showIndicatorNames: true, showIndicatorValues: true } });
|
|
894
|
+
chart.onIndicatorPaneAction(({ id, action }) => {
|
|
895
|
+
if (action === "remove") store.removeIndicator(id);
|
|
896
|
+
if (action === "settings") store.openSettings(id);
|
|
897
|
+
});
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
The eye also toggles visibility internally so it works without a host, and
|
|
901
|
+
hidden indicators render their row dimmed. Position and offsets come from
|
|
902
|
+
`labels.indicatorLegendPosition` / `indicatorLegendOffsetX` / `OffsetY`.
|
|
903
|
+
|
|
904
|
+
---
|
|
905
|
+
|
|
884
906
|
## In-chart data line
|
|
885
907
|
|
|
886
908
|
The symbol/OHLC line TradingView draws in the top-left of the plot. Hosts have
|