@pipsend/charts 2.3.3 → 2.3.10

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.
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @license
3
- * Pipsend Charts v2.3.3
3
+ * Pipsend Charts v2.3.10
4
4
  * Copyright (c) 2026 Pipsend
5
5
  * Licensed under MIT License
6
6
  * Built on TradingView Lightweight Charts™ (Apache 2.0)
@@ -2483,14 +2483,8 @@ class SeriesBarColorer {
2483
2483
  return this._private__styleGetter(this._private__findBar, this._private__series._internal_options(), barIndex, precomputedBars);
2484
2484
  }
2485
2485
  /**
2486
- * Like `barStyle`, but returns null instead of throwing when the bar is
2487
- * gone.
2488
- *
2489
- * Recolouring walks items that were laid out against the data as it was. A
2490
- * bar that has since disappeared is not an error there: the view is about
2491
- * to be rebuilt from the new data anyway. Letting it throw took down
2492
- * whatever asked for the repaint — including `setData`, which left the
2493
- * series without its data and the pane empty until the page was reloaded.
2486
+ * Like `barStyle`, but null instead of throwing when the bar is gone, which
2487
+ * a recolour of items laid out against older data can hit.
2494
2488
  */
2495
2489
  _internal_barStyleOrNull(barIndex, precomputedBars) {
2496
2490
  if (precomputedBars === undefined && this._private__series._internal_bars()._internal_valueAt(barIndex) === null) {
@@ -2892,7 +2886,10 @@ class SeriesPrimitivePriceAxisViewWrapper extends PriceAxisView {
2892
2886
  commonRendererData._internal_additionalPaddingTop = additionalPadding;
2893
2887
  commonRendererData._internal_additionalPaddingBottom = additionalPadding;
2894
2888
  commonRendererData._internal_coordinate = data._internal_coordinate;
2895
- commonRendererData._internal_fixedCoordinate = data._internal_fixedCoordinate;
2889
+ // Re-runs at draw time, after the axis has moved the label clear of overlaps.
2890
+ if (data._internal_fixedCoordinate !== undefined) {
2891
+ commonRendererData._internal_fixedCoordinate = data._internal_fixedCoordinate;
2892
+ }
2896
2893
  axisRendererData._internal_text = data._internal_text;
2897
2894
  axisRendererData._internal_visible = data._internal_visible;
2898
2895
  axisRendererData._internal_tickVisible = data._internal_tickVisible;
@@ -3769,7 +3766,6 @@ class PriceTickSpanCalculator {
3769
3766
  }
3770
3767
  }
3771
3768
 
3772
- const TICK_DENSITY = 2.5;
3773
3769
  class PriceTickMarkBuilder {
3774
3770
  constructor(priceScale, base, coordinateToLogicalFunc, logicalToCoordinateFunc) {
3775
3771
  this._private__marks = [];
@@ -3830,7 +3826,7 @@ class PriceTickMarkBuilder {
3830
3826
  return this._private__priceScale._internal_fontSize();
3831
3827
  }
3832
3828
  _private__tickMarkHeight() {
3833
- return Math.ceil(this._private__fontHeight() * TICK_DENSITY);
3829
+ return Math.max(1, Math.ceil(this._private__fontHeight() * this._private__priceScale._internal_options().tickMarkSpacing));
3834
3830
  }
3835
3831
  _private__updateMarks(firstValue, span, high, low, minCoord, maxCoord) {
3836
3832
  const marks = this._private__marks;
@@ -3995,6 +3991,9 @@ class PriceScale {
3995
3991
  this._private__invalidateInternalHeightCache();
3996
3992
  this._private__marksCache = null;
3997
3993
  }
3994
+ if (options.tickMarkSpacing !== undefined) {
3995
+ this._private__marksCache = null;
3996
+ }
3998
3997
  }
3999
3998
  _internal_isAutoScale() {
4000
3999
  return this._private__options.autoScale;
@@ -5172,6 +5171,9 @@ class TickMarks {
5172
5171
  this._private__uniformDistribution = val;
5173
5172
  this._private__cache = null;
5174
5173
  }
5174
+ _internal_invalidate() {
5175
+ this._private__cache = null;
5176
+ }
5175
5177
  _internal_setTimeScalePoints(newPoints, firstChangedPointIndex) {
5176
5178
  this._private__removeMarksSinceIndex(firstChangedPointIndex);
5177
5179
  this._private__cache = null;
@@ -5190,7 +5192,7 @@ class TickMarks {
5190
5192
  });
5191
5193
  }
5192
5194
  }
5193
- _internal_build(spacing, maxWidth, checkIndicesForData, indicesWithDataMap, indicesWithDataId) {
5195
+ _internal_build(spacing, maxWidth, checkIndicesForData, indicesWithDataMap, indicesWithDataId, allows = () => true) {
5194
5196
  const maxIndexesPerMark = Math.ceil(maxWidth / spacing);
5195
5197
  if (this._private__cache === null ||
5196
5198
  this._private__cache._internal_maxIndexesPerMark !== maxIndexesPerMark ||
@@ -5199,7 +5201,7 @@ class TickMarks {
5199
5201
  this._private__cache = {
5200
5202
  _internal_indicesWithDataId: indicesWithDataId,
5201
5203
  _internal_checkIndicesForData: checkIndicesForData,
5202
- _internal_marks: this._private__buildMarksImpl(maxIndexesPerMark, checkIndicesForData, indicesWithDataMap),
5204
+ _internal_marks: this._private__buildMarksImpl(maxIndexesPerMark, checkIndicesForData, indicesWithDataMap, allows),
5203
5205
  _internal_maxIndexesPerMark: maxIndexesPerMark,
5204
5206
  };
5205
5207
  }
@@ -5223,7 +5225,7 @@ class TickMarks {
5223
5225
  this._private__marksByWeight.delete(weight);
5224
5226
  }
5225
5227
  }
5226
- _private__buildMarksImpl(maxIndexesPerMark, checkIndicesForData, indicesWithDataMap) {
5228
+ _private__buildMarksImpl(maxIndexesPerMark, checkIndicesForData, indicesWithDataMap, allows) {
5227
5229
  let marks = [];
5228
5230
  const canBeIncluded = (mark) => !checkIndicesForData || indicesWithDataMap.has(mark.index);
5229
5231
  for (const weight of Array.from(this._private__marksByWeight.keys()).sort((a, b) => b - a)) {
@@ -5241,6 +5243,11 @@ class TickMarks {
5241
5243
  let leftIndex = -Infinity;
5242
5244
  for (let i = 0; i < currentWeightLength; i++) {
5243
5245
  const mark = currentWeight[i];
5246
+ // Skipped before the fit check: a rejected mark must not count as one
5247
+ // that did not fit, which with uniform distribution drops its whole weight.
5248
+ if (!allows(mark, maxIndexesPerMark)) {
5249
+ continue;
5250
+ }
5244
5251
  const currentIndex = mark.index;
5245
5252
  // Determine indexes with which current index will be compared
5246
5253
  // All marks to the right is moved to new array
@@ -5547,7 +5554,7 @@ class TimeScale {
5547
5554
  const visibleBars = ensureNotNull(this._internal_visibleStrictRange());
5548
5555
  const firstBar = Math.max(visibleBars._internal_left(), visibleBars._internal_left() - indexPerLabel);
5549
5556
  const lastBar = Math.max(visibleBars._internal_right(), visibleBars._internal_right() - indexPerLabel);
5550
- const items = this._private__tickMarks._internal_build(spacing, maxLabelWidth, this._private__options.ignoreWhitespaceIndices, this._private__indicesWithData, this._private__indicesWithDataUpdateId);
5557
+ const items = this._private__tickMarks._internal_build(spacing, maxLabelWidth, this._private__options.ignoreWhitespaceIndices, this._private__indicesWithData, this._private__indicesWithDataUpdateId, (mark, barsPerMark) => this._private__horzScaleBehavior.allowsTickMark?.(mark, barsPerMark) ?? true);
5551
5558
  // according to indexPerLabel value this value means "earliest index which _might be_ used as the second label on time scale"
5552
5559
  const earliestIndexOfSecondLabel = this._private__firstIndex() + indexPerLabel;
5553
5560
  // according to indexPerLabel value this value means "earliest index which _might be_ used as the second last label on time scale"
@@ -5925,6 +5932,7 @@ class TimeScale {
5925
5932
  _private__invalidateTickMarks() {
5926
5933
  this._private__resetTimeMarksCache();
5927
5934
  this._private__formattedByWeight.clear();
5935
+ this._private__tickMarks._internal_invalidate();
5928
5936
  }
5929
5937
  _private__updateDateTimeFormatter() {
5930
5938
  this._private__horzScaleBehavior.updateFormatter(this._private__localizationOptions);
@@ -7039,6 +7047,14 @@ class HorzScaleBehaviorTime {
7039
7047
  const tp = item;
7040
7048
  return this._private__dateTimeFormatter._internal_format(new Date(tp._internal_timestamp * 1000));
7041
7049
  }
7050
+ allowsTickMark(tickMark, barsPerMark) {
7051
+ const filter = this._private__options.timeScale.tickMarkFilter;
7052
+ if (filter === undefined) {
7053
+ return true;
7054
+ }
7055
+ const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
7056
+ return filter(tickMark.originalTime, tickMarkType, barsPerMark);
7057
+ }
7042
7058
  formatTickmark(tickMark, localizationOptions) {
7043
7059
  const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
7044
7060
  const options = this._private__options.timeScale;
@@ -11443,9 +11459,6 @@ class SeriesPaneViewBase {
11443
11459
  _internal__updateOptions() {
11444
11460
  const colorer = this._internal__series._internal_barColorer();
11445
11461
  this._internal__items = this._internal__items.map((item) => {
11446
- // An item whose bar is gone keeps the colour it had. Throwing here
11447
- // took down whatever asked for the repaint — `setData` among them,
11448
- // which left the series without its data and the pane empty.
11449
11462
  const style = colorer._internal_barStyleOrNull(item._internal_time);
11450
11463
  return style === null ? item : { ...item, ...style };
11451
11464
  });
@@ -11525,7 +11538,7 @@ class SeriesCustomPaneView extends SeriesPaneViewBase {
11525
11538
  return {
11526
11539
  _internal_time: row._internal_index,
11527
11540
  _internal_x: NaN,
11528
- ...colorer._internal_barStyle(row._internal_index),
11541
+ ...colorer._internal_barStyle(row._internal_index, { _internal_value: row }),
11529
11542
  _internal_originalData: row._internal_data,
11530
11543
  };
11531
11544
  });
@@ -11748,6 +11761,7 @@ const priceScaleOptionsDefaults = {
11748
11761
  },
11749
11762
  minimumWidth: 0,
11750
11763
  ensureEdgeTickMarksVisible: false,
11764
+ tickMarkSpacing: 2.5,
11751
11765
  };
11752
11766
 
11753
11767
  const timeScaleOptionsDefaults = {
@@ -12843,7 +12857,7 @@ class LinePaneViewBase extends SeriesPaneViewBase {
12843
12857
  const colorer = this._internal__series._internal_barColorer();
12844
12858
  this._internal__items = this._internal__series._internal_bars()._internal_rows().map((row) => {
12845
12859
  const value = row._internal_value[3 /* PlotRowValueIndex.Close */];
12846
- return this._internal__createRawItem(row._internal_index, value, colorer);
12860
+ return this._internal__createRawItem(row._internal_index, value, colorer, row);
12847
12861
  });
12848
12862
  }
12849
12863
  }
@@ -12865,10 +12879,10 @@ styleGetter) {
12865
12879
  if (point) {
12866
12880
  const style = styleGetter(renderingScope, point);
12867
12881
  if (style !== prevStyle) {
12868
- context.beginPath();
12869
12882
  if (prevStyle !== null) {
12870
12883
  context.fill();
12871
12884
  }
12885
+ context.beginPath();
12872
12886
  context.fillStyle = style;
12873
12887
  prevStyle = style;
12874
12888
  }
@@ -13011,10 +13025,10 @@ class SeriesLinePaneView extends LinePaneViewBase {
13011
13025
  super(...arguments);
13012
13026
  this._internal__renderer = new PaneRendererLine();
13013
13027
  }
13014
- _internal__createRawItem(time, price, colorer) {
13028
+ _internal__createRawItem(time, price, colorer, row) {
13015
13029
  return {
13016
13030
  ...this._internal__createRawItemBase(time, price),
13017
- ...colorer._internal_barStyle(time),
13031
+ ...colorer._internal_barStyle(time, { _internal_value: row }),
13018
13032
  };
13019
13033
  }
13020
13034
  _internal__prepareRendererData() {
@@ -13488,10 +13502,10 @@ class SeriesBaselinePaneView extends LinePaneViewBase {
13488
13502
  this._private__baselineLineRenderer = new PaneRendererBaselineLine();
13489
13503
  this._internal__renderer._internal_setRenderers([this._private__baselineAreaRenderer, this._private__baselineLineRenderer]);
13490
13504
  }
13491
- _internal__createRawItem(time, price, colorer) {
13505
+ _internal__createRawItem(time, price, colorer, row) {
13492
13506
  return {
13493
13507
  ...this._internal__createRawItemBase(time, price),
13494
- ...colorer._internal_barStyle(time),
13508
+ ...colorer._internal_barStyle(time, { _internal_value: row }),
13495
13509
  };
13496
13510
  }
13497
13511
  _internal__prepareRendererData() {
@@ -13611,10 +13625,10 @@ class SeriesAreaPaneView extends LinePaneViewBase {
13611
13625
  this._private__lineRenderer = new PaneRendererLine();
13612
13626
  this._internal__renderer._internal_setRenderers([this._private__areaRenderer, this._private__lineRenderer]);
13613
13627
  }
13614
- _internal__createRawItem(time, price, colorer) {
13628
+ _internal__createRawItem(time, price, colorer, row) {
13615
13629
  return {
13616
13630
  ...this._internal__createRawItemBase(time, price),
13617
- ...colorer._internal_barStyle(time),
13631
+ ...colorer._internal_barStyle(time, { _internal_value: row }),
13618
13632
  };
13619
13633
  }
13620
13634
  _internal__prepareRendererData() {
@@ -13819,7 +13833,7 @@ class SeriesBarsPaneView extends BarsPaneViewBase {
13819
13833
  _internal__createRawItem(time, bar, colorer) {
13820
13834
  return {
13821
13835
  ...this._internal__createDefaultItem(time, bar, colorer),
13822
- ...colorer._internal_barStyle(time),
13836
+ ...colorer._internal_barStyle(time, { _internal_value: bar }),
13823
13837
  };
13824
13838
  }
13825
13839
  _internal__prepareRendererData() {
@@ -14012,7 +14026,7 @@ class SeriesCandlesticksPaneView extends BarsPaneViewBase {
14012
14026
  _internal__createRawItem(time, bar, colorer) {
14013
14027
  return {
14014
14028
  ...this._internal__createDefaultItem(time, bar, colorer),
14015
- ...colorer._internal_barStyle(time),
14029
+ ...colorer._internal_barStyle(time, { _internal_value: bar }),
14016
14030
  };
14017
14031
  }
14018
14032
  _internal__prepareRendererData() {
@@ -14180,10 +14194,10 @@ class SeriesHistogramPaneView extends LinePaneViewBase {
14180
14194
  super(...arguments);
14181
14195
  this._internal__renderer = new PaneRendererHistogram();
14182
14196
  }
14183
- _internal__createRawItem(time, price, colorer) {
14197
+ _internal__createRawItem(time, price, colorer, row) {
14184
14198
  return {
14185
14199
  ...this._internal__createRawItemBase(time, price),
14186
- ...colorer._internal_barStyle(time),
14200
+ ...colorer._internal_barStyle(time, { _internal_value: row }),
14187
14201
  };
14188
14202
  }
14189
14203
  _internal__prepareRendererData() {
@@ -17877,7 +17891,7 @@ function applyHeikinAshi(series, chart, options = {}) {
17877
17891
  hideSource: options.hideSource ?? true,
17878
17892
  };
17879
17893
  const sourceOptions = series.options();
17880
- // Same price scale and the same formatting as the source: the candles are a
17894
+ // Same price scale, formatting and axis labels as the source: the candles are a
17881
17895
  // restatement of that series, not a second instrument, so they must not
17882
17896
  // autoscale on their own axis or round to a different precision.
17883
17897
  const haSeries = chart.addSeries(candlestickSeries, {
@@ -17891,6 +17905,8 @@ function applyHeikinAshi(series, chart, options = {}) {
17891
17905
  wickDownColor: resolved.wickDownColor,
17892
17906
  priceScaleId: sourceOptions.priceScaleId,
17893
17907
  priceFormat: sourceOptions.priceFormat,
17908
+ lastValueVisible: sourceOptions.lastValueVisible,
17909
+ priceLineVisible: sourceOptions.priceLineVisible,
17894
17910
  }, resolved.paneIndex);
17895
17911
  let restoreSourcePaint = null;
17896
17912
  const blankSource = (blank) => {
@@ -18092,12 +18108,14 @@ function applyMACD(series, chart, options = {}) {
18092
18108
  const macdSeries = chart.addSeries(lineSeries, {
18093
18109
  color: resolved.colorMACD,
18094
18110
  }, paneIndex);
18111
+ // An index past the last pane opens a new one, so the rest follow MACD to where it landed.
18112
+ const macdPane = paneIndexOf(chart, macdSeries, paneIndex);
18095
18113
  const signalSeries = chart.addSeries(lineSeries, {
18096
18114
  color: resolved.colorSignal,
18097
- }, paneIndex);
18115
+ }, macdPane);
18098
18116
  const histogramSeries$1 = chart.addSeries(histogramSeries, {
18099
18117
  color: resolved.colorHistogramUp,
18100
- }, paneIndex);
18118
+ }, macdPane);
18101
18119
  // Calculate EMA
18102
18120
  const calculateEMA = (prices, period) => {
18103
18121
  const ema = [];
@@ -18229,13 +18247,13 @@ function applyStochastic(series, chart, options = {}) {
18229
18247
  // Stochastic is bounded to 0-100; pinning it keeps the pane readable
18230
18248
  autoscaleInfoProvider: boundedScale,
18231
18249
  }, paneIndex);
18250
+ // An index past the last pane opens a new one, so %D follows %K to where it landed.
18251
+ const scalePane = paneIndexOf(chart, kSeries, paneIndex);
18232
18252
  // Create %D line (slow - signal)
18233
18253
  const dSeries = chart.addSeries(lineSeries, {
18234
18254
  color: resolved.colorD,
18235
18255
  autoscaleInfoProvider: boundedScale,
18236
- }, paneIndex);
18237
- // The pane the series landed in, which is not always the one asked for.
18238
- const scalePane = paneIndexOf(chart, kSeries, paneIndex);
18256
+ }, scalePane);
18239
18257
  chart.priceScale(kSeries.options().priceScaleId ?? 'right', scalePane).applyOptions({
18240
18258
  scaleMargins: {
18241
18259
  top: 0.1,
@@ -18577,15 +18595,16 @@ function applyADX(series, chart, options = {}) {
18577
18595
  color: resolved.colorADX,
18578
18596
  autoscaleInfoProvider: boundedScale,
18579
18597
  }, paneIndex);
18598
+ // An index past the last pane opens a new one, so the DI lines follow ADX to where it landed.
18599
+ const scalePane = paneIndexOf(chart, adxSeries, paneIndex);
18580
18600
  const plusSeries = chart.addSeries(lineSeries, {
18581
18601
  color: resolved.colorPlusDI,
18582
18602
  autoscaleInfoProvider: boundedScale,
18583
- }, paneIndex);
18603
+ }, scalePane);
18584
18604
  const minusSeries = chart.addSeries(lineSeries, {
18585
18605
  color: resolved.colorMinusDI,
18586
18606
  autoscaleInfoProvider: boundedScale,
18587
- }, paneIndex);
18588
- const scalePane = paneIndexOf(chart, adxSeries, paneIndex);
18607
+ }, scalePane);
18589
18608
  chart.priceScale(adxSeries.options().priceScaleId ?? 'right', scalePane).applyOptions({
18590
18609
  scaleMargins: {
18591
18610
  top: 0.1,
@@ -30998,7 +31017,7 @@ const customSeriesDefaultOptions = {
30998
31017
  * Returns the current version as a string. For example `'1.0.0'`.
30999
31018
  */
31000
31019
  function version() {
31001
- return "2.3.3";
31020
+ return "2.3.10";
31002
31021
  }
31003
31022
 
31004
31023
  export { areaSeries as AreaSeries, ArrowTool, barSeries as BarSeries, baselineSeries as BaselineSeries, BrushTool, candlestickSeries as CandlestickSeries, CircleTool, ColorType, CrossLineTool, CrosshairMode, DEFAULT_SESSIONS, DraggablePriceLine, DrawingToolsManager, EXTENDED_FIBONACCI_RATIOS, FibonacciCalculator, FibonacciExtensionTool, FibonacciFanTool, FibonacciTool, GanttTool, histogramSeries as HistogramSeries, HorizontalLineTool, InteractiveLineManager, LastPriceAnimationMode, lineSeries as LineSeries, LineStyle, LineType, MismatchDirection, ParallelChannelTool, PitchforkTool, PolygonTool, PositionCalculator, PositionLine, PositionMarkersManager, PositionTool, PriceLineSource, PriceScaleMode, RectangleTool, RulerCalculator, RulerTool, STANDARD_FIBONACCI_RATIOS, TextTool, TickMarkType, TrackingModeExitMode, TradingSessionsIndicator, TrendLineTool, VerticalLineTool, VolumeProfileIndicator, applyADX, applyATR, applyBollingerBands, applyCCI, applyDonchianChannels, applyEMA, applyHeikinAshi, applyIchimoku, applyKeltnerChannels, applyMACD, applyMFI, applyOBV, applyParabolicSAR, applyPivotPoints, applyRSI, applySMA, applyStochastic, applySuperTrend, applyVWAP, applyVolume, applyWMA, applyWilliamsR, calculateHeikinAshi, calculatePipConfig, coordinateFromTime, createArrowTool, createBrushTool, createChart, createChartEx, createCircleTool, createCrossLineTool, createFibonacciExtensionTool, createFibonacciFanTool, createFibonacciTool, createGanttTool, createHorizontalLineTool, createImageWatermark, createInteractiveLineManager, createOptionsChart, createParallelChannelTool, createPitchforkTool, createPolygonTool, createPositionLine, createPositionMarkers, createPositionTool, createRectangleTool, createRulerTool, createSeriesMarkers, createTextTool, createTextWatermark, createTradingLine, createTradingSessionsIndicator, createTrendLineTool, createUpDownMarkers, createVerticalLineTool, createVolumeProfileIndicator, createYieldCurveChart, customSeriesDefaultOptions, defaultHorzScaleBehavior, getPipConfig, hideSeriesPaint, isBusinessDay, isUTCTimestamp, setSeriesVolumes, setVolumeProfileData, timeFromCoordinate, version };