@pipsend/charts 2.3.19 → 2.3.20
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.
- package/dist/pipsend-charts.development.mjs +160 -115
- package/dist/pipsend-charts.production.mjs +2 -2
- package/dist/pipsend-charts.standalone.development.js +160 -114
- package/dist/pipsend-charts.standalone.development.mjs +160 -115
- package/dist/pipsend-charts.standalone.production.js +2 -2
- package/dist/pipsend-charts.standalone.production.mjs +2 -2
- package/dist/typings.d.ts +29 -6
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @license
|
|
3
|
-
* Pipsend Charts v2.3.
|
|
3
|
+
* Pipsend Charts v2.3.20-dev+202610211649
|
|
4
4
|
* Copyright (c) 2026 Pipsend
|
|
5
5
|
* Licensed under MIT License
|
|
6
6
|
* Built on TradingView Lightweight Charts™ (Apache 2.0)
|
|
@@ -5555,7 +5555,7 @@
|
|
|
5555
5555
|
const visibleBars = ensureNotNull(this._internal_visibleStrictRange());
|
|
5556
5556
|
const firstBar = Math.max(visibleBars._internal_left(), visibleBars._internal_left() - indexPerLabel);
|
|
5557
5557
|
const lastBar = Math.max(visibleBars._internal_right(), visibleBars._internal_right() - indexPerLabel);
|
|
5558
|
-
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);
|
|
5558
|
+
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, this._private__points[mark.index - 1]) ?? true);
|
|
5559
5559
|
// according to indexPerLabel value this value means "earliest index which _might be_ used as the second label on time scale"
|
|
5560
5560
|
const earliestIndexOfSecondLabel = this._private__firstIndex() + indexPerLabel;
|
|
5561
5561
|
// according to indexPerLabel value this value means "earliest index which _might be_ used as the second last label on time scale"
|
|
@@ -6829,6 +6829,75 @@
|
|
|
6829
6829
|
return localDateFromUtc.toLocaleString(locale, formatOptions);
|
|
6830
6830
|
}
|
|
6831
6831
|
|
|
6832
|
+
const DAY = 86400;
|
|
6833
|
+
const QUARTER_HOUR = 900;
|
|
6834
|
+
const zones = new Map();
|
|
6835
|
+
function zoneCache(timeZone) {
|
|
6836
|
+
let cache = zones.get(timeZone);
|
|
6837
|
+
if (cache === undefined) {
|
|
6838
|
+
let format = null;
|
|
6839
|
+
try {
|
|
6840
|
+
format = new Intl.DateTimeFormat('en-US', {
|
|
6841
|
+
timeZone,
|
|
6842
|
+
hourCycle: 'h23',
|
|
6843
|
+
year: 'numeric',
|
|
6844
|
+
month: 'numeric',
|
|
6845
|
+
day: 'numeric',
|
|
6846
|
+
hour: 'numeric',
|
|
6847
|
+
minute: 'numeric',
|
|
6848
|
+
second: 'numeric',
|
|
6849
|
+
});
|
|
6850
|
+
}
|
|
6851
|
+
catch (error) {
|
|
6852
|
+
format = null;
|
|
6853
|
+
}
|
|
6854
|
+
cache = { _internal_format: format, _internal_days: new Map(), _internal_quarters: new Map() };
|
|
6855
|
+
zones.set(timeZone, cache);
|
|
6856
|
+
}
|
|
6857
|
+
return cache;
|
|
6858
|
+
}
|
|
6859
|
+
function exactOffset(format, time) {
|
|
6860
|
+
const parts = format.formatToParts(new Date(time * 1000));
|
|
6861
|
+
const part = (type) => Number(parts.find((p) => p.type === type)?.value ?? 0);
|
|
6862
|
+
const wallClock = Date.UTC(part('year'), part('month') - 1, part('day'), part('hour') % 24, part('minute'), part('second'));
|
|
6863
|
+
return Math.round(wallClock / 1000 - time);
|
|
6864
|
+
}
|
|
6865
|
+
/**
|
|
6866
|
+
* Offset of `timeZone` from UTC at `time`, in seconds. Undefined, `'UTC'` and
|
|
6867
|
+
* unknown zones are 0.
|
|
6868
|
+
*
|
|
6869
|
+
* Resolved once per UTC day, and to the quarter hour only on days with a
|
|
6870
|
+
* transition: asking `Intl` for every bar is too slow for a whole series.
|
|
6871
|
+
*/
|
|
6872
|
+
function timeZoneOffset(timeZone, time) {
|
|
6873
|
+
if (timeZone === undefined || timeZone === 'UTC') {
|
|
6874
|
+
return 0;
|
|
6875
|
+
}
|
|
6876
|
+
const cache = zoneCache(timeZone);
|
|
6877
|
+
const format = cache._internal_format;
|
|
6878
|
+
if (format === null) {
|
|
6879
|
+
return 0;
|
|
6880
|
+
}
|
|
6881
|
+
const day = Math.floor(time / DAY);
|
|
6882
|
+
let wholeDay = cache._internal_days.get(day);
|
|
6883
|
+
if (wholeDay === undefined) {
|
|
6884
|
+
const start = exactOffset(format, day * DAY);
|
|
6885
|
+
const end = exactOffset(format, (day + 1) * DAY - 1);
|
|
6886
|
+
wholeDay = start === end ? start : null;
|
|
6887
|
+
cache._internal_days.set(day, wholeDay);
|
|
6888
|
+
}
|
|
6889
|
+
if (wholeDay !== null) {
|
|
6890
|
+
return wholeDay;
|
|
6891
|
+
}
|
|
6892
|
+
const quarter = Math.floor(time / QUARTER_HOUR);
|
|
6893
|
+
let offset = cache._internal_quarters.get(quarter);
|
|
6894
|
+
if (offset === undefined) {
|
|
6895
|
+
offset = exactOffset(format, quarter * QUARTER_HOUR);
|
|
6896
|
+
cache._internal_quarters.set(quarter, offset);
|
|
6897
|
+
}
|
|
6898
|
+
return offset;
|
|
6899
|
+
}
|
|
6900
|
+
|
|
6832
6901
|
function hours(count) {
|
|
6833
6902
|
return count * 60 * 60 * 1000;
|
|
6834
6903
|
}
|
|
@@ -6868,29 +6937,36 @@
|
|
|
6868
6937
|
function cast(t) {
|
|
6869
6938
|
return t;
|
|
6870
6939
|
}
|
|
6871
|
-
|
|
6940
|
+
// Business days are dates, not instants: never shifted
|
|
6941
|
+
function zonedTimestamp(point, timeZone) {
|
|
6942
|
+
const time = cast(point.time);
|
|
6943
|
+
return time._internal_businessDay === undefined ? time._internal_timestamp + timeZoneOffset(timeZone, time._internal_timestamp) : time._internal_timestamp;
|
|
6944
|
+
}
|
|
6945
|
+
function fillWeightsForPoints(sortedTimePoints, startIndex = 0, timeZone) {
|
|
6872
6946
|
if (sortedTimePoints.length === 0) {
|
|
6873
6947
|
return;
|
|
6874
6948
|
}
|
|
6875
|
-
let prevTime = startIndex === 0 ? null :
|
|
6949
|
+
let prevTime = startIndex === 0 ? null : zonedTimestamp(sortedTimePoints[startIndex - 1], timeZone);
|
|
6876
6950
|
let prevDate = prevTime !== null ? new Date(prevTime * 1000) : null;
|
|
6877
6951
|
let totalTimeDiff = 0;
|
|
6878
6952
|
for (let index = startIndex; index < sortedTimePoints.length; ++index) {
|
|
6879
6953
|
const currentPoint = sortedTimePoints[index];
|
|
6880
|
-
const
|
|
6954
|
+
const currentTime = zonedTimestamp(currentPoint, timeZone);
|
|
6955
|
+
const currentDate = new Date(currentTime * 1000);
|
|
6881
6956
|
if (prevDate !== null) {
|
|
6882
6957
|
currentPoint.timeWeight = weightByTime(currentDate, prevDate);
|
|
6883
6958
|
}
|
|
6884
|
-
totalTimeDiff +=
|
|
6885
|
-
prevTime =
|
|
6959
|
+
totalTimeDiff += currentTime - (prevTime || currentTime);
|
|
6960
|
+
prevTime = currentTime;
|
|
6886
6961
|
prevDate = currentDate;
|
|
6887
6962
|
}
|
|
6888
6963
|
if (startIndex === 0 && sortedTimePoints.length > 1) {
|
|
6889
6964
|
// let's guess a weight for the first point
|
|
6890
6965
|
// let's say the previous point was average time back in the history
|
|
6891
6966
|
const averageTimeDiff = Math.ceil(totalTimeDiff / (sortedTimePoints.length - 1));
|
|
6892
|
-
const
|
|
6893
|
-
|
|
6967
|
+
const firstTime = zonedTimestamp(sortedTimePoints[0], timeZone);
|
|
6968
|
+
const approxPrevDate = new Date((firstTime - averageTimeDiff) * 1000);
|
|
6969
|
+
sortedTimePoints[0].timeWeight = weightByTime(new Date(firstTime * 1000), approxPrevDate);
|
|
6894
6970
|
}
|
|
6895
6971
|
}
|
|
6896
6972
|
|
|
@@ -7045,16 +7121,15 @@
|
|
|
7045
7121
|
}
|
|
7046
7122
|
}
|
|
7047
7123
|
formatHorzItem(item) {
|
|
7048
|
-
|
|
7049
|
-
return this._private__dateTimeFormatter._internal_format(new Date(tp._internal_timestamp * 1000));
|
|
7124
|
+
return this._private__dateTimeFormatter._internal_format(new Date(this._private__zonedTimePoint(item)._internal_timestamp * 1000));
|
|
7050
7125
|
}
|
|
7051
|
-
allowsTickMark(tickMark, barsPerMark) {
|
|
7126
|
+
allowsTickMark(tickMark, barsPerMark, previous) {
|
|
7052
7127
|
const filter = this._private__options.timeScale.tickMarkFilter;
|
|
7053
7128
|
if (filter === undefined) {
|
|
7054
7129
|
return true;
|
|
7055
7130
|
}
|
|
7056
7131
|
const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
|
|
7057
|
-
return filter(tickMark.originalTime, tickMarkType, barsPerMark);
|
|
7132
|
+
return filter(tickMark.originalTime, tickMarkType, barsPerMark, previous === undefined ? null : previous.originalTime);
|
|
7058
7133
|
}
|
|
7059
7134
|
formatTickmark(tickMark, localizationOptions) {
|
|
7060
7135
|
const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
|
|
@@ -7065,7 +7140,7 @@
|
|
|
7065
7140
|
return tickMarkString;
|
|
7066
7141
|
}
|
|
7067
7142
|
}
|
|
7068
|
-
return defaultTickMarkFormatter(tickMark.time, tickMarkType, localizationOptions.locale);
|
|
7143
|
+
return defaultTickMarkFormatter(this._private__zonedTimePoint(tickMark.time), tickMarkType, localizationOptions.locale);
|
|
7069
7144
|
}
|
|
7070
7145
|
maxTickMarkWeight(tickMarks) {
|
|
7071
7146
|
let maxWeight = tickMarks.reduce(markWithGreaterWeight$2, tickMarks[0]).weight;
|
|
@@ -7077,7 +7152,17 @@
|
|
|
7077
7152
|
return maxWeight;
|
|
7078
7153
|
}
|
|
7079
7154
|
fillWeightsForPoints(sortedTimePoints, startIndex) {
|
|
7080
|
-
fillWeightsForPoints(sortedTimePoints, startIndex);
|
|
7155
|
+
fillWeightsForPoints(sortedTimePoints, startIndex, this._private__timeZone());
|
|
7156
|
+
}
|
|
7157
|
+
_private__timeZone() {
|
|
7158
|
+
return this._private__options?.localization.timeZone;
|
|
7159
|
+
}
|
|
7160
|
+
_private__zonedTimePoint(timePoint) {
|
|
7161
|
+
if (timePoint._internal_businessDay !== undefined) {
|
|
7162
|
+
return timePoint;
|
|
7163
|
+
}
|
|
7164
|
+
const offset = timeZoneOffset(this._private__timeZone(), timePoint._internal_timestamp);
|
|
7165
|
+
return offset === 0 ? timePoint : { _internal_timestamp: (timePoint._internal_timestamp + offset) };
|
|
7081
7166
|
}
|
|
7082
7167
|
static _internal_applyDefaults(options) {
|
|
7083
7168
|
return merge({ localization: { dateFormat: 'dd MMM \'yy' } }, options ?? {});
|
|
@@ -11079,6 +11164,10 @@
|
|
|
11079
11164
|
this._private__sortedTimePoints = [];
|
|
11080
11165
|
this._private__horzScaleBehavior = horzScaleBehavior;
|
|
11081
11166
|
}
|
|
11167
|
+
_internal_refillTimeWeights() {
|
|
11168
|
+
this._private__horzScaleBehavior.fillWeightsForPoints(this._private__sortedTimePoints, 0);
|
|
11169
|
+
return this._private__sortedTimePoints;
|
|
11170
|
+
}
|
|
11082
11171
|
_internal_destroy() {
|
|
11083
11172
|
this._private__pointDataByTimePoint.clear();
|
|
11084
11173
|
this._private__seriesRowsBySeries.clear();
|
|
@@ -12583,7 +12672,13 @@
|
|
|
12583
12672
|
throw new Error(`colorParsers option should not be changed once the chart has been created.`);
|
|
12584
12673
|
}
|
|
12585
12674
|
}
|
|
12675
|
+
const timeZone = this.options().localization.timeZone;
|
|
12586
12676
|
this._private__chartWidget._internal_applyOptions(toInternalOptions(options));
|
|
12677
|
+
if (this.options().localization.timeZone !== timeZone) {
|
|
12678
|
+
const model = this._private__chartWidget._internal_model();
|
|
12679
|
+
model._internal_timeScale()._internal_update(this._private__dataLayer._internal_refillTimeWeights(), 0);
|
|
12680
|
+
model._internal_fullUpdate();
|
|
12681
|
+
}
|
|
12587
12682
|
}
|
|
12588
12683
|
options() {
|
|
12589
12684
|
return this._private__chartWidget._internal_options();
|
|
@@ -19221,8 +19316,9 @@
|
|
|
19221
19316
|
const DEFAULT_SESSIONS = [
|
|
19222
19317
|
{
|
|
19223
19318
|
name: 'Tokyo',
|
|
19224
|
-
startHour:
|
|
19225
|
-
endHour:
|
|
19319
|
+
startHour: 9,
|
|
19320
|
+
endHour: 18,
|
|
19321
|
+
timeZone: 'Asia/Tokyo',
|
|
19226
19322
|
color: '#FF6B00',
|
|
19227
19323
|
opacity: 0.1,
|
|
19228
19324
|
},
|
|
@@ -19230,13 +19326,15 @@
|
|
|
19230
19326
|
name: 'London',
|
|
19231
19327
|
startHour: 8,
|
|
19232
19328
|
endHour: 17,
|
|
19329
|
+
timeZone: 'Europe/London',
|
|
19233
19330
|
color: '#2962FF',
|
|
19234
19331
|
opacity: 0.1,
|
|
19235
19332
|
},
|
|
19236
19333
|
{
|
|
19237
19334
|
name: 'New York',
|
|
19238
|
-
startHour:
|
|
19239
|
-
endHour:
|
|
19335
|
+
startHour: 8,
|
|
19336
|
+
endHour: 17,
|
|
19337
|
+
timeZone: 'America/New_York',
|
|
19240
19338
|
color: '#089981',
|
|
19241
19339
|
opacity: 0.1,
|
|
19242
19340
|
},
|
|
@@ -19322,79 +19420,49 @@
|
|
|
19322
19420
|
}
|
|
19323
19421
|
}
|
|
19324
19422
|
_private__highlightSession(session, data) {
|
|
19325
|
-
|
|
19326
|
-
let sessionData = [];
|
|
19327
|
-
for (const point of data) {
|
|
19328
|
-
const time = point.time;
|
|
19329
|
-
const hour = this._private__getUTCHour(time);
|
|
19330
|
-
const isInSession = this._private__isTimeInSession(hour, session.startHour, session.endHour);
|
|
19331
|
-
if (isInSession) {
|
|
19332
|
-
if (!sessionStart) {
|
|
19333
|
-
sessionStart = time;
|
|
19334
|
-
}
|
|
19335
|
-
sessionData.push(point);
|
|
19336
|
-
}
|
|
19337
|
-
else {
|
|
19338
|
-
if (sessionStart && sessionData.length > 0) {
|
|
19339
|
-
// End of session, create highlight box
|
|
19340
|
-
this._private__createSessionBox(sessionStart, sessionData[sessionData.length - 1].time, session);
|
|
19341
|
-
sessionStart = null;
|
|
19342
|
-
sessionData = [];
|
|
19343
|
-
}
|
|
19344
|
-
}
|
|
19345
|
-
}
|
|
19346
|
-
// Handle case where session extends to end of visible range
|
|
19347
|
-
if (sessionStart && sessionData.length > 0) {
|
|
19348
|
-
this._private__createSessionBox(sessionStart, sessionData[sessionData.length - 1].time, session);
|
|
19349
|
-
}
|
|
19423
|
+
this._private__eachRun(data, (time) => this._private__inSession(time, session), (startTime, endTime) => this._private__createSessionBox(startTime, endTime, session));
|
|
19350
19424
|
}
|
|
19425
|
+
// Per bar, since each session reads the clock of its own zone
|
|
19351
19426
|
_private__highlightOverlaps(data) {
|
|
19352
|
-
// Find overlapping sessions
|
|
19353
19427
|
const sessions = this._private__options.sessions;
|
|
19354
19428
|
for (let i = 0; i < sessions.length; i++) {
|
|
19355
19429
|
for (let j = i + 1; j < sessions.length; j++) {
|
|
19356
|
-
|
|
19357
|
-
const session2 = sessions[j];
|
|
19358
|
-
// Check if sessions overlap
|
|
19359
|
-
const overlap = this._private__getSessionOverlap(session1, session2);
|
|
19360
|
-
if (overlap) {
|
|
19361
|
-
this._private__highlightOverlapPeriod(overlap, data);
|
|
19362
|
-
}
|
|
19430
|
+
this._private__eachRun(data, (time) => this._private__inSession(time, sessions[i]) && this._private__inSession(time, sessions[j]), (startTime, endTime) => this._private__createOverlapBox(startTime, endTime));
|
|
19363
19431
|
}
|
|
19364
19432
|
}
|
|
19365
19433
|
}
|
|
19366
|
-
|
|
19367
|
-
|
|
19368
|
-
|
|
19369
|
-
if (start < end) {
|
|
19370
|
-
return { _internal_start: start, _internal_end: end };
|
|
19371
|
-
}
|
|
19372
|
-
return null;
|
|
19373
|
-
}
|
|
19374
|
-
_private__highlightOverlapPeriod(overlap, data) {
|
|
19375
|
-
let overlapStart = null;
|
|
19376
|
-
let overlapData = [];
|
|
19434
|
+
_private__eachRun(data, inside, emit) {
|
|
19435
|
+
let runStart = null;
|
|
19436
|
+
let runEnd = null;
|
|
19377
19437
|
for (const point of data) {
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
if (isInOverlap) {
|
|
19382
|
-
if (!overlapStart) {
|
|
19383
|
-
overlapStart = time;
|
|
19384
|
-
}
|
|
19385
|
-
overlapData.push(point);
|
|
19438
|
+
if (inside(point.time)) {
|
|
19439
|
+
runStart = runStart ?? point.time;
|
|
19440
|
+
runEnd = point.time;
|
|
19386
19441
|
}
|
|
19387
|
-
else {
|
|
19388
|
-
|
|
19389
|
-
|
|
19390
|
-
|
|
19391
|
-
overlapData = [];
|
|
19392
|
-
}
|
|
19442
|
+
else if (runStart !== null && runEnd !== null) {
|
|
19443
|
+
emit(runStart, runEnd);
|
|
19444
|
+
runStart = null;
|
|
19445
|
+
runEnd = null;
|
|
19393
19446
|
}
|
|
19394
19447
|
}
|
|
19395
|
-
if (
|
|
19396
|
-
|
|
19448
|
+
if (runStart !== null && runEnd !== null) {
|
|
19449
|
+
emit(runStart, runEnd);
|
|
19450
|
+
}
|
|
19451
|
+
}
|
|
19452
|
+
_private__inSession(time, session) {
|
|
19453
|
+
const hour = this._private__hourIn(time, session.timeZone);
|
|
19454
|
+
if (session.startHour < session.endHour) {
|
|
19455
|
+
return hour >= session.startHour && hour < session.endHour;
|
|
19456
|
+
}
|
|
19457
|
+
// Crosses midnight
|
|
19458
|
+
return hour >= session.startHour || hour < session.endHour;
|
|
19459
|
+
}
|
|
19460
|
+
_private__hourIn(time, timeZone) {
|
|
19461
|
+
const seconds = typeof time === 'number' ? time : typeof time === 'string' ? Date.parse(time) / 1000 : NaN;
|
|
19462
|
+
if (!Number.isFinite(seconds)) {
|
|
19463
|
+
return 0;
|
|
19397
19464
|
}
|
|
19465
|
+
return new Date((seconds + timeZoneOffset(timeZone, seconds)) * 1000).getUTCHours();
|
|
19398
19466
|
}
|
|
19399
19467
|
_private__createSessionBox(startTime, endTime, session) {
|
|
19400
19468
|
// Validate times
|
|
@@ -19424,29 +19492,6 @@
|
|
|
19424
19492
|
};
|
|
19425
19493
|
this._private__sessionBoxes.push(box);
|
|
19426
19494
|
}
|
|
19427
|
-
_private__isTimeInSession(hour, startHour, endHour) {
|
|
19428
|
-
if (startHour < endHour) {
|
|
19429
|
-
return hour >= startHour && hour < endHour;
|
|
19430
|
-
}
|
|
19431
|
-
else {
|
|
19432
|
-
// Session crosses midnight
|
|
19433
|
-
return hour >= startHour || hour < endHour;
|
|
19434
|
-
}
|
|
19435
|
-
}
|
|
19436
|
-
_private__getUTCHour(time) {
|
|
19437
|
-
// Convert time to UTC hour
|
|
19438
|
-
if (typeof time === 'number') {
|
|
19439
|
-
// Unix timestamp in seconds
|
|
19440
|
-
const date = new Date(time * 1000);
|
|
19441
|
-
return date.getUTCHours();
|
|
19442
|
-
}
|
|
19443
|
-
else if (typeof time === 'string') {
|
|
19444
|
-
// ISO string
|
|
19445
|
-
const date = new Date(time);
|
|
19446
|
-
return date.getUTCHours();
|
|
19447
|
-
}
|
|
19448
|
-
return 0;
|
|
19449
|
-
}
|
|
19450
19495
|
_private__clearSessionBoxes() {
|
|
19451
19496
|
// Clear all session boxes
|
|
19452
19497
|
this._private__sessionBoxes = [];
|
|
@@ -30599,6 +30644,14 @@
|
|
|
30599
30644
|
|
|
30600
30645
|
/** Undo steps kept, each a full snapshot of every drawing. */
|
|
30601
30646
|
const UNDO_HISTORY_LIMIT = 100;
|
|
30647
|
+
/**
|
|
30648
|
+
* Points for a restored freehand tool. Built with bracket notation: a plain
|
|
30649
|
+
* `{ time, price }` literal gets its keys renamed by the build, and the tool,
|
|
30650
|
+
* which reads them by their public names, comes back drawing nothing.
|
|
30651
|
+
*/
|
|
30652
|
+
function restorePoints(points) {
|
|
30653
|
+
return points.map((point) => makeSerializedPoint(readSerializedNumber(point, 'price') ?? 0, readSerializedTime(point)));
|
|
30654
|
+
}
|
|
30602
30655
|
/**
|
|
30603
30656
|
* Central manager for all drawing tools - TradingView style
|
|
30604
30657
|
* Handles multiple tools, selection, deletion, and keyboard shortcuts
|
|
@@ -31078,16 +31131,8 @@
|
|
|
31078
31131
|
...style,
|
|
31079
31132
|
});
|
|
31080
31133
|
case 'polygon':
|
|
31081
|
-
// Bracket notation on the way out too, not just on the way in: a
|
|
31082
|
-
// plain `{ time, price }` literal here gets its keys renamed and
|
|
31083
|
-
// the restored corners come back empty.
|
|
31084
31134
|
return createPolygonTool(context, {
|
|
31085
|
-
points: points
|
|
31086
|
-
const vertex = {};
|
|
31087
|
-
vertex['time'] = pt(index)._internal_t;
|
|
31088
|
-
vertex['price'] = pt(index)._internal_p;
|
|
31089
|
-
return vertex;
|
|
31090
|
-
}),
|
|
31135
|
+
points: restorePoints(points),
|
|
31091
31136
|
...style,
|
|
31092
31137
|
});
|
|
31093
31138
|
case 'crossLine':
|
|
@@ -31153,12 +31198,12 @@
|
|
|
31153
31198
|
});
|
|
31154
31199
|
case 'arrow':
|
|
31155
31200
|
return createArrowTool(context, {
|
|
31156
|
-
points: points
|
|
31201
|
+
points: restorePoints(points),
|
|
31157
31202
|
...style,
|
|
31158
31203
|
});
|
|
31159
31204
|
case 'brush':
|
|
31160
31205
|
return createBrushTool(context, {
|
|
31161
|
-
points: points
|
|
31206
|
+
points: restorePoints(points),
|
|
31162
31207
|
...style,
|
|
31163
31208
|
});
|
|
31164
31209
|
case 'text':
|
|
@@ -31630,7 +31675,7 @@
|
|
|
31630
31675
|
* Returns the current version as a string. For example `'1.0.0'`.
|
|
31631
31676
|
*/
|
|
31632
31677
|
function version() {
|
|
31633
|
-
return "2.3.
|
|
31678
|
+
return "2.3.20-dev+202610211649";
|
|
31634
31679
|
}
|
|
31635
31680
|
|
|
31636
31681
|
var PipsendChartsModule = /*#__PURE__*/Object.freeze({
|
|
@@ -31749,6 +31794,7 @@
|
|
|
31749
31794
|
setSeriesVolumes: setSeriesVolumes,
|
|
31750
31795
|
setVolumeProfileData: setVolumeProfileData,
|
|
31751
31796
|
timeFromCoordinate: timeFromCoordinate,
|
|
31797
|
+
timeZoneOffset: timeZoneOffset,
|
|
31752
31798
|
version: version
|
|
31753
31799
|
});
|
|
31754
31800
|
|