hyperprop-charting-library 0.1.24 → 0.1.25

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/dist/index.cjs CHANGED
@@ -133,6 +133,8 @@ var DEFAULT_OPTIONS = {
133
133
  backgroundColor: "#101114",
134
134
  axisColor: "#7f8289",
135
135
  axis: DEFAULT_AXIS_OPTIONS,
136
+ xAxis: DEFAULT_AXIS_OPTIONS,
137
+ yAxis: DEFAULT_AXIS_OPTIONS,
136
138
  priceDecimals: 2,
137
139
  stabilizePriceLabels: true,
138
140
  priceLabelMinIntegerDigits: 3,
@@ -151,6 +153,7 @@ var DEFAULT_OPTIONS = {
151
153
  candleBodyWidthRatio: 0.7,
152
154
  candleMinWidth: 0.5,
153
155
  candleWickWidth: 1,
156
+ tickSize: 0,
154
157
  candleColorMode: "openClose",
155
158
  candleColorEpsilon: -1,
156
159
  autoScaleSmoothing: 0.16,
@@ -388,6 +391,35 @@ var computeAtrSeries = (data, length) => {
388
391
  }
389
392
  return result;
390
393
  };
394
+ var builtInSeriesCache = /* @__PURE__ */ new Map();
395
+ var getSeriesFingerprint = (data) => {
396
+ const length = data.length;
397
+ const last = length > 0 ? data[length - 1] : void 0;
398
+ const prev = length > 1 ? data[length - 2] : void 0;
399
+ if (!last) return "empty";
400
+ return [
401
+ length,
402
+ last.time.getTime(),
403
+ last.o,
404
+ last.h,
405
+ last.l,
406
+ last.c,
407
+ last.v ?? "",
408
+ prev?.time.getTime() ?? "",
409
+ prev?.c ?? "",
410
+ prev?.v ?? ""
411
+ ].join("|");
412
+ };
413
+ var withCachedSeries = (key, data, compute) => {
414
+ const fingerprint = getSeriesFingerprint(data);
415
+ const existing = builtInSeriesCache.get(key);
416
+ if (existing && existing.fingerprint === fingerprint) {
417
+ return existing.values;
418
+ }
419
+ const values = compute();
420
+ builtInSeriesCache.set(key, { fingerprint, values });
421
+ return values;
422
+ };
391
423
  var drawOverlaySeries = (ctx, renderContext, values, color, width) => {
392
424
  if (!renderContext.yFromPrice) return;
393
425
  const yFromPrice = renderContext.yFromPrice;
@@ -485,6 +517,8 @@ var BUILTIN_VOLUME_INDICATOR = {
485
517
  defaultInputs: {
486
518
  upOpacity: 0.7,
487
519
  downOpacity: 0.7,
520
+ upColor: "",
521
+ downColor: "",
488
522
  minBarWidth: 1,
489
523
  overlayHeightRatio: 0.22
490
524
  },
@@ -515,9 +549,11 @@ var BUILTIN_VOLUME_INDICATOR = {
515
549
  const barY = Math.round(paneBottom - volumeHeight);
516
550
  const direction = renderContext.getCandleDirectionByIndex(index);
517
551
  const opacity = direction === "up" ? upOpacity : downOpacity;
552
+ const upBarColor = inputs.upColor && inputs.upColor.trim().length > 0 ? inputs.upColor : upColor;
553
+ const downBarColor = inputs.downColor && inputs.downColor.trim().length > 0 ? inputs.downColor : downColor;
518
554
  ctx.save();
519
555
  ctx.globalAlpha = opacity;
520
- ctx.fillStyle = direction === "up" ? upColor : downColor;
556
+ ctx.fillStyle = direction === "up" ? upBarColor : downBarColor;
521
557
  ctx.fillRect(barX, barY, Math.max(1, Math.round(barWidth)), volumeHeight);
522
558
  ctx.restore();
523
559
  }
@@ -530,7 +566,11 @@ var BUILTIN_SMA_INDICATOR = {
530
566
  defaultInputs: { length: 20, source: "close", color: "#60a5fa", width: 2 },
531
567
  draw: (ctx, renderContext, inputs) => {
532
568
  const length = clampIndicatorLength(inputs.length, 20);
533
- const values = computeSmaSeries(renderContext.data, length, inputs.source ?? "close");
569
+ const values = withCachedSeries(
570
+ `sma|${length}|${inputs.source ?? "close"}`,
571
+ renderContext.data,
572
+ () => computeSmaSeries(renderContext.data, length, inputs.source ?? "close")
573
+ );
534
574
  drawOverlaySeries(ctx, renderContext, values, inputs.color ?? "#60a5fa", Number(inputs.width) || 2);
535
575
  }
536
576
  };
@@ -541,7 +581,11 @@ var BUILTIN_EMA_INDICATOR = {
541
581
  defaultInputs: { length: 20, source: "close", color: "#f59e0b", width: 2 },
542
582
  draw: (ctx, renderContext, inputs) => {
543
583
  const length = clampIndicatorLength(inputs.length, 20);
544
- const values = computeEmaSeries(renderContext.data, length, inputs.source ?? "close");
584
+ const values = withCachedSeries(
585
+ `ema|${length}|${inputs.source ?? "close"}`,
586
+ renderContext.data,
587
+ () => computeEmaSeries(renderContext.data, length, inputs.source ?? "close")
588
+ );
545
589
  drawOverlaySeries(ctx, renderContext, values, inputs.color ?? "#f59e0b", Number(inputs.width) || 2);
546
590
  }
547
591
  };
@@ -552,7 +596,11 @@ var BUILTIN_WMA_INDICATOR = {
552
596
  defaultInputs: { length: 20, source: "close", color: "#a78bfa", width: 2 },
553
597
  draw: (ctx, renderContext, inputs) => {
554
598
  const length = clampIndicatorLength(inputs.length, 20);
555
- const values = computeWmaSeries(renderContext.data, length, inputs.source ?? "close");
599
+ const values = withCachedSeries(
600
+ `wma|${length}|${inputs.source ?? "close"}`,
601
+ renderContext.data,
602
+ () => computeWmaSeries(renderContext.data, length, inputs.source ?? "close")
603
+ );
556
604
  drawOverlaySeries(ctx, renderContext, values, inputs.color ?? "#a78bfa", Number(inputs.width) || 2);
557
605
  }
558
606
  };
@@ -563,7 +611,11 @@ var BUILTIN_VWMA_INDICATOR = {
563
611
  defaultInputs: { length: 20, source: "close", color: "#ef4444", width: 2 },
564
612
  draw: (ctx, renderContext, inputs) => {
565
613
  const length = clampIndicatorLength(inputs.length, 20);
566
- const values = computeVwmaSeries(renderContext.data, length, inputs.source ?? "close");
614
+ const values = withCachedSeries(
615
+ `vwma|${length}|${inputs.source ?? "close"}`,
616
+ renderContext.data,
617
+ () => computeVwmaSeries(renderContext.data, length, inputs.source ?? "close")
618
+ );
567
619
  drawOverlaySeries(ctx, renderContext, values, inputs.color ?? "#ef4444", Number(inputs.width) || 2);
568
620
  }
569
621
  };
@@ -574,7 +626,11 @@ var BUILTIN_RMA_INDICATOR = {
574
626
  defaultInputs: { length: 14, source: "close", color: "#22c55e", width: 2 },
575
627
  draw: (ctx, renderContext, inputs) => {
576
628
  const length = clampIndicatorLength(inputs.length, 14);
577
- const values = computeRmaSeries(renderContext.data, length, inputs.source ?? "close");
629
+ const values = withCachedSeries(
630
+ `rma|${length}|${inputs.source ?? "close"}`,
631
+ renderContext.data,
632
+ () => computeRmaSeries(renderContext.data, length, inputs.source ?? "close")
633
+ );
578
634
  drawOverlaySeries(ctx, renderContext, values, inputs.color ?? "#22c55e", Number(inputs.width) || 2);
579
635
  }
580
636
  };
@@ -585,7 +641,11 @@ var BUILTIN_HMA_INDICATOR = {
585
641
  defaultInputs: { length: 21, source: "close", color: "#14b8a6", width: 2 },
586
642
  draw: (ctx, renderContext, inputs) => {
587
643
  const length = clampIndicatorLength(inputs.length, 21);
588
- const values = computeHmaSeries(renderContext.data, length, inputs.source ?? "close");
644
+ const values = withCachedSeries(
645
+ `hma|${length}|${inputs.source ?? "close"}`,
646
+ renderContext.data,
647
+ () => computeHmaSeries(renderContext.data, length, inputs.source ?? "close")
648
+ );
589
649
  drawOverlaySeries(ctx, renderContext, values, inputs.color ?? "#14b8a6", Number(inputs.width) || 2);
590
650
  }
591
651
  };
@@ -597,7 +657,11 @@ var BUILTIN_STDDEV_INDICATOR = {
597
657
  defaultInputs: { length: 20, source: "close", color: "#f97316", width: 2 },
598
658
  draw: (ctx, renderContext, inputs) => {
599
659
  const length = clampIndicatorLength(inputs.length, 20);
600
- const values = computeStdDevSeries(renderContext.data, length, inputs.source ?? "close");
660
+ const values = withCachedSeries(
661
+ `stddev|${length}|${inputs.source ?? "close"}`,
662
+ renderContext.data,
663
+ () => computeStdDevSeries(renderContext.data, length, inputs.source ?? "close")
664
+ );
601
665
  drawSeparateSeries(ctx, renderContext, values, inputs.color ?? "#f97316", Number(inputs.width) || 2);
602
666
  }
603
667
  };
@@ -609,7 +673,7 @@ var BUILTIN_ATR_INDICATOR = {
609
673
  defaultInputs: { length: 14, color: "#eab308", width: 2 },
610
674
  draw: (ctx, renderContext, inputs) => {
611
675
  const length = clampIndicatorLength(inputs.length, 14);
612
- const values = computeAtrSeries(renderContext.data, length);
676
+ const values = withCachedSeries(`atr|${length}`, renderContext.data, () => computeAtrSeries(renderContext.data, length));
613
677
  drawSeparateSeries(ctx, renderContext, values, inputs.color ?? "#eab308", Number(inputs.width) || 2);
614
678
  }
615
679
  };
@@ -621,7 +685,7 @@ var BUILTIN_RSI_INDICATOR = {
621
685
  defaultInputs: { length: 14, color: "#3b82f6", width: 2 },
622
686
  draw: (ctx, renderContext, inputs) => {
623
687
  const length = clampIndicatorLength(inputs.length, 14);
624
- const values = computeRsiSeries(renderContext.data, length);
688
+ const values = withCachedSeries(`rsi|${length}`, renderContext.data, () => computeRsiSeries(renderContext.data, length));
625
689
  drawSeparateSeries(
626
690
  ctx,
627
691
  renderContext,
@@ -655,6 +719,18 @@ function createChart(element, options = {}) {
655
719
  ...options.axis ?? {},
656
720
  ...options.axisColor ? { lineColor: options.axisColor, textColor: options.axisColor } : {}
657
721
  },
722
+ xAxis: {
723
+ ...DEFAULT_AXIS_OPTIONS,
724
+ ...options.axis ?? {},
725
+ ...options.axisColor ? { lineColor: options.axisColor, textColor: options.axisColor } : {},
726
+ ...options.xAxis ?? {}
727
+ },
728
+ yAxis: {
729
+ ...DEFAULT_AXIS_OPTIONS,
730
+ ...options.axis ?? {},
731
+ ...options.axisColor ? { lineColor: options.axisColor, textColor: options.axisColor } : {},
732
+ ...options.yAxis ?? {}
733
+ },
658
734
  crosshair: {
659
735
  ...DEFAULT_CROSSHAIR_OPTIONS,
660
736
  ...options.crosshair ?? {}
@@ -710,6 +786,9 @@ function createChart(element, options = {}) {
710
786
  visible: indicator.visible ?? true,
711
787
  pane: indicator.pane ?? plugin?.pane ?? "overlay",
712
788
  ...indicator.paneHeightRatio === void 0 ? {} : { paneHeightRatio: indicator.paneHeightRatio },
789
+ zIndex: Math.round(Number(indicator.zIndex) || 0),
790
+ excludeFromAutoscale: indicator.excludeFromAutoscale ?? true,
791
+ overlayScaleWeight: Math.min(1, Math.max(0, Number(indicator.overlayScaleWeight) || 0.25)),
713
792
  inputs: {
714
793
  ...defaults,
715
794
  ...indicator.inputs ?? {}
@@ -865,20 +944,56 @@ function createChart(element, options = {}) {
865
944
  }
866
945
  return { min: nextMin, max: nextMax };
867
946
  };
947
+ const getConfiguredPriceDecimals = () => clamp(Math.round(mergedOptions.priceDecimals), 0, 8);
948
+ const getConfiguredTickSize = () => {
949
+ const step = Number(mergedOptions.tickSize);
950
+ return Number.isFinite(step) && step > 0 ? step : 0;
951
+ };
952
+ const getTickSizeDecimals = () => {
953
+ const tickSize = getConfiguredTickSize();
954
+ if (tickSize <= 0) {
955
+ return 0;
956
+ }
957
+ let scaled = tickSize;
958
+ let decimals = 0;
959
+ while (decimals < 8 && Math.abs(Math.round(scaled) - scaled) > 1e-10) {
960
+ scaled *= 10;
961
+ decimals += 1;
962
+ }
963
+ return decimals;
964
+ };
965
+ const getDisplayPriceDecimals = () => {
966
+ const configured = getConfiguredPriceDecimals();
967
+ const tickDecimals = getTickSizeDecimals();
968
+ return Math.max(configured, tickDecimals);
969
+ };
970
+ const quantizeToTickSize = (price) => {
971
+ const tickSize = getConfiguredTickSize();
972
+ if (tickSize <= 0 || !Number.isFinite(price)) {
973
+ return price;
974
+ }
975
+ return Math.round(price / tickSize) * tickSize;
976
+ };
868
977
  const formatPrice = (price) => {
869
- const decimals = clamp(Math.round(mergedOptions.priceDecimals), 0, 8);
870
- return price.toFixed(decimals);
978
+ const rounded = quantizeToTickSize(price);
979
+ const decimals = getDisplayPriceDecimals();
980
+ return rounded.toFixed(decimals);
871
981
  };
872
982
  const roundToPricePrecision = (price) => {
873
- const decimals = clamp(Math.round(mergedOptions.priceDecimals), 0, 8);
874
- return Number(price.toFixed(decimals));
983
+ const rounded = quantizeToTickSize(price);
984
+ const decimals = getDisplayPriceDecimals();
985
+ return Number(rounded.toFixed(decimals));
875
986
  };
876
987
  const getResolvedCandleColorEpsilon = () => {
877
988
  const configured = mergedOptions.candleColorEpsilon;
878
989
  if (configured >= 0) {
879
990
  return configured;
880
991
  }
881
- const decimals = clamp(Math.round(mergedOptions.priceDecimals), 0, 8);
992
+ const tickSize = getConfiguredTickSize();
993
+ if (tickSize > 0) {
994
+ return tickSize / 2;
995
+ }
996
+ const decimals = getDisplayPriceDecimals();
882
997
  return decimals > 0 ? 0.5 / 10 ** decimals : 0;
883
998
  };
884
999
  const getDirectionFromDelta = (delta) => {
@@ -1410,6 +1525,10 @@ function createChart(element, options = {}) {
1410
1525
  canvas.height = Math.floor(height * pixelRatio);
1411
1526
  ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
1412
1527
  const axis = { ...DEFAULT_AXIS_OPTIONS, ...mergedOptions.axis ?? {} };
1528
+ const xAxis = { ...DEFAULT_AXIS_OPTIONS, ...mergedOptions.xAxis ?? {} };
1529
+ const yAxis = { ...DEFAULT_AXIS_OPTIONS, ...mergedOptions.yAxis ?? {} };
1530
+ const xAxisFontSize = Math.max(8, xAxis.fontSize);
1531
+ const yAxisFontSize = Math.max(8, yAxis.fontSize);
1413
1532
  ctx.font = `${Math.max(8, axis.fontSize)}px ${mergedOptions.fontFamily}`;
1414
1533
  ctx.fillStyle = mergedOptions.backgroundColor;
1415
1534
  ctx.fillRect(0, 0, width, height);
@@ -1424,6 +1543,9 @@ function createChart(element, options = {}) {
1424
1543
  const separatePaneSpacing = 6;
1425
1544
  const activeSeparateIndicators = indicators.filter((indicator) => indicator.visible).map((indicator) => ({ indicator, plugin: indicatorRegistry.get(indicator.type) })).filter(
1426
1545
  (value) => value.plugin !== void 0 && (value.indicator.pane ?? value.plugin.pane ?? "overlay") === "separate"
1546
+ ).sort((a, b) => a.indicator.zIndex - b.indicator.zIndex);
1547
+ const overlayIndicatorsForScale = indicators.filter((indicator) => indicator.visible).map((indicator) => ({ indicator, plugin: indicatorRegistry.get(indicator.type) })).filter(
1548
+ (value) => value.plugin !== void 0 && (value.indicator.pane ?? value.plugin.pane ?? "overlay") === "overlay"
1427
1549
  );
1428
1550
  const separatePaneHeightDefaults = activeSeparateIndicators.map(({ indicator, plugin }) => {
1429
1551
  const ratio = Math.min(0.45, Math.max(0.08, indicator.paneHeightRatio ?? plugin.paneHeightRatio ?? 0.22));
@@ -1475,8 +1597,47 @@ function createChart(element, options = {}) {
1475
1597
  }
1476
1598
  }
1477
1599
  }
1478
- const minPrice = Math.min(...priceSource.map((point) => point.l));
1479
- const maxPrice = Math.max(...priceSource.map((point) => point.h));
1600
+ let minPrice = Math.min(...priceSource.map((point) => point.l));
1601
+ let maxPrice = Math.max(...priceSource.map((point) => point.h));
1602
+ if (overlayIndicatorsForScale.length > 0) {
1603
+ for (const { indicator } of overlayIndicatorsForScale) {
1604
+ if (indicator.excludeFromAutoscale) {
1605
+ continue;
1606
+ }
1607
+ const type = indicator.type;
1608
+ const inputs = indicator.inputs;
1609
+ const source = inputs.source ?? "close";
1610
+ const length = clampIndicatorLength(inputs.length ?? 14, 14);
1611
+ let series = null;
1612
+ if (type === "sma") series = withCachedSeries(`sma|${length}|${source}`, data, () => computeSmaSeries(data, length, source));
1613
+ if (type === "ema") series = withCachedSeries(`ema|${length}|${source}`, data, () => computeEmaSeries(data, length, source));
1614
+ if (type === "wma") series = withCachedSeries(`wma|${length}|${source}`, data, () => computeWmaSeries(data, length, source));
1615
+ if (type === "vwma") series = withCachedSeries(`vwma|${length}|${source}`, data, () => computeVwmaSeries(data, length, source));
1616
+ if (type === "rma") series = withCachedSeries(`rma|${length}|${source}`, data, () => computeRmaSeries(data, length, source));
1617
+ if (type === "hma") series = withCachedSeries(`hma|${length}|${source}`, data, () => computeHmaSeries(data, length, source));
1618
+ if (!series) {
1619
+ continue;
1620
+ }
1621
+ const visibleValues = [];
1622
+ for (let idx = startIndex; idx <= endIndex; idx += 1) {
1623
+ const value = series[idx];
1624
+ if (Number.isFinite(value ?? Number.NaN)) {
1625
+ visibleValues.push(value);
1626
+ }
1627
+ }
1628
+ if (visibleValues.length === 0) {
1629
+ continue;
1630
+ }
1631
+ const seriesMin = Math.min(...visibleValues);
1632
+ const seriesMax = Math.max(...visibleValues);
1633
+ const weight = Math.min(1, Math.max(0, indicator.overlayScaleWeight));
1634
+ const currentMid = (minPrice + maxPrice) / 2;
1635
+ const weightedMin = currentMid + (seriesMin - currentMid) * weight;
1636
+ const weightedMax = currentMid + (seriesMax - currentMid) * weight;
1637
+ minPrice = Math.min(minPrice, weightedMin);
1638
+ maxPrice = Math.max(maxPrice, weightedMax);
1639
+ }
1640
+ }
1480
1641
  const priceRange = maxPrice - minPrice || 1;
1481
1642
  const autoMin = minPrice - priceRange * 0.08;
1482
1643
  const autoMax = maxPrice + priceRange * 0.08;
@@ -1636,7 +1797,7 @@ function createChart(element, options = {}) {
1636
1797
  }
1637
1798
  const activeOverlayIndicators = indicators.filter((indicator) => indicator.visible).map((indicator) => ({ indicator, plugin: indicatorRegistry.get(indicator.type) })).filter(
1638
1799
  (value) => value.plugin !== void 0 && (value.indicator.pane ?? value.plugin.pane ?? "overlay") === "overlay"
1639
- );
1800
+ ).sort((a, b) => a.indicator.zIndex - b.indicator.zIndex);
1640
1801
  if (activeOverlayIndicators.length > 0) {
1641
1802
  const xFromIndex = (index) => chartLeft + (index + 0.5 - xStart) / xSpan * chartWidth;
1642
1803
  activeOverlayIndicators.forEach(({ indicator, plugin }) => {
@@ -1746,7 +1907,10 @@ function createChart(element, options = {}) {
1746
1907
  const ratio = tick / yTicks;
1747
1908
  const price = yMin + yRange * ratio;
1748
1909
  const y = yFromPrice(price);
1749
- drawText(formatPrice(price), chartRight + 6, y, "left", "middle", axis.textColor);
1910
+ const prevFont = ctx.font;
1911
+ ctx.font = `${yAxisFontSize}px ${mergedOptions.fontFamily}`;
1912
+ drawText(formatPrice(price), chartRight + 6, y, "left", "middle", yAxis.textColor);
1913
+ ctx.font = prevFont;
1750
1914
  }
1751
1915
  const ticker = mergedOptions.tickerLine ?? DEFAULT_OPTIONS.tickerLine;
1752
1916
  const lastPoint = data[data.length - 1];
@@ -1803,7 +1967,10 @@ function createChart(element, options = {}) {
1803
1967
  month: "short",
1804
1968
  day: "numeric"
1805
1969
  });
1806
- drawText(timeLabel, x, fullChartBottom + 8, "center", "top", axis.textColor);
1970
+ const prevFont = ctx.font;
1971
+ ctx.font = `${xAxisFontSize}px ${mergedOptions.fontFamily}`;
1972
+ drawText(timeLabel, x, fullChartBottom + 8, "center", "top", xAxis.textColor);
1973
+ ctx.font = prevFont;
1807
1974
  }
1808
1975
  if (crosshair.visible && crosshairPoint) {
1809
1976
  const cx = clamp(crosshairPoint.x, chartLeft, chartRight);
@@ -2574,6 +2741,27 @@ function createChart(element, options = {}) {
2574
2741
  indicators = indicators.filter((indicator) => indicator.type !== type);
2575
2742
  draw();
2576
2743
  };
2744
+ const listBuiltInIndicators = () => {
2745
+ return BUILTIN_INDICATORS.map((indicator) => ({
2746
+ id: indicator.id,
2747
+ name: indicator.name,
2748
+ pane: indicator.pane ?? "overlay",
2749
+ ...indicator.paneHeightRatio === void 0 ? {} : { paneHeightRatio: indicator.paneHeightRatio }
2750
+ }));
2751
+ };
2752
+ const getIndicators = () => {
2753
+ return indicators.map((indicator) => ({
2754
+ id: indicator.id,
2755
+ type: indicator.type,
2756
+ visible: indicator.visible,
2757
+ pane: indicator.pane,
2758
+ ...indicator.paneHeightRatio === void 0 ? {} : { paneHeightRatio: indicator.paneHeightRatio },
2759
+ zIndex: indicator.zIndex,
2760
+ excludeFromAutoscale: indicator.excludeFromAutoscale,
2761
+ overlayScaleWeight: indicator.overlayScaleWeight,
2762
+ inputs: { ...indicator.inputs }
2763
+ }));
2764
+ };
2577
2765
  const setIndicators = (nextIndicators) => {
2578
2766
  indicators = nextIndicators.map((indicator) => normalizeIndicatorState(indicator));
2579
2767
  draw();
@@ -2603,6 +2791,9 @@ function createChart(element, options = {}) {
2603
2791
  visible: patch.visible ?? indicator.visible,
2604
2792
  pane: patch.pane ?? indicator.pane ?? plugin?.pane ?? "overlay",
2605
2793
  ...patch.paneHeightRatio !== void 0 || indicator.paneHeightRatio !== void 0 ? { paneHeightRatio: patch.paneHeightRatio ?? indicator.paneHeightRatio } : {},
2794
+ zIndex: patch.zIndex === void 0 ? indicator.zIndex : Math.round(Number(patch.zIndex) || 0),
2795
+ excludeFromAutoscale: patch.excludeFromAutoscale ?? indicator.excludeFromAutoscale,
2796
+ overlayScaleWeight: patch.overlayScaleWeight === void 0 ? indicator.overlayScaleWeight : Math.min(1, Math.max(0, Number(patch.overlayScaleWeight) || 0)),
2606
2797
  type: patch.type ?? indicator.type,
2607
2798
  inputs: {
2608
2799
  ...indicator.inputs,
@@ -2652,6 +2843,8 @@ function createChart(element, options = {}) {
2652
2843
  setDoubleClickAction,
2653
2844
  registerIndicator,
2654
2845
  unregisterIndicator,
2846
+ listBuiltInIndicators,
2847
+ getIndicators,
2655
2848
  addIndicator,
2656
2849
  updateIndicator,
2657
2850
  removeIndicator,
package/dist/index.d.cts CHANGED
@@ -4,6 +4,8 @@ interface ChartOptions {
4
4
  backgroundColor?: string;
5
5
  axisColor?: string;
6
6
  axis?: AxisOptions;
7
+ xAxis?: AxisOptions;
8
+ yAxis?: AxisOptions;
7
9
  priceDecimals?: number;
8
10
  stabilizePriceLabels?: boolean;
9
11
  priceLabelMinIntegerDigits?: number;
@@ -22,6 +24,7 @@ interface ChartOptions {
22
24
  candleBodyWidthRatio?: number;
23
25
  candleMinWidth?: number;
24
26
  candleWickWidth?: number;
27
+ tickSize?: number;
25
28
  candleColorMode?: "openClose" | "prevClose";
26
29
  candleColorEpsilon?: number;
27
30
  autoScaleSmoothing?: number;
@@ -44,6 +47,9 @@ interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Rec
44
47
  visible?: boolean;
45
48
  pane?: IndicatorPane;
46
49
  paneHeightRatio?: number;
50
+ zIndex?: number;
51
+ excludeFromAutoscale?: boolean;
52
+ overlayScaleWeight?: number;
47
53
  inputs?: Partial<TInputs>;
48
54
  }
49
55
  interface IndicatorRenderContext {
@@ -80,6 +86,12 @@ interface IndicatorPlugin<TInputs extends Record<string, unknown> = Record<strin
80
86
  defaultInputs?: TInputs;
81
87
  draw: (ctx: CanvasRenderingContext2D, renderContext: IndicatorRenderContext, inputs: TInputs) => void;
82
88
  }
89
+ interface BuiltInIndicatorInfo {
90
+ id: string;
91
+ name: string;
92
+ pane: IndicatorPane;
93
+ paneHeightRatio?: number;
94
+ }
83
95
  interface DashPatternOptions {
84
96
  dotted: [number, number];
85
97
  dashed: [number, number];
@@ -271,6 +283,8 @@ interface ChartInstance {
271
283
  setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
272
284
  registerIndicator: (plugin: IndicatorPlugin<any>) => void;
273
285
  unregisterIndicator: (type: string) => void;
286
+ listBuiltInIndicators: () => BuiltInIndicatorInfo[];
287
+ getIndicators: () => IndicatorInstanceOptions[];
274
288
  addIndicator: (type: string, inputs?: Record<string, unknown>, options?: Partial<IndicatorInstanceOptions>) => string;
275
289
  updateIndicator: (id: string, patch: Partial<IndicatorInstanceOptions>) => void;
276
290
  removeIndicator: (id: string) => void;
@@ -288,4 +302,4 @@ interface OhlcDataPoint {
288
302
  }
289
303
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
290
304
 
291
- export { type AxisOptions, 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 OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type WatermarkOptions, createChart };
305
+ 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 OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type WatermarkOptions, createChart };
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ interface ChartOptions {
4
4
  backgroundColor?: string;
5
5
  axisColor?: string;
6
6
  axis?: AxisOptions;
7
+ xAxis?: AxisOptions;
8
+ yAxis?: AxisOptions;
7
9
  priceDecimals?: number;
8
10
  stabilizePriceLabels?: boolean;
9
11
  priceLabelMinIntegerDigits?: number;
@@ -22,6 +24,7 @@ interface ChartOptions {
22
24
  candleBodyWidthRatio?: number;
23
25
  candleMinWidth?: number;
24
26
  candleWickWidth?: number;
27
+ tickSize?: number;
25
28
  candleColorMode?: "openClose" | "prevClose";
26
29
  candleColorEpsilon?: number;
27
30
  autoScaleSmoothing?: number;
@@ -44,6 +47,9 @@ interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Rec
44
47
  visible?: boolean;
45
48
  pane?: IndicatorPane;
46
49
  paneHeightRatio?: number;
50
+ zIndex?: number;
51
+ excludeFromAutoscale?: boolean;
52
+ overlayScaleWeight?: number;
47
53
  inputs?: Partial<TInputs>;
48
54
  }
49
55
  interface IndicatorRenderContext {
@@ -80,6 +86,12 @@ interface IndicatorPlugin<TInputs extends Record<string, unknown> = Record<strin
80
86
  defaultInputs?: TInputs;
81
87
  draw: (ctx: CanvasRenderingContext2D, renderContext: IndicatorRenderContext, inputs: TInputs) => void;
82
88
  }
89
+ interface BuiltInIndicatorInfo {
90
+ id: string;
91
+ name: string;
92
+ pane: IndicatorPane;
93
+ paneHeightRatio?: number;
94
+ }
83
95
  interface DashPatternOptions {
84
96
  dotted: [number, number];
85
97
  dashed: [number, number];
@@ -271,6 +283,8 @@ interface ChartInstance {
271
283
  setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
272
284
  registerIndicator: (plugin: IndicatorPlugin<any>) => void;
273
285
  unregisterIndicator: (type: string) => void;
286
+ listBuiltInIndicators: () => BuiltInIndicatorInfo[];
287
+ getIndicators: () => IndicatorInstanceOptions[];
274
288
  addIndicator: (type: string, inputs?: Record<string, unknown>, options?: Partial<IndicatorInstanceOptions>) => string;
275
289
  updateIndicator: (id: string, patch: Partial<IndicatorInstanceOptions>) => void;
276
290
  removeIndicator: (id: string) => void;
@@ -288,4 +302,4 @@ interface OhlcDataPoint {
288
302
  }
289
303
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
290
304
 
291
- export { type AxisOptions, 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 OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type WatermarkOptions, createChart };
305
+ 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 OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type WatermarkOptions, createChart };