@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)
|
|
@@ -5554,7 +5554,7 @@ class TimeScale {
|
|
|
5554
5554
|
const visibleBars = ensureNotNull(this._internal_visibleStrictRange());
|
|
5555
5555
|
const firstBar = Math.max(visibleBars._internal_left(), visibleBars._internal_left() - indexPerLabel);
|
|
5556
5556
|
const lastBar = Math.max(visibleBars._internal_right(), visibleBars._internal_right() - indexPerLabel);
|
|
5557
|
-
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);
|
|
5557
|
+
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);
|
|
5558
5558
|
// according to indexPerLabel value this value means "earliest index which _might be_ used as the second label on time scale"
|
|
5559
5559
|
const earliestIndexOfSecondLabel = this._private__firstIndex() + indexPerLabel;
|
|
5560
5560
|
// according to indexPerLabel value this value means "earliest index which _might be_ used as the second last label on time scale"
|
|
@@ -6828,6 +6828,75 @@ function defaultTickMarkFormatter(timePoint, tickMarkType, locale) {
|
|
|
6828
6828
|
return localDateFromUtc.toLocaleString(locale, formatOptions);
|
|
6829
6829
|
}
|
|
6830
6830
|
|
|
6831
|
+
const DAY = 86400;
|
|
6832
|
+
const QUARTER_HOUR = 900;
|
|
6833
|
+
const zones = new Map();
|
|
6834
|
+
function zoneCache(timeZone) {
|
|
6835
|
+
let cache = zones.get(timeZone);
|
|
6836
|
+
if (cache === undefined) {
|
|
6837
|
+
let format = null;
|
|
6838
|
+
try {
|
|
6839
|
+
format = new Intl.DateTimeFormat('en-US', {
|
|
6840
|
+
timeZone,
|
|
6841
|
+
hourCycle: 'h23',
|
|
6842
|
+
year: 'numeric',
|
|
6843
|
+
month: 'numeric',
|
|
6844
|
+
day: 'numeric',
|
|
6845
|
+
hour: 'numeric',
|
|
6846
|
+
minute: 'numeric',
|
|
6847
|
+
second: 'numeric',
|
|
6848
|
+
});
|
|
6849
|
+
}
|
|
6850
|
+
catch (error) {
|
|
6851
|
+
format = null;
|
|
6852
|
+
}
|
|
6853
|
+
cache = { _internal_format: format, _internal_days: new Map(), _internal_quarters: new Map() };
|
|
6854
|
+
zones.set(timeZone, cache);
|
|
6855
|
+
}
|
|
6856
|
+
return cache;
|
|
6857
|
+
}
|
|
6858
|
+
function exactOffset(format, time) {
|
|
6859
|
+
const parts = format.formatToParts(new Date(time * 1000));
|
|
6860
|
+
const part = (type) => Number(parts.find((p) => p.type === type)?.value ?? 0);
|
|
6861
|
+
const wallClock = Date.UTC(part('year'), part('month') - 1, part('day'), part('hour') % 24, part('minute'), part('second'));
|
|
6862
|
+
return Math.round(wallClock / 1000 - time);
|
|
6863
|
+
}
|
|
6864
|
+
/**
|
|
6865
|
+
* Offset of `timeZone` from UTC at `time`, in seconds. Undefined, `'UTC'` and
|
|
6866
|
+
* unknown zones are 0.
|
|
6867
|
+
*
|
|
6868
|
+
* Resolved once per UTC day, and to the quarter hour only on days with a
|
|
6869
|
+
* transition: asking `Intl` for every bar is too slow for a whole series.
|
|
6870
|
+
*/
|
|
6871
|
+
function timeZoneOffset(timeZone, time) {
|
|
6872
|
+
if (timeZone === undefined || timeZone === 'UTC') {
|
|
6873
|
+
return 0;
|
|
6874
|
+
}
|
|
6875
|
+
const cache = zoneCache(timeZone);
|
|
6876
|
+
const format = cache._internal_format;
|
|
6877
|
+
if (format === null) {
|
|
6878
|
+
return 0;
|
|
6879
|
+
}
|
|
6880
|
+
const day = Math.floor(time / DAY);
|
|
6881
|
+
let wholeDay = cache._internal_days.get(day);
|
|
6882
|
+
if (wholeDay === undefined) {
|
|
6883
|
+
const start = exactOffset(format, day * DAY);
|
|
6884
|
+
const end = exactOffset(format, (day + 1) * DAY - 1);
|
|
6885
|
+
wholeDay = start === end ? start : null;
|
|
6886
|
+
cache._internal_days.set(day, wholeDay);
|
|
6887
|
+
}
|
|
6888
|
+
if (wholeDay !== null) {
|
|
6889
|
+
return wholeDay;
|
|
6890
|
+
}
|
|
6891
|
+
const quarter = Math.floor(time / QUARTER_HOUR);
|
|
6892
|
+
let offset = cache._internal_quarters.get(quarter);
|
|
6893
|
+
if (offset === undefined) {
|
|
6894
|
+
offset = exactOffset(format, quarter * QUARTER_HOUR);
|
|
6895
|
+
cache._internal_quarters.set(quarter, offset);
|
|
6896
|
+
}
|
|
6897
|
+
return offset;
|
|
6898
|
+
}
|
|
6899
|
+
|
|
6831
6900
|
function hours(count) {
|
|
6832
6901
|
return count * 60 * 60 * 1000;
|
|
6833
6902
|
}
|
|
@@ -6867,29 +6936,36 @@ function weightByTime(currentDate, prevDate) {
|
|
|
6867
6936
|
function cast(t) {
|
|
6868
6937
|
return t;
|
|
6869
6938
|
}
|
|
6870
|
-
|
|
6939
|
+
// Business days are dates, not instants: never shifted
|
|
6940
|
+
function zonedTimestamp(point, timeZone) {
|
|
6941
|
+
const time = cast(point.time);
|
|
6942
|
+
return time._internal_businessDay === undefined ? time._internal_timestamp + timeZoneOffset(timeZone, time._internal_timestamp) : time._internal_timestamp;
|
|
6943
|
+
}
|
|
6944
|
+
function fillWeightsForPoints(sortedTimePoints, startIndex = 0, timeZone) {
|
|
6871
6945
|
if (sortedTimePoints.length === 0) {
|
|
6872
6946
|
return;
|
|
6873
6947
|
}
|
|
6874
|
-
let prevTime = startIndex === 0 ? null :
|
|
6948
|
+
let prevTime = startIndex === 0 ? null : zonedTimestamp(sortedTimePoints[startIndex - 1], timeZone);
|
|
6875
6949
|
let prevDate = prevTime !== null ? new Date(prevTime * 1000) : null;
|
|
6876
6950
|
let totalTimeDiff = 0;
|
|
6877
6951
|
for (let index = startIndex; index < sortedTimePoints.length; ++index) {
|
|
6878
6952
|
const currentPoint = sortedTimePoints[index];
|
|
6879
|
-
const
|
|
6953
|
+
const currentTime = zonedTimestamp(currentPoint, timeZone);
|
|
6954
|
+
const currentDate = new Date(currentTime * 1000);
|
|
6880
6955
|
if (prevDate !== null) {
|
|
6881
6956
|
currentPoint.timeWeight = weightByTime(currentDate, prevDate);
|
|
6882
6957
|
}
|
|
6883
|
-
totalTimeDiff +=
|
|
6884
|
-
prevTime =
|
|
6958
|
+
totalTimeDiff += currentTime - (prevTime || currentTime);
|
|
6959
|
+
prevTime = currentTime;
|
|
6885
6960
|
prevDate = currentDate;
|
|
6886
6961
|
}
|
|
6887
6962
|
if (startIndex === 0 && sortedTimePoints.length > 1) {
|
|
6888
6963
|
// let's guess a weight for the first point
|
|
6889
6964
|
// let's say the previous point was average time back in the history
|
|
6890
6965
|
const averageTimeDiff = Math.ceil(totalTimeDiff / (sortedTimePoints.length - 1));
|
|
6891
|
-
const
|
|
6892
|
-
|
|
6966
|
+
const firstTime = zonedTimestamp(sortedTimePoints[0], timeZone);
|
|
6967
|
+
const approxPrevDate = new Date((firstTime - averageTimeDiff) * 1000);
|
|
6968
|
+
sortedTimePoints[0].timeWeight = weightByTime(new Date(firstTime * 1000), approxPrevDate);
|
|
6893
6969
|
}
|
|
6894
6970
|
}
|
|
6895
6971
|
|
|
@@ -7044,16 +7120,15 @@ class HorzScaleBehaviorTime {
|
|
|
7044
7120
|
}
|
|
7045
7121
|
}
|
|
7046
7122
|
formatHorzItem(item) {
|
|
7047
|
-
|
|
7048
|
-
return this._private__dateTimeFormatter._internal_format(new Date(tp._internal_timestamp * 1000));
|
|
7123
|
+
return this._private__dateTimeFormatter._internal_format(new Date(this._private__zonedTimePoint(item)._internal_timestamp * 1000));
|
|
7049
7124
|
}
|
|
7050
|
-
allowsTickMark(tickMark, barsPerMark) {
|
|
7125
|
+
allowsTickMark(tickMark, barsPerMark, previous) {
|
|
7051
7126
|
const filter = this._private__options.timeScale.tickMarkFilter;
|
|
7052
7127
|
if (filter === undefined) {
|
|
7053
7128
|
return true;
|
|
7054
7129
|
}
|
|
7055
7130
|
const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
|
|
7056
|
-
return filter(tickMark.originalTime, tickMarkType, barsPerMark);
|
|
7131
|
+
return filter(tickMark.originalTime, tickMarkType, barsPerMark, previous === undefined ? null : previous.originalTime);
|
|
7057
7132
|
}
|
|
7058
7133
|
formatTickmark(tickMark, localizationOptions) {
|
|
7059
7134
|
const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
|
|
@@ -7064,7 +7139,7 @@ class HorzScaleBehaviorTime {
|
|
|
7064
7139
|
return tickMarkString;
|
|
7065
7140
|
}
|
|
7066
7141
|
}
|
|
7067
|
-
return defaultTickMarkFormatter(tickMark.time, tickMarkType, localizationOptions.locale);
|
|
7142
|
+
return defaultTickMarkFormatter(this._private__zonedTimePoint(tickMark.time), tickMarkType, localizationOptions.locale);
|
|
7068
7143
|
}
|
|
7069
7144
|
maxTickMarkWeight(tickMarks) {
|
|
7070
7145
|
let maxWeight = tickMarks.reduce(markWithGreaterWeight$2, tickMarks[0]).weight;
|
|
@@ -7076,7 +7151,17 @@ class HorzScaleBehaviorTime {
|
|
|
7076
7151
|
return maxWeight;
|
|
7077
7152
|
}
|
|
7078
7153
|
fillWeightsForPoints(sortedTimePoints, startIndex) {
|
|
7079
|
-
fillWeightsForPoints(sortedTimePoints, startIndex);
|
|
7154
|
+
fillWeightsForPoints(sortedTimePoints, startIndex, this._private__timeZone());
|
|
7155
|
+
}
|
|
7156
|
+
_private__timeZone() {
|
|
7157
|
+
return this._private__options?.localization.timeZone;
|
|
7158
|
+
}
|
|
7159
|
+
_private__zonedTimePoint(timePoint) {
|
|
7160
|
+
if (timePoint._internal_businessDay !== undefined) {
|
|
7161
|
+
return timePoint;
|
|
7162
|
+
}
|
|
7163
|
+
const offset = timeZoneOffset(this._private__timeZone(), timePoint._internal_timestamp);
|
|
7164
|
+
return offset === 0 ? timePoint : { _internal_timestamp: (timePoint._internal_timestamp + offset) };
|
|
7080
7165
|
}
|
|
7081
7166
|
static _internal_applyDefaults(options) {
|
|
7082
7167
|
return merge({ localization: { dateFormat: 'dd MMM \'yy' } }, options ?? {});
|
|
@@ -10683,6 +10768,10 @@ class DataLayer {
|
|
|
10683
10768
|
this._private__sortedTimePoints = [];
|
|
10684
10769
|
this._private__horzScaleBehavior = horzScaleBehavior;
|
|
10685
10770
|
}
|
|
10771
|
+
_internal_refillTimeWeights() {
|
|
10772
|
+
this._private__horzScaleBehavior.fillWeightsForPoints(this._private__sortedTimePoints, 0);
|
|
10773
|
+
return this._private__sortedTimePoints;
|
|
10774
|
+
}
|
|
10686
10775
|
_internal_destroy() {
|
|
10687
10776
|
this._private__pointDataByTimePoint.clear();
|
|
10688
10777
|
this._private__seriesRowsBySeries.clear();
|
|
@@ -12187,7 +12276,13 @@ class ChartApi {
|
|
|
12187
12276
|
throw new Error(`colorParsers option should not be changed once the chart has been created.`);
|
|
12188
12277
|
}
|
|
12189
12278
|
}
|
|
12279
|
+
const timeZone = this.options().localization.timeZone;
|
|
12190
12280
|
this._private__chartWidget._internal_applyOptions(toInternalOptions(options));
|
|
12281
|
+
if (this.options().localization.timeZone !== timeZone) {
|
|
12282
|
+
const model = this._private__chartWidget._internal_model();
|
|
12283
|
+
model._internal_timeScale()._internal_update(this._private__dataLayer._internal_refillTimeWeights(), 0);
|
|
12284
|
+
model._internal_fullUpdate();
|
|
12285
|
+
}
|
|
12191
12286
|
}
|
|
12192
12287
|
options() {
|
|
12193
12288
|
return this._private__chartWidget._internal_options();
|
|
@@ -18825,8 +18920,9 @@ class TradingSessionsPaneView {
|
|
|
18825
18920
|
const DEFAULT_SESSIONS = [
|
|
18826
18921
|
{
|
|
18827
18922
|
name: 'Tokyo',
|
|
18828
|
-
startHour:
|
|
18829
|
-
endHour:
|
|
18923
|
+
startHour: 9,
|
|
18924
|
+
endHour: 18,
|
|
18925
|
+
timeZone: 'Asia/Tokyo',
|
|
18830
18926
|
color: '#FF6B00',
|
|
18831
18927
|
opacity: 0.1,
|
|
18832
18928
|
},
|
|
@@ -18834,13 +18930,15 @@ const DEFAULT_SESSIONS = [
|
|
|
18834
18930
|
name: 'London',
|
|
18835
18931
|
startHour: 8,
|
|
18836
18932
|
endHour: 17,
|
|
18933
|
+
timeZone: 'Europe/London',
|
|
18837
18934
|
color: '#2962FF',
|
|
18838
18935
|
opacity: 0.1,
|
|
18839
18936
|
},
|
|
18840
18937
|
{
|
|
18841
18938
|
name: 'New York',
|
|
18842
|
-
startHour:
|
|
18843
|
-
endHour:
|
|
18939
|
+
startHour: 8,
|
|
18940
|
+
endHour: 17,
|
|
18941
|
+
timeZone: 'America/New_York',
|
|
18844
18942
|
color: '#089981',
|
|
18845
18943
|
opacity: 0.1,
|
|
18846
18944
|
},
|
|
@@ -18926,79 +19024,49 @@ class TradingSessionsIndicator {
|
|
|
18926
19024
|
}
|
|
18927
19025
|
}
|
|
18928
19026
|
_private__highlightSession(session, data) {
|
|
18929
|
-
|
|
18930
|
-
let sessionData = [];
|
|
18931
|
-
for (const point of data) {
|
|
18932
|
-
const time = point.time;
|
|
18933
|
-
const hour = this._private__getUTCHour(time);
|
|
18934
|
-
const isInSession = this._private__isTimeInSession(hour, session.startHour, session.endHour);
|
|
18935
|
-
if (isInSession) {
|
|
18936
|
-
if (!sessionStart) {
|
|
18937
|
-
sessionStart = time;
|
|
18938
|
-
}
|
|
18939
|
-
sessionData.push(point);
|
|
18940
|
-
}
|
|
18941
|
-
else {
|
|
18942
|
-
if (sessionStart && sessionData.length > 0) {
|
|
18943
|
-
// End of session, create highlight box
|
|
18944
|
-
this._private__createSessionBox(sessionStart, sessionData[sessionData.length - 1].time, session);
|
|
18945
|
-
sessionStart = null;
|
|
18946
|
-
sessionData = [];
|
|
18947
|
-
}
|
|
18948
|
-
}
|
|
18949
|
-
}
|
|
18950
|
-
// Handle case where session extends to end of visible range
|
|
18951
|
-
if (sessionStart && sessionData.length > 0) {
|
|
18952
|
-
this._private__createSessionBox(sessionStart, sessionData[sessionData.length - 1].time, session);
|
|
18953
|
-
}
|
|
19027
|
+
this._private__eachRun(data, (time) => this._private__inSession(time, session), (startTime, endTime) => this._private__createSessionBox(startTime, endTime, session));
|
|
18954
19028
|
}
|
|
19029
|
+
// Per bar, since each session reads the clock of its own zone
|
|
18955
19030
|
_private__highlightOverlaps(data) {
|
|
18956
|
-
// Find overlapping sessions
|
|
18957
19031
|
const sessions = this._private__options.sessions;
|
|
18958
19032
|
for (let i = 0; i < sessions.length; i++) {
|
|
18959
19033
|
for (let j = i + 1; j < sessions.length; j++) {
|
|
18960
|
-
|
|
18961
|
-
const session2 = sessions[j];
|
|
18962
|
-
// Check if sessions overlap
|
|
18963
|
-
const overlap = this._private__getSessionOverlap(session1, session2);
|
|
18964
|
-
if (overlap) {
|
|
18965
|
-
this._private__highlightOverlapPeriod(overlap, data);
|
|
18966
|
-
}
|
|
19034
|
+
this._private__eachRun(data, (time) => this._private__inSession(time, sessions[i]) && this._private__inSession(time, sessions[j]), (startTime, endTime) => this._private__createOverlapBox(startTime, endTime));
|
|
18967
19035
|
}
|
|
18968
19036
|
}
|
|
18969
19037
|
}
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
if (start < end) {
|
|
18974
|
-
return { _internal_start: start, _internal_end: end };
|
|
18975
|
-
}
|
|
18976
|
-
return null;
|
|
18977
|
-
}
|
|
18978
|
-
_private__highlightOverlapPeriod(overlap, data) {
|
|
18979
|
-
let overlapStart = null;
|
|
18980
|
-
let overlapData = [];
|
|
19038
|
+
_private__eachRun(data, inside, emit) {
|
|
19039
|
+
let runStart = null;
|
|
19040
|
+
let runEnd = null;
|
|
18981
19041
|
for (const point of data) {
|
|
18982
|
-
|
|
18983
|
-
|
|
18984
|
-
|
|
18985
|
-
if (isInOverlap) {
|
|
18986
|
-
if (!overlapStart) {
|
|
18987
|
-
overlapStart = time;
|
|
18988
|
-
}
|
|
18989
|
-
overlapData.push(point);
|
|
19042
|
+
if (inside(point.time)) {
|
|
19043
|
+
runStart = runStart ?? point.time;
|
|
19044
|
+
runEnd = point.time;
|
|
18990
19045
|
}
|
|
18991
|
-
else {
|
|
18992
|
-
|
|
18993
|
-
|
|
18994
|
-
|
|
18995
|
-
overlapData = [];
|
|
18996
|
-
}
|
|
19046
|
+
else if (runStart !== null && runEnd !== null) {
|
|
19047
|
+
emit(runStart, runEnd);
|
|
19048
|
+
runStart = null;
|
|
19049
|
+
runEnd = null;
|
|
18997
19050
|
}
|
|
18998
19051
|
}
|
|
18999
|
-
if (
|
|
19000
|
-
|
|
19052
|
+
if (runStart !== null && runEnd !== null) {
|
|
19053
|
+
emit(runStart, runEnd);
|
|
19054
|
+
}
|
|
19055
|
+
}
|
|
19056
|
+
_private__inSession(time, session) {
|
|
19057
|
+
const hour = this._private__hourIn(time, session.timeZone);
|
|
19058
|
+
if (session.startHour < session.endHour) {
|
|
19059
|
+
return hour >= session.startHour && hour < session.endHour;
|
|
19060
|
+
}
|
|
19061
|
+
// Crosses midnight
|
|
19062
|
+
return hour >= session.startHour || hour < session.endHour;
|
|
19063
|
+
}
|
|
19064
|
+
_private__hourIn(time, timeZone) {
|
|
19065
|
+
const seconds = typeof time === 'number' ? time : typeof time === 'string' ? Date.parse(time) / 1000 : NaN;
|
|
19066
|
+
if (!Number.isFinite(seconds)) {
|
|
19067
|
+
return 0;
|
|
19001
19068
|
}
|
|
19069
|
+
return new Date((seconds + timeZoneOffset(timeZone, seconds)) * 1000).getUTCHours();
|
|
19002
19070
|
}
|
|
19003
19071
|
_private__createSessionBox(startTime, endTime, session) {
|
|
19004
19072
|
// Validate times
|
|
@@ -19028,29 +19096,6 @@ class TradingSessionsIndicator {
|
|
|
19028
19096
|
};
|
|
19029
19097
|
this._private__sessionBoxes.push(box);
|
|
19030
19098
|
}
|
|
19031
|
-
_private__isTimeInSession(hour, startHour, endHour) {
|
|
19032
|
-
if (startHour < endHour) {
|
|
19033
|
-
return hour >= startHour && hour < endHour;
|
|
19034
|
-
}
|
|
19035
|
-
else {
|
|
19036
|
-
// Session crosses midnight
|
|
19037
|
-
return hour >= startHour || hour < endHour;
|
|
19038
|
-
}
|
|
19039
|
-
}
|
|
19040
|
-
_private__getUTCHour(time) {
|
|
19041
|
-
// Convert time to UTC hour
|
|
19042
|
-
if (typeof time === 'number') {
|
|
19043
|
-
// Unix timestamp in seconds
|
|
19044
|
-
const date = new Date(time * 1000);
|
|
19045
|
-
return date.getUTCHours();
|
|
19046
|
-
}
|
|
19047
|
-
else if (typeof time === 'string') {
|
|
19048
|
-
// ISO string
|
|
19049
|
-
const date = new Date(time);
|
|
19050
|
-
return date.getUTCHours();
|
|
19051
|
-
}
|
|
19052
|
-
return 0;
|
|
19053
|
-
}
|
|
19054
19099
|
_private__clearSessionBoxes() {
|
|
19055
19100
|
// Clear all session boxes
|
|
19056
19101
|
this._private__sessionBoxes = [];
|
|
@@ -30203,6 +30248,14 @@ function createGanttTool(context, options) {
|
|
|
30203
30248
|
|
|
30204
30249
|
/** Undo steps kept, each a full snapshot of every drawing. */
|
|
30205
30250
|
const UNDO_HISTORY_LIMIT = 100;
|
|
30251
|
+
/**
|
|
30252
|
+
* Points for a restored freehand tool. Built with bracket notation: a plain
|
|
30253
|
+
* `{ time, price }` literal gets its keys renamed by the build, and the tool,
|
|
30254
|
+
* which reads them by their public names, comes back drawing nothing.
|
|
30255
|
+
*/
|
|
30256
|
+
function restorePoints(points) {
|
|
30257
|
+
return points.map((point) => makeSerializedPoint(readSerializedNumber(point, 'price') ?? 0, readSerializedTime(point)));
|
|
30258
|
+
}
|
|
30206
30259
|
/**
|
|
30207
30260
|
* Central manager for all drawing tools - TradingView style
|
|
30208
30261
|
* Handles multiple tools, selection, deletion, and keyboard shortcuts
|
|
@@ -30682,16 +30735,8 @@ class DrawingToolsManager {
|
|
|
30682
30735
|
...style,
|
|
30683
30736
|
});
|
|
30684
30737
|
case 'polygon':
|
|
30685
|
-
// Bracket notation on the way out too, not just on the way in: a
|
|
30686
|
-
// plain `{ time, price }` literal here gets its keys renamed and
|
|
30687
|
-
// the restored corners come back empty.
|
|
30688
30738
|
return createPolygonTool(context, {
|
|
30689
|
-
points: points
|
|
30690
|
-
const vertex = {};
|
|
30691
|
-
vertex['time'] = pt(index)._internal_t;
|
|
30692
|
-
vertex['price'] = pt(index)._internal_p;
|
|
30693
|
-
return vertex;
|
|
30694
|
-
}),
|
|
30739
|
+
points: restorePoints(points),
|
|
30695
30740
|
...style,
|
|
30696
30741
|
});
|
|
30697
30742
|
case 'crossLine':
|
|
@@ -30757,12 +30802,12 @@ class DrawingToolsManager {
|
|
|
30757
30802
|
});
|
|
30758
30803
|
case 'arrow':
|
|
30759
30804
|
return createArrowTool(context, {
|
|
30760
|
-
points: points
|
|
30805
|
+
points: restorePoints(points),
|
|
30761
30806
|
...style,
|
|
30762
30807
|
});
|
|
30763
30808
|
case 'brush':
|
|
30764
30809
|
return createBrushTool(context, {
|
|
30765
|
-
points: points
|
|
30810
|
+
points: restorePoints(points),
|
|
30766
30811
|
...style,
|
|
30767
30812
|
});
|
|
30768
30813
|
case 'text':
|
|
@@ -31234,7 +31279,7 @@ const customSeriesDefaultOptions = {
|
|
|
31234
31279
|
* Returns the current version as a string. For example `'1.0.0'`.
|
|
31235
31280
|
*/
|
|
31236
31281
|
function version() {
|
|
31237
|
-
return "2.3.
|
|
31282
|
+
return "2.3.20-dev+202610211649";
|
|
31238
31283
|
}
|
|
31239
31284
|
|
|
31240
|
-
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 };
|
|
31285
|
+
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 };
|