hyperprop-charting-library 0.1.155 → 0.1.157

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.
@@ -3339,7 +3339,17 @@ var DRAWING_TOOL_ICONS = {
3339
3339
  path("M9.5 11.5h9"),
3340
3340
  path("M5 14.5a9 9 0 0 0 18 0")
3341
3341
  ],
3342
- indicators: [path("M4 19.5l5.5-6.5 4.5 4.5 9.5-11")]
3342
+ indicators: [path("M4 19.5l5.5-6.5 4.5 4.5 9.5-11")],
3343
+ camera: [
3344
+ path("M10 8.5 11.6 6h4.8L18 8.5"),
3345
+ { kind: "rect", x: 4, y: 8.5, width: 20, height: 13.5 },
3346
+ { kind: "circle", cx: 14, cy: 15, r: 4.2 }
3347
+ ],
3348
+ undo: [path("M6.5 10.5H16a6 6 0 0 1 0 12h-4"), path("M10.5 6.5 6.5 10.5l4 4")],
3349
+ redo: [path("M21.5 10.5H12a6 6 0 0 0 0 12h4"), path("M17.5 6.5l4 4-4 4")],
3350
+ maximize: [path("M4.5 10V4.5H10M18 4.5h5.5V10M23.5 18v5.5H18M10 23.5H4.5V18")],
3351
+ minimize: [path("M10 4.5V10H4.5M18 4.5V10h5.5M23.5 18H18v5.5M4.5 18H10v5.5")],
3352
+ compare: [path("M4 20l5-5.5 4 3.5 6.5-7.5"), path("M21 4.5v6M18 7.5h6")]
3343
3353
  };
3344
3354
 
3345
3355
  // src/themes.ts
@@ -8470,30 +8480,42 @@ function createChart(element, options = {}) {
8470
8480
  ctx.fill();
8471
8481
  cursorX += dotRadius * 2 + 6;
8472
8482
  }
8473
- const headline = [dataLine.symbol, dataLine.interval, dataLine.exchange].filter((part) => part && part.length > 0).join(" \xB7 ");
8483
+ const headline = [
8484
+ dataLine.symbol,
8485
+ dataLine.description,
8486
+ dataLine.interval,
8487
+ dataLine.exchange,
8488
+ dataLine.chartTypeLabel
8489
+ ].filter((part) => part && part.length > 0).join(" \xB7 ");
8474
8490
  if (headline) {
8475
8491
  ctx.fillStyle = symbolColor;
8476
8492
  ctx.fillText(headline, cursorX, rowY);
8477
- cursorX += measureTextWidth(headline) + 10;
8493
+ cursorX += measureTextWidth(headline) + 12;
8478
8494
  }
8479
8495
  if (dataLine.showOhlc !== false) {
8480
- const ohlc = `O${formatPrice(bar.o)} H${formatPrice(bar.h)} L${formatPrice(bar.l)} C${formatPrice(bar.c)}`;
8481
- ctx.fillStyle = changeColor;
8482
- ctx.fillText(ohlc, cursorX, rowY);
8483
- cursorX += measureTextWidth(ohlc) + 8;
8496
+ const ohlcLabelColor = dataLine.ohlcLabelColor || textColor;
8497
+ const pairs = [
8498
+ ["O", formatPrice(bar.o)],
8499
+ ["H", formatPrice(bar.h)],
8500
+ ["L", formatPrice(bar.l)],
8501
+ ["C", formatPrice(bar.c)]
8502
+ ];
8503
+ for (const [label, value] of pairs) {
8504
+ ctx.fillStyle = ohlcLabelColor;
8505
+ ctx.fillText(label, cursorX, rowY);
8506
+ cursorX += measureTextWidth(label) + 2;
8507
+ ctx.fillStyle = changeColor;
8508
+ ctx.fillText(value, cursorX, rowY);
8509
+ cursorX += measureTextWidth(value) + 9;
8510
+ }
8511
+ cursorX += 3;
8484
8512
  }
8485
8513
  if (dataLine.showChange !== false) {
8486
8514
  const pct = bar.o !== 0 ? changeAbs / bar.o * 100 : 0;
8487
8515
  const changeText = `${changeAbs >= 0 ? "+" : ""}${formatPrice(changeAbs)} (${changeAbs >= 0 ? "+" : ""}${pct.toFixed(2)}%)`;
8488
8516
  ctx.fillStyle = changeColor;
8489
8517
  ctx.fillText(changeText, cursorX, rowY);
8490
- cursorX += measureTextWidth(changeText) + 10;
8491
- }
8492
- if (dataLine.showVolume && bar.v !== void 0) {
8493
- const volumeText = `Vol ${bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v))}`;
8494
- ctx.fillStyle = textColor;
8495
- ctx.fillText(volumeText, cursorX, rowY);
8496
- cursorX += measureTextWidth(volumeText) + 10;
8518
+ cursorX += measureTextWidth(changeText) + 12;
8497
8519
  }
8498
8520
  for (const detail of dataLine.details ?? []) {
8499
8521
  const text = detail.label ? `${detail.label} ${detail.value}` : detail.value;
@@ -8507,7 +8529,14 @@ function createChart(element, options = {}) {
8507
8529
  ctx.fillText(text, cursorX, rowY);
8508
8530
  cursorX += width2 + 12;
8509
8531
  }
8510
- dataLineBottom = rowY + fontSize + 6;
8532
+ let lastRowY = rowY;
8533
+ if (dataLine.showVolume && bar.v !== void 0) {
8534
+ const volumeText = `Vol ${bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v))}`;
8535
+ lastRowY = rowY + fontSize + 4;
8536
+ ctx.fillStyle = textColor;
8537
+ ctx.fillText(volumeText, chartLeft + legendInsetX, lastRowY);
8538
+ }
8539
+ dataLineBottom = lastRowY + fontSize + 6;
8511
8540
  ctx.font = prevFont;
8512
8541
  }
8513
8542
  }
@@ -697,15 +697,26 @@ interface DataLineOptions {
697
697
  visible?: boolean;
698
698
  /** e.g. "NQU6" — drawn first, in the emphasis color. */
699
699
  symbol?: string;
700
+ /**
701
+ * Long instrument name, e.g. "NASDAQ 100 E-mini Futures". Drawn after the
702
+ * symbol in the emphasis color, the way other charting platforms label a
703
+ * pane. Omit to keep the headline to the code alone.
704
+ */
705
+ description?: string;
700
706
  /** e.g. "1h". */
701
707
  interval?: string;
702
708
  /** e.g. "CME". */
703
709
  exchange?: string;
710
+ /**
711
+ * Chart style, e.g. "Candles" or "Renko [ATR(14), 1000]" — the last part of
712
+ * the headline, so a non-default style is never a surprise.
713
+ */
714
+ chartTypeLabel?: string;
704
715
  /** O/H/L/C values for the hovered (or latest) bar. Default true. */
705
716
  showOhlc?: boolean;
706
717
  /** Absolute and percent change of that bar, colored by direction. Default true. */
707
718
  showChange?: boolean;
708
- /** Bar volume. Default false. */
719
+ /** Bar volume. Drawn on its own row beneath the values. Default false. */
709
720
  showVolume?: boolean;
710
721
  /**
711
722
  * Extra chips after the values — session, currency, a "Closed" badge. Each
@@ -724,6 +735,12 @@ interface DataLineOptions {
724
735
  symbolColor?: string;
725
736
  /** Everything after the symbol. Defaults to the indicator legend color. */
726
737
  textColor?: string;
738
+ /**
739
+ * Color of the O/H/L/C letters. Values stay colored by direction, so dimming
740
+ * the letters is what makes the numbers readable at a glance rather than one
741
+ * run of same-colored text. Defaults to `textColor`.
742
+ */
743
+ ohlcLabelColor?: string;
727
744
  }
728
745
  interface IndicatorUpdateOptions {
729
746
  /**
@@ -1475,7 +1492,7 @@ type DrawingIconShape = {
1475
1492
  width: number;
1476
1493
  height: number;
1477
1494
  };
1478
- type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout" | "magnet" | "trash" | "pencil" | "eye-off" | "lock" | "unlock" | "clone" | "settings" | "source-code" | "go-to-realtime" | "fit-bars" | "reset" | "log-scale" | "percent-scale" | "invert-scale" | "arrow-up" | "arrow-down" | "replay" | "play" | "pause" | "skip-back" | "skip-forward" | "alert" | "anchor" | "indicators";
1495
+ type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout" | "magnet" | "trash" | "pencil" | "eye-off" | "lock" | "unlock" | "clone" | "settings" | "source-code" | "go-to-realtime" | "fit-bars" | "reset" | "log-scale" | "percent-scale" | "invert-scale" | "arrow-up" | "arrow-down" | "replay" | "play" | "pause" | "skip-back" | "skip-forward" | "alert" | "anchor" | "indicators" | "camera" | "undo" | "redo" | "maximize" | "minimize" | "compare";
1479
1496
  declare const DRAWING_ICON_VIEWBOX = 28;
1480
1497
  declare const DRAWING_ICON_STROKE_WIDTH = 1.6;
1481
1498
  declare const DRAWING_TOOL_ICONS: Record<DrawingIconName, DrawingIconShape[]>;
@@ -3300,7 +3300,17 @@ var DRAWING_TOOL_ICONS = {
3300
3300
  path("M9.5 11.5h9"),
3301
3301
  path("M5 14.5a9 9 0 0 0 18 0")
3302
3302
  ],
3303
- indicators: [path("M4 19.5l5.5-6.5 4.5 4.5 9.5-11")]
3303
+ indicators: [path("M4 19.5l5.5-6.5 4.5 4.5 9.5-11")],
3304
+ camera: [
3305
+ path("M10 8.5 11.6 6h4.8L18 8.5"),
3306
+ { kind: "rect", x: 4, y: 8.5, width: 20, height: 13.5 },
3307
+ { kind: "circle", cx: 14, cy: 15, r: 4.2 }
3308
+ ],
3309
+ undo: [path("M6.5 10.5H16a6 6 0 0 1 0 12h-4"), path("M10.5 6.5 6.5 10.5l4 4")],
3310
+ redo: [path("M21.5 10.5H12a6 6 0 0 0 0 12h4"), path("M17.5 6.5l4 4-4 4")],
3311
+ maximize: [path("M4.5 10V4.5H10M18 4.5h5.5V10M23.5 18v5.5H18M10 23.5H4.5V18")],
3312
+ minimize: [path("M10 4.5V10H4.5M18 4.5V10h5.5M23.5 18H18v5.5M4.5 18H10v5.5")],
3313
+ compare: [path("M4 20l5-5.5 4 3.5 6.5-7.5"), path("M21 4.5v6M18 7.5h6")]
3304
3314
  };
3305
3315
 
3306
3316
  // src/themes.ts
@@ -8431,30 +8441,42 @@ function createChart(element, options = {}) {
8431
8441
  ctx.fill();
8432
8442
  cursorX += dotRadius * 2 + 6;
8433
8443
  }
8434
- const headline = [dataLine.symbol, dataLine.interval, dataLine.exchange].filter((part) => part && part.length > 0).join(" \xB7 ");
8444
+ const headline = [
8445
+ dataLine.symbol,
8446
+ dataLine.description,
8447
+ dataLine.interval,
8448
+ dataLine.exchange,
8449
+ dataLine.chartTypeLabel
8450
+ ].filter((part) => part && part.length > 0).join(" \xB7 ");
8435
8451
  if (headline) {
8436
8452
  ctx.fillStyle = symbolColor;
8437
8453
  ctx.fillText(headline, cursorX, rowY);
8438
- cursorX += measureTextWidth(headline) + 10;
8454
+ cursorX += measureTextWidth(headline) + 12;
8439
8455
  }
8440
8456
  if (dataLine.showOhlc !== false) {
8441
- const ohlc = `O${formatPrice(bar.o)} H${formatPrice(bar.h)} L${formatPrice(bar.l)} C${formatPrice(bar.c)}`;
8442
- ctx.fillStyle = changeColor;
8443
- ctx.fillText(ohlc, cursorX, rowY);
8444
- cursorX += measureTextWidth(ohlc) + 8;
8457
+ const ohlcLabelColor = dataLine.ohlcLabelColor || textColor;
8458
+ const pairs = [
8459
+ ["O", formatPrice(bar.o)],
8460
+ ["H", formatPrice(bar.h)],
8461
+ ["L", formatPrice(bar.l)],
8462
+ ["C", formatPrice(bar.c)]
8463
+ ];
8464
+ for (const [label, value] of pairs) {
8465
+ ctx.fillStyle = ohlcLabelColor;
8466
+ ctx.fillText(label, cursorX, rowY);
8467
+ cursorX += measureTextWidth(label) + 2;
8468
+ ctx.fillStyle = changeColor;
8469
+ ctx.fillText(value, cursorX, rowY);
8470
+ cursorX += measureTextWidth(value) + 9;
8471
+ }
8472
+ cursorX += 3;
8445
8473
  }
8446
8474
  if (dataLine.showChange !== false) {
8447
8475
  const pct = bar.o !== 0 ? changeAbs / bar.o * 100 : 0;
8448
8476
  const changeText = `${changeAbs >= 0 ? "+" : ""}${formatPrice(changeAbs)} (${changeAbs >= 0 ? "+" : ""}${pct.toFixed(2)}%)`;
8449
8477
  ctx.fillStyle = changeColor;
8450
8478
  ctx.fillText(changeText, cursorX, rowY);
8451
- cursorX += measureTextWidth(changeText) + 10;
8452
- }
8453
- if (dataLine.showVolume && bar.v !== void 0) {
8454
- const volumeText = `Vol ${bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v))}`;
8455
- ctx.fillStyle = textColor;
8456
- ctx.fillText(volumeText, cursorX, rowY);
8457
- cursorX += measureTextWidth(volumeText) + 10;
8479
+ cursorX += measureTextWidth(changeText) + 12;
8458
8480
  }
8459
8481
  for (const detail of dataLine.details ?? []) {
8460
8482
  const text = detail.label ? `${detail.label} ${detail.value}` : detail.value;
@@ -8468,7 +8490,14 @@ function createChart(element, options = {}) {
8468
8490
  ctx.fillText(text, cursorX, rowY);
8469
8491
  cursorX += width2 + 12;
8470
8492
  }
8471
- dataLineBottom = rowY + fontSize + 6;
8493
+ let lastRowY = rowY;
8494
+ if (dataLine.showVolume && bar.v !== void 0) {
8495
+ const volumeText = `Vol ${bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v))}`;
8496
+ lastRowY = rowY + fontSize + 4;
8497
+ ctx.fillStyle = textColor;
8498
+ ctx.fillText(volumeText, chartLeft + legendInsetX, lastRowY);
8499
+ }
8500
+ dataLineBottom = lastRowY + fontSize + 6;
8472
8501
  ctx.font = prevFont;
8473
8502
  }
8474
8503
  }
package/dist/index.cjs CHANGED
@@ -3339,7 +3339,17 @@ var DRAWING_TOOL_ICONS = {
3339
3339
  path("M9.5 11.5h9"),
3340
3340
  path("M5 14.5a9 9 0 0 0 18 0")
3341
3341
  ],
3342
- indicators: [path("M4 19.5l5.5-6.5 4.5 4.5 9.5-11")]
3342
+ indicators: [path("M4 19.5l5.5-6.5 4.5 4.5 9.5-11")],
3343
+ camera: [
3344
+ path("M10 8.5 11.6 6h4.8L18 8.5"),
3345
+ { kind: "rect", x: 4, y: 8.5, width: 20, height: 13.5 },
3346
+ { kind: "circle", cx: 14, cy: 15, r: 4.2 }
3347
+ ],
3348
+ undo: [path("M6.5 10.5H16a6 6 0 0 1 0 12h-4"), path("M10.5 6.5 6.5 10.5l4 4")],
3349
+ redo: [path("M21.5 10.5H12a6 6 0 0 0 0 12h4"), path("M17.5 6.5l4 4-4 4")],
3350
+ maximize: [path("M4.5 10V4.5H10M18 4.5h5.5V10M23.5 18v5.5H18M10 23.5H4.5V18")],
3351
+ minimize: [path("M10 4.5V10H4.5M18 4.5V10h5.5M23.5 18H18v5.5M4.5 18H10v5.5")],
3352
+ compare: [path("M4 20l5-5.5 4 3.5 6.5-7.5"), path("M21 4.5v6M18 7.5h6")]
3343
3353
  };
3344
3354
 
3345
3355
  // src/themes.ts
@@ -8470,30 +8480,42 @@ function createChart(element, options = {}) {
8470
8480
  ctx.fill();
8471
8481
  cursorX += dotRadius * 2 + 6;
8472
8482
  }
8473
- const headline = [dataLine.symbol, dataLine.interval, dataLine.exchange].filter((part) => part && part.length > 0).join(" \xB7 ");
8483
+ const headline = [
8484
+ dataLine.symbol,
8485
+ dataLine.description,
8486
+ dataLine.interval,
8487
+ dataLine.exchange,
8488
+ dataLine.chartTypeLabel
8489
+ ].filter((part) => part && part.length > 0).join(" \xB7 ");
8474
8490
  if (headline) {
8475
8491
  ctx.fillStyle = symbolColor;
8476
8492
  ctx.fillText(headline, cursorX, rowY);
8477
- cursorX += measureTextWidth(headline) + 10;
8493
+ cursorX += measureTextWidth(headline) + 12;
8478
8494
  }
8479
8495
  if (dataLine.showOhlc !== false) {
8480
- const ohlc = `O${formatPrice(bar.o)} H${formatPrice(bar.h)} L${formatPrice(bar.l)} C${formatPrice(bar.c)}`;
8481
- ctx.fillStyle = changeColor;
8482
- ctx.fillText(ohlc, cursorX, rowY);
8483
- cursorX += measureTextWidth(ohlc) + 8;
8496
+ const ohlcLabelColor = dataLine.ohlcLabelColor || textColor;
8497
+ const pairs = [
8498
+ ["O", formatPrice(bar.o)],
8499
+ ["H", formatPrice(bar.h)],
8500
+ ["L", formatPrice(bar.l)],
8501
+ ["C", formatPrice(bar.c)]
8502
+ ];
8503
+ for (const [label, value] of pairs) {
8504
+ ctx.fillStyle = ohlcLabelColor;
8505
+ ctx.fillText(label, cursorX, rowY);
8506
+ cursorX += measureTextWidth(label) + 2;
8507
+ ctx.fillStyle = changeColor;
8508
+ ctx.fillText(value, cursorX, rowY);
8509
+ cursorX += measureTextWidth(value) + 9;
8510
+ }
8511
+ cursorX += 3;
8484
8512
  }
8485
8513
  if (dataLine.showChange !== false) {
8486
8514
  const pct = bar.o !== 0 ? changeAbs / bar.o * 100 : 0;
8487
8515
  const changeText = `${changeAbs >= 0 ? "+" : ""}${formatPrice(changeAbs)} (${changeAbs >= 0 ? "+" : ""}${pct.toFixed(2)}%)`;
8488
8516
  ctx.fillStyle = changeColor;
8489
8517
  ctx.fillText(changeText, cursorX, rowY);
8490
- cursorX += measureTextWidth(changeText) + 10;
8491
- }
8492
- if (dataLine.showVolume && bar.v !== void 0) {
8493
- const volumeText = `Vol ${bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v))}`;
8494
- ctx.fillStyle = textColor;
8495
- ctx.fillText(volumeText, cursorX, rowY);
8496
- cursorX += measureTextWidth(volumeText) + 10;
8518
+ cursorX += measureTextWidth(changeText) + 12;
8497
8519
  }
8498
8520
  for (const detail of dataLine.details ?? []) {
8499
8521
  const text = detail.label ? `${detail.label} ${detail.value}` : detail.value;
@@ -8507,7 +8529,14 @@ function createChart(element, options = {}) {
8507
8529
  ctx.fillText(text, cursorX, rowY);
8508
8530
  cursorX += width2 + 12;
8509
8531
  }
8510
- dataLineBottom = rowY + fontSize + 6;
8532
+ let lastRowY = rowY;
8533
+ if (dataLine.showVolume && bar.v !== void 0) {
8534
+ const volumeText = `Vol ${bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v))}`;
8535
+ lastRowY = rowY + fontSize + 4;
8536
+ ctx.fillStyle = textColor;
8537
+ ctx.fillText(volumeText, chartLeft + legendInsetX, lastRowY);
8538
+ }
8539
+ dataLineBottom = lastRowY + fontSize + 6;
8511
8540
  ctx.font = prevFont;
8512
8541
  }
8513
8542
  }
package/dist/index.d.cts CHANGED
@@ -697,15 +697,26 @@ interface DataLineOptions {
697
697
  visible?: boolean;
698
698
  /** e.g. "NQU6" — drawn first, in the emphasis color. */
699
699
  symbol?: string;
700
+ /**
701
+ * Long instrument name, e.g. "NASDAQ 100 E-mini Futures". Drawn after the
702
+ * symbol in the emphasis color, the way other charting platforms label a
703
+ * pane. Omit to keep the headline to the code alone.
704
+ */
705
+ description?: string;
700
706
  /** e.g. "1h". */
701
707
  interval?: string;
702
708
  /** e.g. "CME". */
703
709
  exchange?: string;
710
+ /**
711
+ * Chart style, e.g. "Candles" or "Renko [ATR(14), 1000]" — the last part of
712
+ * the headline, so a non-default style is never a surprise.
713
+ */
714
+ chartTypeLabel?: string;
704
715
  /** O/H/L/C values for the hovered (or latest) bar. Default true. */
705
716
  showOhlc?: boolean;
706
717
  /** Absolute and percent change of that bar, colored by direction. Default true. */
707
718
  showChange?: boolean;
708
- /** Bar volume. Default false. */
719
+ /** Bar volume. Drawn on its own row beneath the values. Default false. */
709
720
  showVolume?: boolean;
710
721
  /**
711
722
  * Extra chips after the values — session, currency, a "Closed" badge. Each
@@ -724,6 +735,12 @@ interface DataLineOptions {
724
735
  symbolColor?: string;
725
736
  /** Everything after the symbol. Defaults to the indicator legend color. */
726
737
  textColor?: string;
738
+ /**
739
+ * Color of the O/H/L/C letters. Values stay colored by direction, so dimming
740
+ * the letters is what makes the numbers readable at a glance rather than one
741
+ * run of same-colored text. Defaults to `textColor`.
742
+ */
743
+ ohlcLabelColor?: string;
727
744
  }
728
745
  interface IndicatorUpdateOptions {
729
746
  /**
@@ -1475,7 +1492,7 @@ type DrawingIconShape = {
1475
1492
  width: number;
1476
1493
  height: number;
1477
1494
  };
1478
- type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout" | "magnet" | "trash" | "pencil" | "eye-off" | "lock" | "unlock" | "clone" | "settings" | "source-code" | "go-to-realtime" | "fit-bars" | "reset" | "log-scale" | "percent-scale" | "invert-scale" | "arrow-up" | "arrow-down" | "replay" | "play" | "pause" | "skip-back" | "skip-forward" | "alert" | "anchor" | "indicators";
1495
+ type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout" | "magnet" | "trash" | "pencil" | "eye-off" | "lock" | "unlock" | "clone" | "settings" | "source-code" | "go-to-realtime" | "fit-bars" | "reset" | "log-scale" | "percent-scale" | "invert-scale" | "arrow-up" | "arrow-down" | "replay" | "play" | "pause" | "skip-back" | "skip-forward" | "alert" | "anchor" | "indicators" | "camera" | "undo" | "redo" | "maximize" | "minimize" | "compare";
1479
1496
  declare const DRAWING_ICON_VIEWBOX = 28;
1480
1497
  declare const DRAWING_ICON_STROKE_WIDTH = 1.6;
1481
1498
  declare const DRAWING_TOOL_ICONS: Record<DrawingIconName, DrawingIconShape[]>;
package/dist/index.d.ts CHANGED
@@ -697,15 +697,26 @@ interface DataLineOptions {
697
697
  visible?: boolean;
698
698
  /** e.g. "NQU6" — drawn first, in the emphasis color. */
699
699
  symbol?: string;
700
+ /**
701
+ * Long instrument name, e.g. "NASDAQ 100 E-mini Futures". Drawn after the
702
+ * symbol in the emphasis color, the way other charting platforms label a
703
+ * pane. Omit to keep the headline to the code alone.
704
+ */
705
+ description?: string;
700
706
  /** e.g. "1h". */
701
707
  interval?: string;
702
708
  /** e.g. "CME". */
703
709
  exchange?: string;
710
+ /**
711
+ * Chart style, e.g. "Candles" or "Renko [ATR(14), 1000]" — the last part of
712
+ * the headline, so a non-default style is never a surprise.
713
+ */
714
+ chartTypeLabel?: string;
704
715
  /** O/H/L/C values for the hovered (or latest) bar. Default true. */
705
716
  showOhlc?: boolean;
706
717
  /** Absolute and percent change of that bar, colored by direction. Default true. */
707
718
  showChange?: boolean;
708
- /** Bar volume. Default false. */
719
+ /** Bar volume. Drawn on its own row beneath the values. Default false. */
709
720
  showVolume?: boolean;
710
721
  /**
711
722
  * Extra chips after the values — session, currency, a "Closed" badge. Each
@@ -724,6 +735,12 @@ interface DataLineOptions {
724
735
  symbolColor?: string;
725
736
  /** Everything after the symbol. Defaults to the indicator legend color. */
726
737
  textColor?: string;
738
+ /**
739
+ * Color of the O/H/L/C letters. Values stay colored by direction, so dimming
740
+ * the letters is what makes the numbers readable at a glance rather than one
741
+ * run of same-colored text. Defaults to `textColor`.
742
+ */
743
+ ohlcLabelColor?: string;
727
744
  }
728
745
  interface IndicatorUpdateOptions {
729
746
  /**
@@ -1475,7 +1492,7 @@ type DrawingIconShape = {
1475
1492
  width: number;
1476
1493
  height: number;
1477
1494
  };
1478
- type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout" | "magnet" | "trash" | "pencil" | "eye-off" | "lock" | "unlock" | "clone" | "settings" | "source-code" | "go-to-realtime" | "fit-bars" | "reset" | "log-scale" | "percent-scale" | "invert-scale" | "arrow-up" | "arrow-down" | "replay" | "play" | "pause" | "skip-back" | "skip-forward" | "alert" | "anchor" | "indicators";
1495
+ type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout" | "magnet" | "trash" | "pencil" | "eye-off" | "lock" | "unlock" | "clone" | "settings" | "source-code" | "go-to-realtime" | "fit-bars" | "reset" | "log-scale" | "percent-scale" | "invert-scale" | "arrow-up" | "arrow-down" | "replay" | "play" | "pause" | "skip-back" | "skip-forward" | "alert" | "anchor" | "indicators" | "camera" | "undo" | "redo" | "maximize" | "minimize" | "compare";
1479
1496
  declare const DRAWING_ICON_VIEWBOX = 28;
1480
1497
  declare const DRAWING_ICON_STROKE_WIDTH = 1.6;
1481
1498
  declare const DRAWING_TOOL_ICONS: Record<DrawingIconName, DrawingIconShape[]>;
package/dist/index.js CHANGED
@@ -3300,7 +3300,17 @@ var DRAWING_TOOL_ICONS = {
3300
3300
  path("M9.5 11.5h9"),
3301
3301
  path("M5 14.5a9 9 0 0 0 18 0")
3302
3302
  ],
3303
- indicators: [path("M4 19.5l5.5-6.5 4.5 4.5 9.5-11")]
3303
+ indicators: [path("M4 19.5l5.5-6.5 4.5 4.5 9.5-11")],
3304
+ camera: [
3305
+ path("M10 8.5 11.6 6h4.8L18 8.5"),
3306
+ { kind: "rect", x: 4, y: 8.5, width: 20, height: 13.5 },
3307
+ { kind: "circle", cx: 14, cy: 15, r: 4.2 }
3308
+ ],
3309
+ undo: [path("M6.5 10.5H16a6 6 0 0 1 0 12h-4"), path("M10.5 6.5 6.5 10.5l4 4")],
3310
+ redo: [path("M21.5 10.5H12a6 6 0 0 0 0 12h4"), path("M17.5 6.5l4 4-4 4")],
3311
+ maximize: [path("M4.5 10V4.5H10M18 4.5h5.5V10M23.5 18v5.5H18M10 23.5H4.5V18")],
3312
+ minimize: [path("M10 4.5V10H4.5M18 4.5V10h5.5M23.5 18H18v5.5M4.5 18H10v5.5")],
3313
+ compare: [path("M4 20l5-5.5 4 3.5 6.5-7.5"), path("M21 4.5v6M18 7.5h6")]
3304
3314
  };
3305
3315
 
3306
3316
  // src/themes.ts
@@ -8431,30 +8441,42 @@ function createChart(element, options = {}) {
8431
8441
  ctx.fill();
8432
8442
  cursorX += dotRadius * 2 + 6;
8433
8443
  }
8434
- const headline = [dataLine.symbol, dataLine.interval, dataLine.exchange].filter((part) => part && part.length > 0).join(" \xB7 ");
8444
+ const headline = [
8445
+ dataLine.symbol,
8446
+ dataLine.description,
8447
+ dataLine.interval,
8448
+ dataLine.exchange,
8449
+ dataLine.chartTypeLabel
8450
+ ].filter((part) => part && part.length > 0).join(" \xB7 ");
8435
8451
  if (headline) {
8436
8452
  ctx.fillStyle = symbolColor;
8437
8453
  ctx.fillText(headline, cursorX, rowY);
8438
- cursorX += measureTextWidth(headline) + 10;
8454
+ cursorX += measureTextWidth(headline) + 12;
8439
8455
  }
8440
8456
  if (dataLine.showOhlc !== false) {
8441
- const ohlc = `O${formatPrice(bar.o)} H${formatPrice(bar.h)} L${formatPrice(bar.l)} C${formatPrice(bar.c)}`;
8442
- ctx.fillStyle = changeColor;
8443
- ctx.fillText(ohlc, cursorX, rowY);
8444
- cursorX += measureTextWidth(ohlc) + 8;
8457
+ const ohlcLabelColor = dataLine.ohlcLabelColor || textColor;
8458
+ const pairs = [
8459
+ ["O", formatPrice(bar.o)],
8460
+ ["H", formatPrice(bar.h)],
8461
+ ["L", formatPrice(bar.l)],
8462
+ ["C", formatPrice(bar.c)]
8463
+ ];
8464
+ for (const [label, value] of pairs) {
8465
+ ctx.fillStyle = ohlcLabelColor;
8466
+ ctx.fillText(label, cursorX, rowY);
8467
+ cursorX += measureTextWidth(label) + 2;
8468
+ ctx.fillStyle = changeColor;
8469
+ ctx.fillText(value, cursorX, rowY);
8470
+ cursorX += measureTextWidth(value) + 9;
8471
+ }
8472
+ cursorX += 3;
8445
8473
  }
8446
8474
  if (dataLine.showChange !== false) {
8447
8475
  const pct = bar.o !== 0 ? changeAbs / bar.o * 100 : 0;
8448
8476
  const changeText = `${changeAbs >= 0 ? "+" : ""}${formatPrice(changeAbs)} (${changeAbs >= 0 ? "+" : ""}${pct.toFixed(2)}%)`;
8449
8477
  ctx.fillStyle = changeColor;
8450
8478
  ctx.fillText(changeText, cursorX, rowY);
8451
- cursorX += measureTextWidth(changeText) + 10;
8452
- }
8453
- if (dataLine.showVolume && bar.v !== void 0) {
8454
- const volumeText = `Vol ${bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v))}`;
8455
- ctx.fillStyle = textColor;
8456
- ctx.fillText(volumeText, cursorX, rowY);
8457
- cursorX += measureTextWidth(volumeText) + 10;
8479
+ cursorX += measureTextWidth(changeText) + 12;
8458
8480
  }
8459
8481
  for (const detail of dataLine.details ?? []) {
8460
8482
  const text = detail.label ? `${detail.label} ${detail.value}` : detail.value;
@@ -8468,7 +8490,14 @@ function createChart(element, options = {}) {
8468
8490
  ctx.fillText(text, cursorX, rowY);
8469
8491
  cursorX += width2 + 12;
8470
8492
  }
8471
- dataLineBottom = rowY + fontSize + 6;
8493
+ let lastRowY = rowY;
8494
+ if (dataLine.showVolume && bar.v !== void 0) {
8495
+ const volumeText = `Vol ${bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v))}`;
8496
+ lastRowY = rowY + fontSize + 4;
8497
+ ctx.fillStyle = textColor;
8498
+ ctx.fillText(volumeText, chartLeft + legendInsetX, lastRowY);
8499
+ }
8500
+ dataLineBottom = lastRowY + fontSize + 6;
8472
8501
  ctx.font = prevFont;
8473
8502
  }
8474
8503
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperprop-charting-library",
3
- "version": "0.1.155",
3
+ "version": "0.1.157",
4
4
  "description": "Lightweight TypeScript charting core",
5
5
  "type": "module",
6
6
  "main": "./dist/hyperprop-charting-library.cjs",