@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)
|
|
@@ -5552,7 +5552,7 @@ class TimeScale {
|
|
|
5552
5552
|
const visibleBars = ensureNotNull(this._internal_visibleStrictRange());
|
|
5553
5553
|
const firstBar = Math.max(visibleBars._internal_left(), visibleBars._internal_left() - indexPerLabel);
|
|
5554
5554
|
const lastBar = Math.max(visibleBars._internal_right(), visibleBars._internal_right() - indexPerLabel);
|
|
5555
|
-
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);
|
|
5555
|
+
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);
|
|
5556
5556
|
// according to indexPerLabel value this value means "earliest index which _might be_ used as the second label on time scale"
|
|
5557
5557
|
const earliestIndexOfSecondLabel = this._private__firstIndex() + indexPerLabel;
|
|
5558
5558
|
// according to indexPerLabel value this value means "earliest index which _might be_ used as the second last label on time scale"
|
|
@@ -6826,6 +6826,75 @@ function defaultTickMarkFormatter(timePoint, tickMarkType, locale) {
|
|
|
6826
6826
|
return localDateFromUtc.toLocaleString(locale, formatOptions);
|
|
6827
6827
|
}
|
|
6828
6828
|
|
|
6829
|
+
const DAY = 86400;
|
|
6830
|
+
const QUARTER_HOUR = 900;
|
|
6831
|
+
const zones = new Map();
|
|
6832
|
+
function zoneCache(timeZone) {
|
|
6833
|
+
let cache = zones.get(timeZone);
|
|
6834
|
+
if (cache === undefined) {
|
|
6835
|
+
let format = null;
|
|
6836
|
+
try {
|
|
6837
|
+
format = new Intl.DateTimeFormat('en-US', {
|
|
6838
|
+
timeZone,
|
|
6839
|
+
hourCycle: 'h23',
|
|
6840
|
+
year: 'numeric',
|
|
6841
|
+
month: 'numeric',
|
|
6842
|
+
day: 'numeric',
|
|
6843
|
+
hour: 'numeric',
|
|
6844
|
+
minute: 'numeric',
|
|
6845
|
+
second: 'numeric',
|
|
6846
|
+
});
|
|
6847
|
+
}
|
|
6848
|
+
catch (error) {
|
|
6849
|
+
format = null;
|
|
6850
|
+
}
|
|
6851
|
+
cache = { _internal_format: format, _internal_days: new Map(), _internal_quarters: new Map() };
|
|
6852
|
+
zones.set(timeZone, cache);
|
|
6853
|
+
}
|
|
6854
|
+
return cache;
|
|
6855
|
+
}
|
|
6856
|
+
function exactOffset(format, time) {
|
|
6857
|
+
const parts = format.formatToParts(new Date(time * 1000));
|
|
6858
|
+
const part = (type) => Number(parts.find((p) => p.type === type)?.value ?? 0);
|
|
6859
|
+
const wallClock = Date.UTC(part('year'), part('month') - 1, part('day'), part('hour') % 24, part('minute'), part('second'));
|
|
6860
|
+
return Math.round(wallClock / 1000 - time);
|
|
6861
|
+
}
|
|
6862
|
+
/**
|
|
6863
|
+
* Offset of `timeZone` from UTC at `time`, in seconds. Undefined, `'UTC'` and
|
|
6864
|
+
* unknown zones are 0.
|
|
6865
|
+
*
|
|
6866
|
+
* Resolved once per UTC day, and to the quarter hour only on days with a
|
|
6867
|
+
* transition: asking `Intl` for every bar is too slow for a whole series.
|
|
6868
|
+
*/
|
|
6869
|
+
function timeZoneOffset(timeZone, time) {
|
|
6870
|
+
if (timeZone === undefined || timeZone === 'UTC') {
|
|
6871
|
+
return 0;
|
|
6872
|
+
}
|
|
6873
|
+
const cache = zoneCache(timeZone);
|
|
6874
|
+
const format = cache._internal_format;
|
|
6875
|
+
if (format === null) {
|
|
6876
|
+
return 0;
|
|
6877
|
+
}
|
|
6878
|
+
const day = Math.floor(time / DAY);
|
|
6879
|
+
let wholeDay = cache._internal_days.get(day);
|
|
6880
|
+
if (wholeDay === undefined) {
|
|
6881
|
+
const start = exactOffset(format, day * DAY);
|
|
6882
|
+
const end = exactOffset(format, (day + 1) * DAY - 1);
|
|
6883
|
+
wholeDay = start === end ? start : null;
|
|
6884
|
+
cache._internal_days.set(day, wholeDay);
|
|
6885
|
+
}
|
|
6886
|
+
if (wholeDay !== null) {
|
|
6887
|
+
return wholeDay;
|
|
6888
|
+
}
|
|
6889
|
+
const quarter = Math.floor(time / QUARTER_HOUR);
|
|
6890
|
+
let offset = cache._internal_quarters.get(quarter);
|
|
6891
|
+
if (offset === undefined) {
|
|
6892
|
+
offset = exactOffset(format, quarter * QUARTER_HOUR);
|
|
6893
|
+
cache._internal_quarters.set(quarter, offset);
|
|
6894
|
+
}
|
|
6895
|
+
return offset;
|
|
6896
|
+
}
|
|
6897
|
+
|
|
6829
6898
|
function hours(count) {
|
|
6830
6899
|
return count * 60 * 60 * 1000;
|
|
6831
6900
|
}
|
|
@@ -6865,29 +6934,36 @@ function weightByTime(currentDate, prevDate) {
|
|
|
6865
6934
|
function cast(t) {
|
|
6866
6935
|
return t;
|
|
6867
6936
|
}
|
|
6868
|
-
|
|
6937
|
+
// Business days are dates, not instants: never shifted
|
|
6938
|
+
function zonedTimestamp(point, timeZone) {
|
|
6939
|
+
const time = cast(point.time);
|
|
6940
|
+
return time._internal_businessDay === undefined ? time._internal_timestamp + timeZoneOffset(timeZone, time._internal_timestamp) : time._internal_timestamp;
|
|
6941
|
+
}
|
|
6942
|
+
function fillWeightsForPoints(sortedTimePoints, startIndex = 0, timeZone) {
|
|
6869
6943
|
if (sortedTimePoints.length === 0) {
|
|
6870
6944
|
return;
|
|
6871
6945
|
}
|
|
6872
|
-
let prevTime = startIndex === 0 ? null :
|
|
6946
|
+
let prevTime = startIndex === 0 ? null : zonedTimestamp(sortedTimePoints[startIndex - 1], timeZone);
|
|
6873
6947
|
let prevDate = prevTime !== null ? new Date(prevTime * 1000) : null;
|
|
6874
6948
|
let totalTimeDiff = 0;
|
|
6875
6949
|
for (let index = startIndex; index < sortedTimePoints.length; ++index) {
|
|
6876
6950
|
const currentPoint = sortedTimePoints[index];
|
|
6877
|
-
const
|
|
6951
|
+
const currentTime = zonedTimestamp(currentPoint, timeZone);
|
|
6952
|
+
const currentDate = new Date(currentTime * 1000);
|
|
6878
6953
|
if (prevDate !== null) {
|
|
6879
6954
|
currentPoint.timeWeight = weightByTime(currentDate, prevDate);
|
|
6880
6955
|
}
|
|
6881
|
-
totalTimeDiff +=
|
|
6882
|
-
prevTime =
|
|
6956
|
+
totalTimeDiff += currentTime - (prevTime || currentTime);
|
|
6957
|
+
prevTime = currentTime;
|
|
6883
6958
|
prevDate = currentDate;
|
|
6884
6959
|
}
|
|
6885
6960
|
if (startIndex === 0 && sortedTimePoints.length > 1) {
|
|
6886
6961
|
// let's guess a weight for the first point
|
|
6887
6962
|
// let's say the previous point was average time back in the history
|
|
6888
6963
|
const averageTimeDiff = Math.ceil(totalTimeDiff / (sortedTimePoints.length - 1));
|
|
6889
|
-
const
|
|
6890
|
-
|
|
6964
|
+
const firstTime = zonedTimestamp(sortedTimePoints[0], timeZone);
|
|
6965
|
+
const approxPrevDate = new Date((firstTime - averageTimeDiff) * 1000);
|
|
6966
|
+
sortedTimePoints[0].timeWeight = weightByTime(new Date(firstTime * 1000), approxPrevDate);
|
|
6891
6967
|
}
|
|
6892
6968
|
}
|
|
6893
6969
|
|
|
@@ -7042,16 +7118,15 @@ class HorzScaleBehaviorTime {
|
|
|
7042
7118
|
}
|
|
7043
7119
|
}
|
|
7044
7120
|
formatHorzItem(item) {
|
|
7045
|
-
|
|
7046
|
-
return this._private__dateTimeFormatter._internal_format(new Date(tp._internal_timestamp * 1000));
|
|
7121
|
+
return this._private__dateTimeFormatter._internal_format(new Date(this._private__zonedTimePoint(item)._internal_timestamp * 1000));
|
|
7047
7122
|
}
|
|
7048
|
-
allowsTickMark(tickMark, barsPerMark) {
|
|
7123
|
+
allowsTickMark(tickMark, barsPerMark, previous) {
|
|
7049
7124
|
const filter = this._private__options.timeScale.tickMarkFilter;
|
|
7050
7125
|
if (filter === undefined) {
|
|
7051
7126
|
return true;
|
|
7052
7127
|
}
|
|
7053
7128
|
const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
|
|
7054
|
-
return filter(tickMark.originalTime, tickMarkType, barsPerMark);
|
|
7129
|
+
return filter(tickMark.originalTime, tickMarkType, barsPerMark, previous === undefined ? null : previous.originalTime);
|
|
7055
7130
|
}
|
|
7056
7131
|
formatTickmark(tickMark, localizationOptions) {
|
|
7057
7132
|
const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
|
|
@@ -7062,7 +7137,7 @@ class HorzScaleBehaviorTime {
|
|
|
7062
7137
|
return tickMarkString;
|
|
7063
7138
|
}
|
|
7064
7139
|
}
|
|
7065
|
-
return defaultTickMarkFormatter(tickMark.time, tickMarkType, localizationOptions.locale);
|
|
7140
|
+
return defaultTickMarkFormatter(this._private__zonedTimePoint(tickMark.time), tickMarkType, localizationOptions.locale);
|
|
7066
7141
|
}
|
|
7067
7142
|
maxTickMarkWeight(tickMarks) {
|
|
7068
7143
|
let maxWeight = tickMarks.reduce(markWithGreaterWeight$2, tickMarks[0]).weight;
|
|
@@ -7074,7 +7149,17 @@ class HorzScaleBehaviorTime {
|
|
|
7074
7149
|
return maxWeight;
|
|
7075
7150
|
}
|
|
7076
7151
|
fillWeightsForPoints(sortedTimePoints, startIndex) {
|
|
7077
|
-
fillWeightsForPoints(sortedTimePoints, startIndex);
|
|
7152
|
+
fillWeightsForPoints(sortedTimePoints, startIndex, this._private__timeZone());
|
|
7153
|
+
}
|
|
7154
|
+
_private__timeZone() {
|
|
7155
|
+
return this._private__options?.localization.timeZone;
|
|
7156
|
+
}
|
|
7157
|
+
_private__zonedTimePoint(timePoint) {
|
|
7158
|
+
if (timePoint._internal_businessDay !== undefined) {
|
|
7159
|
+
return timePoint;
|
|
7160
|
+
}
|
|
7161
|
+
const offset = timeZoneOffset(this._private__timeZone(), timePoint._internal_timestamp);
|
|
7162
|
+
return offset === 0 ? timePoint : { _internal_timestamp: (timePoint._internal_timestamp + offset) };
|
|
7078
7163
|
}
|
|
7079
7164
|
static _internal_applyDefaults(options) {
|
|
7080
7165
|
return merge({ localization: { dateFormat: 'dd MMM \'yy' } }, options ?? {});
|
|
@@ -11076,6 +11161,10 @@ class DataLayer {
|
|
|
11076
11161
|
this._private__sortedTimePoints = [];
|
|
11077
11162
|
this._private__horzScaleBehavior = horzScaleBehavior;
|
|
11078
11163
|
}
|
|
11164
|
+
_internal_refillTimeWeights() {
|
|
11165
|
+
this._private__horzScaleBehavior.fillWeightsForPoints(this._private__sortedTimePoints, 0);
|
|
11166
|
+
return this._private__sortedTimePoints;
|
|
11167
|
+
}
|
|
11079
11168
|
_internal_destroy() {
|
|
11080
11169
|
this._private__pointDataByTimePoint.clear();
|
|
11081
11170
|
this._private__seriesRowsBySeries.clear();
|
|
@@ -12580,7 +12669,13 @@ class ChartApi {
|
|
|
12580
12669
|
throw new Error(`colorParsers option should not be changed once the chart has been created.`);
|
|
12581
12670
|
}
|
|
12582
12671
|
}
|
|
12672
|
+
const timeZone = this.options().localization.timeZone;
|
|
12583
12673
|
this._private__chartWidget._internal_applyOptions(toInternalOptions(options));
|
|
12674
|
+
if (this.options().localization.timeZone !== timeZone) {
|
|
12675
|
+
const model = this._private__chartWidget._internal_model();
|
|
12676
|
+
model._internal_timeScale()._internal_update(this._private__dataLayer._internal_refillTimeWeights(), 0);
|
|
12677
|
+
model._internal_fullUpdate();
|
|
12678
|
+
}
|
|
12584
12679
|
}
|
|
12585
12680
|
options() {
|
|
12586
12681
|
return this._private__chartWidget._internal_options();
|
|
@@ -19218,8 +19313,9 @@ class TradingSessionsPaneView {
|
|
|
19218
19313
|
const DEFAULT_SESSIONS = [
|
|
19219
19314
|
{
|
|
19220
19315
|
name: 'Tokyo',
|
|
19221
|
-
startHour:
|
|
19222
|
-
endHour:
|
|
19316
|
+
startHour: 9,
|
|
19317
|
+
endHour: 18,
|
|
19318
|
+
timeZone: 'Asia/Tokyo',
|
|
19223
19319
|
color: '#FF6B00',
|
|
19224
19320
|
opacity: 0.1,
|
|
19225
19321
|
},
|
|
@@ -19227,13 +19323,15 @@ const DEFAULT_SESSIONS = [
|
|
|
19227
19323
|
name: 'London',
|
|
19228
19324
|
startHour: 8,
|
|
19229
19325
|
endHour: 17,
|
|
19326
|
+
timeZone: 'Europe/London',
|
|
19230
19327
|
color: '#2962FF',
|
|
19231
19328
|
opacity: 0.1,
|
|
19232
19329
|
},
|
|
19233
19330
|
{
|
|
19234
19331
|
name: 'New York',
|
|
19235
|
-
startHour:
|
|
19236
|
-
endHour:
|
|
19332
|
+
startHour: 8,
|
|
19333
|
+
endHour: 17,
|
|
19334
|
+
timeZone: 'America/New_York',
|
|
19237
19335
|
color: '#089981',
|
|
19238
19336
|
opacity: 0.1,
|
|
19239
19337
|
},
|
|
@@ -19319,79 +19417,49 @@ class TradingSessionsIndicator {
|
|
|
19319
19417
|
}
|
|
19320
19418
|
}
|
|
19321
19419
|
_private__highlightSession(session, data) {
|
|
19322
|
-
|
|
19323
|
-
let sessionData = [];
|
|
19324
|
-
for (const point of data) {
|
|
19325
|
-
const time = point.time;
|
|
19326
|
-
const hour = this._private__getUTCHour(time);
|
|
19327
|
-
const isInSession = this._private__isTimeInSession(hour, session.startHour, session.endHour);
|
|
19328
|
-
if (isInSession) {
|
|
19329
|
-
if (!sessionStart) {
|
|
19330
|
-
sessionStart = time;
|
|
19331
|
-
}
|
|
19332
|
-
sessionData.push(point);
|
|
19333
|
-
}
|
|
19334
|
-
else {
|
|
19335
|
-
if (sessionStart && sessionData.length > 0) {
|
|
19336
|
-
// End of session, create highlight box
|
|
19337
|
-
this._private__createSessionBox(sessionStart, sessionData[sessionData.length - 1].time, session);
|
|
19338
|
-
sessionStart = null;
|
|
19339
|
-
sessionData = [];
|
|
19340
|
-
}
|
|
19341
|
-
}
|
|
19342
|
-
}
|
|
19343
|
-
// Handle case where session extends to end of visible range
|
|
19344
|
-
if (sessionStart && sessionData.length > 0) {
|
|
19345
|
-
this._private__createSessionBox(sessionStart, sessionData[sessionData.length - 1].time, session);
|
|
19346
|
-
}
|
|
19420
|
+
this._private__eachRun(data, (time) => this._private__inSession(time, session), (startTime, endTime) => this._private__createSessionBox(startTime, endTime, session));
|
|
19347
19421
|
}
|
|
19422
|
+
// Per bar, since each session reads the clock of its own zone
|
|
19348
19423
|
_private__highlightOverlaps(data) {
|
|
19349
|
-
// Find overlapping sessions
|
|
19350
19424
|
const sessions = this._private__options.sessions;
|
|
19351
19425
|
for (let i = 0; i < sessions.length; i++) {
|
|
19352
19426
|
for (let j = i + 1; j < sessions.length; j++) {
|
|
19353
|
-
|
|
19354
|
-
const session2 = sessions[j];
|
|
19355
|
-
// Check if sessions overlap
|
|
19356
|
-
const overlap = this._private__getSessionOverlap(session1, session2);
|
|
19357
|
-
if (overlap) {
|
|
19358
|
-
this._private__highlightOverlapPeriod(overlap, data);
|
|
19359
|
-
}
|
|
19427
|
+
this._private__eachRun(data, (time) => this._private__inSession(time, sessions[i]) && this._private__inSession(time, sessions[j]), (startTime, endTime) => this._private__createOverlapBox(startTime, endTime));
|
|
19360
19428
|
}
|
|
19361
19429
|
}
|
|
19362
19430
|
}
|
|
19363
|
-
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
if (start < end) {
|
|
19367
|
-
return { _internal_start: start, _internal_end: end };
|
|
19368
|
-
}
|
|
19369
|
-
return null;
|
|
19370
|
-
}
|
|
19371
|
-
_private__highlightOverlapPeriod(overlap, data) {
|
|
19372
|
-
let overlapStart = null;
|
|
19373
|
-
let overlapData = [];
|
|
19431
|
+
_private__eachRun(data, inside, emit) {
|
|
19432
|
+
let runStart = null;
|
|
19433
|
+
let runEnd = null;
|
|
19374
19434
|
for (const point of data) {
|
|
19375
|
-
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
if (isInOverlap) {
|
|
19379
|
-
if (!overlapStart) {
|
|
19380
|
-
overlapStart = time;
|
|
19381
|
-
}
|
|
19382
|
-
overlapData.push(point);
|
|
19435
|
+
if (inside(point.time)) {
|
|
19436
|
+
runStart = runStart ?? point.time;
|
|
19437
|
+
runEnd = point.time;
|
|
19383
19438
|
}
|
|
19384
|
-
else {
|
|
19385
|
-
|
|
19386
|
-
|
|
19387
|
-
|
|
19388
|
-
overlapData = [];
|
|
19389
|
-
}
|
|
19439
|
+
else if (runStart !== null && runEnd !== null) {
|
|
19440
|
+
emit(runStart, runEnd);
|
|
19441
|
+
runStart = null;
|
|
19442
|
+
runEnd = null;
|
|
19390
19443
|
}
|
|
19391
19444
|
}
|
|
19392
|
-
if (
|
|
19393
|
-
|
|
19445
|
+
if (runStart !== null && runEnd !== null) {
|
|
19446
|
+
emit(runStart, runEnd);
|
|
19447
|
+
}
|
|
19448
|
+
}
|
|
19449
|
+
_private__inSession(time, session) {
|
|
19450
|
+
const hour = this._private__hourIn(time, session.timeZone);
|
|
19451
|
+
if (session.startHour < session.endHour) {
|
|
19452
|
+
return hour >= session.startHour && hour < session.endHour;
|
|
19453
|
+
}
|
|
19454
|
+
// Crosses midnight
|
|
19455
|
+
return hour >= session.startHour || hour < session.endHour;
|
|
19456
|
+
}
|
|
19457
|
+
_private__hourIn(time, timeZone) {
|
|
19458
|
+
const seconds = typeof time === 'number' ? time : typeof time === 'string' ? Date.parse(time) / 1000 : NaN;
|
|
19459
|
+
if (!Number.isFinite(seconds)) {
|
|
19460
|
+
return 0;
|
|
19394
19461
|
}
|
|
19462
|
+
return new Date((seconds + timeZoneOffset(timeZone, seconds)) * 1000).getUTCHours();
|
|
19395
19463
|
}
|
|
19396
19464
|
_private__createSessionBox(startTime, endTime, session) {
|
|
19397
19465
|
// Validate times
|
|
@@ -19421,29 +19489,6 @@ class TradingSessionsIndicator {
|
|
|
19421
19489
|
};
|
|
19422
19490
|
this._private__sessionBoxes.push(box);
|
|
19423
19491
|
}
|
|
19424
|
-
_private__isTimeInSession(hour, startHour, endHour) {
|
|
19425
|
-
if (startHour < endHour) {
|
|
19426
|
-
return hour >= startHour && hour < endHour;
|
|
19427
|
-
}
|
|
19428
|
-
else {
|
|
19429
|
-
// Session crosses midnight
|
|
19430
|
-
return hour >= startHour || hour < endHour;
|
|
19431
|
-
}
|
|
19432
|
-
}
|
|
19433
|
-
_private__getUTCHour(time) {
|
|
19434
|
-
// Convert time to UTC hour
|
|
19435
|
-
if (typeof time === 'number') {
|
|
19436
|
-
// Unix timestamp in seconds
|
|
19437
|
-
const date = new Date(time * 1000);
|
|
19438
|
-
return date.getUTCHours();
|
|
19439
|
-
}
|
|
19440
|
-
else if (typeof time === 'string') {
|
|
19441
|
-
// ISO string
|
|
19442
|
-
const date = new Date(time);
|
|
19443
|
-
return date.getUTCHours();
|
|
19444
|
-
}
|
|
19445
|
-
return 0;
|
|
19446
|
-
}
|
|
19447
19492
|
_private__clearSessionBoxes() {
|
|
19448
19493
|
// Clear all session boxes
|
|
19449
19494
|
this._private__sessionBoxes = [];
|
|
@@ -30596,6 +30641,14 @@ function createGanttTool(context, options) {
|
|
|
30596
30641
|
|
|
30597
30642
|
/** Undo steps kept, each a full snapshot of every drawing. */
|
|
30598
30643
|
const UNDO_HISTORY_LIMIT = 100;
|
|
30644
|
+
/**
|
|
30645
|
+
* Points for a restored freehand tool. Built with bracket notation: a plain
|
|
30646
|
+
* `{ time, price }` literal gets its keys renamed by the build, and the tool,
|
|
30647
|
+
* which reads them by their public names, comes back drawing nothing.
|
|
30648
|
+
*/
|
|
30649
|
+
function restorePoints(points) {
|
|
30650
|
+
return points.map((point) => makeSerializedPoint(readSerializedNumber(point, 'price') ?? 0, readSerializedTime(point)));
|
|
30651
|
+
}
|
|
30599
30652
|
/**
|
|
30600
30653
|
* Central manager for all drawing tools - TradingView style
|
|
30601
30654
|
* Handles multiple tools, selection, deletion, and keyboard shortcuts
|
|
@@ -31075,16 +31128,8 @@ class DrawingToolsManager {
|
|
|
31075
31128
|
...style,
|
|
31076
31129
|
});
|
|
31077
31130
|
case 'polygon':
|
|
31078
|
-
// Bracket notation on the way out too, not just on the way in: a
|
|
31079
|
-
// plain `{ time, price }` literal here gets its keys renamed and
|
|
31080
|
-
// the restored corners come back empty.
|
|
31081
31131
|
return createPolygonTool(context, {
|
|
31082
|
-
points: points
|
|
31083
|
-
const vertex = {};
|
|
31084
|
-
vertex['time'] = pt(index)._internal_t;
|
|
31085
|
-
vertex['price'] = pt(index)._internal_p;
|
|
31086
|
-
return vertex;
|
|
31087
|
-
}),
|
|
31132
|
+
points: restorePoints(points),
|
|
31088
31133
|
...style,
|
|
31089
31134
|
});
|
|
31090
31135
|
case 'crossLine':
|
|
@@ -31150,12 +31195,12 @@ class DrawingToolsManager {
|
|
|
31150
31195
|
});
|
|
31151
31196
|
case 'arrow':
|
|
31152
31197
|
return createArrowTool(context, {
|
|
31153
|
-
points: points
|
|
31198
|
+
points: restorePoints(points),
|
|
31154
31199
|
...style,
|
|
31155
31200
|
});
|
|
31156
31201
|
case 'brush':
|
|
31157
31202
|
return createBrushTool(context, {
|
|
31158
|
-
points: points
|
|
31203
|
+
points: restorePoints(points),
|
|
31159
31204
|
...style,
|
|
31160
31205
|
});
|
|
31161
31206
|
case 'text':
|
|
@@ -31627,7 +31672,7 @@ const customSeriesDefaultOptions = {
|
|
|
31627
31672
|
* Returns the current version as a string. For example `'1.0.0'`.
|
|
31628
31673
|
*/
|
|
31629
31674
|
function version() {
|
|
31630
|
-
return "2.3.
|
|
31675
|
+
return "2.3.20-dev+202610211649";
|
|
31631
31676
|
}
|
|
31632
31677
|
|
|
31633
|
-
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 };
|
|
31678
|
+
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, timeZoneOffset, version };
|