@pipsend/charts 2.3.16 → 2.3.17

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.16-dev+202610080459
3
+ * Pipsend Charts v2.3.17-dev+202610130113
4
4
  * Copyright (c) 2026 Pipsend
5
5
  * Licensed under MIT License
6
6
  * Built on TradingView Lightweight Charts™ (Apache 2.0)
@@ -20612,8 +20612,11 @@
20612
20612
  * move — which is invisible, and cheaper than forcing a second pass.
20613
20613
  */
20614
20614
  _internal_setClaims(ownerId, claims) {
20615
+ const previous = this._private__claims.get(ownerId);
20615
20616
  this._private__claims.set(ownerId, claims);
20616
- this._private__invalidated = true;
20617
+ if (previous === undefined || !sameClaims(previous, claims)) {
20618
+ this._private__invalidated = true;
20619
+ }
20617
20620
  }
20618
20621
  /** How far down a label has to move to clear the ones already placed. */
20619
20622
  _internal_offsetFor(ownerId, level) {
@@ -20634,7 +20637,10 @@
20634
20637
  // them only need the few pixels they are short of — stepping by a
20635
20638
  // full gap each time is what made the fan look flung open.
20636
20639
  let y = claim._internal_y;
20637
- for (const other of [...placed].sort(byY)) {
20640
+ for (const other of placed) {
20641
+ if (other._internal_y >= y + gap) {
20642
+ break;
20643
+ }
20638
20644
  if (Math.abs(y - other._internal_y) < gap) {
20639
20645
  y = other._internal_y + gap;
20640
20646
  }
@@ -20645,7 +20651,7 @@
20645
20651
  // no worse than before and keeps the pile from running off.
20646
20652
  offset = 0;
20647
20653
  }
20648
- placed.push({ _internal_y: claim._internal_y + offset, _internal_height: claim._internal_height });
20654
+ insertByY(placed, { _internal_y: claim._internal_y + offset, _internal_height: claim._internal_height });
20649
20655
  offsets.set(key(ownerId, claim._internal_level), offset);
20650
20656
  }
20651
20657
  }
@@ -20663,8 +20669,30 @@
20663
20669
  function minGap(height) {
20664
20670
  return Math.max(9, Math.round(height * 0.4));
20665
20671
  }
20666
- function byY(a, b) {
20667
- return a._internal_y - b._internal_y;
20672
+ function insertByY(placed, claim) {
20673
+ let low = 0;
20674
+ let high = placed.length;
20675
+ while (low < high) {
20676
+ const middle = (low + high) >> 1;
20677
+ if (placed[middle]._internal_y <= claim._internal_y) {
20678
+ low = middle + 1;
20679
+ }
20680
+ else {
20681
+ high = middle;
20682
+ }
20683
+ }
20684
+ placed.splice(low, 0, claim);
20685
+ }
20686
+ function sameClaims(a, b) {
20687
+ if (a.length !== b.length) {
20688
+ return false;
20689
+ }
20690
+ for (let i = 0; i < a.length; i++) {
20691
+ if (a[i]._internal_level !== b[i]._internal_level || a[i]._internal_y !== b[i]._internal_y || a[i]._internal_height !== b[i]._internal_height) {
20692
+ return false;
20693
+ }
20694
+ }
20695
+ return true;
20668
20696
  }
20669
20697
  const layouts = new WeakMap();
20670
20698
  /** The layout is shared by every position line on the same chart. */
@@ -21019,6 +21047,7 @@
21019
21047
  constructor(chart, series, options) {
21020
21048
  this._private__paneView = new PositionLinePaneView();
21021
21049
  this._private__colorParser = new ColorParser([]);
21050
+ this._private__axisLabels = new Map();
21022
21051
  this._private__attached = false;
21023
21052
  this._private__hoveredLevel = null;
21024
21053
  this._private__hoveredPart = null;
@@ -21310,12 +21339,22 @@
21310
21339
  return null;
21311
21340
  }
21312
21341
  const color = options.color ?? positionLineDefaultColors[level];
21313
- return {
21342
+ const formatter = this._private__series.priceFormatter();
21343
+ const cached = this._private__axisLabels.get(level);
21344
+ if (cached !== undefined && cached._internal_price === options.price && cached._internal_color === color && cached._internal_formatter === formatter) {
21345
+ if (cached._internal_label._internal_coordinate !== y) {
21346
+ cached._internal_label = { ...cached._internal_label, _internal_coordinate: y };
21347
+ }
21348
+ return cached._internal_label;
21349
+ }
21350
+ const label = {
21314
21351
  _internal_coordinate: y,
21315
- _internal_text: this._private__series.priceFormatter().format(options.price),
21352
+ _internal_text: formatter.format(options.price),
21316
21353
  _internal_color: color,
21317
21354
  _internal_textColor: this._private__colorParser._internal_generateContrastColors(color)._internal_foreground,
21318
21355
  };
21356
+ this._private__axisLabels.set(level, { _internal_price: options.price, _internal_color: color, _internal_formatter: formatter, _internal_label: label });
21357
+ return label;
21319
21358
  }
21320
21359
  _private__levelOptions(level) {
21321
21360
  const options = level === 'entry' ? this._private__options.entry : this._private__options[level];
@@ -31446,7 +31485,7 @@
31446
31485
  * Returns the current version as a string. For example `'1.0.0'`.
31447
31486
  */
31448
31487
  function version() {
31449
- return "2.3.16-dev+202610080459";
31488
+ return "2.3.17-dev+202610130113";
31450
31489
  }
31451
31490
 
31452
31491
  var PipsendChartsModule = /*#__PURE__*/Object.freeze({
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @license
3
- * Pipsend Charts v2.3.16-dev+202610080459
3
+ * Pipsend Charts v2.3.17-dev+202610130113
4
4
  * Copyright (c) 2026 Pipsend
5
5
  * Licensed under MIT License
6
6
  * Built on TradingView Lightweight Charts™ (Apache 2.0)
@@ -20609,8 +20609,11 @@ class PositionLineLabelLayout {
20609
20609
  * move — which is invisible, and cheaper than forcing a second pass.
20610
20610
  */
20611
20611
  _internal_setClaims(ownerId, claims) {
20612
+ const previous = this._private__claims.get(ownerId);
20612
20613
  this._private__claims.set(ownerId, claims);
20613
- this._private__invalidated = true;
20614
+ if (previous === undefined || !sameClaims(previous, claims)) {
20615
+ this._private__invalidated = true;
20616
+ }
20614
20617
  }
20615
20618
  /** How far down a label has to move to clear the ones already placed. */
20616
20619
  _internal_offsetFor(ownerId, level) {
@@ -20631,7 +20634,10 @@ class PositionLineLabelLayout {
20631
20634
  // them only need the few pixels they are short of — stepping by a
20632
20635
  // full gap each time is what made the fan look flung open.
20633
20636
  let y = claim._internal_y;
20634
- for (const other of [...placed].sort(byY)) {
20637
+ for (const other of placed) {
20638
+ if (other._internal_y >= y + gap) {
20639
+ break;
20640
+ }
20635
20641
  if (Math.abs(y - other._internal_y) < gap) {
20636
20642
  y = other._internal_y + gap;
20637
20643
  }
@@ -20642,7 +20648,7 @@ class PositionLineLabelLayout {
20642
20648
  // no worse than before and keeps the pile from running off.
20643
20649
  offset = 0;
20644
20650
  }
20645
- placed.push({ _internal_y: claim._internal_y + offset, _internal_height: claim._internal_height });
20651
+ insertByY(placed, { _internal_y: claim._internal_y + offset, _internal_height: claim._internal_height });
20646
20652
  offsets.set(key(ownerId, claim._internal_level), offset);
20647
20653
  }
20648
20654
  }
@@ -20660,8 +20666,30 @@ function key(ownerId, level) {
20660
20666
  function minGap(height) {
20661
20667
  return Math.max(9, Math.round(height * 0.4));
20662
20668
  }
20663
- function byY(a, b) {
20664
- return a._internal_y - b._internal_y;
20669
+ function insertByY(placed, claim) {
20670
+ let low = 0;
20671
+ let high = placed.length;
20672
+ while (low < high) {
20673
+ const middle = (low + high) >> 1;
20674
+ if (placed[middle]._internal_y <= claim._internal_y) {
20675
+ low = middle + 1;
20676
+ }
20677
+ else {
20678
+ high = middle;
20679
+ }
20680
+ }
20681
+ placed.splice(low, 0, claim);
20682
+ }
20683
+ function sameClaims(a, b) {
20684
+ if (a.length !== b.length) {
20685
+ return false;
20686
+ }
20687
+ for (let i = 0; i < a.length; i++) {
20688
+ if (a[i]._internal_level !== b[i]._internal_level || a[i]._internal_y !== b[i]._internal_y || a[i]._internal_height !== b[i]._internal_height) {
20689
+ return false;
20690
+ }
20691
+ }
20692
+ return true;
20665
20693
  }
20666
20694
  const layouts = new WeakMap();
20667
20695
  /** The layout is shared by every position line on the same chart. */
@@ -21016,6 +21044,7 @@ class PositionLine {
21016
21044
  constructor(chart, series, options) {
21017
21045
  this._private__paneView = new PositionLinePaneView();
21018
21046
  this._private__colorParser = new ColorParser([]);
21047
+ this._private__axisLabels = new Map();
21019
21048
  this._private__attached = false;
21020
21049
  this._private__hoveredLevel = null;
21021
21050
  this._private__hoveredPart = null;
@@ -21307,12 +21336,22 @@ class PositionLine {
21307
21336
  return null;
21308
21337
  }
21309
21338
  const color = options.color ?? positionLineDefaultColors[level];
21310
- return {
21339
+ const formatter = this._private__series.priceFormatter();
21340
+ const cached = this._private__axisLabels.get(level);
21341
+ if (cached !== undefined && cached._internal_price === options.price && cached._internal_color === color && cached._internal_formatter === formatter) {
21342
+ if (cached._internal_label._internal_coordinate !== y) {
21343
+ cached._internal_label = { ...cached._internal_label, _internal_coordinate: y };
21344
+ }
21345
+ return cached._internal_label;
21346
+ }
21347
+ const label = {
21311
21348
  _internal_coordinate: y,
21312
- _internal_text: this._private__series.priceFormatter().format(options.price),
21349
+ _internal_text: formatter.format(options.price),
21313
21350
  _internal_color: color,
21314
21351
  _internal_textColor: this._private__colorParser._internal_generateContrastColors(color)._internal_foreground,
21315
21352
  };
21353
+ this._private__axisLabels.set(level, { _internal_price: options.price, _internal_color: color, _internal_formatter: formatter, _internal_label: label });
21354
+ return label;
21316
21355
  }
21317
21356
  _private__levelOptions(level) {
21318
21357
  const options = level === 'entry' ? this._private__options.entry : this._private__options[level];
@@ -31443,7 +31482,7 @@ const customSeriesDefaultOptions = {
31443
31482
  * Returns the current version as a string. For example `'1.0.0'`.
31444
31483
  */
31445
31484
  function version() {
31446
- return "2.3.16-dev+202610080459";
31485
+ return "2.3.17-dev+202610130113";
31447
31486
  }
31448
31487
 
31449
31488
  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 };