@pipsend/charts 2.3.16 → 2.3.18

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.18-dev+202610170141
4
4
  * Copyright (c) 2026 Pipsend
5
5
  * Licensed under MIT License
6
6
  * Built on TradingView Lightweight Charts™ (Apache 2.0)
@@ -15528,6 +15528,127 @@ function createUpDownMarkers(series, options = {}) {
15528
15528
  return wrapper;
15529
15529
  }
15530
15530
 
15531
+ const timeLabelsOptionsDefaults = {
15532
+ position: 'bottom',
15533
+ offset: 4,
15534
+ fontSize: 11,
15535
+ fontFamily: '',
15536
+ color: '#787B86',
15537
+ };
15538
+
15539
+ class TimeLabelsRenderer {
15540
+ constructor(data) {
15541
+ this._private__data = data;
15542
+ }
15543
+ draw(target) {
15544
+ const { _internal_items: items, _internal_position: position, _internal_offset: offset } = this._private__data;
15545
+ if (items.length === 0) {
15546
+ return;
15547
+ }
15548
+ target.useMediaCoordinateSpace(({ context: ctx, mediaSize }) => {
15549
+ const y = position === 'top' ? offset : mediaSize.height - offset;
15550
+ ctx.save();
15551
+ ctx.textAlign = 'center';
15552
+ ctx.textBaseline = position === 'top' ? 'top' : 'bottom';
15553
+ for (const item of items) {
15554
+ if (item._internal_x < -100 /* Constants.OffscreenMargin */ || item._internal_x > mediaSize.width + 100 /* Constants.OffscreenMargin */) {
15555
+ continue;
15556
+ }
15557
+ ctx.font = item._internal_font;
15558
+ ctx.fillStyle = item._internal_color;
15559
+ ctx.fillText(item._internal_text, item._internal_x, y);
15560
+ }
15561
+ ctx.restore();
15562
+ });
15563
+ }
15564
+ }
15565
+ class TimeLabelsPaneView {
15566
+ constructor() {
15567
+ this._private__data = { _internal_items: [], _internal_position: 'bottom', _internal_offset: 0 };
15568
+ }
15569
+ _internal_update(data) {
15570
+ this._private__data = data;
15571
+ }
15572
+ zOrder() {
15573
+ return 'top';
15574
+ }
15575
+ renderer() {
15576
+ return new TimeLabelsRenderer(this._private__data);
15577
+ }
15578
+ }
15579
+ class TimeLabelsPrimitive {
15580
+ constructor(options) {
15581
+ this._private__chart = null;
15582
+ this._private__requestUpdate = null;
15583
+ this._private__labels = [];
15584
+ this._private__paneView = new TimeLabelsPaneView();
15585
+ this._private__options = { ...timeLabelsOptionsDefaults, ...options };
15586
+ }
15587
+ attached(param) {
15588
+ this._private__chart = param.chart;
15589
+ this._private__requestUpdate = param.requestUpdate;
15590
+ this._private__requestUpdate();
15591
+ }
15592
+ detached() {
15593
+ this._private__chart = null;
15594
+ this._private__requestUpdate = null;
15595
+ }
15596
+ _internal_setLabels(labels) {
15597
+ this._private__labels = labels.slice();
15598
+ this._private__requestUpdate?.();
15599
+ }
15600
+ _internal_labels() {
15601
+ return this._private__labels;
15602
+ }
15603
+ _internal_applyOptions(options) {
15604
+ this._private__options = { ...this._private__options, ...options };
15605
+ this._private__requestUpdate?.();
15606
+ }
15607
+ updateAllViews() {
15608
+ const chart = this._private__chart;
15609
+ const options = this._private__options;
15610
+ if (chart === null) {
15611
+ this._private__paneView._internal_update({ _internal_items: [], _internal_position: options.position, _internal_offset: options.offset });
15612
+ return;
15613
+ }
15614
+ const timeScale = chart.timeScale();
15615
+ const family = options.fontFamily || chart.options().layout.fontFamily;
15616
+ const items = [];
15617
+ for (const label of this._private__labels) {
15618
+ const x = timeScale.timeToCoordinate(label.time);
15619
+ if (x === null) {
15620
+ continue;
15621
+ }
15622
+ items.push({
15623
+ _internal_x: x,
15624
+ _internal_text: label.text,
15625
+ _internal_color: label.color ?? options.color,
15626
+ _internal_font: makeFont(label.size ?? options.fontSize, family),
15627
+ });
15628
+ }
15629
+ this._private__paneView._internal_update({ _internal_items: items, _internal_position: options.position, _internal_offset: options.offset });
15630
+ }
15631
+ paneViews() {
15632
+ return [this._private__paneView];
15633
+ }
15634
+ }
15635
+
15636
+ class TimeLabelsPrimitiveWrapper extends SeriesPrimitiveAdapter {
15637
+ setLabels(labels) {
15638
+ this._internal__primitive._internal_setLabels(labels);
15639
+ }
15640
+ labels() {
15641
+ return this._internal__primitive._internal_labels();
15642
+ }
15643
+ }
15644
+ function createTimeLabels(series, labels, options) {
15645
+ const wrapper = new TimeLabelsPrimitiveWrapper(series, new TimeLabelsPrimitive(options));
15646
+ if (labels) {
15647
+ wrapper.setLabels(labels);
15648
+ }
15649
+ return wrapper;
15650
+ }
15651
+
15531
15652
  class PositionMarkersManager {
15532
15653
  constructor(series, options) {
15533
15654
  this._private__markersPlugin = null;
@@ -20216,8 +20337,11 @@ class PositionLineLabelLayout {
20216
20337
  * move — which is invisible, and cheaper than forcing a second pass.
20217
20338
  */
20218
20339
  _internal_setClaims(ownerId, claims) {
20340
+ const previous = this._private__claims.get(ownerId);
20219
20341
  this._private__claims.set(ownerId, claims);
20220
- this._private__invalidated = true;
20342
+ if (previous === undefined || !sameClaims(previous, claims)) {
20343
+ this._private__invalidated = true;
20344
+ }
20221
20345
  }
20222
20346
  /** How far down a label has to move to clear the ones already placed. */
20223
20347
  _internal_offsetFor(ownerId, level) {
@@ -20238,7 +20362,10 @@ class PositionLineLabelLayout {
20238
20362
  // them only need the few pixels they are short of — stepping by a
20239
20363
  // full gap each time is what made the fan look flung open.
20240
20364
  let y = claim._internal_y;
20241
- for (const other of [...placed].sort(byY)) {
20365
+ for (const other of placed) {
20366
+ if (other._internal_y >= y + gap) {
20367
+ break;
20368
+ }
20242
20369
  if (Math.abs(y - other._internal_y) < gap) {
20243
20370
  y = other._internal_y + gap;
20244
20371
  }
@@ -20249,7 +20376,7 @@ class PositionLineLabelLayout {
20249
20376
  // no worse than before and keeps the pile from running off.
20250
20377
  offset = 0;
20251
20378
  }
20252
- placed.push({ _internal_y: claim._internal_y + offset, _internal_height: claim._internal_height });
20379
+ insertByY(placed, { _internal_y: claim._internal_y + offset, _internal_height: claim._internal_height });
20253
20380
  offsets.set(key(ownerId, claim._internal_level), offset);
20254
20381
  }
20255
20382
  }
@@ -20267,8 +20394,30 @@ function key(ownerId, level) {
20267
20394
  function minGap(height) {
20268
20395
  return Math.max(9, Math.round(height * 0.4));
20269
20396
  }
20270
- function byY(a, b) {
20271
- return a._internal_y - b._internal_y;
20397
+ function insertByY(placed, claim) {
20398
+ let low = 0;
20399
+ let high = placed.length;
20400
+ while (low < high) {
20401
+ const middle = (low + high) >> 1;
20402
+ if (placed[middle]._internal_y <= claim._internal_y) {
20403
+ low = middle + 1;
20404
+ }
20405
+ else {
20406
+ high = middle;
20407
+ }
20408
+ }
20409
+ placed.splice(low, 0, claim);
20410
+ }
20411
+ function sameClaims(a, b) {
20412
+ if (a.length !== b.length) {
20413
+ return false;
20414
+ }
20415
+ for (let i = 0; i < a.length; i++) {
20416
+ 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) {
20417
+ return false;
20418
+ }
20419
+ }
20420
+ return true;
20272
20421
  }
20273
20422
  const layouts = new WeakMap();
20274
20423
  /** The layout is shared by every position line on the same chart. */
@@ -20623,6 +20772,7 @@ class PositionLine {
20623
20772
  constructor(chart, series, options) {
20624
20773
  this._private__paneView = new PositionLinePaneView();
20625
20774
  this._private__colorParser = new ColorParser([]);
20775
+ this._private__axisLabels = new Map();
20626
20776
  this._private__attached = false;
20627
20777
  this._private__hoveredLevel = null;
20628
20778
  this._private__hoveredPart = null;
@@ -20914,12 +21064,22 @@ class PositionLine {
20914
21064
  return null;
20915
21065
  }
20916
21066
  const color = options.color ?? positionLineDefaultColors[level];
20917
- return {
21067
+ const formatter = this._private__series.priceFormatter();
21068
+ const cached = this._private__axisLabels.get(level);
21069
+ if (cached !== undefined && cached._internal_price === options.price && cached._internal_color === color && cached._internal_formatter === formatter) {
21070
+ if (cached._internal_label._internal_coordinate !== y) {
21071
+ cached._internal_label = { ...cached._internal_label, _internal_coordinate: y };
21072
+ }
21073
+ return cached._internal_label;
21074
+ }
21075
+ const label = {
20918
21076
  _internal_coordinate: y,
20919
- _internal_text: this._private__series.priceFormatter().format(options.price),
21077
+ _internal_text: formatter.format(options.price),
20920
21078
  _internal_color: color,
20921
21079
  _internal_textColor: this._private__colorParser._internal_generateContrastColors(color)._internal_foreground,
20922
21080
  };
21081
+ this._private__axisLabels.set(level, { _internal_price: options.price, _internal_color: color, _internal_formatter: formatter, _internal_label: label });
21082
+ return label;
20923
21083
  }
20924
21084
  _private__levelOptions(level) {
20925
21085
  const options = level === 'entry' ? this._private__options.entry : this._private__options[level];
@@ -31050,7 +31210,7 @@ const customSeriesDefaultOptions = {
31050
31210
  * Returns the current version as a string. For example `'1.0.0'`.
31051
31211
  */
31052
31212
  function version() {
31053
- return "2.3.16-dev+202610080459";
31213
+ return "2.3.18-dev+202610170141";
31054
31214
  }
31055
31215
 
31056
- 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 };
31216
+ 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, createTimeLabels, createTradingLine, createTradingSessionsIndicator, createTrendLineTool, createUpDownMarkers, createVerticalLineTool, createVolumeProfileIndicator, createYieldCurveChart, customSeriesDefaultOptions, defaultHorzScaleBehavior, getPipConfig, hideSeriesPaint, isBusinessDay, isUTCTimestamp, setSeriesVolumes, setVolumeProfileData, timeFromCoordinate, version };