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 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 maxPanBars = 1e6;
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 = 5;
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 requestedVisibleBars = Math.max(5, Math.floor(mergedOptions.initialVisibleBars));
276
- xSpan = Math.min(requestedVisibleBars, Math.max(5, count));
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
- if (mergedLine.style === "dotted") {
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
- if (mergedLine.style === "dotted") {
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
- if (mergedLine.connectorStyle === "dotted") {
507
- ctx.setLineDash([2, 5]);
508
- } else if (mergedLine.connectorStyle === "dashed") {
509
- ctx.setLineDash([6, 5]);
510
- } else {
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
- if (actionBorderStyle === "dotted") {
616
- ctx.setLineDash([2, 3]);
617
- } else if (actionBorderStyle === "dashed") {
618
- ctx.setLineDash([6, 4]);
619
- } else {
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
- if (crosshair.style === "dotted") {
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
- if (tickerStyle === "dotted") {
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
- if (labelBorderStyle === "dotted") {
1077
- ctx.setLineDash([2, 3]);
1078
- } else if (labelBorderStyle === "dashed") {
1079
- ctx.setLineDash([6, 4]);
1080
- } else {
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 = 5;
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 = 5;
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
- yMinOverride = null;
1527
- yMaxOverride = null;
1528
- autoYMin = null;
1529
- autoYMax = null;
1607
+ resetYViewport();
1530
1608
  draw();
1531
1609
  return;
1532
1610
  }
1533
- fitXViewport();
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
- yMinOverride = null;
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
- yMinOverride = null;
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 };