hyperprop-charting-library 0.1.49 → 0.1.51

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.
@@ -98,6 +98,10 @@ var DEFAULT_LABELS_OPTIONS = {
98
98
  askPrice: Number.NaN,
99
99
  showIndicatorNames: false,
100
100
  showIndicatorValues: false,
101
+ showIndicatorValueLabels: true,
102
+ indicatorLegendPosition: "top-left",
103
+ indicatorLegendOffsetX: 10,
104
+ indicatorLegendOffsetY: 10,
101
105
  showCountdownToBarClose: false,
102
106
  noOverlapping: true,
103
107
  backgroundColor: "#0b1220",
@@ -531,7 +535,7 @@ var drawOverlaySeries = (ctx, renderContext, values, color, width) => {
531
535
  }
532
536
  ctx.restore();
533
537
  };
534
- var drawSeparateSeries = (ctx, renderContext, values, color, width, minOverride, maxOverride, guideLines) => {
538
+ var drawSeparateSeries = (ctx, renderContext, values, color, width, minOverride, maxOverride, guideLines, options = {}) => {
535
539
  const visible = [];
536
540
  for (let index = renderContext.startIndex; index <= renderContext.endIndex; index += 1) {
537
541
  const value = values[index];
@@ -539,7 +543,7 @@ var drawSeparateSeries = (ctx, renderContext, values, color, width, minOverride,
539
543
  visible.push(value);
540
544
  }
541
545
  }
542
- if (visible.length === 0) return;
546
+ if (visible.length === 0) return void 0;
543
547
  const minValue = minOverride ?? Math.min(...visible);
544
548
  const maxValue = maxOverride ?? Math.max(...visible);
545
549
  const range = maxValue - minValue || 1;
@@ -588,6 +592,51 @@ var drawSeparateSeries = (ctx, renderContext, values, color, width, minOverride,
588
592
  }
589
593
  }
590
594
  ctx.restore();
595
+ let latestValue = null;
596
+ for (let index = values.length - 1; index >= 0; index -= 1) {
597
+ const value = values[index];
598
+ if (Number.isFinite(value ?? Number.NaN)) {
599
+ latestValue = value;
600
+ break;
601
+ }
602
+ }
603
+ const decimals = options.decimals ?? 2;
604
+ const formatValue = (value) => value.toFixed(decimals);
605
+ const axisTicks = options.axisTicks ?? guideLines;
606
+ const paneInfo = {
607
+ ...options.title ? { title: options.title } : {},
608
+ axis: {
609
+ min: minValue,
610
+ max: maxValue,
611
+ ...axisTicks ? { ticks: axisTicks } : {},
612
+ decimals
613
+ }
614
+ };
615
+ if (guideLines) {
616
+ paneInfo.guideLines = guideLines.map((value) => ({ value, label: formatValue(value), style: "dotted" }));
617
+ }
618
+ if (latestValue !== null) {
619
+ paneInfo.legendValues = [
620
+ {
621
+ ...options.legendLabel ? { label: options.legendLabel } : {},
622
+ value: latestValue,
623
+ text: formatValue(latestValue),
624
+ color
625
+ }
626
+ ];
627
+ }
628
+ if (options.valueLabel !== false && latestValue !== null) {
629
+ paneInfo.valueLabels = [
630
+ {
631
+ value: latestValue,
632
+ text: formatValue(latestValue),
633
+ color: options.valueLabelColor ?? color,
634
+ backgroundColor: options.valueLabelBackgroundColor ?? options.valueLabelColor ?? color,
635
+ textColor: options.valueLabelTextColor ?? "#0f172a"
636
+ }
637
+ ];
638
+ }
639
+ return paneInfo;
591
640
  };
592
641
  var getPercentileValue = (values, percentile) => {
593
642
  if (values.length === 0) {
@@ -760,7 +809,10 @@ var BUILTIN_STDDEV_INDICATOR = {
760
809
  renderContext.data,
761
810
  () => computeStdDevSeries(renderContext.data, length, inputs.source ?? "close")
762
811
  );
763
- drawSeparateSeries(ctx, renderContext, values, inputs.color ?? "#f97316", Number(inputs.width) || 2);
812
+ return drawSeparateSeries(ctx, renderContext, values, inputs.color ?? "#f97316", Number(inputs.width) || 2, void 0, void 0, void 0, {
813
+ title: `StdDev ${length}`,
814
+ decimals: 2
815
+ });
764
816
  }
765
817
  };
766
818
  var BUILTIN_ATR_INDICATOR = {
@@ -772,7 +824,10 @@ var BUILTIN_ATR_INDICATOR = {
772
824
  draw: (ctx, renderContext, inputs) => {
773
825
  const length = clampIndicatorLength(inputs.length, 14);
774
826
  const values = withCachedSeries(`atr|${length}`, renderContext.data, () => computeAtrSeries(renderContext.data, length));
775
- drawSeparateSeries(ctx, renderContext, values, inputs.color ?? "#eab308", Number(inputs.width) || 2);
827
+ return drawSeparateSeries(ctx, renderContext, values, inputs.color ?? "#eab308", Number(inputs.width) || 2, void 0, void 0, void 0, {
828
+ title: `ATR ${length}`,
829
+ decimals: 2
830
+ });
776
831
  }
777
832
  };
778
833
  var BUILTIN_RSI_INDICATOR = {
@@ -784,7 +839,7 @@ var BUILTIN_RSI_INDICATOR = {
784
839
  draw: (ctx, renderContext, inputs) => {
785
840
  const length = clampIndicatorLength(inputs.length, 14);
786
841
  const values = withCachedSeries(`rsi|${length}`, renderContext.data, () => computeRsiSeries(renderContext.data, length));
787
- drawSeparateSeries(
842
+ return drawSeparateSeries(
788
843
  ctx,
789
844
  renderContext,
790
845
  values,
@@ -792,7 +847,15 @@ var BUILTIN_RSI_INDICATOR = {
792
847
  Number(inputs.width) || 2,
793
848
  0,
794
849
  100,
795
- [30, 50, 70]
850
+ [30, 50, 70],
851
+ {
852
+ title: `RSI ${length}`,
853
+ axisTicks: [0, 30, 50, 70, 100],
854
+ decimals: 2,
855
+ valueLabelColor: "#9E9E9E",
856
+ valueLabelBackgroundColor: "#9E9E9E",
857
+ valueLabelTextColor: "#0f172a"
858
+ }
796
859
  );
797
860
  }
798
861
  };
@@ -1356,6 +1419,11 @@ function createChart(element, options = {}) {
1356
1419
  const pad = (value) => String(value).padStart(2, "0");
1357
1420
  return hours > 0 ? `${hours}:${pad(minutes)}:${pad(seconds)}` : `${pad(minutes)}:${pad(seconds)}`;
1358
1421
  };
1422
+ const getRightAxisLabelX = (chartRight) => chartRight + 1;
1423
+ const getRightAxisLabelWidth = (chartRight, contentWidth) => {
1424
+ const scaleWidth = Math.max(0, Math.floor(width - getRightAxisLabelX(chartRight)));
1425
+ return Math.max(contentWidth, scaleWidth);
1426
+ };
1359
1427
  const drawPriceLine = (line, yFromPrice, chartLeft, chartTop, chartRight, chartBottom) => {
1360
1428
  const mergedLine = { ...DEFAULT_PRICE_LINE_OPTIONS, ...line };
1361
1429
  if (!mergedLine.visible || !Number.isFinite(mergedLine.price)) {
@@ -1380,8 +1448,9 @@ function createChart(element, options = {}) {
1380
1448
  ctx.font = `${Math.max(8, axis.fontSize)}px ${mergedOptions.fontFamily}`;
1381
1449
  const labelPaddingX = 8;
1382
1450
  const labelHeight = 20;
1383
- const labelWidth = mergedLine.label === void 0 ? getPriceLabelWidth(labelText, labelPaddingX) : Math.ceil(ctx.measureText(labelText).width) + labelPaddingX * 2;
1384
- const labelX = chartRight + 4;
1451
+ const measuredLabelWidth = mergedLine.label === void 0 ? getPriceLabelWidth(labelText, labelPaddingX) : Math.ceil(ctx.measureText(labelText).width) + labelPaddingX * 2;
1452
+ const labelWidth = getRightAxisLabelWidth(chartRight, measuredLabelWidth);
1453
+ const labelX = getRightAxisLabelX(chartRight);
1385
1454
  const labelY = placeRightAxisLabel(lineY - labelHeight / 2, labelHeight, chartTop, chartBottom - labelHeight);
1386
1455
  ctx.fillStyle = mergedLine.labelBackgroundColor;
1387
1456
  fillRoundedRect(
@@ -1619,11 +1688,11 @@ function createChart(element, options = {}) {
1619
1688
  const priceText = formatPrice(renderPrice);
1620
1689
  const pricePaddingX = 8;
1621
1690
  const measuredPriceWidth = getPriceLabelWidth(priceText, pricePaddingX);
1622
- const priceWidth = mergedLine.id === void 0 ? measuredPriceWidth : Math.max(measuredPriceWidth, orderPriceTagWidthById.get(mergedLine.id) ?? 0);
1691
+ const priceWidth = mergedLine.id === void 0 ? getRightAxisLabelWidth(chartRight, measuredPriceWidth) : getRightAxisLabelWidth(chartRight, Math.max(measuredPriceWidth, orderPriceTagWidthById.get(mergedLine.id) ?? 0));
1623
1692
  if (mergedLine.id) {
1624
1693
  orderPriceTagWidthById.set(mergedLine.id, priceWidth);
1625
1694
  }
1626
- const priceX = chartRight + 4;
1695
+ const priceX = getRightAxisLabelX(chartRight);
1627
1696
  const priceY = placeRightAxisLabel(targetLabelY, labelHeight, chartTop, chartBottom - labelHeight);
1628
1697
  ctx.fillStyle = mergedLine.labelBackgroundColor ?? color;
1629
1698
  fillRoundedRect(Math.round(priceX), Math.round(priceY), priceWidth, labelHeight, borderRadius);
@@ -1698,9 +1767,63 @@ function createChart(element, options = {}) {
1698
1767
  ctx.font = `${Math.max(8, axis.fontSize)}px ${mergedOptions.fontFamily}`;
1699
1768
  ctx.fillStyle = mergedOptions.backgroundColor;
1700
1769
  ctx.fillRect(0, 0, width, height);
1770
+ const labels = { ...DEFAULT_LABELS_OPTIONS, ...mergedOptions.labels ?? {} };
1771
+ const estimateRightMargin = () => {
1772
+ const paddingX = Math.max(4, labels.labelPaddingX);
1773
+ const measure = (text) => Math.ceil(ctx.measureText(text).width) + paddingX * 2;
1774
+ let required = margin.right - 1;
1775
+ const include = (text) => {
1776
+ const normalized = text?.trim();
1777
+ if (normalized) {
1778
+ required = Math.max(required, measure(normalized));
1779
+ }
1780
+ };
1781
+ const ticker2 = mergedOptions.tickerLine ?? DEFAULT_OPTIONS.tickerLine;
1782
+ const lastPoint2 = data[data.length - 1];
1783
+ if ((ticker2.visible ?? true) && labels.showLastPrice && lastPoint2) {
1784
+ include(formatPrice(lastPoint2.c));
1785
+ if (ticker2.labelSubtext) include(String(ticker2.labelSubtext));
1786
+ for (const subtext of ticker2.labelSubtexts ?? []) {
1787
+ include(String(subtext));
1788
+ }
1789
+ }
1790
+ if (labels.showSymbolName) {
1791
+ include(labels.symbolName);
1792
+ }
1793
+ if (labels.showPreviousClose) {
1794
+ const previousCloseCandidate = Number.isFinite(labels.previousClosePrice) ? labels.previousClosePrice : data.length > 1 ? data[data.length - 2]?.c : Number.NaN;
1795
+ if (previousCloseCandidate !== void 0 && Number.isFinite(previousCloseCandidate)) {
1796
+ include(`PDC ${formatPrice(previousCloseCandidate)}`);
1797
+ }
1798
+ }
1799
+ if (labels.showHighLow && data.length > 0) {
1800
+ include(`H ${formatPrice(Math.max(...data.map((point) => point.h)))}`);
1801
+ include(`L ${formatPrice(Math.min(...data.map((point) => point.l)))}`);
1802
+ }
1803
+ if (labels.showBidAsk) {
1804
+ if (Number.isFinite(labels.bidPrice)) include(`B ${formatPrice(labels.bidPrice)}`);
1805
+ if (Number.isFinite(labels.askPrice)) include(`A ${formatPrice(labels.askPrice)}`);
1806
+ }
1807
+ for (const line of priceLines) {
1808
+ const mergedLine = { ...DEFAULT_PRICE_LINE_OPTIONS, ...line };
1809
+ if (mergedLine.visible && Number.isFinite(mergedLine.price)) {
1810
+ include(mergedLine.label ?? formatPrice(mergedLine.price));
1811
+ }
1812
+ }
1813
+ for (const line of orderLines) {
1814
+ const mergedLine = { ...DEFAULT_ORDER_LINE_OPTIONS, ...line };
1815
+ const renderPrice = mergedLine.behavior === "follow" && Number.isFinite(mergedLine.followPrice) ? mergedLine.followPrice : mergedLine.price;
1816
+ if (mergedLine.visible && Number.isFinite(renderPrice)) {
1817
+ include(formatPrice(renderPrice));
1818
+ }
1819
+ }
1820
+ const maxRightMargin = Math.max(margin.right, width - margin.left - 160);
1821
+ return Math.min(maxRightMargin, Math.max(margin.right, Math.ceil(required + 1)));
1822
+ };
1823
+ const rightMargin = estimateRightMargin();
1701
1824
  const chartLeft = margin.left;
1702
1825
  const chartTop = margin.top;
1703
- const chartWidth = width - margin.left - margin.right;
1826
+ const chartWidth = width - margin.left - rightMargin;
1704
1827
  const fullChartHeight = height - margin.top - margin.bottom;
1705
1828
  const fullChartBottom = chartTop + fullChartHeight;
1706
1829
  const chartRight = chartLeft + chartWidth;
@@ -2053,7 +2176,7 @@ function createChart(element, options = {}) {
2053
2176
  ctx.beginPath();
2054
2177
  ctx.rect(chartLeft + 1, paneTop + 1, Math.max(0, chartWidth - 2), Math.max(0, paneHeight - 2));
2055
2178
  ctx.clip();
2056
- plugin.draw(
2179
+ const paneInfo = plugin.draw(
2057
2180
  ctx,
2058
2181
  {
2059
2182
  data,
@@ -2086,6 +2209,63 @@ function createChart(element, options = {}) {
2086
2209
  ctx.lineTo(crisp(chartRight), crisp(paneTop));
2087
2210
  ctx.stroke();
2088
2211
  ctx.restore();
2212
+ const axisInfo = paneInfo?.axis;
2213
+ if (axisInfo && Number.isFinite(axisInfo.min) && Number.isFinite(axisInfo.max) && axisInfo.max !== axisInfo.min) {
2214
+ const paneRange = axisInfo.max - axisInfo.min;
2215
+ const yFromPaneValue = (value) => {
2216
+ const ratio = (value - axisInfo.min) / paneRange;
2217
+ return paneBottom - ratio * paneHeight;
2218
+ };
2219
+ const formatPaneValue = (value) => {
2220
+ if (axisInfo.format) {
2221
+ return axisInfo.format(value);
2222
+ }
2223
+ const decimals = axisInfo.decimals ?? (Math.abs(paneRange) <= 2 ? 2 : Math.abs(paneRange) <= 20 ? 1 : 0);
2224
+ return value.toFixed(Math.max(0, Math.min(8, Math.round(decimals))));
2225
+ };
2226
+ const axisTicks = axisInfo.ticks && axisInfo.ticks.length > 0 ? axisInfo.ticks : [axisInfo.min, axisInfo.min + paneRange / 2, axisInfo.max];
2227
+ const uniqueTicks = Array.from(new Set(axisTicks.filter((tick) => Number.isFinite(tick))));
2228
+ ctx.save();
2229
+ ctx.font = `${yAxisFontSize}px ${mergedOptions.fontFamily}`;
2230
+ for (const tick of uniqueTicks) {
2231
+ if (tick < axisInfo.min || tick > axisInfo.max) {
2232
+ continue;
2233
+ }
2234
+ drawText(formatPaneValue(tick), chartRight + 6, yFromPaneValue(tick), "left", "middle", yAxis.textColor);
2235
+ }
2236
+ ctx.restore();
2237
+ if (labels.visible) {
2238
+ const prevFont = ctx.font;
2239
+ ctx.font = `${Math.max(8, axis.fontSize)}px ${mergedOptions.fontFamily}`;
2240
+ const legendTitle = paneInfo.title ?? plugin.name;
2241
+ const legendValues = paneInfo.legendValues ?? [];
2242
+ const legendParts = [
2243
+ legendTitle,
2244
+ ...legendValues.map((value) => value.text ?? (value.value === void 0 ? "" : formatPaneValue(value.value))).filter(Boolean)
2245
+ ].filter(Boolean);
2246
+ if (legendParts.length > 0) {
2247
+ drawText(legendParts.join(" "), chartLeft + 10, paneTop + 8, "left", "top", labels.indicatorTextColor);
2248
+ }
2249
+ for (const label of paneInfo.valueLabels ?? []) {
2250
+ if (!labels.showIndicatorValueLabels) {
2251
+ continue;
2252
+ }
2253
+ if (!Number.isFinite(label.value) || label.value < axisInfo.min || label.value > axisInfo.max) {
2254
+ continue;
2255
+ }
2256
+ const text = label.text ?? formatPaneValue(label.value);
2257
+ const labelPaddingX = 7;
2258
+ const labelHeight = Math.max(16, yAxisFontSize + 8);
2259
+ const labelWidth = getRightAxisLabelWidth(chartRight, Math.ceil(ctx.measureText(text).width) + labelPaddingX * 2);
2260
+ const labelX = getRightAxisLabelX(chartRight);
2261
+ const labelY = clamp(yFromPaneValue(label.value) - labelHeight / 2, paneTop + 2, paneBottom - labelHeight - 2);
2262
+ ctx.fillStyle = label.backgroundColor ?? label.color ?? labels.backgroundColor;
2263
+ fillRoundedRect(Math.round(labelX), Math.round(labelY), labelWidth, labelHeight, Math.max(0, labels.borderRadius));
2264
+ drawText(text, labelX + labelPaddingX, labelY + labelHeight / 2, "left", "middle", label.textColor ?? labels.textColor);
2265
+ }
2266
+ ctx.font = prevFont;
2267
+ }
2268
+ }
2089
2269
  });
2090
2270
  }
2091
2271
  if (crosshair.visible && crosshairPoint && crosshair.showVertical) {
@@ -2117,7 +2297,6 @@ function createChart(element, options = {}) {
2117
2297
  drawText(formatPrice(price), chartRight + 6, y, "left", "middle", yAxis.textColor);
2118
2298
  ctx.font = prevFont;
2119
2299
  }
2120
- const labels = { ...DEFAULT_LABELS_OPTIONS, ...mergedOptions.labels ?? {} };
2121
2300
  resetLabelSlots(labels.noOverlapping);
2122
2301
  const priceAxisLabels = [];
2123
2302
  const addPriceAxisLabel = (label) => {
@@ -2281,12 +2460,13 @@ function createChart(element, options = {}) {
2281
2460
  ctx.font = baseFont;
2282
2461
  }
2283
2462
  const labelTextWidth = Math.max(primaryWidth, subtextWidth);
2463
+ const labelWidth = getRightAxisLabelWidth(chartRight, labelTextWidth);
2284
2464
  return {
2285
2465
  ...label,
2286
2466
  subtexts,
2287
2467
  subtextFontSize,
2288
2468
  height: labelHeight,
2289
- width: labelTextWidth,
2469
+ width: labelWidth,
2290
2470
  targetY: clamp(yFromPrice(label.price), chartTop + 1, chartBottom - 1) - labelHeight / 2,
2291
2471
  y: 0
2292
2472
  };
@@ -2316,7 +2496,7 @@ function createChart(element, options = {}) {
2316
2496
  );
2317
2497
  rightAxisLabelSlots.sort((a, b) => a.y - b.y);
2318
2498
  }
2319
- const labelX = chartRight + 4;
2499
+ const labelX = getRightAxisLabelX(chartRight);
2320
2500
  for (const label of positionedLabels) {
2321
2501
  ctx.fillStyle = label.backgroundColor;
2322
2502
  fillRoundedRect(Math.round(labelX), Math.round(label.y), label.width, label.height, labelRadius);
@@ -2361,7 +2541,14 @@ function createChart(element, options = {}) {
2361
2541
  const prevFont = ctx.font;
2362
2542
  ctx.font = `${Math.max(8, axis.fontSize)}px ${mergedOptions.fontFamily}`;
2363
2543
  const legendText = labelEntries.join(" ");
2364
- drawText(legendText, chartLeft + 10, chartTop + 10, "left", "top", labels.indicatorTextColor);
2544
+ const offsetX = Math.max(0, Number(labels.indicatorLegendOffsetX) || 0);
2545
+ const offsetY = Math.max(0, Number(labels.indicatorLegendOffsetY) || 0);
2546
+ const position = labels.indicatorLegendPosition;
2547
+ const isRight = position === "top-right" || position === "bottom-right";
2548
+ const isBottom = position === "bottom-left" || position === "bottom-right";
2549
+ const legendX = isRight ? chartRight - offsetX : chartLeft + offsetX;
2550
+ const legendY = isBottom ? chartBottom - offsetY : chartTop + offsetY;
2551
+ drawText(legendText, legendX, legendY, isRight ? "right" : "left", isBottom ? "bottom" : "top", labels.indicatorTextColor);
2365
2552
  ctx.font = prevFont;
2366
2553
  }
2367
2554
  }
@@ -2419,8 +2606,8 @@ function createChart(element, options = {}) {
2419
2606
  if (crosshair.showPriceLabel) {
2420
2607
  const hoverPrice = yMin + (chartBottom - cy) / chartHeight * yRange;
2421
2608
  const priceText = formatPrice(hoverPrice);
2422
- const priceWidth = getPriceLabelWidth(priceText, labelPaddingX);
2423
- const priceX = chartRight + 4;
2609
+ const priceWidth = getRightAxisLabelWidth(chartRight, getPriceLabelWidth(priceText, labelPaddingX));
2610
+ const priceX = getRightAxisLabelX(chartRight);
2424
2611
  const priceY = clamp(cy - labelHeight / 2, chartTop, chartBottom - labelHeight);
2425
2612
  ctx.fillStyle = labelBackground;
2426
2613
  fillRoundedRect(Math.round(priceX), Math.round(priceY), priceWidth, labelHeight, labelRadius);
@@ -80,13 +80,46 @@ interface IndicatorRenderContext {
80
80
  upColor: string;
81
81
  downColor: string;
82
82
  }
83
+ interface IndicatorPaneAxisOptions {
84
+ min: number;
85
+ max: number;
86
+ ticks?: number[];
87
+ decimals?: number;
88
+ format?: (value: number) => string;
89
+ }
90
+ interface IndicatorPaneGuideLine {
91
+ value: number;
92
+ label?: string;
93
+ color?: string;
94
+ style?: "solid" | "dotted" | "dashed";
95
+ }
96
+ interface IndicatorPaneValue {
97
+ label?: string;
98
+ value?: number;
99
+ text?: string;
100
+ color?: string;
101
+ }
102
+ interface IndicatorPaneValueLabel {
103
+ value: number;
104
+ text?: string;
105
+ color?: string;
106
+ backgroundColor?: string;
107
+ textColor?: string;
108
+ }
109
+ interface IndicatorPaneRenderInfo {
110
+ title?: string;
111
+ axis?: IndicatorPaneAxisOptions;
112
+ guideLines?: IndicatorPaneGuideLine[];
113
+ legendValues?: IndicatorPaneValue[];
114
+ valueLabels?: IndicatorPaneValueLabel[];
115
+ }
83
116
  interface IndicatorPlugin<TInputs extends Record<string, unknown> = Record<string, unknown>> {
84
117
  id: string;
85
118
  name: string;
86
119
  pane?: IndicatorPane;
87
120
  paneHeightRatio?: number;
88
121
  defaultInputs?: TInputs;
89
- draw: (ctx: CanvasRenderingContext2D, renderContext: IndicatorRenderContext, inputs: TInputs) => void;
122
+ draw: (ctx: CanvasRenderingContext2D, renderContext: IndicatorRenderContext, inputs: TInputs) => void | IndicatorPaneRenderInfo;
90
123
  }
91
124
  interface BuiltInIndicatorInfo {
92
125
  id: string;
@@ -282,6 +315,10 @@ interface LabelsOptions {
282
315
  askPrice?: number;
283
316
  showIndicatorNames?: boolean;
284
317
  showIndicatorValues?: boolean;
318
+ showIndicatorValueLabels?: boolean;
319
+ indicatorLegendPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
320
+ indicatorLegendOffsetX?: number;
321
+ indicatorLegendOffsetY?: number;
285
322
  showCountdownToBarClose?: boolean;
286
323
  noOverlapping?: boolean;
287
324
  backgroundColor?: string;
@@ -361,4 +398,4 @@ interface ViewportState {
361
398
  }
362
399
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
363
400
 
364
- export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
401
+ export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, 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 };