Fix chart viewport regressions from tail refresh and period switch.
Remove pendingViewportEpoch, fetch only 30 tail bars on poll, restore wasViewingTail logic, and fix left-scroll range shift from actual merge delta. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -178,7 +178,7 @@
|
||||
let chartRangeUserLocked = false;
|
||||
let chartRangeLockTimer = null;
|
||||
let suppressRangeUserLock = false;
|
||||
let pendingViewportEpoch = -1;
|
||||
const CHART_TAIL_REFRESH_LIMIT = 30;
|
||||
let priceTagTimer = null;
|
||||
let tfDigitBuf = "";
|
||||
let tfDigitTimer = null;
|
||||
@@ -2033,7 +2033,6 @@
|
||||
}
|
||||
|
||||
function markChartRangeUserAdjusted() {
|
||||
pendingViewportEpoch = -1;
|
||||
chartRangeUserLocked = true;
|
||||
if (chartRangeLockTimer) clearTimeout(chartRangeLockTimer);
|
||||
chartRangeLockTimer = setTimeout(function () {
|
||||
@@ -2168,6 +2167,7 @@
|
||||
});
|
||||
if (params.before_ms) qs.set("before_ms", String(params.before_ms));
|
||||
if (params.refresh) qs.set("refresh", "1");
|
||||
if (params.tail) qs.set("tail", "1");
|
||||
const r = await fetch("/api/chart/ohlcv?" + qs.toString(), { credentials: "same-origin" });
|
||||
const data = await r.json();
|
||||
if (!r.ok) {
|
||||
@@ -2197,8 +2197,10 @@
|
||||
if (data.exhausted) exhaustedLeft = true;
|
||||
const incoming = alignCandlesToTick(data.candles || []);
|
||||
if (!incoming.length) return;
|
||||
const shift = incoming.length;
|
||||
applyCandlesToChart(mergeCandles(lastCandles, incoming, { prepend: true }), shift);
|
||||
const prevLen = lastCandles.length;
|
||||
const merged = mergeCandles(lastCandles, incoming, { prepend: true });
|
||||
const shift = merged.length - prevLen;
|
||||
applyCandlesToChart(merged, shift);
|
||||
if (elStatus && !elStatus.classList.contains("err")) {
|
||||
elStatus.textContent =
|
||||
"已加载 " +
|
||||
@@ -2230,12 +2232,15 @@
|
||||
const candleCountBefore = lastCandles.length;
|
||||
let savedRange = null;
|
||||
if (chart) savedRange = chart.timeScale().getVisibleLogicalRange();
|
||||
const wasViewingTail =
|
||||
!savedRange || isViewingChartTail(savedRange, candleCountBefore);
|
||||
try {
|
||||
const data = await fetchChartChunk({
|
||||
exchange_key: exKey,
|
||||
symbol: sym,
|
||||
timeframe: tf,
|
||||
limit: chartChunkLimit(tf),
|
||||
limit: CHART_TAIL_REFRESH_LIMIT,
|
||||
tail: true,
|
||||
});
|
||||
if (myToken !== loadToken) return;
|
||||
if (vKey !== lastViewKey) return;
|
||||
@@ -2250,25 +2255,28 @@
|
||||
applyChartPriceFormat();
|
||||
}
|
||||
}
|
||||
const keepViewport =
|
||||
pendingViewportEpoch !== chartViewEpoch &&
|
||||
const shouldPreserve =
|
||||
savedRange &&
|
||||
isVisibleRangeValidForCandles(savedRange, candleCountBefore);
|
||||
isVisibleRangeValidForCandles(savedRange, candleCountBefore) &&
|
||||
(chartRangeUserLocked || !wasViewingTail);
|
||||
applyCandlesToChart(
|
||||
mergeCandles(lastCandles, alignCandlesToTick(data.candles), { prepend: false }),
|
||||
0,
|
||||
{
|
||||
preserveRange: !!keepViewport,
|
||||
preserveRange: !!shouldPreserve,
|
||||
skipAutoScale: chartRangeUserLocked,
|
||||
}
|
||||
);
|
||||
if (epochAtStart !== chartViewEpoch) return;
|
||||
const n = lastCandles.length;
|
||||
if (pendingViewportEpoch === chartViewEpoch) {
|
||||
applyDefaultVisibleRange();
|
||||
} else if (savedRange && isVisibleRangeValidForCandles(savedRange, n)) {
|
||||
restoreVisibleLogicalRange(savedRange, n);
|
||||
} else if (!chartRangeUserLocked) {
|
||||
const minorTailUpdate = Math.abs(n - candleCountBefore) <= CHART_TAIL_REFRESH_LIMIT + 5;
|
||||
if (wasViewingTail && !chartRangeUserLocked) {
|
||||
restoreVisibleLogicalRange(tailVisibleLogicalRange(n), n);
|
||||
} else if (shouldPreserve && minorTailUpdate) {
|
||||
if (!restoreVisibleLogicalRange(savedRange, n) && !chartRangeUserLocked) {
|
||||
restoreVisibleLogicalRange(tailVisibleLogicalRange(n), n);
|
||||
}
|
||||
} else if (!restoreVisibleLogicalRange(savedRange, n) && !chartRangeUserLocked) {
|
||||
const curRange = chart && chart.timeScale().getVisibleLogicalRange();
|
||||
if (!curRange || !isVisibleRangeValidForCandles(curRange, n)) {
|
||||
restoreVisibleLogicalRange(tailVisibleLogicalRange(n), n);
|
||||
@@ -2525,7 +2533,6 @@
|
||||
chartDataLoading = true;
|
||||
if (resetView) {
|
||||
chartViewEpoch += 1;
|
||||
pendingViewportEpoch = chartViewEpoch;
|
||||
chartRangeUserLocked = false;
|
||||
if (chartRangeLockTimer) {
|
||||
clearTimeout(chartRangeLockTimer);
|
||||
|
||||
Reference in New Issue
Block a user