hyperprop-charting-library 0.1.11 → 0.1.13
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/README.md +16 -1
- package/dist/hyperprop-charting-library.cjs +152 -77
- package/dist/hyperprop-charting-library.d.ts +21 -1
- package/dist/hyperprop-charting-library.js +152 -77
- package/dist/index.cjs +135 -77
- package/dist/index.d.cts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +135 -77
- package/docs/API.md +29 -8
- package/docs/RECIPES.md +13 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,20 @@ const data: OhlcDataPoint[] = [
|
|
|
32
32
|
chart.setData(data);
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
## Dash Pattern Styling
|
|
36
|
+
|
|
37
|
+
You can control dotted/dashed spacing globally with `dashPatterns`:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
const chart = createChart(root, {
|
|
41
|
+
dashPatterns: {
|
|
42
|
+
dotted: [2, 1],
|
|
43
|
+
connectorDotted: [2, 2],
|
|
44
|
+
borderDotted: [2, 1]
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
35
49
|
## Full Documentation
|
|
36
50
|
|
|
37
51
|
- API reference: `docs/API.md`
|
|
@@ -46,8 +60,9 @@ chart.setData(data);
|
|
|
46
60
|
- `chart.setData(data)`
|
|
47
61
|
- `chart.setPriceLines(lines)` / `chart.addPriceLine(line)` / `chart.removePriceLine(id)`
|
|
48
62
|
- `chart.setOrderLines(lines)` / `chart.addOrderLine(line)` / `chart.updateOrderLine(id, patch)` / `chart.removeOrderLine(id)`
|
|
49
|
-
- `chart.onOrderAction(handler)` / `chart.onChartClick(handler)`
|
|
63
|
+
- `chart.onOrderAction(handler)` / `chart.onChartClick(handler)` / `chart.onCrosshairMove(handler)`
|
|
50
64
|
- `chart.setDoubleClickEnabled(enabled)` / `chart.setDoubleClickAction(action)`
|
|
65
|
+
- `chart.zoomInX()` / `chart.zoomOutX()` / `chart.panX(bars)` / `chart.resetViewport()`
|
|
51
66
|
- `chart.resize(width, height)` / `chart.destroy()`
|
|
52
67
|
|
|
53
68
|
## Scope
|
|
@@ -68,6 +68,14 @@ var DEFAULT_WATERMARK_OPTIONS = {
|
|
|
68
68
|
imageTintColor: "",
|
|
69
69
|
imageTintOpacity: 1
|
|
70
70
|
};
|
|
71
|
+
var DEFAULT_DASH_PATTERNS = {
|
|
72
|
+
dotted: [2, 2],
|
|
73
|
+
dashed: [8, 6],
|
|
74
|
+
connectorDotted: [2, 3],
|
|
75
|
+
connectorDashed: [6, 5],
|
|
76
|
+
borderDotted: [2, 2],
|
|
77
|
+
borderDashed: [6, 4]
|
|
78
|
+
};
|
|
71
79
|
var DEFAULT_PRICE_LINE_OPTIONS = {
|
|
72
80
|
visible: true,
|
|
73
81
|
style: "solid",
|
|
@@ -118,6 +126,9 @@ var DEFAULT_OPTIONS = {
|
|
|
118
126
|
priceDecimals: 2,
|
|
119
127
|
initialViewport: "latest",
|
|
120
128
|
initialVisibleBars: 60,
|
|
129
|
+
minVisibleBars: 5,
|
|
130
|
+
maxVisibleBars: 2e4,
|
|
131
|
+
maxPanBars: 1e6,
|
|
121
132
|
rightEdgePaddingBars: 2,
|
|
122
133
|
preserveViewportOnDataUpdate: true,
|
|
123
134
|
upColor: "#2fb171",
|
|
@@ -144,8 +155,13 @@ var DEFAULT_OPTIONS = {
|
|
|
144
155
|
labelBackgroundColor: "#38bdf8",
|
|
145
156
|
labelTextColor: "#0b1220",
|
|
146
157
|
labelBorderRadius: 3
|
|
147
|
-
}
|
|
158
|
+
},
|
|
159
|
+
dashPatterns: DEFAULT_DASH_PATTERNS
|
|
148
160
|
};
|
|
161
|
+
var BRAND_LOGO_VIEWBOX_WIDTH = 190;
|
|
162
|
+
var BRAND_LOGO_VIEWBOX_HEIGHT = 186;
|
|
163
|
+
var BRAND_LOGO_PATH_A = "M0 93.0171V45.2271H48.9851V75.0332C48.9851 84.9545 57.0416 93.0001 66.9763 93.0001H94.9957V186H49.0531V110.984C49.0531 101.063 40.9965 93.0171 31.0619 93.0171H0Z";
|
|
164
|
+
var BRAND_LOGO_PATH_B = "M190 92.9915V140.782H141.015V110.975C141.015 101.054 132.958 93.0085 123.023 93.0085H95.0039V0H140.955V75.0162C140.955 84.9374 149.012 92.9831 158.946 92.9831H190V92.9915Z";
|
|
149
165
|
function createChart(element, options = {}) {
|
|
150
166
|
const mergedOptions = {
|
|
151
167
|
...DEFAULT_OPTIONS,
|
|
@@ -170,6 +186,10 @@ function createChart(element, options = {}) {
|
|
|
170
186
|
tickerLine: {
|
|
171
187
|
...DEFAULT_OPTIONS.tickerLine,
|
|
172
188
|
...options.tickerLine
|
|
189
|
+
},
|
|
190
|
+
dashPatterns: {
|
|
191
|
+
...DEFAULT_DASH_PATTERNS,
|
|
192
|
+
...options.dashPatterns ?? {}
|
|
173
193
|
}
|
|
174
194
|
};
|
|
175
195
|
let width = mergedOptions.width;
|
|
@@ -198,6 +218,8 @@ function createChart(element, options = {}) {
|
|
|
198
218
|
let yMaxOverride = null;
|
|
199
219
|
let autoYMin = null;
|
|
200
220
|
let autoYMax = null;
|
|
221
|
+
const brandLogoPathA = new Path2D(BRAND_LOGO_PATH_A);
|
|
222
|
+
const brandLogoPathB = new Path2D(BRAND_LOGO_PATH_B);
|
|
201
223
|
let watermarkImageSrc = null;
|
|
202
224
|
let watermarkImage = null;
|
|
203
225
|
let watermarkImageReady = false;
|
|
@@ -218,7 +240,9 @@ function createChart(element, options = {}) {
|
|
|
218
240
|
element.innerHTML = "";
|
|
219
241
|
element.appendChild(canvas);
|
|
220
242
|
const margin = { top: 16, right: 72, bottom: 34, left: 12 };
|
|
221
|
-
const
|
|
243
|
+
const minVisibleBars = Math.max(1, Math.floor(mergedOptions.minVisibleBars));
|
|
244
|
+
const maxVisibleBars = Math.max(minVisibleBars, Math.floor(mergedOptions.maxVisibleBars));
|
|
245
|
+
const maxPanBars = Math.max(0, Math.floor(mergedOptions.maxPanBars));
|
|
222
246
|
const rightEdgePaddingBars = Math.max(0, mergedOptions.rightEdgePaddingBars);
|
|
223
247
|
const getPixelRatio = () => {
|
|
224
248
|
if (typeof window === "undefined") {
|
|
@@ -253,6 +277,23 @@ function createChart(element, options = {}) {
|
|
|
253
277
|
const clamp = (value, min, max) => {
|
|
254
278
|
return Math.min(max, Math.max(min, value));
|
|
255
279
|
};
|
|
280
|
+
const dashPatterns = {
|
|
281
|
+
dotted: mergedOptions.dashPatterns.dotted ?? DEFAULT_DASH_PATTERNS.dotted,
|
|
282
|
+
dashed: mergedOptions.dashPatterns.dashed ?? DEFAULT_DASH_PATTERNS.dashed,
|
|
283
|
+
connectorDotted: mergedOptions.dashPatterns.connectorDotted ?? DEFAULT_DASH_PATTERNS.connectorDotted,
|
|
284
|
+
connectorDashed: mergedOptions.dashPatterns.connectorDashed ?? DEFAULT_DASH_PATTERNS.connectorDashed,
|
|
285
|
+
borderDotted: mergedOptions.dashPatterns.borderDotted ?? DEFAULT_DASH_PATTERNS.borderDotted,
|
|
286
|
+
borderDashed: mergedOptions.dashPatterns.borderDashed ?? DEFAULT_DASH_PATTERNS.borderDashed
|
|
287
|
+
};
|
|
288
|
+
const applyDashPattern = (style, dotted, dashed) => {
|
|
289
|
+
if (style === "dotted") {
|
|
290
|
+
ctx.setLineDash(dotted);
|
|
291
|
+
} else if (style === "dashed") {
|
|
292
|
+
ctx.setLineDash(dashed);
|
|
293
|
+
} else {
|
|
294
|
+
ctx.setLineDash([]);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
256
297
|
const clampXViewport = () => {
|
|
257
298
|
const count = data.length;
|
|
258
299
|
if (count === 0) {
|
|
@@ -260,8 +301,8 @@ function createChart(element, options = {}) {
|
|
|
260
301
|
xSpan = 60;
|
|
261
302
|
return;
|
|
262
303
|
}
|
|
263
|
-
const minSpan =
|
|
264
|
-
const maxSpan = Math.max(minSpan, count + maxPanBars * 2);
|
|
304
|
+
const minSpan = minVisibleBars;
|
|
305
|
+
const maxSpan = Math.min(maxVisibleBars, Math.max(minSpan, count + maxPanBars * 2));
|
|
265
306
|
xSpan = clamp(xSpan, minSpan, maxSpan);
|
|
266
307
|
xCenter = clamp(xCenter, -maxPanBars, count + maxPanBars);
|
|
267
308
|
};
|
|
@@ -272,8 +313,9 @@ function createChart(element, options = {}) {
|
|
|
272
313
|
xSpan = 60;
|
|
273
314
|
return;
|
|
274
315
|
}
|
|
275
|
-
const
|
|
276
|
-
|
|
316
|
+
const maxSpan = Math.min(maxVisibleBars, Math.max(minVisibleBars, count + maxPanBars * 2));
|
|
317
|
+
const requestedVisibleBars = clamp(Math.floor(mergedOptions.initialVisibleBars), minVisibleBars, maxSpan);
|
|
318
|
+
xSpan = requestedVisibleBars;
|
|
277
319
|
if (mergedOptions.initialViewport === "center") {
|
|
278
320
|
xCenter = count / 2;
|
|
279
321
|
} else {
|
|
@@ -425,13 +467,7 @@ function createChart(element, options = {}) {
|
|
|
425
467
|
ctx.save();
|
|
426
468
|
ctx.strokeStyle = color;
|
|
427
469
|
ctx.lineWidth = Math.max(1, mergedLine.thickness);
|
|
428
|
-
|
|
429
|
-
ctx.setLineDash([2, 4]);
|
|
430
|
-
} else if (mergedLine.style === "dashed") {
|
|
431
|
-
ctx.setLineDash([8, 6]);
|
|
432
|
-
} else {
|
|
433
|
-
ctx.setLineDash([]);
|
|
434
|
-
}
|
|
470
|
+
applyDashPattern(mergedLine.style, dashPatterns.dotted, dashPatterns.dashed);
|
|
435
471
|
ctx.beginPath();
|
|
436
472
|
ctx.moveTo(crisp(chartLeft), crisp(lineY));
|
|
437
473
|
ctx.lineTo(crisp(chartRight), crisp(lineY));
|
|
@@ -485,13 +521,7 @@ function createChart(element, options = {}) {
|
|
|
485
521
|
ctx.save();
|
|
486
522
|
ctx.strokeStyle = color;
|
|
487
523
|
ctx.lineWidth = Math.max(1, mergedLine.thickness);
|
|
488
|
-
|
|
489
|
-
ctx.setLineDash([2, 4]);
|
|
490
|
-
} else if (mergedLine.style === "dashed") {
|
|
491
|
-
ctx.setLineDash([8, 6]);
|
|
492
|
-
} else {
|
|
493
|
-
ctx.setLineDash([]);
|
|
494
|
-
}
|
|
524
|
+
applyDashPattern(mergedLine.style, dashPatterns.dotted, dashPatterns.dashed);
|
|
495
525
|
ctx.beginPath();
|
|
496
526
|
ctx.moveTo(crisp(chartLeft), crisp(lineY));
|
|
497
527
|
ctx.lineTo(crisp(chartRight), crisp(lineY));
|
|
@@ -503,13 +533,11 @@ function createChart(element, options = {}) {
|
|
|
503
533
|
ctx.save();
|
|
504
534
|
ctx.strokeStyle = mergedLine.connectorColor ?? color;
|
|
505
535
|
ctx.lineWidth = Math.max(1, mergedLine.connectorThickness);
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
ctx.setLineDash([]);
|
|
512
|
-
}
|
|
536
|
+
applyDashPattern(
|
|
537
|
+
mergedLine.connectorStyle,
|
|
538
|
+
dashPatterns.connectorDotted,
|
|
539
|
+
dashPatterns.connectorDashed
|
|
540
|
+
);
|
|
513
541
|
ctx.beginPath();
|
|
514
542
|
ctx.moveTo(crisp(connectorX), crisp(lineY));
|
|
515
543
|
ctx.lineTo(crisp(connectorX), crisp(connectorY));
|
|
@@ -612,13 +640,11 @@ function createChart(element, options = {}) {
|
|
|
612
640
|
ctx.save();
|
|
613
641
|
ctx.strokeStyle = actionBorderColor;
|
|
614
642
|
ctx.lineWidth = 1;
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
ctx.setLineDash([]);
|
|
621
|
-
}
|
|
643
|
+
applyDashPattern(
|
|
644
|
+
actionBorderStyle,
|
|
645
|
+
dashPatterns.borderDotted,
|
|
646
|
+
dashPatterns.borderDashed
|
|
647
|
+
);
|
|
622
648
|
strokeRoundedRect(Math.round(actionX), Math.round(actionY), actionW, actionH, actionRadius);
|
|
623
649
|
ctx.restore();
|
|
624
650
|
const baseFont = ctx.font;
|
|
@@ -957,13 +983,7 @@ function createChart(element, options = {}) {
|
|
|
957
983
|
ctx.save();
|
|
958
984
|
ctx.strokeStyle = crosshair.color;
|
|
959
985
|
ctx.lineWidth = Math.max(1, crosshair.width);
|
|
960
|
-
|
|
961
|
-
ctx.setLineDash([2, 4]);
|
|
962
|
-
} else if (crosshair.style === "dashed") {
|
|
963
|
-
ctx.setLineDash([8, 6]);
|
|
964
|
-
} else {
|
|
965
|
-
ctx.setLineDash([]);
|
|
966
|
-
}
|
|
986
|
+
applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
|
|
967
987
|
if (crosshair.showVertical) {
|
|
968
988
|
ctx.beginPath();
|
|
969
989
|
ctx.moveTo(crisp(cx), crisp(chartTop));
|
|
@@ -1005,13 +1025,7 @@ function createChart(element, options = {}) {
|
|
|
1005
1025
|
ctx.save();
|
|
1006
1026
|
ctx.strokeStyle = tickerColor;
|
|
1007
1027
|
ctx.lineWidth = tickerThickness;
|
|
1008
|
-
|
|
1009
|
-
ctx.setLineDash([2, 4]);
|
|
1010
|
-
} else if (tickerStyle === "dashed") {
|
|
1011
|
-
ctx.setLineDash([8, 6]);
|
|
1012
|
-
} else {
|
|
1013
|
-
ctx.setLineDash([]);
|
|
1014
|
-
}
|
|
1028
|
+
applyDashPattern(tickerStyle, dashPatterns.dotted, dashPatterns.dashed);
|
|
1015
1029
|
ctx.beginPath();
|
|
1016
1030
|
ctx.moveTo(crisp(chartLeft), crisp(lineY));
|
|
1017
1031
|
ctx.lineTo(crisp(chartRight), crisp(lineY));
|
|
@@ -1055,6 +1069,17 @@ function createChart(element, options = {}) {
|
|
|
1055
1069
|
});
|
|
1056
1070
|
drawText(timeLabel, x, chartBottom + 8, "center", "top", axis.textColor);
|
|
1057
1071
|
}
|
|
1072
|
+
const brandLogoWidth = 34;
|
|
1073
|
+
const brandLogoHeight = BRAND_LOGO_VIEWBOX_HEIGHT / BRAND_LOGO_VIEWBOX_WIDTH * brandLogoWidth;
|
|
1074
|
+
const brandLogoX = chartLeft + 16;
|
|
1075
|
+
const brandLogoY = chartBottom - brandLogoHeight - 10;
|
|
1076
|
+
ctx.save();
|
|
1077
|
+
ctx.translate(brandLogoX, brandLogoY);
|
|
1078
|
+
ctx.scale(brandLogoWidth / BRAND_LOGO_VIEWBOX_WIDTH, brandLogoHeight / BRAND_LOGO_VIEWBOX_HEIGHT);
|
|
1079
|
+
ctx.fillStyle = "#ffffff";
|
|
1080
|
+
ctx.fill(brandLogoPathA);
|
|
1081
|
+
ctx.fill(brandLogoPathB);
|
|
1082
|
+
ctx.restore();
|
|
1058
1083
|
if (crosshair.visible && crosshairPoint) {
|
|
1059
1084
|
const cx = clamp(crosshairPoint.x, chartLeft, chartRight);
|
|
1060
1085
|
const cy = clamp(crosshairPoint.y, chartTop, chartBottom);
|
|
@@ -1073,13 +1098,11 @@ function createChart(element, options = {}) {
|
|
|
1073
1098
|
ctx.save();
|
|
1074
1099
|
ctx.strokeStyle = labelBorderColor;
|
|
1075
1100
|
ctx.lineWidth = labelBorderWidth;
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
ctx.setLineDash([]);
|
|
1082
|
-
}
|
|
1101
|
+
applyDashPattern(
|
|
1102
|
+
labelBorderStyle,
|
|
1103
|
+
dashPatterns.borderDotted,
|
|
1104
|
+
dashPatterns.borderDashed
|
|
1105
|
+
);
|
|
1083
1106
|
strokeRoundedRect(Math.round(x), Math.round(y), widthValue, labelHeight, labelRadius);
|
|
1084
1107
|
ctx.restore();
|
|
1085
1108
|
};
|
|
@@ -1115,8 +1138,8 @@ function createChart(element, options = {}) {
|
|
|
1115
1138
|
if (!drawState || data.length === 0) {
|
|
1116
1139
|
return;
|
|
1117
1140
|
}
|
|
1118
|
-
const minSpan =
|
|
1119
|
-
const maxSpan = Math.max(minSpan, data.length + maxPanBars * 2);
|
|
1141
|
+
const minSpan = minVisibleBars;
|
|
1142
|
+
const maxSpan = Math.min(maxVisibleBars, Math.max(minSpan, data.length + maxPanBars * 2));
|
|
1120
1143
|
const nextSpan = clamp(xSpan * factor, minSpan, maxSpan);
|
|
1121
1144
|
const anchorRatio = clamp((anchorX - drawState.chartLeft) / drawState.chartWidth, 0, 1);
|
|
1122
1145
|
const anchorIndex = drawState.xStart + anchorRatio * xSpan;
|
|
@@ -1130,8 +1153,8 @@ function createChart(element, options = {}) {
|
|
|
1130
1153
|
if (!drawState || data.length === 0) {
|
|
1131
1154
|
return;
|
|
1132
1155
|
}
|
|
1133
|
-
const minSpan =
|
|
1134
|
-
const maxSpan = Math.max(minSpan, data.length + maxPanBars * 2);
|
|
1156
|
+
const minSpan = minVisibleBars;
|
|
1157
|
+
const maxSpan = Math.min(maxVisibleBars, Math.max(minSpan, data.length + maxPanBars * 2));
|
|
1135
1158
|
const nextSpan = clamp(xSpan * factor, minSpan, maxSpan);
|
|
1136
1159
|
const rightEdgeIndex = data.length + rightEdgePaddingBars;
|
|
1137
1160
|
const nextStart = rightEdgeIndex - nextSpan;
|
|
@@ -1180,6 +1203,64 @@ function createChart(element, options = {}) {
|
|
|
1180
1203
|
}
|
|
1181
1204
|
draw();
|
|
1182
1205
|
};
|
|
1206
|
+
const resetYViewport = () => {
|
|
1207
|
+
yMinOverride = null;
|
|
1208
|
+
yMaxOverride = null;
|
|
1209
|
+
autoYMin = null;
|
|
1210
|
+
autoYMax = null;
|
|
1211
|
+
};
|
|
1212
|
+
const zoomInX = (factor = 1.25) => {
|
|
1213
|
+
if (!drawState) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
zoomX(1 / Math.max(1.01, factor), drawState.chartLeft + drawState.chartWidth / 2);
|
|
1217
|
+
};
|
|
1218
|
+
const zoomOutX = (factor = 1.25) => {
|
|
1219
|
+
if (!drawState) {
|
|
1220
|
+
return;
|
|
1221
|
+
}
|
|
1222
|
+
zoomX(Math.max(1.01, factor), drawState.chartLeft + drawState.chartWidth / 2);
|
|
1223
|
+
};
|
|
1224
|
+
const zoomInY = (factor = 1.25) => {
|
|
1225
|
+
if (!drawState) {
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
zoomY(1 / Math.max(1.01, factor), drawState.chartTop + drawState.chartHeight / 2);
|
|
1229
|
+
};
|
|
1230
|
+
const zoomOutY = (factor = 1.25) => {
|
|
1231
|
+
if (!drawState) {
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
zoomY(Math.max(1.01, factor), drawState.chartTop + drawState.chartHeight / 2);
|
|
1235
|
+
};
|
|
1236
|
+
const panX = (bars) => {
|
|
1237
|
+
if (!Number.isFinite(bars) || bars === 0) {
|
|
1238
|
+
return;
|
|
1239
|
+
}
|
|
1240
|
+
xCenter += bars;
|
|
1241
|
+
clampXViewport();
|
|
1242
|
+
draw();
|
|
1243
|
+
};
|
|
1244
|
+
const panY = (priceDelta) => {
|
|
1245
|
+
if (!drawState || !Number.isFinite(priceDelta) || priceDelta === 0) {
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
1248
|
+
const currentMin = yMinOverride ?? drawState.yMin;
|
|
1249
|
+
const currentMax = yMaxOverride ?? drawState.yMax;
|
|
1250
|
+
const clamped = clampYRange(currentMin + priceDelta, currentMax + priceDelta);
|
|
1251
|
+
yMinOverride = clamped.min;
|
|
1252
|
+
yMaxOverride = clamped.max;
|
|
1253
|
+
draw();
|
|
1254
|
+
};
|
|
1255
|
+
const fitContent = () => {
|
|
1256
|
+
fitXViewport();
|
|
1257
|
+
draw();
|
|
1258
|
+
};
|
|
1259
|
+
const resetViewport = () => {
|
|
1260
|
+
fitXViewport();
|
|
1261
|
+
resetYViewport();
|
|
1262
|
+
draw();
|
|
1263
|
+
};
|
|
1183
1264
|
const getCanvasPoint = (event) => {
|
|
1184
1265
|
const rect = canvas.getBoundingClientRect();
|
|
1185
1266
|
return {
|
|
@@ -1523,19 +1604,11 @@ function createChart(element, options = {}) {
|
|
|
1523
1604
|
return;
|
|
1524
1605
|
}
|
|
1525
1606
|
if (region === "y-axis") {
|
|
1526
|
-
|
|
1527
|
-
yMaxOverride = null;
|
|
1528
|
-
autoYMin = null;
|
|
1529
|
-
autoYMax = null;
|
|
1607
|
+
resetYViewport();
|
|
1530
1608
|
draw();
|
|
1531
1609
|
return;
|
|
1532
1610
|
}
|
|
1533
|
-
|
|
1534
|
-
yMinOverride = null;
|
|
1535
|
-
yMaxOverride = null;
|
|
1536
|
-
autoYMin = null;
|
|
1537
|
-
autoYMax = null;
|
|
1538
|
-
draw();
|
|
1611
|
+
resetViewport();
|
|
1539
1612
|
};
|
|
1540
1613
|
canvas.addEventListener("pointerdown", onPointerDown);
|
|
1541
1614
|
canvas.addEventListener("pointermove", onPointerMove);
|
|
@@ -1559,19 +1632,13 @@ function createChart(element, options = {}) {
|
|
|
1559
1632
|
if (data.length === 0) {
|
|
1560
1633
|
xCenter = 0;
|
|
1561
1634
|
xSpan = 60;
|
|
1562
|
-
|
|
1563
|
-
yMaxOverride = null;
|
|
1564
|
-
autoYMin = null;
|
|
1565
|
-
autoYMax = null;
|
|
1635
|
+
resetYViewport();
|
|
1566
1636
|
draw();
|
|
1567
1637
|
return;
|
|
1568
1638
|
}
|
|
1569
1639
|
if (!hadData) {
|
|
1570
1640
|
fitXViewport();
|
|
1571
|
-
|
|
1572
|
-
yMaxOverride = null;
|
|
1573
|
-
autoYMin = null;
|
|
1574
|
-
autoYMax = null;
|
|
1641
|
+
resetYViewport();
|
|
1575
1642
|
} else {
|
|
1576
1643
|
if (mergedOptions.preserveViewportOnDataUpdate) {
|
|
1577
1644
|
clampXViewport();
|
|
@@ -1670,6 +1737,14 @@ function createChart(element, options = {}) {
|
|
|
1670
1737
|
onOrderAction,
|
|
1671
1738
|
onChartClick,
|
|
1672
1739
|
onCrosshairMove,
|
|
1740
|
+
zoomInX,
|
|
1741
|
+
zoomOutX,
|
|
1742
|
+
zoomInY,
|
|
1743
|
+
zoomOutY,
|
|
1744
|
+
panX,
|
|
1745
|
+
panY,
|
|
1746
|
+
resetViewport,
|
|
1747
|
+
fitContent,
|
|
1673
1748
|
setDoubleClickEnabled,
|
|
1674
1749
|
setDoubleClickAction,
|
|
1675
1750
|
resize,
|
|
@@ -7,6 +7,9 @@ interface ChartOptions {
|
|
|
7
7
|
priceDecimals?: number;
|
|
8
8
|
initialViewport?: "latest" | "center";
|
|
9
9
|
initialVisibleBars?: number;
|
|
10
|
+
minVisibleBars?: number;
|
|
11
|
+
maxVisibleBars?: number;
|
|
12
|
+
maxPanBars?: number;
|
|
10
13
|
rightEdgePaddingBars?: number;
|
|
11
14
|
preserveViewportOnDataUpdate?: boolean;
|
|
12
15
|
upColor?: string;
|
|
@@ -26,6 +29,15 @@ interface ChartOptions {
|
|
|
26
29
|
priceLines?: PriceLineOptions[];
|
|
27
30
|
orderLines?: OrderLineOptions[];
|
|
28
31
|
tickerLine?: TickerLineOptions;
|
|
32
|
+
dashPatterns?: Partial<DashPatternOptions>;
|
|
33
|
+
}
|
|
34
|
+
interface DashPatternOptions {
|
|
35
|
+
dotted: [number, number];
|
|
36
|
+
dashed: [number, number];
|
|
37
|
+
connectorDotted: [number, number];
|
|
38
|
+
connectorDashed: [number, number];
|
|
39
|
+
borderDotted: [number, number];
|
|
40
|
+
borderDashed: [number, number];
|
|
29
41
|
}
|
|
30
42
|
interface AxisOptions {
|
|
31
43
|
lineColor?: string;
|
|
@@ -182,6 +194,14 @@ interface ChartInstance {
|
|
|
182
194
|
onOrderAction: (handler: ((event: OrderActionEvent) => void) | null) => void;
|
|
183
195
|
onChartClick: (handler: ((event: ChartClickEvent) => void) | null) => void;
|
|
184
196
|
onCrosshairMove: (handler: ((event: CrosshairMoveEvent) => void) | null) => void;
|
|
197
|
+
zoomInX: (factor?: number) => void;
|
|
198
|
+
zoomOutX: (factor?: number) => void;
|
|
199
|
+
zoomInY: (factor?: number) => void;
|
|
200
|
+
zoomOutY: (factor?: number) => void;
|
|
201
|
+
panX: (bars: number) => void;
|
|
202
|
+
panY: (priceDelta: number) => void;
|
|
203
|
+
resetViewport: () => void;
|
|
204
|
+
fitContent: () => void;
|
|
185
205
|
setDoubleClickEnabled: (enabled: boolean) => void;
|
|
186
206
|
setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
|
|
187
207
|
resize: (width?: number, height?: number) => void;
|
|
@@ -197,4 +217,4 @@ interface OhlcDataPoint {
|
|
|
197
217
|
}
|
|
198
218
|
declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
|
|
199
219
|
|
|
200
|
-
export { type AxisOptions, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type GridOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type WatermarkOptions, createChart };
|
|
220
|
+
export { type AxisOptions, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type DashPatternOptions, type GridOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type WatermarkOptions, createChart };
|