hyperprop-charting-library 0.1.138 → 0.1.139

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.
@@ -2853,6 +2853,7 @@ var DEFAULT_OPTIONS = {
2853
2853
  doubleClickAction: "reset",
2854
2854
  keyboard: { enabled: true, panBars: 1, deleteSelectedDrawing: true },
2855
2855
  accessibility: { label: "Price chart", description: "", focusable: true },
2856
+ downsampling: { enabled: true, thresholdPx: 1.5 },
2856
2857
  crosshair: DEFAULT_CROSSHAIR_OPTIONS,
2857
2858
  grid: DEFAULT_GRID_OPTIONS,
2858
2859
  watermark: DEFAULT_WATERMARK_OPTIONS,
@@ -2903,6 +2904,10 @@ var mergeChartOptions = (baseOptions, options = {}) => ({
2903
2904
  ...baseOptions.accessibility,
2904
2905
  ...options.accessibility ?? {}
2905
2906
  },
2907
+ downsampling: {
2908
+ ...baseOptions.downsampling,
2909
+ ...options.downsampling ?? {}
2910
+ },
2906
2911
  crosshair: {
2907
2912
  ...baseOptions.crosshair,
2908
2913
  ...options.crosshair ?? {}
@@ -3778,6 +3783,64 @@ function createChart(element, options = {}) {
3778
3783
  heikinAshiFingerprint = fingerprint;
3779
3784
  return result;
3780
3785
  };
3786
+ let compareSeriesStates = [];
3787
+ const prepareCompareSeries = (options2) => {
3788
+ const rows = [];
3789
+ for (const point of options2.data ?? []) {
3790
+ const t = new Date(point.t).getTime();
3791
+ const c = Number(point.c);
3792
+ if (Number.isFinite(t) && Number.isFinite(c)) rows.push({ t, c });
3793
+ }
3794
+ rows.sort((a, b) => a.t - b.t);
3795
+ return {
3796
+ options: options2,
3797
+ times: rows.map((row) => row.t),
3798
+ closes: rows.map((row) => row.c),
3799
+ aligned: null,
3800
+ alignedFingerprint: ""
3801
+ };
3802
+ };
3803
+ const mainDataFingerprint = () => {
3804
+ const last = data[data.length - 1];
3805
+ return last ? `${data.length}|${data[0].time.getTime()}|${last.time.getTime()}` : "empty";
3806
+ };
3807
+ const getAlignedCompareValues = (state) => {
3808
+ const fingerprint = `${mainDataFingerprint()}|${state.times.length}|${state.times[state.times.length - 1] ?? 0}`;
3809
+ if (state.aligned && state.alignedFingerprint === fingerprint) {
3810
+ return state.aligned;
3811
+ }
3812
+ const aligned = new Float64Array(data.length).fill(Number.NaN);
3813
+ let cursor = 0;
3814
+ let lastValue = Number.NaN;
3815
+ for (let i = 0; i < data.length; i += 1) {
3816
+ const barTime = data[i].time.getTime();
3817
+ while (cursor < state.times.length && state.times[cursor] <= barTime) {
3818
+ lastValue = state.closes[cursor];
3819
+ cursor += 1;
3820
+ }
3821
+ aligned[i] = lastValue;
3822
+ }
3823
+ state.aligned = aligned;
3824
+ state.alignedFingerprint = fingerprint;
3825
+ return aligned;
3826
+ };
3827
+ const visibleCompareSeries = () => compareSeriesStates.filter((state) => state.options.visible !== false && state.times.length > 0);
3828
+ const setCompareSeries = (series) => {
3829
+ compareSeriesStates = (series ?? []).filter((entry) => entry && entry.id).map(prepareCompareSeries);
3830
+ scheduleDraw({ updateAutoScale: true });
3831
+ };
3832
+ const addCompareSeries = (series) => {
3833
+ if (!series?.id) return;
3834
+ compareSeriesStates = [...compareSeriesStates.filter((state) => state.options.id !== series.id), prepareCompareSeries(series)];
3835
+ scheduleDraw({ updateAutoScale: true });
3836
+ };
3837
+ const removeCompareSeries = (id) => {
3838
+ const next = compareSeriesStates.filter((state) => state.options.id !== id);
3839
+ if (next.length === compareSeriesStates.length) return;
3840
+ compareSeriesStates = next;
3841
+ scheduleDraw({ updateAutoScale: true });
3842
+ };
3843
+ const getCompareSeries = () => compareSeriesStates.map((state) => state.options);
3781
3844
  const formatHoverTimeLabel = (time, mode) => {
3782
3845
  if (mode === "time") {
3783
3846
  return time.toLocaleTimeString(void 0, {
@@ -4383,6 +4446,31 @@ function createChart(element, options = {}) {
4383
4446
  const chartType = mergedOptions.chartType;
4384
4447
  const seriesData = chartType === "heikin-ashi" ? getHeikinAshiData() : data;
4385
4448
  const isLineStyleChart = chartType === "line" || chartType === "area" || chartType === "baseline";
4449
+ const comparePlans = [];
4450
+ for (const state of visibleCompareSeries()) {
4451
+ const aligned = getAlignedCompareValues(state);
4452
+ let anchorIndex = -1;
4453
+ for (let index = startIndex; index <= endIndex; index += 1) {
4454
+ if (Number.isFinite(aligned[index] ?? Number.NaN)) {
4455
+ anchorIndex = index;
4456
+ break;
4457
+ }
4458
+ }
4459
+ if (anchorIndex < 0) continue;
4460
+ const baseCompare = aligned[anchorIndex];
4461
+ const baseMain = seriesData[anchorIndex]?.c ?? 0;
4462
+ const usePercent = (state.options.scale ?? "percent") !== "price";
4463
+ const toPrice = usePercent && baseCompare > 0 ? (value) => baseMain * value / baseCompare : (value) => value;
4464
+ let lastNativeValue = Number.NaN;
4465
+ for (let index = endIndex; index >= startIndex; index -= 1) {
4466
+ const value = aligned[index];
4467
+ if (value !== void 0 && Number.isFinite(value)) {
4468
+ lastNativeValue = value;
4469
+ break;
4470
+ }
4471
+ }
4472
+ comparePlans.push({ state, aligned, toPrice, usePercent, baseCompare, lastNativeValue });
4473
+ }
4386
4474
  const skipLatestIndex = mergedOptions.autoScaleIgnoreLatestCandle && data.length > 1 ? data.length - 1 : -1;
4387
4475
  const scanCandleRange = (from, to) => {
4388
4476
  let min = Number.POSITIVE_INFINITY;
@@ -4428,6 +4516,23 @@ function createChart(element, options = {}) {
4428
4516
  maxPrice = Math.max(maxPrice, weightedMax);
4429
4517
  }
4430
4518
  }
4519
+ for (const plan of comparePlans) {
4520
+ if (plan.state.options.includeInAutoScale === false) continue;
4521
+ let compareMin = Number.POSITIVE_INFINITY;
4522
+ let compareMax = Number.NEGATIVE_INFINITY;
4523
+ for (let index = startIndex; index <= endIndex; index += 1) {
4524
+ const value = plan.aligned[index];
4525
+ if (value === void 0 || !Number.isFinite(value)) continue;
4526
+ const price = plan.toPrice(value);
4527
+ if (!Number.isFinite(price)) continue;
4528
+ if (price < compareMin) compareMin = price;
4529
+ if (price > compareMax) compareMax = price;
4530
+ }
4531
+ if (compareMin <= compareMax) {
4532
+ minPrice = Math.min(minPrice, compareMin);
4533
+ maxPrice = Math.max(maxPrice, compareMax);
4534
+ }
4535
+ }
4431
4536
  const priceRange = maxPrice - minPrice || 1;
4432
4537
  const autoMin = minPrice - priceRange * 0.08;
4433
4538
  const autoMax = maxPrice + priceRange * 0.08;
@@ -5539,7 +5644,106 @@ function createChart(element, options = {}) {
5539
5644
  }
5540
5645
  return data[index]?.v;
5541
5646
  };
5542
- if (isLineStyleChart) {
5647
+ const downsamplingOptions = mergedOptions.downsampling ?? DEFAULT_OPTIONS.downsampling;
5648
+ const downsampleThresholdPx = Math.max(0.2, downsamplingOptions?.thresholdPx ?? 1.5);
5649
+ const shouldDownsample = (downsamplingOptions?.enabled ?? true) && candleSpacing < downsampleThresholdPx && endIndex - startIndex > 2;
5650
+ const seriesColumns = [];
5651
+ if (shouldDownsample) {
5652
+ let current = null;
5653
+ let currentColumn = Number.NaN;
5654
+ for (let index = startIndex; index <= endIndex; index += 1) {
5655
+ const point = seriesData[index];
5656
+ if (!point) continue;
5657
+ const column = Math.round(chartLeft + (index + 0.5 - xStart) / xSpan * chartWidth);
5658
+ if (!current || column !== currentColumn) {
5659
+ currentColumn = column;
5660
+ current = {
5661
+ x: column,
5662
+ open: point.o,
5663
+ high: point.h,
5664
+ low: point.l,
5665
+ close: point.c,
5666
+ minClose: point.c,
5667
+ maxClose: point.c,
5668
+ minCloseIndex: index,
5669
+ maxCloseIndex: index
5670
+ };
5671
+ seriesColumns.push(current);
5672
+ continue;
5673
+ }
5674
+ if (point.h > current.high) current.high = point.h;
5675
+ if (point.l < current.low) current.low = point.l;
5676
+ current.close = point.c;
5677
+ if (point.c < current.minClose) {
5678
+ current.minClose = point.c;
5679
+ current.minCloseIndex = index;
5680
+ }
5681
+ if (point.c > current.maxClose) {
5682
+ current.maxClose = point.c;
5683
+ current.maxCloseIndex = index;
5684
+ }
5685
+ }
5686
+ }
5687
+ if (shouldDownsample && !isLineStyleChart) {
5688
+ const upColumns = new Path2D();
5689
+ const downColumns = new Path2D();
5690
+ for (const column of seriesColumns) {
5691
+ const path = column.close >= column.open ? upColumns : downColumns;
5692
+ const x = column.x + 0.5;
5693
+ const top = crisp(yFromPrice(column.high));
5694
+ const bottom = crisp(yFromPrice(column.low));
5695
+ path.moveTo(x, top);
5696
+ path.lineTo(x, bottom === top ? bottom + 1 : bottom);
5697
+ }
5698
+ ctx.lineWidth = 1;
5699
+ ctx.strokeStyle = mergedOptions.upColor;
5700
+ ctx.stroke(upColumns);
5701
+ ctx.strokeStyle = mergedOptions.downColor;
5702
+ ctx.stroke(downColumns);
5703
+ } else if (shouldDownsample && isLineStyleChart) {
5704
+ const seriesLineWidth = Math.max(1, mergedOptions.lineWidth);
5705
+ const linePath = new Path2D();
5706
+ let started = false;
5707
+ let firstX = 0;
5708
+ let lastX = 0;
5709
+ for (const column of seriesColumns) {
5710
+ const lowFirst = column.minCloseIndex <= column.maxCloseIndex;
5711
+ const first = lowFirst ? column.minClose : column.maxClose;
5712
+ const second = lowFirst ? column.maxClose : column.minClose;
5713
+ const x = column.x;
5714
+ if (!started) {
5715
+ linePath.moveTo(x, yFromPrice(first));
5716
+ firstX = x;
5717
+ started = true;
5718
+ } else {
5719
+ linePath.lineTo(x, yFromPrice(first));
5720
+ }
5721
+ if (second !== first) {
5722
+ linePath.lineTo(x, yFromPrice(second));
5723
+ }
5724
+ lastX = x;
5725
+ }
5726
+ if (started) {
5727
+ if (chartType === "area" || chartType === "baseline") {
5728
+ const baseY = chartType === "baseline" ? yFromPrice(mergedOptions.baselinePrice ?? (yMin + yMax) / 2) : chartBottom;
5729
+ const fillPath = new Path2D(linePath);
5730
+ fillPath.lineTo(lastX, baseY);
5731
+ fillPath.lineTo(firstX, baseY);
5732
+ fillPath.closePath();
5733
+ ctx.save();
5734
+ ctx.globalAlpha = Math.max(0, Math.min(1, mergedOptions.areaFillOpacity));
5735
+ ctx.fillStyle = chartType === "baseline" ? mergedOptions.upColor : mergedOptions.lineColor;
5736
+ ctx.fill(fillPath);
5737
+ ctx.restore();
5738
+ }
5739
+ ctx.save();
5740
+ ctx.strokeStyle = chartType === "baseline" ? mergedOptions.upColor : mergedOptions.lineColor;
5741
+ ctx.lineWidth = seriesLineWidth;
5742
+ ctx.lineJoin = "round";
5743
+ ctx.stroke(linePath);
5744
+ ctx.restore();
5745
+ }
5746
+ } else if (isLineStyleChart) {
5543
5747
  const seriesLineWidth = Math.max(1, mergedOptions.lineWidth);
5544
5748
  const linePath = new Path2D();
5545
5749
  let started = false;
@@ -5705,6 +5909,105 @@ function createChart(element, options = {}) {
5705
5909
  ctx.stroke(downHollowBodies);
5706
5910
  }
5707
5911
  }
5912
+ const compareAxisTags = [];
5913
+ for (const plan of comparePlans) {
5914
+ const color = plan.state.options.color ?? "#f59e0b";
5915
+ const lineWidth = Math.max(1, plan.state.options.lineWidth ?? 1.5);
5916
+ const path = new Path2D();
5917
+ let started = false;
5918
+ let firstX = 0;
5919
+ let lastX = 0;
5920
+ let lastY = 0;
5921
+ let lastPrice = Number.NaN;
5922
+ const emit = (x, y) => {
5923
+ if (!started) {
5924
+ path.moveTo(x, y);
5925
+ firstX = x;
5926
+ started = true;
5927
+ } else {
5928
+ path.lineTo(x, y);
5929
+ }
5930
+ lastX = x;
5931
+ lastY = y;
5932
+ };
5933
+ const xForIndex = (index) => chartLeft + (index + 0.5 - xStart) / xSpan * chartWidth;
5934
+ if (shouldDownsample) {
5935
+ let column = Number.NaN;
5936
+ let minValue = 0;
5937
+ let maxValue = 0;
5938
+ let minIndex = 0;
5939
+ let maxIndex = 0;
5940
+ let hasColumn = false;
5941
+ const flushColumn = () => {
5942
+ if (!hasColumn) return;
5943
+ const lowFirst = minIndex <= maxIndex;
5944
+ const first = plan.toPrice(lowFirst ? minValue : maxValue);
5945
+ const second = plan.toPrice(lowFirst ? maxValue : minValue);
5946
+ if (Number.isFinite(first)) emit(column, yFromPrice(first));
5947
+ if (Number.isFinite(second) && second !== first) emit(column, yFromPrice(second));
5948
+ lastPrice = plan.toPrice(maxIndex >= minIndex ? maxValue : minValue);
5949
+ };
5950
+ for (let index = startIndex; index <= endIndex; index += 1) {
5951
+ const value = plan.aligned[index];
5952
+ if (value === void 0 || !Number.isFinite(value)) continue;
5953
+ const nextColumn = Math.round(xForIndex(index));
5954
+ if (!hasColumn || nextColumn !== column) {
5955
+ flushColumn();
5956
+ column = nextColumn;
5957
+ minValue = value;
5958
+ maxValue = value;
5959
+ minIndex = index;
5960
+ maxIndex = index;
5961
+ hasColumn = true;
5962
+ continue;
5963
+ }
5964
+ if (value < minValue) {
5965
+ minValue = value;
5966
+ minIndex = index;
5967
+ }
5968
+ if (value > maxValue) {
5969
+ maxValue = value;
5970
+ maxIndex = index;
5971
+ }
5972
+ }
5973
+ flushColumn();
5974
+ } else {
5975
+ for (let index = startIndex; index <= endIndex; index += 1) {
5976
+ const value = plan.aligned[index];
5977
+ if (value === void 0 || !Number.isFinite(value)) continue;
5978
+ const price = plan.toPrice(value);
5979
+ if (!Number.isFinite(price)) continue;
5980
+ lastPrice = price;
5981
+ emit(xForIndex(index), yFromPrice(price));
5982
+ }
5983
+ }
5984
+ if (!started) continue;
5985
+ if (plan.state.options.style === "area") {
5986
+ const fillPath = new Path2D(path);
5987
+ fillPath.lineTo(lastX, chartBottom);
5988
+ fillPath.lineTo(firstX, chartBottom);
5989
+ fillPath.closePath();
5990
+ ctx.save();
5991
+ ctx.globalAlpha = Math.max(0, Math.min(1, mergedOptions.areaFillOpacity)) * 0.6;
5992
+ ctx.fillStyle = color;
5993
+ ctx.fill(fillPath);
5994
+ ctx.restore();
5995
+ }
5996
+ ctx.save();
5997
+ ctx.strokeStyle = color;
5998
+ ctx.lineWidth = lineWidth;
5999
+ ctx.lineJoin = "round";
6000
+ ctx.stroke(path);
6001
+ ctx.restore();
6002
+ if (Number.isFinite(lastPrice)) {
6003
+ const label = plan.state.options.label ?? plan.state.options.id;
6004
+ const nativeLast = plan.lastNativeValue;
6005
+ const usePercentTag = plan.usePercent && plan.baseCompare > 0 && Number.isFinite(nativeLast);
6006
+ const changePct = usePercentTag ? (nativeLast / plan.baseCompare - 1) * 100 : 0;
6007
+ const shortText = usePercentTag ? `${changePct >= 0 ? "+" : ""}${changePct.toFixed(2)}%` : formatPrice(nativeLast);
6008
+ compareAxisTags.push({ y: lastY, text: `${label} ${shortText}`, shortText, color });
6009
+ }
6010
+ }
5708
6011
  const activeOverlayIndicators = indicators.filter((indicator) => indicator.visible).map((indicator) => ({ indicator, plugin: indicatorRegistry.get(indicator.type) })).filter(
5709
6012
  (value) => value.plugin !== void 0 && (value.indicator.pane ?? value.plugin.pane ?? "overlay") === "overlay"
5710
6013
  ).sort((a, b) => a.indicator.zIndex - b.indicator.zIndex);
@@ -6479,6 +6782,35 @@ function createChart(element, options = {}) {
6479
6782
  drawText(countdownText, chartRight + 6, (fullChartBottom + height) / 2, "left", "middle", xAxis.textColor);
6480
6783
  ctx.font = prevFont;
6481
6784
  }
6785
+ if (compareAxisTags.length > 0 && width - chartRight > 0) {
6786
+ const prevFont = ctx.font;
6787
+ const tagFontSize = Math.max(9, (resolvedAxis.fontSize ?? 12) - 2);
6788
+ ctx.font = `${tagFontSize}px ${mergedOptions.fontFamily}`;
6789
+ ctx.textBaseline = "middle";
6790
+ ctx.textAlign = "left";
6791
+ const placed = [];
6792
+ const tagHeight = tagFontSize + 6;
6793
+ const gutterWidth = width - chartRight - 4;
6794
+ for (const tag of [...compareAxisTags].sort((a, b) => a.y - b.y)) {
6795
+ const text = measureTextWidth(tag.text) + 10 <= gutterWidth ? tag.text : tag.shortText;
6796
+ const tagWidth = Math.min(gutterWidth, measureTextWidth(text) + 10);
6797
+ if (tagWidth <= 0) continue;
6798
+ let tagY = clamp(tag.y - tagHeight / 2, chartTop, chartBottom - tagHeight);
6799
+ for (const slot of placed) {
6800
+ if (tagY < slot.bottom + 2 && tagY + tagHeight > slot.top - 2) {
6801
+ tagY = slot.bottom + 2;
6802
+ }
6803
+ }
6804
+ placed.push({ top: tagY, bottom: tagY + tagHeight });
6805
+ ctx.save();
6806
+ ctx.fillStyle = tag.color;
6807
+ fillRoundedRect(chartRight + 2, Math.round(tagY), Math.round(tagWidth), tagHeight, 3);
6808
+ ctx.fillStyle = labelTextColorOn(tag.color, "#ffffff");
6809
+ ctx.fillText(text, chartRight + 7, Math.round(tagY + tagHeight / 2));
6810
+ ctx.restore();
6811
+ }
6812
+ ctx.font = prevFont;
6813
+ }
6482
6814
  if (baseCtx) {
6483
6815
  if (baseCanvas.width !== canvas.width || baseCanvas.height !== canvas.height) {
6484
6816
  baseCanvas.width = canvas.width;
@@ -9580,6 +9912,10 @@ function createChart(element, options = {}) {
9580
9912
  getMagnetMode,
9581
9913
  setPriceScale,
9582
9914
  getPriceScale,
9915
+ setCompareSeries,
9916
+ addCompareSeries,
9917
+ removeCompareSeries,
9918
+ getCompareSeries,
9583
9919
  cancelDrawing,
9584
9920
  setTradeMarkers,
9585
9921
  setSelectedDrawing,
@@ -80,6 +80,7 @@ interface ChartOptions {
80
80
  doubleClickAction?: "reset" | "placeLimitOrder";
81
81
  keyboard?: KeyboardOptions;
82
82
  accessibility?: AccessibilityOptions;
83
+ downsampling?: DownsamplingOptions;
83
84
  crosshair?: CrosshairOptions;
84
85
  grid?: GridOptions;
85
86
  watermark?: WatermarkOptions;
@@ -552,6 +553,45 @@ interface KeyboardOptions {
552
553
  /** Delete/Backspace removes the selected drawing. Default true. */
553
554
  deleteSelectedDrawing?: boolean;
554
555
  }
556
+ /**
557
+ * Deep zoom-out rendering. Once bars are narrower than `thresholdPx`, several
558
+ * of them share a pixel column and drawing each one is wasted work, so the
559
+ * chart aggregates every column into one min/max bucket: path operations then
560
+ * scale with the chart's width instead of the number of bars. Extremes are
561
+ * preserved exactly (a spike never disappears), which is why this uses
562
+ * min/max rather than sampling.
563
+ */
564
+ interface DownsamplingOptions {
565
+ /** Default true. */
566
+ enabled?: boolean;
567
+ /** Bar width in pixels below which columns are aggregated. Default 1.5. */
568
+ thresholdPx?: number;
569
+ }
570
+ /**
571
+ * An extra instrument overlaid on the main pane ("compare" in TradingView).
572
+ * The host owns the data and keeps it fresh; the chart aligns it to the main
573
+ * series by timestamp and draws it.
574
+ */
575
+ interface CompareSeriesOptions {
576
+ id: string;
577
+ /** Shown on the right-axis tag, e.g. "NQ1!". */
578
+ label?: string;
579
+ /** Bars for the compared instrument; aligned to the main series by time. */
580
+ data: OhlcDataPoint[];
581
+ color?: string;
582
+ lineWidth?: number;
583
+ style?: "line" | "area";
584
+ /**
585
+ * "percent" (default) normalises both instruments to their first visible
586
+ * bar so shapes can be compared regardless of nominal price — the same
587
+ * thing TradingView does when you add a comparison. "price" plots the raw
588
+ * values on the main scale, which only makes sense for related instruments.
589
+ */
590
+ scale?: "percent" | "price";
591
+ visible?: boolean;
592
+ /** Let this series widen the price scale. Default true. */
593
+ includeInAutoScale?: boolean;
594
+ }
555
595
  interface AccessibilityOptions {
556
596
  /** aria-label on the canvas. Default "Price chart". */
557
597
  label?: string;
@@ -708,6 +748,17 @@ interface ChartInstance {
708
748
  */
709
749
  setPriceScale: (options: Partial<PriceScaleOptions>) => void;
710
750
  getPriceScale: () => PriceScaleOptions;
751
+ /**
752
+ * Overlay other instruments on the main pane for comparison. Series are
753
+ * aligned to the main series by timestamp (last known value carries forward
754
+ * across gaps) and, by default, normalised to percent change from the first
755
+ * visible bar so differently-priced instruments stay comparable. Data is not
756
+ * part of `saveState()` — the host re-supplies it.
757
+ */
758
+ setCompareSeries: (series: CompareSeriesOptions[]) => void;
759
+ addCompareSeries: (series: CompareSeriesOptions) => void;
760
+ removeCompareSeries: (id: string) => void;
761
+ getCompareSeries: () => CompareSeriesOptions[];
711
762
  cancelDrawing: () => boolean;
712
763
  setTradeMarkers: (markers: TradeMarkerOptions[]) => void;
713
764
  onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
@@ -897,4 +948,4 @@ declare const compileScriptIndicator: (definition: ScriptIndicatorDefinition) =>
897
948
 
898
949
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
899
950
 
900
- export { type AccessibilityOptions, type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartOptions, type ChartSavedState, type ChartType, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type KeyboardOptions, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, SCRIPT_SOURCE_INPUT_VALUES, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type TickerLineOptions, type TradeMarkerOptions, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, validateScriptSource };
951
+ export { type AccessibilityOptions, type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartOptions, type ChartSavedState, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type KeyboardOptions, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, SCRIPT_SOURCE_INPUT_VALUES, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type TickerLineOptions, type TradeMarkerOptions, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, validateScriptSource };