@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)
@@ -2485,14 +2485,8 @@ class SeriesBarColorer {
2485
2485
  return this._private__styleGetter(this._private__findBar, this._private__series._internal_options(), barIndex, precomputedBars);
2486
2486
  }
2487
2487
  /**
2488
- * Like `barStyle`, but returns null instead of throwing when the bar is
2489
- * gone.
2490
- *
2491
- * Recolouring walks items that were laid out against the data as it was. A
2492
- * bar that has since disappeared is not an error there: the view is about
2493
- * to be rebuilt from the new data anyway. Letting it throw took down
2494
- * whatever asked for the repaint — including `setData`, which left the
2495
- * series without its data and the pane empty until the page was reloaded.
2488
+ * Like `barStyle`, but null instead of throwing when the bar is gone, which
2489
+ * a recolour of items laid out against older data can hit.
2496
2490
  */
2497
2491
  _internal_barStyleOrNull(barIndex, precomputedBars) {
2498
2492
  if (precomputedBars === undefined && this._private__series._internal_bars()._internal_valueAt(barIndex) === null) {
@@ -2894,7 +2888,10 @@ class SeriesPrimitivePriceAxisViewWrapper extends PriceAxisView {
2894
2888
  commonRendererData._internal_additionalPaddingTop = additionalPadding;
2895
2889
  commonRendererData._internal_additionalPaddingBottom = additionalPadding;
2896
2890
  commonRendererData._internal_coordinate = data._internal_coordinate;
2897
- commonRendererData._internal_fixedCoordinate = data._internal_fixedCoordinate;
2891
+ // Re-runs at draw time, after the axis has moved the label clear of overlaps.
2892
+ if (data._internal_fixedCoordinate !== undefined) {
2893
+ commonRendererData._internal_fixedCoordinate = data._internal_fixedCoordinate;
2894
+ }
2898
2895
  axisRendererData._internal_text = data._internal_text;
2899
2896
  axisRendererData._internal_visible = data._internal_visible;
2900
2897
  axisRendererData._internal_tickVisible = data._internal_tickVisible;
@@ -3771,7 +3768,6 @@ class PriceTickSpanCalculator {
3771
3768
  }
3772
3769
  }
3773
3770
 
3774
- const TICK_DENSITY = 2.5;
3775
3771
  class PriceTickMarkBuilder {
3776
3772
  constructor(priceScale, base, coordinateToLogicalFunc, logicalToCoordinateFunc) {
3777
3773
  this._private__marks = [];
@@ -3832,7 +3828,7 @@ class PriceTickMarkBuilder {
3832
3828
  return this._private__priceScale._internal_fontSize();
3833
3829
  }
3834
3830
  _private__tickMarkHeight() {
3835
- return Math.ceil(this._private__fontHeight() * TICK_DENSITY);
3831
+ return Math.max(1, Math.ceil(this._private__fontHeight() * this._private__priceScale._internal_options().tickMarkSpacing));
3836
3832
  }
3837
3833
  _private__updateMarks(firstValue, span, high, low, minCoord, maxCoord) {
3838
3834
  const marks = this._private__marks;
@@ -3997,6 +3993,9 @@ class PriceScale {
3997
3993
  this._private__invalidateInternalHeightCache();
3998
3994
  this._private__marksCache = null;
3999
3995
  }
3996
+ if (options.tickMarkSpacing !== undefined) {
3997
+ this._private__marksCache = null;
3998
+ }
4000
3999
  }
4001
4000
  _internal_isAutoScale() {
4002
4001
  return this._private__options.autoScale;
@@ -5174,6 +5173,9 @@ class TickMarks {
5174
5173
  this._private__uniformDistribution = val;
5175
5174
  this._private__cache = null;
5176
5175
  }
5176
+ _internal_invalidate() {
5177
+ this._private__cache = null;
5178
+ }
5177
5179
  _internal_setTimeScalePoints(newPoints, firstChangedPointIndex) {
5178
5180
  this._private__removeMarksSinceIndex(firstChangedPointIndex);
5179
5181
  this._private__cache = null;
@@ -5192,7 +5194,7 @@ class TickMarks {
5192
5194
  });
5193
5195
  }
5194
5196
  }
5195
- _internal_build(spacing, maxWidth, checkIndicesForData, indicesWithDataMap, indicesWithDataId) {
5197
+ _internal_build(spacing, maxWidth, checkIndicesForData, indicesWithDataMap, indicesWithDataId, allows = () => true) {
5196
5198
  const maxIndexesPerMark = Math.ceil(maxWidth / spacing);
5197
5199
  if (this._private__cache === null ||
5198
5200
  this._private__cache._internal_maxIndexesPerMark !== maxIndexesPerMark ||
@@ -5201,7 +5203,7 @@ class TickMarks {
5201
5203
  this._private__cache = {
5202
5204
  _internal_indicesWithDataId: indicesWithDataId,
5203
5205
  _internal_checkIndicesForData: checkIndicesForData,
5204
- _internal_marks: this._private__buildMarksImpl(maxIndexesPerMark, checkIndicesForData, indicesWithDataMap),
5206
+ _internal_marks: this._private__buildMarksImpl(maxIndexesPerMark, checkIndicesForData, indicesWithDataMap, allows),
5205
5207
  _internal_maxIndexesPerMark: maxIndexesPerMark,
5206
5208
  };
5207
5209
  }
@@ -5225,7 +5227,7 @@ class TickMarks {
5225
5227
  this._private__marksByWeight.delete(weight);
5226
5228
  }
5227
5229
  }
5228
- _private__buildMarksImpl(maxIndexesPerMark, checkIndicesForData, indicesWithDataMap) {
5230
+ _private__buildMarksImpl(maxIndexesPerMark, checkIndicesForData, indicesWithDataMap, allows) {
5229
5231
  let marks = [];
5230
5232
  const canBeIncluded = (mark) => !checkIndicesForData || indicesWithDataMap.has(mark.index);
5231
5233
  for (const weight of Array.from(this._private__marksByWeight.keys()).sort((a, b) => b - a)) {
@@ -5243,6 +5245,11 @@ class TickMarks {
5243
5245
  let leftIndex = -Infinity;
5244
5246
  for (let i = 0; i < currentWeightLength; i++) {
5245
5247
  const mark = currentWeight[i];
5248
+ // Skipped before the fit check: a rejected mark must not count as one
5249
+ // that did not fit, which with uniform distribution drops its whole weight.
5250
+ if (!allows(mark, maxIndexesPerMark)) {
5251
+ continue;
5252
+ }
5246
5253
  const currentIndex = mark.index;
5247
5254
  // Determine indexes with which current index will be compared
5248
5255
  // All marks to the right is moved to new array
@@ -5549,7 +5556,7 @@ class TimeScale {
5549
5556
  const visibleBars = ensureNotNull(this._internal_visibleStrictRange());
5550
5557
  const firstBar = Math.max(visibleBars._internal_left(), visibleBars._internal_left() - indexPerLabel);
5551
5558
  const lastBar = Math.max(visibleBars._internal_right(), visibleBars._internal_right() - indexPerLabel);
5552
- const items = this._private__tickMarks._internal_build(spacing, maxLabelWidth, this._private__options.ignoreWhitespaceIndices, this._private__indicesWithData, this._private__indicesWithDataUpdateId);
5559
+ 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);
5553
5560
  // according to indexPerLabel value this value means "earliest index which _might be_ used as the second label on time scale"
5554
5561
  const earliestIndexOfSecondLabel = this._private__firstIndex() + indexPerLabel;
5555
5562
  // according to indexPerLabel value this value means "earliest index which _might be_ used as the second last label on time scale"
@@ -5927,6 +5934,7 @@ class TimeScale {
5927
5934
  _private__invalidateTickMarks() {
5928
5935
  this._private__resetTimeMarksCache();
5929
5936
  this._private__formattedByWeight.clear();
5937
+ this._private__tickMarks._internal_invalidate();
5930
5938
  }
5931
5939
  _private__updateDateTimeFormatter() {
5932
5940
  this._private__horzScaleBehavior.updateFormatter(this._private__localizationOptions);
@@ -7041,6 +7049,14 @@ class HorzScaleBehaviorTime {
7041
7049
  const tp = item;
7042
7050
  return this._private__dateTimeFormatter._internal_format(new Date(tp._internal_timestamp * 1000));
7043
7051
  }
7052
+ allowsTickMark(tickMark, barsPerMark) {
7053
+ const filter = this._private__options.timeScale.tickMarkFilter;
7054
+ if (filter === undefined) {
7055
+ return true;
7056
+ }
7057
+ const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
7058
+ return filter(tickMark.originalTime, tickMarkType, barsPerMark);
7059
+ }
7044
7060
  formatTickmark(tickMark, localizationOptions) {
7045
7061
  const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
7046
7062
  const options = this._private__options.timeScale;
@@ -11050,9 +11066,6 @@ class SeriesPaneViewBase {
11050
11066
  _internal__updateOptions() {
11051
11067
  const colorer = this._internal__series._internal_barColorer();
11052
11068
  this._internal__items = this._internal__items.map((item) => {
11053
- // An item whose bar is gone keeps the colour it had. Throwing here
11054
- // took down whatever asked for the repaint — `setData` among them,
11055
- // which left the series without its data and the pane empty.
11056
11069
  const style = colorer._internal_barStyleOrNull(item._internal_time);
11057
11070
  return style === null ? item : { ...item, ...style };
11058
11071
  });
@@ -11132,7 +11145,7 @@ class SeriesCustomPaneView extends SeriesPaneViewBase {
11132
11145
  return {
11133
11146
  _internal_time: row._internal_index,
11134
11147
  _internal_x: NaN,
11135
- ...colorer._internal_barStyle(row._internal_index),
11148
+ ...colorer._internal_barStyle(row._internal_index, { _internal_value: row }),
11136
11149
  _internal_originalData: row._internal_data,
11137
11150
  };
11138
11151
  });
@@ -11355,6 +11368,7 @@ const priceScaleOptionsDefaults = {
11355
11368
  },
11356
11369
  minimumWidth: 0,
11357
11370
  ensureEdgeTickMarksVisible: false,
11371
+ tickMarkSpacing: 2.5,
11358
11372
  };
11359
11373
 
11360
11374
  const timeScaleOptionsDefaults = {
@@ -12450,7 +12464,7 @@ class LinePaneViewBase extends SeriesPaneViewBase {
12450
12464
  const colorer = this._internal__series._internal_barColorer();
12451
12465
  this._internal__items = this._internal__series._internal_bars()._internal_rows().map((row) => {
12452
12466
  const value = row._internal_value[3 /* PlotRowValueIndex.Close */];
12453
- return this._internal__createRawItem(row._internal_index, value, colorer);
12467
+ return this._internal__createRawItem(row._internal_index, value, colorer, row);
12454
12468
  });
12455
12469
  }
12456
12470
  }
@@ -12472,10 +12486,10 @@ styleGetter) {
12472
12486
  if (point) {
12473
12487
  const style = styleGetter(renderingScope, point);
12474
12488
  if (style !== prevStyle) {
12475
- context.beginPath();
12476
12489
  if (prevStyle !== null) {
12477
12490
  context.fill();
12478
12491
  }
12492
+ context.beginPath();
12479
12493
  context.fillStyle = style;
12480
12494
  prevStyle = style;
12481
12495
  }
@@ -12618,10 +12632,10 @@ class SeriesLinePaneView extends LinePaneViewBase {
12618
12632
  super(...arguments);
12619
12633
  this._internal__renderer = new PaneRendererLine();
12620
12634
  }
12621
- _internal__createRawItem(time, price, colorer) {
12635
+ _internal__createRawItem(time, price, colorer, row) {
12622
12636
  return {
12623
12637
  ...this._internal__createRawItemBase(time, price),
12624
- ...colorer._internal_barStyle(time),
12638
+ ...colorer._internal_barStyle(time, { _internal_value: row }),
12625
12639
  };
12626
12640
  }
12627
12641
  _internal__prepareRendererData() {
@@ -13095,10 +13109,10 @@ class SeriesBaselinePaneView extends LinePaneViewBase {
13095
13109
  this._private__baselineLineRenderer = new PaneRendererBaselineLine();
13096
13110
  this._internal__renderer._internal_setRenderers([this._private__baselineAreaRenderer, this._private__baselineLineRenderer]);
13097
13111
  }
13098
- _internal__createRawItem(time, price, colorer) {
13112
+ _internal__createRawItem(time, price, colorer, row) {
13099
13113
  return {
13100
13114
  ...this._internal__createRawItemBase(time, price),
13101
- ...colorer._internal_barStyle(time),
13115
+ ...colorer._internal_barStyle(time, { _internal_value: row }),
13102
13116
  };
13103
13117
  }
13104
13118
  _internal__prepareRendererData() {
@@ -13218,10 +13232,10 @@ class SeriesAreaPaneView extends LinePaneViewBase {
13218
13232
  this._private__lineRenderer = new PaneRendererLine();
13219
13233
  this._internal__renderer._internal_setRenderers([this._private__areaRenderer, this._private__lineRenderer]);
13220
13234
  }
13221
- _internal__createRawItem(time, price, colorer) {
13235
+ _internal__createRawItem(time, price, colorer, row) {
13222
13236
  return {
13223
13237
  ...this._internal__createRawItemBase(time, price),
13224
- ...colorer._internal_barStyle(time),
13238
+ ...colorer._internal_barStyle(time, { _internal_value: row }),
13225
13239
  };
13226
13240
  }
13227
13241
  _internal__prepareRendererData() {
@@ -13426,7 +13440,7 @@ class SeriesBarsPaneView extends BarsPaneViewBase {
13426
13440
  _internal__createRawItem(time, bar, colorer) {
13427
13441
  return {
13428
13442
  ...this._internal__createDefaultItem(time, bar, colorer),
13429
- ...colorer._internal_barStyle(time),
13443
+ ...colorer._internal_barStyle(time, { _internal_value: bar }),
13430
13444
  };
13431
13445
  }
13432
13446
  _internal__prepareRendererData() {
@@ -13619,7 +13633,7 @@ class SeriesCandlesticksPaneView extends BarsPaneViewBase {
13619
13633
  _internal__createRawItem(time, bar, colorer) {
13620
13634
  return {
13621
13635
  ...this._internal__createDefaultItem(time, bar, colorer),
13622
- ...colorer._internal_barStyle(time),
13636
+ ...colorer._internal_barStyle(time, { _internal_value: bar }),
13623
13637
  };
13624
13638
  }
13625
13639
  _internal__prepareRendererData() {
@@ -13787,10 +13801,10 @@ class SeriesHistogramPaneView extends LinePaneViewBase {
13787
13801
  super(...arguments);
13788
13802
  this._internal__renderer = new PaneRendererHistogram();
13789
13803
  }
13790
- _internal__createRawItem(time, price, colorer) {
13804
+ _internal__createRawItem(time, price, colorer, row) {
13791
13805
  return {
13792
13806
  ...this._internal__createRawItemBase(time, price),
13793
- ...colorer._internal_barStyle(time),
13807
+ ...colorer._internal_barStyle(time, { _internal_value: row }),
13794
13808
  };
13795
13809
  }
13796
13810
  _internal__prepareRendererData() {
@@ -17484,7 +17498,7 @@ function applyHeikinAshi(series, chart, options = {}) {
17484
17498
  hideSource: options.hideSource ?? true,
17485
17499
  };
17486
17500
  const sourceOptions = series.options();
17487
- // Same price scale and the same formatting as the source: the candles are a
17501
+ // Same price scale, formatting and axis labels as the source: the candles are a
17488
17502
  // restatement of that series, not a second instrument, so they must not
17489
17503
  // autoscale on their own axis or round to a different precision.
17490
17504
  const haSeries = chart.addSeries(candlestickSeries, {
@@ -17498,6 +17512,8 @@ function applyHeikinAshi(series, chart, options = {}) {
17498
17512
  wickDownColor: resolved.wickDownColor,
17499
17513
  priceScaleId: sourceOptions.priceScaleId,
17500
17514
  priceFormat: sourceOptions.priceFormat,
17515
+ lastValueVisible: sourceOptions.lastValueVisible,
17516
+ priceLineVisible: sourceOptions.priceLineVisible,
17501
17517
  }, resolved.paneIndex);
17502
17518
  let restoreSourcePaint = null;
17503
17519
  const blankSource = (blank) => {
@@ -17699,12 +17715,14 @@ function applyMACD(series, chart, options = {}) {
17699
17715
  const macdSeries = chart.addSeries(lineSeries, {
17700
17716
  color: resolved.colorMACD,
17701
17717
  }, paneIndex);
17718
+ // An index past the last pane opens a new one, so the rest follow MACD to where it landed.
17719
+ const macdPane = paneIndexOf(chart, macdSeries, paneIndex);
17702
17720
  const signalSeries = chart.addSeries(lineSeries, {
17703
17721
  color: resolved.colorSignal,
17704
- }, paneIndex);
17722
+ }, macdPane);
17705
17723
  const histogramSeries$1 = chart.addSeries(histogramSeries, {
17706
17724
  color: resolved.colorHistogramUp,
17707
- }, paneIndex);
17725
+ }, macdPane);
17708
17726
  // Calculate EMA
17709
17727
  const calculateEMA = (prices, period) => {
17710
17728
  const ema = [];
@@ -17836,13 +17854,13 @@ function applyStochastic(series, chart, options = {}) {
17836
17854
  // Stochastic is bounded to 0-100; pinning it keeps the pane readable
17837
17855
  autoscaleInfoProvider: boundedScale,
17838
17856
  }, paneIndex);
17857
+ // An index past the last pane opens a new one, so %D follows %K to where it landed.
17858
+ const scalePane = paneIndexOf(chart, kSeries, paneIndex);
17839
17859
  // Create %D line (slow - signal)
17840
17860
  const dSeries = chart.addSeries(lineSeries, {
17841
17861
  color: resolved.colorD,
17842
17862
  autoscaleInfoProvider: boundedScale,
17843
- }, paneIndex);
17844
- // The pane the series landed in, which is not always the one asked for.
17845
- const scalePane = paneIndexOf(chart, kSeries, paneIndex);
17863
+ }, scalePane);
17846
17864
  chart.priceScale(kSeries.options().priceScaleId ?? 'right', scalePane).applyOptions({
17847
17865
  scaleMargins: {
17848
17866
  top: 0.1,
@@ -18184,15 +18202,16 @@ function applyADX(series, chart, options = {}) {
18184
18202
  color: resolved.colorADX,
18185
18203
  autoscaleInfoProvider: boundedScale,
18186
18204
  }, paneIndex);
18205
+ // An index past the last pane opens a new one, so the DI lines follow ADX to where it landed.
18206
+ const scalePane = paneIndexOf(chart, adxSeries, paneIndex);
18187
18207
  const plusSeries = chart.addSeries(lineSeries, {
18188
18208
  color: resolved.colorPlusDI,
18189
18209
  autoscaleInfoProvider: boundedScale,
18190
- }, paneIndex);
18210
+ }, scalePane);
18191
18211
  const minusSeries = chart.addSeries(lineSeries, {
18192
18212
  color: resolved.colorMinusDI,
18193
18213
  autoscaleInfoProvider: boundedScale,
18194
- }, paneIndex);
18195
- const scalePane = paneIndexOf(chart, adxSeries, paneIndex);
18214
+ }, scalePane);
18196
18215
  chart.priceScale(adxSeries.options().priceScaleId ?? 'right', scalePane).applyOptions({
18197
18216
  scaleMargins: {
18198
18217
  top: 0.1,
@@ -30605,7 +30624,7 @@ const customSeriesDefaultOptions = {
30605
30624
  * Returns the current version as a string. For example `'1.0.0'`.
30606
30625
  */
30607
30626
  function version() {
30608
- return "2.3.3";
30627
+ return "2.3.10";
30609
30628
  }
30610
30629
 
30611
30630
  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 };