hyperprop-charting-library 0.1.68 → 0.1.70

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.
@@ -20,9 +20,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ FIB_DEFAULT_PALETTE: () => FIB_DEFAULT_PALETTE,
23
24
  createChart: () => createChart
24
25
  });
25
26
  module.exports = __toCommonJS(index_exports);
27
+ var FIB_DEFAULT_PALETTE = [
28
+ "#787b86",
29
+ "#f23645",
30
+ "#ff9800",
31
+ "#4caf50",
32
+ "#089981",
33
+ "#00bcd4",
34
+ "#2962ff",
35
+ "#9c27b0"
36
+ ];
26
37
  var DEFAULT_GRID_OPTIONS = {
27
38
  color: "#2b2f38",
28
39
  opacity: 0.38,
@@ -43,6 +54,8 @@ var DEFAULT_CROSSHAIR_OPTIONS = {
43
54
  color: "#94a3b8",
44
55
  width: 1,
45
56
  style: "dotted",
57
+ mode: "cross",
58
+ dotRadius: 3,
46
59
  showHorizontal: true,
47
60
  showVertical: true,
48
61
  showPriceLabel: true,
@@ -942,6 +955,7 @@ function createChart(element, options = {}) {
942
955
  })),
943
956
  visible: drawing.visible ?? true,
944
957
  color: drawing.color ?? "#94a3b8",
958
+ colors: Array.isArray(drawing.colors) ? drawing.colors.filter((value) => typeof value === "string") : [],
945
959
  style: drawing.style ?? "dotted",
946
960
  width: Math.max(1, Number(drawing.width) || 1),
947
961
  locked: drawing.locked ?? false,
@@ -953,6 +967,7 @@ function createChart(element, options = {}) {
953
967
  points: drawing.points.map((point) => ({ ...point })),
954
968
  visible: drawing.visible,
955
969
  color: drawing.color,
970
+ colors: [...drawing.colors],
956
971
  style: drawing.style,
957
972
  width: drawing.width,
958
973
  locked: drawing.locked,
@@ -2242,32 +2257,33 @@ function createChart(element, options = {}) {
2242
2257
  const secondY = yFromPrice(second.price);
2243
2258
  const lineLeft = chartLeft;
2244
2259
  const lineRight = chartRight;
2260
+ const palette = drawing.colors.length > 0 ? drawing.colors : null;
2261
+ const levelColorAt = (index) => palette ? palette[index % palette.length] : drawing.color;
2245
2262
  const levelLines = FIB_RATIOS.map((ratio) => {
2246
2263
  const price = first.price + (second.price - first.price) * (1 - ratio);
2247
2264
  return { ratio, price, y: yFromPrice(price) };
2248
2265
  });
2249
- const bandColor = hexToRgba(drawing.color, 0.1);
2250
2266
  for (let index = 0; index < levelLines.length - 1; index += 1) {
2251
2267
  const top = levelLines[index];
2252
2268
  const bottom = levelLines[index + 1];
2253
2269
  const bandTop = Math.min(top.y, bottom.y);
2254
2270
  const bandBottom = Math.max(top.y, bottom.y);
2255
2271
  ctx.save();
2256
- ctx.fillStyle = bandColor;
2272
+ ctx.fillStyle = hexToRgba(levelColorAt(index), 0.1);
2257
2273
  ctx.globalAlpha = draft ? 0.5 : 1;
2258
2274
  ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
2259
2275
  ctx.restore();
2260
2276
  }
2261
2277
  ctx.save();
2262
2278
  ctx.lineWidth = drawing.width;
2263
- ctx.strokeStyle = drawing.color;
2264
2279
  applyDashPattern(drawing.style, dashPatterns.dotted, dashPatterns.dashed);
2265
- for (const level of levelLines) {
2280
+ levelLines.forEach((level, index) => {
2281
+ ctx.strokeStyle = levelColorAt(index);
2266
2282
  ctx.beginPath();
2267
2283
  ctx.moveTo(crisp(lineLeft), crisp(level.y));
2268
2284
  ctx.lineTo(crisp(lineRight), crisp(level.y));
2269
2285
  ctx.stroke();
2270
- }
2286
+ });
2271
2287
  ctx.restore();
2272
2288
  ctx.save();
2273
2289
  ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
@@ -2282,7 +2298,7 @@ function createChart(element, options = {}) {
2282
2298
  drawDrawingHandle(secondX, secondY, drawing.color);
2283
2299
  const prevFont = ctx.font;
2284
2300
  ctx.font = `500 11px ${mergedOptions.fontFamily}`;
2285
- for (const level of levelLines) {
2301
+ levelLines.forEach((level, index) => {
2286
2302
  const labelText = `${level.ratio} (${formatPrice(level.price)})`;
2287
2303
  const textWidth = ctx.measureText(labelText).width;
2288
2304
  const padding = 4;
@@ -2290,11 +2306,11 @@ function createChart(element, options = {}) {
2290
2306
  const bgY = level.y - 9;
2291
2307
  ctx.fillStyle = mergedOptions.backgroundColor;
2292
2308
  fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
2293
- ctx.fillStyle = drawing.color;
2309
+ ctx.fillStyle = levelColorAt(index);
2294
2310
  ctx.textAlign = "left";
2295
2311
  ctx.textBaseline = "middle";
2296
2312
  ctx.fillText(labelText, bgX + padding, bgY + 8);
2297
- }
2313
+ });
2298
2314
  ctx.font = prevFont;
2299
2315
  }
2300
2316
  }
@@ -2479,23 +2495,32 @@ function createChart(element, options = {}) {
2479
2495
  if (crosshair.visible && crosshairPoint) {
2480
2496
  const cx = clamp(crosshairPoint.x, chartLeft, chartRight);
2481
2497
  const cy = clamp(crosshairPoint.y, chartTop, chartBottom);
2482
- ctx.save();
2483
- ctx.strokeStyle = crosshair.color;
2484
- ctx.lineWidth = Math.max(1, crosshair.width);
2485
- applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
2486
- if (crosshair.showVertical) {
2487
- ctx.beginPath();
2488
- ctx.moveTo(crisp(cx), crisp(chartTop));
2489
- ctx.lineTo(crisp(cx), crisp(chartBottom));
2490
- ctx.stroke();
2491
- }
2492
- if (crosshair.showHorizontal) {
2498
+ if (crosshair.mode === "dot") {
2499
+ ctx.save();
2500
+ ctx.fillStyle = crosshair.color;
2493
2501
  ctx.beginPath();
2494
- ctx.moveTo(crisp(chartLeft), crisp(cy));
2495
- ctx.lineTo(crisp(chartRight), crisp(cy));
2496
- ctx.stroke();
2502
+ ctx.arc(cx, cy, Math.max(1, crosshair.dotRadius), 0, Math.PI * 2);
2503
+ ctx.fill();
2504
+ ctx.restore();
2505
+ } else {
2506
+ ctx.save();
2507
+ ctx.strokeStyle = crosshair.color;
2508
+ ctx.lineWidth = Math.max(1, crosshair.width);
2509
+ applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
2510
+ if (crosshair.showVertical) {
2511
+ ctx.beginPath();
2512
+ ctx.moveTo(crisp(cx), crisp(chartTop));
2513
+ ctx.lineTo(crisp(cx), crisp(chartBottom));
2514
+ ctx.stroke();
2515
+ }
2516
+ if (crosshair.showHorizontal) {
2517
+ ctx.beginPath();
2518
+ ctx.moveTo(crisp(chartLeft), crisp(cy));
2519
+ ctx.lineTo(crisp(chartRight), crisp(cy));
2520
+ ctx.stroke();
2521
+ }
2522
+ ctx.restore();
2497
2523
  }
2498
- ctx.restore();
2499
2524
  }
2500
2525
  ctx.restore();
2501
2526
  if (activeSeparateIndicators.length > 0) {
@@ -3609,6 +3634,7 @@ function createChart(element, options = {}) {
3609
3634
  type: "fib-retracement",
3610
3635
  points: [point, point],
3611
3636
  color: defaults.color ?? "#2563eb",
3637
+ colors: defaults.colors ?? FIB_DEFAULT_PALETTE,
3612
3638
  style: defaults.style ?? "solid",
3613
3639
  width: defaults.width ?? 1
3614
3640
  });
@@ -4538,5 +4564,6 @@ function createChart(element, options = {}) {
4538
4564
  }
4539
4565
  // Annotate the CommonJS export names for ESM import in node:
4540
4566
  0 && (module.exports = {
4567
+ FIB_DEFAULT_PALETTE,
4541
4568
  createChart
4542
4569
  });
@@ -56,11 +56,19 @@ interface DrawingObjectOptions {
56
56
  points: DrawingPoint[];
57
57
  visible?: boolean;
58
58
  color?: string;
59
+ /**
60
+ * Optional per-level colors. Currently used by `fib-retracement`: when set
61
+ * (non-empty), each level/band cycles through these colors instead of using
62
+ * the single `color`. Leave empty for a monochrome drawing.
63
+ */
64
+ colors?: string[];
59
65
  style?: "solid" | "dotted" | "dashed";
60
66
  width?: number;
61
67
  label?: string;
62
68
  locked?: boolean;
63
69
  }
70
+ /** Default multi-color palette for fib-retracement levels. */
71
+ declare const FIB_DEFAULT_PALETTE: string[];
64
72
  interface DrawingSelectEvent {
65
73
  drawing: DrawingObjectOptions;
66
74
  target: "line" | "handle";
@@ -74,7 +82,7 @@ interface DrawingHoverEvent {
74
82
  x: number;
75
83
  y: number;
76
84
  }
77
- type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "style" | "width">>;
85
+ type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width">>;
78
86
  interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
79
87
  id?: string;
80
88
  type: string;
@@ -188,6 +196,8 @@ interface CrosshairOptions {
188
196
  color?: string;
189
197
  width?: number;
190
198
  style?: "solid" | "dotted" | "dashed";
199
+ mode?: "cross" | "dot";
200
+ dotRadius?: number;
191
201
  showHorizontal?: boolean;
192
202
  showVertical?: boolean;
193
203
  showPriceLabel?: boolean;
@@ -445,4 +455,4 @@ interface ViewportState {
445
455
  }
446
456
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
447
457
 
448
- export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, 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 };
458
+ export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, 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 };
@@ -1,4 +1,14 @@
1
1
  // src/index.ts
2
+ var FIB_DEFAULT_PALETTE = [
3
+ "#787b86",
4
+ "#f23645",
5
+ "#ff9800",
6
+ "#4caf50",
7
+ "#089981",
8
+ "#00bcd4",
9
+ "#2962ff",
10
+ "#9c27b0"
11
+ ];
2
12
  var DEFAULT_GRID_OPTIONS = {
3
13
  color: "#2b2f38",
4
14
  opacity: 0.38,
@@ -19,6 +29,8 @@ var DEFAULT_CROSSHAIR_OPTIONS = {
19
29
  color: "#94a3b8",
20
30
  width: 1,
21
31
  style: "dotted",
32
+ mode: "cross",
33
+ dotRadius: 3,
22
34
  showHorizontal: true,
23
35
  showVertical: true,
24
36
  showPriceLabel: true,
@@ -918,6 +930,7 @@ function createChart(element, options = {}) {
918
930
  })),
919
931
  visible: drawing.visible ?? true,
920
932
  color: drawing.color ?? "#94a3b8",
933
+ colors: Array.isArray(drawing.colors) ? drawing.colors.filter((value) => typeof value === "string") : [],
921
934
  style: drawing.style ?? "dotted",
922
935
  width: Math.max(1, Number(drawing.width) || 1),
923
936
  locked: drawing.locked ?? false,
@@ -929,6 +942,7 @@ function createChart(element, options = {}) {
929
942
  points: drawing.points.map((point) => ({ ...point })),
930
943
  visible: drawing.visible,
931
944
  color: drawing.color,
945
+ colors: [...drawing.colors],
932
946
  style: drawing.style,
933
947
  width: drawing.width,
934
948
  locked: drawing.locked,
@@ -2218,32 +2232,33 @@ function createChart(element, options = {}) {
2218
2232
  const secondY = yFromPrice(second.price);
2219
2233
  const lineLeft = chartLeft;
2220
2234
  const lineRight = chartRight;
2235
+ const palette = drawing.colors.length > 0 ? drawing.colors : null;
2236
+ const levelColorAt = (index) => palette ? palette[index % palette.length] : drawing.color;
2221
2237
  const levelLines = FIB_RATIOS.map((ratio) => {
2222
2238
  const price = first.price + (second.price - first.price) * (1 - ratio);
2223
2239
  return { ratio, price, y: yFromPrice(price) };
2224
2240
  });
2225
- const bandColor = hexToRgba(drawing.color, 0.1);
2226
2241
  for (let index = 0; index < levelLines.length - 1; index += 1) {
2227
2242
  const top = levelLines[index];
2228
2243
  const bottom = levelLines[index + 1];
2229
2244
  const bandTop = Math.min(top.y, bottom.y);
2230
2245
  const bandBottom = Math.max(top.y, bottom.y);
2231
2246
  ctx.save();
2232
- ctx.fillStyle = bandColor;
2247
+ ctx.fillStyle = hexToRgba(levelColorAt(index), 0.1);
2233
2248
  ctx.globalAlpha = draft ? 0.5 : 1;
2234
2249
  ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
2235
2250
  ctx.restore();
2236
2251
  }
2237
2252
  ctx.save();
2238
2253
  ctx.lineWidth = drawing.width;
2239
- ctx.strokeStyle = drawing.color;
2240
2254
  applyDashPattern(drawing.style, dashPatterns.dotted, dashPatterns.dashed);
2241
- for (const level of levelLines) {
2255
+ levelLines.forEach((level, index) => {
2256
+ ctx.strokeStyle = levelColorAt(index);
2242
2257
  ctx.beginPath();
2243
2258
  ctx.moveTo(crisp(lineLeft), crisp(level.y));
2244
2259
  ctx.lineTo(crisp(lineRight), crisp(level.y));
2245
2260
  ctx.stroke();
2246
- }
2261
+ });
2247
2262
  ctx.restore();
2248
2263
  ctx.save();
2249
2264
  ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
@@ -2258,7 +2273,7 @@ function createChart(element, options = {}) {
2258
2273
  drawDrawingHandle(secondX, secondY, drawing.color);
2259
2274
  const prevFont = ctx.font;
2260
2275
  ctx.font = `500 11px ${mergedOptions.fontFamily}`;
2261
- for (const level of levelLines) {
2276
+ levelLines.forEach((level, index) => {
2262
2277
  const labelText = `${level.ratio} (${formatPrice(level.price)})`;
2263
2278
  const textWidth = ctx.measureText(labelText).width;
2264
2279
  const padding = 4;
@@ -2266,11 +2281,11 @@ function createChart(element, options = {}) {
2266
2281
  const bgY = level.y - 9;
2267
2282
  ctx.fillStyle = mergedOptions.backgroundColor;
2268
2283
  fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
2269
- ctx.fillStyle = drawing.color;
2284
+ ctx.fillStyle = levelColorAt(index);
2270
2285
  ctx.textAlign = "left";
2271
2286
  ctx.textBaseline = "middle";
2272
2287
  ctx.fillText(labelText, bgX + padding, bgY + 8);
2273
- }
2288
+ });
2274
2289
  ctx.font = prevFont;
2275
2290
  }
2276
2291
  }
@@ -2455,23 +2470,32 @@ function createChart(element, options = {}) {
2455
2470
  if (crosshair.visible && crosshairPoint) {
2456
2471
  const cx = clamp(crosshairPoint.x, chartLeft, chartRight);
2457
2472
  const cy = clamp(crosshairPoint.y, chartTop, chartBottom);
2458
- ctx.save();
2459
- ctx.strokeStyle = crosshair.color;
2460
- ctx.lineWidth = Math.max(1, crosshair.width);
2461
- applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
2462
- if (crosshair.showVertical) {
2463
- ctx.beginPath();
2464
- ctx.moveTo(crisp(cx), crisp(chartTop));
2465
- ctx.lineTo(crisp(cx), crisp(chartBottom));
2466
- ctx.stroke();
2467
- }
2468
- if (crosshair.showHorizontal) {
2473
+ if (crosshair.mode === "dot") {
2474
+ ctx.save();
2475
+ ctx.fillStyle = crosshair.color;
2469
2476
  ctx.beginPath();
2470
- ctx.moveTo(crisp(chartLeft), crisp(cy));
2471
- ctx.lineTo(crisp(chartRight), crisp(cy));
2472
- ctx.stroke();
2477
+ ctx.arc(cx, cy, Math.max(1, crosshair.dotRadius), 0, Math.PI * 2);
2478
+ ctx.fill();
2479
+ ctx.restore();
2480
+ } else {
2481
+ ctx.save();
2482
+ ctx.strokeStyle = crosshair.color;
2483
+ ctx.lineWidth = Math.max(1, crosshair.width);
2484
+ applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
2485
+ if (crosshair.showVertical) {
2486
+ ctx.beginPath();
2487
+ ctx.moveTo(crisp(cx), crisp(chartTop));
2488
+ ctx.lineTo(crisp(cx), crisp(chartBottom));
2489
+ ctx.stroke();
2490
+ }
2491
+ if (crosshair.showHorizontal) {
2492
+ ctx.beginPath();
2493
+ ctx.moveTo(crisp(chartLeft), crisp(cy));
2494
+ ctx.lineTo(crisp(chartRight), crisp(cy));
2495
+ ctx.stroke();
2496
+ }
2497
+ ctx.restore();
2473
2498
  }
2474
- ctx.restore();
2475
2499
  }
2476
2500
  ctx.restore();
2477
2501
  if (activeSeparateIndicators.length > 0) {
@@ -3585,6 +3609,7 @@ function createChart(element, options = {}) {
3585
3609
  type: "fib-retracement",
3586
3610
  points: [point, point],
3587
3611
  color: defaults.color ?? "#2563eb",
3612
+ colors: defaults.colors ?? FIB_DEFAULT_PALETTE,
3588
3613
  style: defaults.style ?? "solid",
3589
3614
  width: defaults.width ?? 1
3590
3615
  });
@@ -4513,5 +4538,6 @@ function createChart(element, options = {}) {
4513
4538
  };
4514
4539
  }
4515
4540
  export {
4541
+ FIB_DEFAULT_PALETTE,
4516
4542
  createChart
4517
4543
  };
package/dist/index.cjs CHANGED
@@ -20,9 +20,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ FIB_DEFAULT_PALETTE: () => FIB_DEFAULT_PALETTE,
23
24
  createChart: () => createChart
24
25
  });
25
26
  module.exports = __toCommonJS(index_exports);
27
+ var FIB_DEFAULT_PALETTE = [
28
+ "#787b86",
29
+ "#f23645",
30
+ "#ff9800",
31
+ "#4caf50",
32
+ "#089981",
33
+ "#00bcd4",
34
+ "#2962ff",
35
+ "#9c27b0"
36
+ ];
26
37
  var DEFAULT_GRID_OPTIONS = {
27
38
  color: "#2b2f38",
28
39
  opacity: 0.38,
@@ -43,6 +54,8 @@ var DEFAULT_CROSSHAIR_OPTIONS = {
43
54
  color: "#94a3b8",
44
55
  width: 1,
45
56
  style: "dotted",
57
+ mode: "cross",
58
+ dotRadius: 3,
46
59
  showHorizontal: true,
47
60
  showVertical: true,
48
61
  showPriceLabel: true,
@@ -942,6 +955,7 @@ function createChart(element, options = {}) {
942
955
  })),
943
956
  visible: drawing.visible ?? true,
944
957
  color: drawing.color ?? "#94a3b8",
958
+ colors: Array.isArray(drawing.colors) ? drawing.colors.filter((value) => typeof value === "string") : [],
945
959
  style: drawing.style ?? "dotted",
946
960
  width: Math.max(1, Number(drawing.width) || 1),
947
961
  locked: drawing.locked ?? false,
@@ -953,6 +967,7 @@ function createChart(element, options = {}) {
953
967
  points: drawing.points.map((point) => ({ ...point })),
954
968
  visible: drawing.visible,
955
969
  color: drawing.color,
970
+ colors: [...drawing.colors],
956
971
  style: drawing.style,
957
972
  width: drawing.width,
958
973
  locked: drawing.locked,
@@ -2242,32 +2257,33 @@ function createChart(element, options = {}) {
2242
2257
  const secondY = yFromPrice(second.price);
2243
2258
  const lineLeft = chartLeft;
2244
2259
  const lineRight = chartRight;
2260
+ const palette = drawing.colors.length > 0 ? drawing.colors : null;
2261
+ const levelColorAt = (index) => palette ? palette[index % palette.length] : drawing.color;
2245
2262
  const levelLines = FIB_RATIOS.map((ratio) => {
2246
2263
  const price = first.price + (second.price - first.price) * (1 - ratio);
2247
2264
  return { ratio, price, y: yFromPrice(price) };
2248
2265
  });
2249
- const bandColor = hexToRgba(drawing.color, 0.1);
2250
2266
  for (let index = 0; index < levelLines.length - 1; index += 1) {
2251
2267
  const top = levelLines[index];
2252
2268
  const bottom = levelLines[index + 1];
2253
2269
  const bandTop = Math.min(top.y, bottom.y);
2254
2270
  const bandBottom = Math.max(top.y, bottom.y);
2255
2271
  ctx.save();
2256
- ctx.fillStyle = bandColor;
2272
+ ctx.fillStyle = hexToRgba(levelColorAt(index), 0.1);
2257
2273
  ctx.globalAlpha = draft ? 0.5 : 1;
2258
2274
  ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
2259
2275
  ctx.restore();
2260
2276
  }
2261
2277
  ctx.save();
2262
2278
  ctx.lineWidth = drawing.width;
2263
- ctx.strokeStyle = drawing.color;
2264
2279
  applyDashPattern(drawing.style, dashPatterns.dotted, dashPatterns.dashed);
2265
- for (const level of levelLines) {
2280
+ levelLines.forEach((level, index) => {
2281
+ ctx.strokeStyle = levelColorAt(index);
2266
2282
  ctx.beginPath();
2267
2283
  ctx.moveTo(crisp(lineLeft), crisp(level.y));
2268
2284
  ctx.lineTo(crisp(lineRight), crisp(level.y));
2269
2285
  ctx.stroke();
2270
- }
2286
+ });
2271
2287
  ctx.restore();
2272
2288
  ctx.save();
2273
2289
  ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
@@ -2282,7 +2298,7 @@ function createChart(element, options = {}) {
2282
2298
  drawDrawingHandle(secondX, secondY, drawing.color);
2283
2299
  const prevFont = ctx.font;
2284
2300
  ctx.font = `500 11px ${mergedOptions.fontFamily}`;
2285
- for (const level of levelLines) {
2301
+ levelLines.forEach((level, index) => {
2286
2302
  const labelText = `${level.ratio} (${formatPrice(level.price)})`;
2287
2303
  const textWidth = ctx.measureText(labelText).width;
2288
2304
  const padding = 4;
@@ -2290,11 +2306,11 @@ function createChart(element, options = {}) {
2290
2306
  const bgY = level.y - 9;
2291
2307
  ctx.fillStyle = mergedOptions.backgroundColor;
2292
2308
  fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
2293
- ctx.fillStyle = drawing.color;
2309
+ ctx.fillStyle = levelColorAt(index);
2294
2310
  ctx.textAlign = "left";
2295
2311
  ctx.textBaseline = "middle";
2296
2312
  ctx.fillText(labelText, bgX + padding, bgY + 8);
2297
- }
2313
+ });
2298
2314
  ctx.font = prevFont;
2299
2315
  }
2300
2316
  }
@@ -2479,23 +2495,32 @@ function createChart(element, options = {}) {
2479
2495
  if (crosshair.visible && crosshairPoint) {
2480
2496
  const cx = clamp(crosshairPoint.x, chartLeft, chartRight);
2481
2497
  const cy = clamp(crosshairPoint.y, chartTop, chartBottom);
2482
- ctx.save();
2483
- ctx.strokeStyle = crosshair.color;
2484
- ctx.lineWidth = Math.max(1, crosshair.width);
2485
- applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
2486
- if (crosshair.showVertical) {
2487
- ctx.beginPath();
2488
- ctx.moveTo(crisp(cx), crisp(chartTop));
2489
- ctx.lineTo(crisp(cx), crisp(chartBottom));
2490
- ctx.stroke();
2491
- }
2492
- if (crosshair.showHorizontal) {
2498
+ if (crosshair.mode === "dot") {
2499
+ ctx.save();
2500
+ ctx.fillStyle = crosshair.color;
2493
2501
  ctx.beginPath();
2494
- ctx.moveTo(crisp(chartLeft), crisp(cy));
2495
- ctx.lineTo(crisp(chartRight), crisp(cy));
2496
- ctx.stroke();
2502
+ ctx.arc(cx, cy, Math.max(1, crosshair.dotRadius), 0, Math.PI * 2);
2503
+ ctx.fill();
2504
+ ctx.restore();
2505
+ } else {
2506
+ ctx.save();
2507
+ ctx.strokeStyle = crosshair.color;
2508
+ ctx.lineWidth = Math.max(1, crosshair.width);
2509
+ applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
2510
+ if (crosshair.showVertical) {
2511
+ ctx.beginPath();
2512
+ ctx.moveTo(crisp(cx), crisp(chartTop));
2513
+ ctx.lineTo(crisp(cx), crisp(chartBottom));
2514
+ ctx.stroke();
2515
+ }
2516
+ if (crosshair.showHorizontal) {
2517
+ ctx.beginPath();
2518
+ ctx.moveTo(crisp(chartLeft), crisp(cy));
2519
+ ctx.lineTo(crisp(chartRight), crisp(cy));
2520
+ ctx.stroke();
2521
+ }
2522
+ ctx.restore();
2497
2523
  }
2498
- ctx.restore();
2499
2524
  }
2500
2525
  ctx.restore();
2501
2526
  if (activeSeparateIndicators.length > 0) {
@@ -3609,6 +3634,7 @@ function createChart(element, options = {}) {
3609
3634
  type: "fib-retracement",
3610
3635
  points: [point, point],
3611
3636
  color: defaults.color ?? "#2563eb",
3637
+ colors: defaults.colors ?? FIB_DEFAULT_PALETTE,
3612
3638
  style: defaults.style ?? "solid",
3613
3639
  width: defaults.width ?? 1
3614
3640
  });
@@ -4538,5 +4564,6 @@ function createChart(element, options = {}) {
4538
4564
  }
4539
4565
  // Annotate the CommonJS export names for ESM import in node:
4540
4566
  0 && (module.exports = {
4567
+ FIB_DEFAULT_PALETTE,
4541
4568
  createChart
4542
4569
  });
package/dist/index.d.cts CHANGED
@@ -56,11 +56,19 @@ interface DrawingObjectOptions {
56
56
  points: DrawingPoint[];
57
57
  visible?: boolean;
58
58
  color?: string;
59
+ /**
60
+ * Optional per-level colors. Currently used by `fib-retracement`: when set
61
+ * (non-empty), each level/band cycles through these colors instead of using
62
+ * the single `color`. Leave empty for a monochrome drawing.
63
+ */
64
+ colors?: string[];
59
65
  style?: "solid" | "dotted" | "dashed";
60
66
  width?: number;
61
67
  label?: string;
62
68
  locked?: boolean;
63
69
  }
70
+ /** Default multi-color palette for fib-retracement levels. */
71
+ declare const FIB_DEFAULT_PALETTE: string[];
64
72
  interface DrawingSelectEvent {
65
73
  drawing: DrawingObjectOptions;
66
74
  target: "line" | "handle";
@@ -74,7 +82,7 @@ interface DrawingHoverEvent {
74
82
  x: number;
75
83
  y: number;
76
84
  }
77
- type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "style" | "width">>;
85
+ type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width">>;
78
86
  interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
79
87
  id?: string;
80
88
  type: string;
@@ -188,6 +196,8 @@ interface CrosshairOptions {
188
196
  color?: string;
189
197
  width?: number;
190
198
  style?: "solid" | "dotted" | "dashed";
199
+ mode?: "cross" | "dot";
200
+ dotRadius?: number;
191
201
  showHorizontal?: boolean;
192
202
  showVertical?: boolean;
193
203
  showPriceLabel?: boolean;
@@ -445,4 +455,4 @@ interface ViewportState {
445
455
  }
446
456
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
447
457
 
448
- export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, 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 };
458
+ export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, 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
@@ -56,11 +56,19 @@ interface DrawingObjectOptions {
56
56
  points: DrawingPoint[];
57
57
  visible?: boolean;
58
58
  color?: string;
59
+ /**
60
+ * Optional per-level colors. Currently used by `fib-retracement`: when set
61
+ * (non-empty), each level/band cycles through these colors instead of using
62
+ * the single `color`. Leave empty for a monochrome drawing.
63
+ */
64
+ colors?: string[];
59
65
  style?: "solid" | "dotted" | "dashed";
60
66
  width?: number;
61
67
  label?: string;
62
68
  locked?: boolean;
63
69
  }
70
+ /** Default multi-color palette for fib-retracement levels. */
71
+ declare const FIB_DEFAULT_PALETTE: string[];
64
72
  interface DrawingSelectEvent {
65
73
  drawing: DrawingObjectOptions;
66
74
  target: "line" | "handle";
@@ -74,7 +82,7 @@ interface DrawingHoverEvent {
74
82
  x: number;
75
83
  y: number;
76
84
  }
77
- type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "style" | "width">>;
85
+ type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "colors" | "style" | "width">>;
78
86
  interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
79
87
  id?: string;
80
88
  type: string;
@@ -188,6 +196,8 @@ interface CrosshairOptions {
188
196
  color?: string;
189
197
  width?: number;
190
198
  style?: "solid" | "dotted" | "dashed";
199
+ mode?: "cross" | "dot";
200
+ dotRadius?: number;
191
201
  showHorizontal?: boolean;
192
202
  showVertical?: boolean;
193
203
  showPriceLabel?: boolean;
@@ -445,4 +455,4 @@ interface ViewportState {
445
455
  }
446
456
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
447
457
 
448
- export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, 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 };
458
+ export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, 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
@@ -1,4 +1,14 @@
1
1
  // src/index.ts
2
+ var FIB_DEFAULT_PALETTE = [
3
+ "#787b86",
4
+ "#f23645",
5
+ "#ff9800",
6
+ "#4caf50",
7
+ "#089981",
8
+ "#00bcd4",
9
+ "#2962ff",
10
+ "#9c27b0"
11
+ ];
2
12
  var DEFAULT_GRID_OPTIONS = {
3
13
  color: "#2b2f38",
4
14
  opacity: 0.38,
@@ -19,6 +29,8 @@ var DEFAULT_CROSSHAIR_OPTIONS = {
19
29
  color: "#94a3b8",
20
30
  width: 1,
21
31
  style: "dotted",
32
+ mode: "cross",
33
+ dotRadius: 3,
22
34
  showHorizontal: true,
23
35
  showVertical: true,
24
36
  showPriceLabel: true,
@@ -918,6 +930,7 @@ function createChart(element, options = {}) {
918
930
  })),
919
931
  visible: drawing.visible ?? true,
920
932
  color: drawing.color ?? "#94a3b8",
933
+ colors: Array.isArray(drawing.colors) ? drawing.colors.filter((value) => typeof value === "string") : [],
921
934
  style: drawing.style ?? "dotted",
922
935
  width: Math.max(1, Number(drawing.width) || 1),
923
936
  locked: drawing.locked ?? false,
@@ -929,6 +942,7 @@ function createChart(element, options = {}) {
929
942
  points: drawing.points.map((point) => ({ ...point })),
930
943
  visible: drawing.visible,
931
944
  color: drawing.color,
945
+ colors: [...drawing.colors],
932
946
  style: drawing.style,
933
947
  width: drawing.width,
934
948
  locked: drawing.locked,
@@ -2218,32 +2232,33 @@ function createChart(element, options = {}) {
2218
2232
  const secondY = yFromPrice(second.price);
2219
2233
  const lineLeft = chartLeft;
2220
2234
  const lineRight = chartRight;
2235
+ const palette = drawing.colors.length > 0 ? drawing.colors : null;
2236
+ const levelColorAt = (index) => palette ? palette[index % palette.length] : drawing.color;
2221
2237
  const levelLines = FIB_RATIOS.map((ratio) => {
2222
2238
  const price = first.price + (second.price - first.price) * (1 - ratio);
2223
2239
  return { ratio, price, y: yFromPrice(price) };
2224
2240
  });
2225
- const bandColor = hexToRgba(drawing.color, 0.1);
2226
2241
  for (let index = 0; index < levelLines.length - 1; index += 1) {
2227
2242
  const top = levelLines[index];
2228
2243
  const bottom = levelLines[index + 1];
2229
2244
  const bandTop = Math.min(top.y, bottom.y);
2230
2245
  const bandBottom = Math.max(top.y, bottom.y);
2231
2246
  ctx.save();
2232
- ctx.fillStyle = bandColor;
2247
+ ctx.fillStyle = hexToRgba(levelColorAt(index), 0.1);
2233
2248
  ctx.globalAlpha = draft ? 0.5 : 1;
2234
2249
  ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
2235
2250
  ctx.restore();
2236
2251
  }
2237
2252
  ctx.save();
2238
2253
  ctx.lineWidth = drawing.width;
2239
- ctx.strokeStyle = drawing.color;
2240
2254
  applyDashPattern(drawing.style, dashPatterns.dotted, dashPatterns.dashed);
2241
- for (const level of levelLines) {
2255
+ levelLines.forEach((level, index) => {
2256
+ ctx.strokeStyle = levelColorAt(index);
2242
2257
  ctx.beginPath();
2243
2258
  ctx.moveTo(crisp(lineLeft), crisp(level.y));
2244
2259
  ctx.lineTo(crisp(lineRight), crisp(level.y));
2245
2260
  ctx.stroke();
2246
- }
2261
+ });
2247
2262
  ctx.restore();
2248
2263
  ctx.save();
2249
2264
  ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
@@ -2258,7 +2273,7 @@ function createChart(element, options = {}) {
2258
2273
  drawDrawingHandle(secondX, secondY, drawing.color);
2259
2274
  const prevFont = ctx.font;
2260
2275
  ctx.font = `500 11px ${mergedOptions.fontFamily}`;
2261
- for (const level of levelLines) {
2276
+ levelLines.forEach((level, index) => {
2262
2277
  const labelText = `${level.ratio} (${formatPrice(level.price)})`;
2263
2278
  const textWidth = ctx.measureText(labelText).width;
2264
2279
  const padding = 4;
@@ -2266,11 +2281,11 @@ function createChart(element, options = {}) {
2266
2281
  const bgY = level.y - 9;
2267
2282
  ctx.fillStyle = mergedOptions.backgroundColor;
2268
2283
  fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
2269
- ctx.fillStyle = drawing.color;
2284
+ ctx.fillStyle = levelColorAt(index);
2270
2285
  ctx.textAlign = "left";
2271
2286
  ctx.textBaseline = "middle";
2272
2287
  ctx.fillText(labelText, bgX + padding, bgY + 8);
2273
- }
2288
+ });
2274
2289
  ctx.font = prevFont;
2275
2290
  }
2276
2291
  }
@@ -2455,23 +2470,32 @@ function createChart(element, options = {}) {
2455
2470
  if (crosshair.visible && crosshairPoint) {
2456
2471
  const cx = clamp(crosshairPoint.x, chartLeft, chartRight);
2457
2472
  const cy = clamp(crosshairPoint.y, chartTop, chartBottom);
2458
- ctx.save();
2459
- ctx.strokeStyle = crosshair.color;
2460
- ctx.lineWidth = Math.max(1, crosshair.width);
2461
- applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
2462
- if (crosshair.showVertical) {
2463
- ctx.beginPath();
2464
- ctx.moveTo(crisp(cx), crisp(chartTop));
2465
- ctx.lineTo(crisp(cx), crisp(chartBottom));
2466
- ctx.stroke();
2467
- }
2468
- if (crosshair.showHorizontal) {
2473
+ if (crosshair.mode === "dot") {
2474
+ ctx.save();
2475
+ ctx.fillStyle = crosshair.color;
2469
2476
  ctx.beginPath();
2470
- ctx.moveTo(crisp(chartLeft), crisp(cy));
2471
- ctx.lineTo(crisp(chartRight), crisp(cy));
2472
- ctx.stroke();
2477
+ ctx.arc(cx, cy, Math.max(1, crosshair.dotRadius), 0, Math.PI * 2);
2478
+ ctx.fill();
2479
+ ctx.restore();
2480
+ } else {
2481
+ ctx.save();
2482
+ ctx.strokeStyle = crosshair.color;
2483
+ ctx.lineWidth = Math.max(1, crosshair.width);
2484
+ applyDashPattern(crosshair.style, dashPatterns.dotted, dashPatterns.dashed);
2485
+ if (crosshair.showVertical) {
2486
+ ctx.beginPath();
2487
+ ctx.moveTo(crisp(cx), crisp(chartTop));
2488
+ ctx.lineTo(crisp(cx), crisp(chartBottom));
2489
+ ctx.stroke();
2490
+ }
2491
+ if (crosshair.showHorizontal) {
2492
+ ctx.beginPath();
2493
+ ctx.moveTo(crisp(chartLeft), crisp(cy));
2494
+ ctx.lineTo(crisp(chartRight), crisp(cy));
2495
+ ctx.stroke();
2496
+ }
2497
+ ctx.restore();
2473
2498
  }
2474
- ctx.restore();
2475
2499
  }
2476
2500
  ctx.restore();
2477
2501
  if (activeSeparateIndicators.length > 0) {
@@ -3585,6 +3609,7 @@ function createChart(element, options = {}) {
3585
3609
  type: "fib-retracement",
3586
3610
  points: [point, point],
3587
3611
  color: defaults.color ?? "#2563eb",
3612
+ colors: defaults.colors ?? FIB_DEFAULT_PALETTE,
3588
3613
  style: defaults.style ?? "solid",
3589
3614
  width: defaults.width ?? 1
3590
3615
  });
@@ -4513,5 +4538,6 @@ function createChart(element, options = {}) {
4513
4538
  };
4514
4539
  }
4515
4540
  export {
4541
+ FIB_DEFAULT_PALETTE,
4516
4542
  createChart
4517
4543
  };
package/docs/API.md CHANGED
@@ -94,6 +94,8 @@ Top-level options:
94
94
  - `color` (default `#94a3b8`)
95
95
  - `width` (default `1`)
96
96
  - `style` (`"solid" | "dotted" | "dashed"`, default `"dotted"`)
97
+ - `mode` (`"cross" | "dot"`, default `"cross"`; `"dot"` draws a dot at the cursor instead of crosshair lines)
98
+ - `dotRadius` (default `3`; dot radius in px when `mode` is `"dot"`)
97
99
  - `showHorizontal` (default `true`)
98
100
  - `showVertical` (default `true`)
99
101
  - `showPriceLabel` (default `true`)
@@ -422,6 +424,7 @@ Drawings are user-created chart tools, separate from indicators. They are intera
422
424
  - `points: DrawingPoint[]`
423
425
  - `visible?: boolean`
424
426
  - `color?: string`
427
+ - `colors?: string[]` (per-level colors; used by `fib-retracement`. When non-empty, each level/band cycles through these instead of `color`. New fib drawings default to `FIB_DEFAULT_PALETTE`; set `colors: []` for a monochrome fib that follows `color`.)
425
428
  - `style?: "solid" | "dotted" | "dashed"`
426
429
  - `width?: number`
427
430
  - `label?: string`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperprop-charting-library",
3
- "version": "0.1.68",
3
+ "version": "0.1.70",
4
4
  "description": "Lightweight TypeScript charting core",
5
5
  "type": "module",
6
6
  "main": "./dist/hyperprop-charting-library.cjs",