@trdrs/quickcharts 2.2.0 → 2.4.0
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/CHANGELOG.md +20 -0
- package/README.md +54 -0
- package/dist/chunk-GFQQSY47.js +41 -0
- package/dist/chunk-GFQQSY47.js.map +1 -0
- package/dist/feature-manifest.json +25 -1
- package/dist/format.d.ts +37 -1
- package/dist/index.d.ts +43 -219
- package/dist/index.js +203 -67
- package/dist/index.js.map +1 -1
- package/dist/{format-ConXazzy.d.ts → symbology-D3SLclrU.d.ts} +1 -34
- package/dist/symbols-BL1fD4CS.d.ts +222 -0
- package/dist/symbols.d.ts +2 -0
- package/dist/symbols.js +9 -0
- package/dist/symbols.js.map +1 -0
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -110,6 +110,9 @@ import {
|
|
|
110
110
|
ICON_CATEGORIES,
|
|
111
111
|
isEmojiGlyph
|
|
112
112
|
} from "./chunk-QYGSDD2Q.js";
|
|
113
|
+
import {
|
|
114
|
+
symbolNames
|
|
115
|
+
} from "./chunk-GFQQSY47.js";
|
|
113
116
|
|
|
114
117
|
// src/datafeed.ts
|
|
115
118
|
function olderPageVerdict(page, askedTo, alreadyHopped) {
|
|
@@ -3079,7 +3082,8 @@ var FEATURE_KEYS = {
|
|
|
3079
3082
|
replay: "flag",
|
|
3080
3083
|
history: "flag",
|
|
3081
3084
|
sessions: "flag",
|
|
3082
|
-
crosshair: "flag"
|
|
3085
|
+
crosshair: "flag",
|
|
3086
|
+
navigation: "flag"
|
|
3083
3087
|
};
|
|
3084
3088
|
var TOP_BAR_KEYS = {
|
|
3085
3089
|
symbol: "flag",
|
|
@@ -3108,7 +3112,9 @@ var UI_KEYS = {
|
|
|
3108
3112
|
toasts: "flag",
|
|
3109
3113
|
symbolSearch: "flag",
|
|
3110
3114
|
indicatorPicker: "flag",
|
|
3111
|
-
indicatorSettings: "flag"
|
|
3115
|
+
indicatorSettings: "flag",
|
|
3116
|
+
priceScale: "flag",
|
|
3117
|
+
crosshair: { horizontal: "flag", labels: "flag", solid: "flag" }
|
|
3112
3118
|
};
|
|
3113
3119
|
function checkKeys(path, value, keys) {
|
|
3114
3120
|
if (value === void 0) return;
|
|
@@ -3136,7 +3142,8 @@ function resolveFeatures(config) {
|
|
|
3136
3142
|
replay: on(config?.replay),
|
|
3137
3143
|
history: on(config?.history),
|
|
3138
3144
|
sessions: on(config?.sessions),
|
|
3139
|
-
crosshair: on(config?.crosshair)
|
|
3145
|
+
crosshair: on(config?.crosshair),
|
|
3146
|
+
navigation: on(config?.navigation)
|
|
3140
3147
|
};
|
|
3141
3148
|
}
|
|
3142
3149
|
var shown = (value) => value !== false;
|
|
@@ -3152,6 +3159,9 @@ function resolveUi(config, features, offered = {}) {
|
|
|
3152
3159
|
const inLegend = (key) => legend2 && (typeof legendConfig !== "object" || shown(legendConfig[key]));
|
|
3153
3160
|
const symbolSearch = shown(config?.symbolSearch);
|
|
3154
3161
|
const indicatorPicker = shown(config?.indicatorPicker);
|
|
3162
|
+
const crosshairConfig = config?.crosshair;
|
|
3163
|
+
const crosshair = features.crosshair && shown(crosshairConfig);
|
|
3164
|
+
const inCrosshair = (key) => crosshair && (typeof crosshairConfig !== "object" || shown(crosshairConfig[key]));
|
|
3155
3165
|
return {
|
|
3156
3166
|
topBar,
|
|
3157
3167
|
symbolPill: inBar("symbol") && symbolSearch,
|
|
@@ -3175,13 +3185,19 @@ function resolveUi(config, features, offered = {}) {
|
|
|
3175
3185
|
legend: legend2,
|
|
3176
3186
|
legendValues: inLegend("values"),
|
|
3177
3187
|
marketStatus: inLegend("marketStatus"),
|
|
3178
|
-
navigation: shown(config?.navigation),
|
|
3188
|
+
navigation: features.navigation && shown(config?.navigation),
|
|
3179
3189
|
contextMenu: shown(config?.contextMenu),
|
|
3180
3190
|
replayTransport: features.replay && shown(config?.replayTransport),
|
|
3181
3191
|
toasts: shown(config?.toasts),
|
|
3182
3192
|
symbolSearch,
|
|
3183
3193
|
indicatorPicker,
|
|
3184
|
-
indicatorSettings: shown(config?.indicatorSettings)
|
|
3194
|
+
indicatorSettings: shown(config?.indicatorSettings),
|
|
3195
|
+
priceScale: shown(config?.priceScale),
|
|
3196
|
+
crosshair,
|
|
3197
|
+
crosshairHorizontal: inCrosshair("horizontal"),
|
|
3198
|
+
crosshairLabels: inCrosshair("labels"),
|
|
3199
|
+
// Solid is the one part that is off unless named: a crosshair is dashed by default.
|
|
3200
|
+
crosshairSolid: crosshair && typeof crosshairConfig === "object" && crosshairConfig.solid === true
|
|
3185
3201
|
};
|
|
3186
3202
|
}
|
|
3187
3203
|
function canCopyImage() {
|
|
@@ -3310,6 +3326,29 @@ function styleOptions(style, paint) {
|
|
|
3310
3326
|
return candleOptions(paint);
|
|
3311
3327
|
}
|
|
3312
3328
|
}
|
|
3329
|
+
function fadedStyleOptions(style, paint, alpha) {
|
|
3330
|
+
const a = Math.min(1, Math.max(0, alpha));
|
|
3331
|
+
const up = paint.appearance.upColor;
|
|
3332
|
+
const down = paint.appearance.downColor;
|
|
3333
|
+
switch (style) {
|
|
3334
|
+
case "line":
|
|
3335
|
+
case "stepline":
|
|
3336
|
+
return { color: withAlpha2(paint.canvas.neutral, a) };
|
|
3337
|
+
case "area":
|
|
3338
|
+
return { lineColor: withAlpha2(up, a), topColor: withAlpha2(up, 0.28 * a), bottomColor: withAlpha2(up, 0.04 * a) };
|
|
3339
|
+
case "baseline":
|
|
3340
|
+
return {
|
|
3341
|
+
topLineColor: withAlpha2(up, a),
|
|
3342
|
+
bottomLineColor: withAlpha2(down, a),
|
|
3343
|
+
topFillColor1: withAlpha2(up, 0.28 * a),
|
|
3344
|
+
topFillColor2: withAlpha2(up, 0.04 * a),
|
|
3345
|
+
bottomFillColor1: withAlpha2(down, 0.04 * a),
|
|
3346
|
+
bottomFillColor2: withAlpha2(down, 0.28 * a)
|
|
3347
|
+
};
|
|
3348
|
+
default:
|
|
3349
|
+
return styleOptions(style, paint);
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3313
3352
|
function lineOptions(paint) {
|
|
3314
3353
|
return { color: paint.canvas.neutral, lineWidth: 2 };
|
|
3315
3354
|
}
|
|
@@ -4960,6 +4999,7 @@ import {
|
|
|
4960
4999
|
createChart as createRenderer,
|
|
4961
5000
|
HistogramSeries as HistogramSeries2,
|
|
4962
5001
|
LineSeries as LineSeries4,
|
|
5002
|
+
LineStyle as LineStyle3,
|
|
4963
5003
|
TrackingModeExitMode
|
|
4964
5004
|
} from "lightweight-charts";
|
|
4965
5005
|
|
|
@@ -5014,6 +5054,59 @@ function coerceScaleMode(raw) {
|
|
|
5014
5054
|
return SCALE_MODES.includes(raw ?? "") ? raw : "normal";
|
|
5015
5055
|
}
|
|
5016
5056
|
|
|
5057
|
+
// src/widget/styleMorph.ts
|
|
5058
|
+
var STYLE_MORPH_MS = 500;
|
|
5059
|
+
function morphEase(t) {
|
|
5060
|
+
const clamped = Math.min(1, Math.max(0, t));
|
|
5061
|
+
return (1 - Math.cos(Math.PI * clamped)) / 2;
|
|
5062
|
+
}
|
|
5063
|
+
function foldBar(bar, fold) {
|
|
5064
|
+
const keep = 1 - Math.min(1, Math.max(0, fold));
|
|
5065
|
+
return {
|
|
5066
|
+
time: bar.t,
|
|
5067
|
+
open: bar.c + (bar.o - bar.c) * keep,
|
|
5068
|
+
high: bar.c + (bar.h - bar.c) * keep,
|
|
5069
|
+
low: bar.c + (bar.l - bar.c) * keep,
|
|
5070
|
+
close: bar.c
|
|
5071
|
+
};
|
|
5072
|
+
}
|
|
5073
|
+
function startStyleMorph(deps) {
|
|
5074
|
+
const frame = deps.frame ?? ((tick2) => requestAnimationFrame(tick2));
|
|
5075
|
+
const cancel = deps.cancelFrame ?? ((handle2) => cancelAnimationFrame(handle2));
|
|
5076
|
+
const now = deps.now ?? (() => performance.now());
|
|
5077
|
+
const start = now();
|
|
5078
|
+
let handle = null;
|
|
5079
|
+
let ended = false;
|
|
5080
|
+
const draw = (t) => {
|
|
5081
|
+
const p = morphEase(t);
|
|
5082
|
+
const fold = deps.direction === "fold" ? p : 1 - p;
|
|
5083
|
+
deps.bars.setData(deps.shown().map((bar) => foldBar(bar, fold)));
|
|
5084
|
+
deps.fadeLine(fold);
|
|
5085
|
+
};
|
|
5086
|
+
const finish = () => {
|
|
5087
|
+
if (ended) return;
|
|
5088
|
+
ended = true;
|
|
5089
|
+
if (handle !== null) cancel(handle);
|
|
5090
|
+
handle = null;
|
|
5091
|
+
draw(1);
|
|
5092
|
+
deps.done();
|
|
5093
|
+
};
|
|
5094
|
+
const tick = () => {
|
|
5095
|
+
handle = null;
|
|
5096
|
+
if (ended) return;
|
|
5097
|
+
const t = (now() - start) / STYLE_MORPH_MS;
|
|
5098
|
+
if (t >= 1) {
|
|
5099
|
+
finish();
|
|
5100
|
+
return;
|
|
5101
|
+
}
|
|
5102
|
+
draw(t);
|
|
5103
|
+
handle = frame(tick);
|
|
5104
|
+
};
|
|
5105
|
+
draw(0);
|
|
5106
|
+
handle = frame(tick);
|
|
5107
|
+
return { running: () => !ended, finish };
|
|
5108
|
+
}
|
|
5109
|
+
|
|
5017
5110
|
// src/widget/baselineLevel.ts
|
|
5018
5111
|
var BASELINE_SCREEN_PERCENT = 50;
|
|
5019
5112
|
var BASELINE_DRIFT_PX = 0.5;
|
|
@@ -5707,8 +5800,8 @@ function bundledGlyphSource(glyph2) {
|
|
|
5707
5800
|
}
|
|
5708
5801
|
|
|
5709
5802
|
// src/pointerInput.ts
|
|
5710
|
-
function pointerLock(locked) {
|
|
5711
|
-
const on = !locked;
|
|
5803
|
+
function pointerLock(locked, navigable = true) {
|
|
5804
|
+
const on = !locked && navigable;
|
|
5712
5805
|
return {
|
|
5713
5806
|
handleScroll: on,
|
|
5714
5807
|
handleScale: { mouseWheel: on, pinch: false, axisPressedMouseMove: on, axisDoubleClickReset: on },
|
|
@@ -6822,7 +6915,7 @@ function attachDrawings(options) {
|
|
|
6822
6915
|
const locked = () => allLocked || workflow().allLocked === true;
|
|
6823
6916
|
const changed = () => events.onChange?.();
|
|
6824
6917
|
const lockPointer = (locked2) => {
|
|
6825
|
-
const lock = pointerLock(locked2);
|
|
6918
|
+
const lock = pointerLock(locked2, options.navigable ?? true);
|
|
6826
6919
|
chart.applyOptions({ handleScroll: lock.handleScroll, handleScale: lock.handleScale });
|
|
6827
6920
|
container.style.touchAction = lock.touchAction;
|
|
6828
6921
|
};
|
|
@@ -10336,6 +10429,7 @@ function attachDrawingsPlane(deps) {
|
|
|
10336
10429
|
const handle = attachDrawings({
|
|
10337
10430
|
chart: deps.chart,
|
|
10338
10431
|
series: deps.series,
|
|
10432
|
+
navigable: deps.navigable,
|
|
10339
10433
|
container: deps.container,
|
|
10340
10434
|
symbol: deps.symbol,
|
|
10341
10435
|
timeframe: deps.timeframe,
|
|
@@ -12584,42 +12678,6 @@ function attachCompare(chart, deps) {
|
|
|
12584
12678
|
return handle;
|
|
12585
12679
|
}
|
|
12586
12680
|
|
|
12587
|
-
// src/symbolLabel.ts
|
|
12588
|
-
function bareTicker(symbol) {
|
|
12589
|
-
return /^[A-Za-z][A-Za-z0-9._-]*:([A-Za-z0-9][A-Za-z0-9._!]*)$/.exec(symbol)?.[1] ?? symbol;
|
|
12590
|
-
}
|
|
12591
|
-
var SLASH_PAIR = /^[A-Za-z][A-Za-z0-9.]*\/[A-Za-z][A-Za-z0-9.]*$/;
|
|
12592
|
-
function symbolLabel(symbol) {
|
|
12593
|
-
const ticker = bareTicker(symbol);
|
|
12594
|
-
return SLASH_PAIR.test(ticker) ? ticker.replace("/", "") : ticker;
|
|
12595
|
-
}
|
|
12596
|
-
var PAIR_MARKETS = /* @__PURE__ */ new Set(["crypto", "forex"]);
|
|
12597
|
-
function pairLabel(ticker, type, currencyCode) {
|
|
12598
|
-
const quote = currencyCode?.trim();
|
|
12599
|
-
if (!quote || !PAIR_MARKETS.has(type.toLowerCase())) return null;
|
|
12600
|
-
const bare = bareTicker(ticker);
|
|
12601
|
-
const base = bare.length > quote.length && bare.toUpperCase().endsWith(quote.toUpperCase()) ? bare.slice(0, -quote.length) : bare;
|
|
12602
|
-
return base && base.toUpperCase() !== quote.toUpperCase() ? `${base} / ${quote}` : null;
|
|
12603
|
-
}
|
|
12604
|
-
function factsOf(symbol) {
|
|
12605
|
-
if (typeof symbol === "string") return { ticker: symbol, type: "", shortName: "", longName: "", currencyCode: void 0 };
|
|
12606
|
-
if ("symbol" in symbol) return { ticker: symbol.symbol, type: symbol.type, shortName: "", longName: symbol.name.trim(), currencyCode: symbol.currencyCode };
|
|
12607
|
-
const name2 = symbol.name.trim();
|
|
12608
|
-
const description = symbol.description.trim();
|
|
12609
|
-
return { ticker: symbol.ticker, type: symbol.type, shortName: name2 !== description ? name2 : "", longName: description, currencyCode: symbol.currencyCode };
|
|
12610
|
-
}
|
|
12611
|
-
function symbolNames(symbol) {
|
|
12612
|
-
const facts = factsOf(symbol);
|
|
12613
|
-
if (facts.type.toLowerCase() === "spread") return { mark: facts.ticker, title: facts.ticker, description: facts.ticker };
|
|
12614
|
-
const bare = bareTicker(facts.ticker);
|
|
12615
|
-
const pair = pairLabel(facts.ticker, facts.type, facts.currencyCode) ?? (SLASH_PAIR.test(bare) ? bare.replace("/", " / ") : null);
|
|
12616
|
-
return {
|
|
12617
|
-
mark: pair ? pair.replace(" / ", "") : symbolLabel(facts.ticker),
|
|
12618
|
-
title: pair ?? (facts.shortName || bare),
|
|
12619
|
-
description: pair ?? (facts.longName || bare)
|
|
12620
|
-
};
|
|
12621
|
-
}
|
|
12622
|
-
|
|
12623
12681
|
// src/widget/compare.ts
|
|
12624
12682
|
var CHIP_THROTTLE_MS = 250;
|
|
12625
12683
|
function attachComparePlane(deps) {
|
|
@@ -12787,6 +12845,7 @@ function composeFormingBar(parent, subs, k) {
|
|
|
12787
12845
|
}
|
|
12788
12846
|
|
|
12789
12847
|
// src/widget/replay.ts
|
|
12848
|
+
var START_HOLD_MS = 250;
|
|
12790
12849
|
function coerceReplaySpeed(raw) {
|
|
12791
12850
|
const n = Number(raw);
|
|
12792
12851
|
return REPLAY_SPEEDS.includes(n) ? n : 10;
|
|
@@ -12805,6 +12864,13 @@ function attachReplayPlane(deps) {
|
|
|
12805
12864
|
let stepping = null;
|
|
12806
12865
|
let generation = 0;
|
|
12807
12866
|
let destroyed = false;
|
|
12867
|
+
let glide = null;
|
|
12868
|
+
const stopGlide = () => {
|
|
12869
|
+
if (glide) {
|
|
12870
|
+
clearTimeout(glide);
|
|
12871
|
+
glide = null;
|
|
12872
|
+
}
|
|
12873
|
+
};
|
|
12808
12874
|
const invalidateStep = () => {
|
|
12809
12875
|
generation += 1;
|
|
12810
12876
|
stepping = null;
|
|
@@ -12825,15 +12891,34 @@ function attachReplayPlane(deps) {
|
|
|
12825
12891
|
const currentGrain = () => autoGrain ? "auto" : manualGrain ?? "auto";
|
|
12826
12892
|
const paintCursor = () => {
|
|
12827
12893
|
if (!master) return;
|
|
12894
|
+
stopGlide();
|
|
12828
12895
|
deps.paint(master.slice(0, cursor));
|
|
12829
12896
|
deps.chart.timeScale().scrollToRealTime();
|
|
12830
12897
|
};
|
|
12831
12898
|
const paintForming = () => {
|
|
12832
12899
|
if (!master || !subs) return;
|
|
12900
|
+
stopGlide();
|
|
12833
12901
|
const parent = master[cursor - 1];
|
|
12834
12902
|
deps.paint([...master.slice(0, cursor - 1), composeFormingBar(parent, subs, formK)]);
|
|
12835
12903
|
deps.chart.timeScale().scrollToRealTime();
|
|
12836
12904
|
};
|
|
12905
|
+
const paintStart = () => {
|
|
12906
|
+
if (!master) return;
|
|
12907
|
+
const scale = deps.chart.timeScale();
|
|
12908
|
+
const shown2 = scale.getVisibleRange();
|
|
12909
|
+
const view = scale.getVisibleLogicalRange();
|
|
12910
|
+
const chosen = master[cursor - 1].t;
|
|
12911
|
+
const from = shown2?.from;
|
|
12912
|
+
const to = shown2?.to;
|
|
12913
|
+
if (!view || typeof from !== "number" || typeof to !== "number" || chosen < from || chosen > to) return paintCursor();
|
|
12914
|
+
stopGlide();
|
|
12915
|
+
deps.paint(master.slice(0, cursor));
|
|
12916
|
+
scale.setVisibleLogicalRange(view);
|
|
12917
|
+
glide = setTimeout(() => {
|
|
12918
|
+
glide = null;
|
|
12919
|
+
if (master && !destroyed && !deps.disposed()) scale.scrollToRealTime();
|
|
12920
|
+
}, START_HOLD_MS);
|
|
12921
|
+
};
|
|
12837
12922
|
const stopTimer = () => {
|
|
12838
12923
|
if (timer) {
|
|
12839
12924
|
clearInterval(timer);
|
|
@@ -12917,6 +13002,7 @@ function attachReplayPlane(deps) {
|
|
|
12917
13002
|
};
|
|
12918
13003
|
function abandon() {
|
|
12919
13004
|
invalidateStep();
|
|
13005
|
+
stopGlide();
|
|
12920
13006
|
if (!master) return;
|
|
12921
13007
|
stopTimer();
|
|
12922
13008
|
playing = false;
|
|
@@ -12944,7 +13030,7 @@ function attachReplayPlane(deps) {
|
|
|
12944
13030
|
const idx = master.findIndex((b) => b.t >= atSec);
|
|
12945
13031
|
cursor = Math.max(2, (idx === -1 ? master.length - 1 : idx) + 1);
|
|
12946
13032
|
deps.setHeader(true);
|
|
12947
|
-
|
|
13033
|
+
paintStart();
|
|
12948
13034
|
sync();
|
|
12949
13035
|
},
|
|
12950
13036
|
exit() {
|
|
@@ -13467,7 +13553,7 @@ function attachExtensionsPlane(deps) {
|
|
|
13467
13553
|
},
|
|
13468
13554
|
lockPanZoom: (locked) => {
|
|
13469
13555
|
if (deps.disposed()) return;
|
|
13470
|
-
const state = pointerLock(locked);
|
|
13556
|
+
const state = pointerLock(locked, deps.navigable);
|
|
13471
13557
|
deps.chart.applyOptions({ handleScroll: state.handleScroll, handleScale: state.handleScale });
|
|
13472
13558
|
deps.setTouchAction(state.touchAction);
|
|
13473
13559
|
}
|
|
@@ -15976,10 +16062,11 @@ function registerChartCommands(deps) {
|
|
|
15976
16062
|
});
|
|
15977
16063
|
add({ id: "chart.view.reset", scope: "chart", label: "command.viewReset", shortcut: "Alt+KeyR", available: always, execute: () => handle.reset() });
|
|
15978
16064
|
add({ id: "chart.view.goLive", scope: "chart", label: "command.viewGoLive", shortcut: "Alt+KeyL", available: always, execute: () => handle.goLive() });
|
|
15979
|
-
|
|
15980
|
-
add({ id: "chart.view.
|
|
15981
|
-
add({ id: "chart.view.
|
|
15982
|
-
add({ id: "chart.view.
|
|
16065
|
+
const navigable = () => features.navigation;
|
|
16066
|
+
add({ id: "chart.view.zoomIn", scope: "chart", label: "command.viewZoomIn", shortcut: "Equal", available: navigable, execute: () => deps.zoom("in") });
|
|
16067
|
+
add({ id: "chart.view.zoomOut", scope: "chart", label: "command.viewZoomOut", shortcut: "Minus", available: navigable, execute: () => deps.zoom("out") });
|
|
16068
|
+
add({ id: "chart.view.scrollLeft", scope: "chart", label: "command.viewScrollLeft", shortcut: "ArrowLeft", available: navigable, execute: () => deps.scroll("left") });
|
|
16069
|
+
add({ id: "chart.view.scrollRight", scope: "chart", label: "command.viewScrollRight", shortcut: "ArrowRight", available: navigable, execute: () => deps.scroll("right") });
|
|
15983
16070
|
add({
|
|
15984
16071
|
id: "chart.data.download",
|
|
15985
16072
|
scope: "chart",
|
|
@@ -16783,14 +16870,21 @@ function createChartInstance(deps) {
|
|
|
16783
16870
|
vertLines: { color: canvas().grid, visible: eff.appearance.grid },
|
|
16784
16871
|
horzLines: { color: canvas().grid, visible: eff.appearance.grid }
|
|
16785
16872
|
},
|
|
16786
|
-
crosshair: {
|
|
16873
|
+
crosshair: {
|
|
16874
|
+
mode: deps.ui.crosshair ? CrosshairMode.Normal : CrosshairMode.Hidden,
|
|
16875
|
+
vertLine: { labelVisible: deps.ui.crosshairLabels, ...deps.ui.crosshairSolid ? { style: LineStyle3.Solid } : {} },
|
|
16876
|
+
horzLine: { visible: deps.ui.crosshairHorizontal, labelVisible: deps.ui.crosshairLabels, ...deps.ui.crosshairSolid ? { style: LineStyle3.Solid } : {} }
|
|
16877
|
+
},
|
|
16787
16878
|
// A finger held on the plot scrubs the crosshair for as long as it stays down, and lifting it
|
|
16788
16879
|
// takes the crosshair away, so the next one-finger drag pans: the way a native chart reads.
|
|
16789
16880
|
trackingMode: { exitMode: TrackingModeExitMode.OnTouchEnd },
|
|
16790
16881
|
// The renderer's own momentum throws a flick as fast as seven pixels a millisecond and coasts
|
|
16791
16882
|
// it thousands of pixels; the chart coasts a flick itself, calmly.
|
|
16792
16883
|
kineticScroll: { touch: false, mouse: false },
|
|
16793
|
-
|
|
16884
|
+
// A chart that holds its view takes no drag, wheel, pinch or scale gesture from the renderer.
|
|
16885
|
+
handleScroll: deps.features.navigation,
|
|
16886
|
+
handleScale: deps.features.navigation,
|
|
16887
|
+
rightPriceScale: { visible: deps.ui.priceScale, borderVisible: false, scaleMargins: { top: 0.08, bottom: 0.08 } },
|
|
16794
16888
|
timeScale: { borderVisible: false, timeVisible: true, secondsVisible: false, rightOffset: 4, barSpacing: 8, minBarSpacing: 0.5 }
|
|
16795
16889
|
});
|
|
16796
16890
|
const anchor = chart.addSeries(LineSeries4, {
|
|
@@ -16799,7 +16893,13 @@ function createChartInstance(deps) {
|
|
|
16799
16893
|
priceLineVisible: false,
|
|
16800
16894
|
crosshairMarkerVisible: false
|
|
16801
16895
|
});
|
|
16802
|
-
|
|
16896
|
+
const addMainSeries = (id) => {
|
|
16897
|
+
const added = addStyleSeries(chart, id, paint());
|
|
16898
|
+
if (!deps.ui.priceScale) added.applyOptions({ priceLineVisible: false, lastValueVisible: false });
|
|
16899
|
+
return added;
|
|
16900
|
+
};
|
|
16901
|
+
let series2 = addMainSeries(style);
|
|
16902
|
+
let morph = null;
|
|
16803
16903
|
const baselineLevel = createBaselineLevel({ paneHeight: () => chart.paneSize().height });
|
|
16804
16904
|
if (style === "baseline") baselineLevel.follow(series2);
|
|
16805
16905
|
const volume2 = chart.addSeries(HistogramSeries2, {
|
|
@@ -16930,15 +17030,17 @@ function createChartInstance(deps) {
|
|
|
16930
17030
|
const crosshairSubs = /* @__PURE__ */ new Set();
|
|
16931
17031
|
const timeClickSubs = /* @__PURE__ */ new Set();
|
|
16932
17032
|
const rangeSubs = /* @__PURE__ */ new Set();
|
|
17033
|
+
const reducedMotion = () => gestures.ownerDocument.defaultView?.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
|
|
16933
17034
|
const ranges = createRangeApi({
|
|
16934
17035
|
chart,
|
|
16935
17036
|
disposed: disposedFn,
|
|
16936
17037
|
muted,
|
|
16937
17038
|
mirrored,
|
|
16938
17039
|
onGlide: () => followLiveEdge(),
|
|
16939
|
-
reducedMotion
|
|
17040
|
+
reducedMotion
|
|
16940
17041
|
});
|
|
16941
|
-
const
|
|
17042
|
+
const still = { stop: () => void 0, destroy: () => void 0 };
|
|
17043
|
+
const fling = deps.features.navigation ? attachFling({ chart, target: gestures }) : still;
|
|
16942
17044
|
let unregisterRangeMirror = () => void 0;
|
|
16943
17045
|
function applyTimezone() {
|
|
16944
17046
|
if (disposed) return;
|
|
@@ -17046,6 +17148,7 @@ function createChartInstance(deps) {
|
|
|
17046
17148
|
const drawings2 = attachDrawingsPlane({
|
|
17047
17149
|
chart,
|
|
17048
17150
|
series: anchor,
|
|
17151
|
+
navigable: deps.features.navigation,
|
|
17049
17152
|
container: gestures,
|
|
17050
17153
|
chrome: chrome2,
|
|
17051
17154
|
chartId: deps.id,
|
|
@@ -17119,7 +17222,7 @@ function createChartInstance(deps) {
|
|
|
17119
17222
|
setHeader: () => legend2.setHeader(symbol, tf),
|
|
17120
17223
|
// A chart whose crosshair the host switched OFF keeps it off: replay may take the crosshair
|
|
17121
17224
|
// away for the length of a question, never hand one back that was never there.
|
|
17122
|
-
setCrosshair: (visible) => chart.applyOptions({ crosshair: { mode: visible && deps.
|
|
17225
|
+
setCrosshair: (visible) => chart.applyOptions({ crosshair: { mode: visible && deps.ui.crosshair ? CrosshairMode.Normal : CrosshairMode.Hidden } }),
|
|
17123
17226
|
// The feed's own grains: a chart never offers, or fetches, a timeframe its feed cannot serve.
|
|
17124
17227
|
resolutions: () => deps.capabilities().resolutions,
|
|
17125
17228
|
persist: (key, value) => storage.set(key === "speed" ? REPLAY_SPEED_KEY : REPLAY_TIMEFRAME_KEY, value),
|
|
@@ -17153,6 +17256,7 @@ function createChartInstance(deps) {
|
|
|
17153
17256
|
const extensions = attachExtensionsPlane({
|
|
17154
17257
|
chartId: deps.id,
|
|
17155
17258
|
chart,
|
|
17259
|
+
navigable: deps.features.navigation,
|
|
17156
17260
|
series: () => anchor,
|
|
17157
17261
|
visible: () => series2,
|
|
17158
17262
|
gestures,
|
|
@@ -17260,8 +17364,8 @@ function createChartInstance(deps) {
|
|
|
17260
17364
|
navigationRoot.addEventListener("mouseup", onNativeDragEnd, { passive: true });
|
|
17261
17365
|
navigationRoot.addEventListener("pointerup", onNativeDragEnd, { passive: true });
|
|
17262
17366
|
navigationRoot.addEventListener("pointercancel", onNativeDragEnd, { passive: true });
|
|
17263
|
-
const pinch = attachPinch({ chart, target: gestures });
|
|
17264
|
-
const freePan = deps.freePan ? attachFreePan({
|
|
17367
|
+
const pinch = deps.features.navigation ? attachPinch({ chart, target: gestures }) : null;
|
|
17368
|
+
const freePan = deps.freePan && deps.features.navigation ? attachFreePan({
|
|
17265
17369
|
chart,
|
|
17266
17370
|
target: gestures,
|
|
17267
17371
|
framing: () => priceAxisPolicy() === "auto",
|
|
@@ -17285,9 +17389,11 @@ function createChartInstance(deps) {
|
|
|
17285
17389
|
const painted = shownBars();
|
|
17286
17390
|
const values = painted.map((b) => ({ time: b.t, value: b.c }));
|
|
17287
17391
|
anchor.setData(values);
|
|
17288
|
-
series2
|
|
17289
|
-
|
|
17290
|
-
|
|
17392
|
+
if (morph?.bars !== series2) {
|
|
17393
|
+
series2.setData(
|
|
17394
|
+
shaped ? values : painted.map((b) => ({ time: b.t, open: b.o, high: b.h, low: b.l, close: b.c }))
|
|
17395
|
+
);
|
|
17396
|
+
}
|
|
17291
17397
|
if (volumeInstance()) paintVolume();
|
|
17292
17398
|
indicators2.recompute();
|
|
17293
17399
|
compare?.sync();
|
|
@@ -17613,20 +17719,48 @@ function createChartInstance(deps) {
|
|
|
17613
17719
|
function setStyle(next) {
|
|
17614
17720
|
if (disposed || next === style || !deps.styles.includes(next)) return;
|
|
17615
17721
|
const keep = chart.timeScale().getVisibleLogicalRange();
|
|
17722
|
+
morph?.run.finish();
|
|
17616
17723
|
const previous = series2;
|
|
17724
|
+
const previousStyle = style;
|
|
17617
17725
|
style = next;
|
|
17618
17726
|
storage.set(STYLE_KEY, next);
|
|
17619
|
-
series2 =
|
|
17727
|
+
series2 = addMainSeries(next);
|
|
17620
17728
|
baselineLevel.follow(next === "baseline" ? series2 : null);
|
|
17621
17729
|
countdown?.seriesChanged(previous);
|
|
17622
17730
|
extensions.visibleSeriesReplaced();
|
|
17623
17731
|
applyPriceFormat();
|
|
17624
|
-
|
|
17625
|
-
|
|
17626
|
-
|
|
17627
|
-
|
|
17732
|
+
const remove = (leaving) => {
|
|
17733
|
+
try {
|
|
17734
|
+
chart.removeSeries(leaving);
|
|
17735
|
+
} catch {
|
|
17736
|
+
}
|
|
17737
|
+
};
|
|
17738
|
+
const folding = valueShaped(next) && !valueShaped(previousStyle);
|
|
17739
|
+
const unfolding = !valueShaped(next) && valueShaped(previousStyle);
|
|
17740
|
+
const morphing = !!deps.styleMorph && (folding || unfolding) && !reducedMotion();
|
|
17741
|
+
if (!morphing) remove(previous);
|
|
17628
17742
|
paintAll();
|
|
17629
17743
|
if (keep) chart.timeScale().setVisibleLogicalRange(keep);
|
|
17744
|
+
if (morphing) {
|
|
17745
|
+
const bars2 = folding ? previous : series2;
|
|
17746
|
+
const line2 = folding ? series2 : previous;
|
|
17747
|
+
const lineStyle2 = folding ? next : previousStyle;
|
|
17748
|
+
const entry = {
|
|
17749
|
+
bars: bars2,
|
|
17750
|
+
run: startStyleMorph({
|
|
17751
|
+
bars: bars2,
|
|
17752
|
+
fadeLine: (alpha) => line2.applyOptions(fadedStyleOptions(lineStyle2, paint(), alpha)),
|
|
17753
|
+
shown: shownBars,
|
|
17754
|
+
direction: folding ? "fold" : "unfold",
|
|
17755
|
+
done: () => {
|
|
17756
|
+
if (morph === entry) morph = null;
|
|
17757
|
+
remove(previous);
|
|
17758
|
+
if (folding) line2.applyOptions(styleOptions(lineStyle2, paint()));
|
|
17759
|
+
}
|
|
17760
|
+
})
|
|
17761
|
+
};
|
|
17762
|
+
morph = entry;
|
|
17763
|
+
}
|
|
17630
17764
|
events.emit("style", next);
|
|
17631
17765
|
}
|
|
17632
17766
|
function content() {
|
|
@@ -18038,8 +18172,9 @@ function createChartInstance(deps) {
|
|
|
18038
18172
|
countdownClock.destroy();
|
|
18039
18173
|
pointer?.destroy();
|
|
18040
18174
|
ranges.stopGlide();
|
|
18175
|
+
morph?.run.finish();
|
|
18041
18176
|
fling.destroy();
|
|
18042
|
-
pinch
|
|
18177
|
+
pinch?.destroy();
|
|
18043
18178
|
freePan?.destroy();
|
|
18044
18179
|
plotArea.destroy();
|
|
18045
18180
|
extensions.destroy();
|
|
@@ -23133,6 +23268,7 @@ function createChart(options) {
|
|
|
23133
23268
|
container: element,
|
|
23134
23269
|
hostContainer: options.container,
|
|
23135
23270
|
freePan: options.touch?.freePan === true,
|
|
23271
|
+
styleMorph: options.transitions?.style === true,
|
|
23136
23272
|
layer,
|
|
23137
23273
|
datafeed: options.datafeed,
|
|
23138
23274
|
externalDrawingToolbar: !!options.drawingToolbarContainer,
|