Fix chart viewport hiding after timeframe switch.

Use pendingViewportEpoch so tail refresh applies default range on new timeframe instead of reusing the previous period's saved range.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-08 08:12:33 +08:00
parent c2203abfa8
commit 7ea51818f1
+17 -3
View File
@@ -178,6 +178,7 @@
let chartRangeUserLocked = false; let chartRangeUserLocked = false;
let chartRangeLockTimer = null; let chartRangeLockTimer = null;
let suppressRangeUserLock = false; let suppressRangeUserLock = false;
let pendingViewportEpoch = -1;
let priceTagTimer = null; let priceTagTimer = null;
let tfDigitBuf = ""; let tfDigitBuf = "";
let tfDigitTimer = null; let tfDigitTimer = null;
@@ -2032,6 +2033,7 @@
} }
function markChartRangeUserAdjusted() { function markChartRangeUserAdjusted() {
pendingViewportEpoch = -1;
chartRangeUserLocked = true; chartRangeUserLocked = true;
if (chartRangeLockTimer) clearTimeout(chartRangeLockTimer); if (chartRangeLockTimer) clearTimeout(chartRangeLockTimer);
chartRangeLockTimer = setTimeout(function () { chartRangeLockTimer = setTimeout(function () {
@@ -2248,16 +2250,27 @@
applyChartPriceFormat(); applyChartPriceFormat();
} }
} }
const keepViewport =
pendingViewportEpoch !== chartViewEpoch &&
savedRange &&
isVisibleRangeValidForCandles(savedRange, candleCountBefore);
applyCandlesToChart( applyCandlesToChart(
mergeCandles(lastCandles, alignCandlesToTick(data.candles), { prepend: false }), mergeCandles(lastCandles, alignCandlesToTick(data.candles), { prepend: false }),
0, 0,
{ preserveRange: true, skipAutoScale: chartRangeUserLocked } {
preserveRange: !!keepViewport,
skipAutoScale: chartRangeUserLocked,
}
); );
if (epochAtStart !== chartViewEpoch) return; if (epochAtStart !== chartViewEpoch) return;
const n = lastCandles.length; const n = lastCandles.length;
if (!restoreVisibleLogicalRange(savedRange, n)) { if (pendingViewportEpoch === chartViewEpoch) {
applyDefaultVisibleRange();
} else if (savedRange && isVisibleRangeValidForCandles(savedRange, n)) {
restoreVisibleLogicalRange(savedRange, n);
} else if (!chartRangeUserLocked) {
const curRange = chart && chart.timeScale().getVisibleLogicalRange(); const curRange = chart && chart.timeScale().getVisibleLogicalRange();
if (!chartRangeUserLocked && curRange && !isVisibleRangeValidForCandles(curRange, n)) { if (!curRange || !isVisibleRangeValidForCandles(curRange, n)) {
restoreVisibleLogicalRange(tailVisibleLogicalRange(n), n); restoreVisibleLogicalRange(tailVisibleLogicalRange(n), n);
} }
} }
@@ -2512,6 +2525,7 @@
chartDataLoading = true; chartDataLoading = true;
if (resetView) { if (resetView) {
chartViewEpoch += 1; chartViewEpoch += 1;
pendingViewportEpoch = chartViewEpoch;
chartRangeUserLocked = false; chartRangeUserLocked = false;
if (chartRangeLockTimer) { if (chartRangeLockTimer) {
clearTimeout(chartRangeLockTimer); clearTimeout(chartRangeLockTimer);