修正了刷新图表缩放和位置不变的bug

This commit is contained in:
jackyu66git
2026-04-16 02:31:48 +08:00
parent 7815eada00
commit 04d8f73b94
3 changed files with 112 additions and 41 deletions
+76 -29
View File
@@ -2052,12 +2052,7 @@
// 保存当前的可见范围(周期切换时不保留,避免范围越界)
if (!periodChanged && tvWidget && tvWidget.mainChart) {
try {
const ts = tvWidget.mainChart.timeScale();
window._pendingRestoreView = {
barSpacing: ts.options().barSpacing,
scrollPosition: ts.scrollPosition(),
rightOffset: ts.options().rightOffset
};
window._pendingRestoreView = captureChartViewState(tvWidget.mainChart);
} catch (e) {
window._pendingRestoreView = null;
}
@@ -2215,6 +2210,64 @@
}
});
}
function captureChartViewState(chart) {
if (!chart || !chart.timeScale) return null;
const ts = chart.timeScale();
const tsOptions = ts.options ? ts.options() : {};
return {
barSpacing: tsOptions.barSpacing,
rightOffset: tsOptions.rightOffset,
scrollPosition: ts.scrollPosition ? ts.scrollPosition() : null,
visibleRange: ts.getVisibleRange ? ts.getVisibleRange() : null,
logicalRange: ts.getVisibleLogicalRange ? ts.getVisibleLogicalRange() : null
};
}
function restoreChartViewState(charts, viewState) {
if (!viewState || !Array.isArray(charts) || charts.length === 0) return;
const validCharts = charts.filter(c => c && c.timeScale);
if (validCharts.length === 0) return;
validCharts.forEach(c => {
try {
const optionsPatch = {};
if (typeof viewState.barSpacing === 'number') optionsPatch.barSpacing = viewState.barSpacing;
if (typeof viewState.rightOffset === 'number') optionsPatch.rightOffset = viewState.rightOffset;
if (Object.keys(optionsPatch).length) {
c.timeScale().applyOptions(optionsPatch);
}
} catch (e) {}
});
let restored = false;
// 优先按逻辑范围恢复(对新数据更稳健)
if (viewState.logicalRange && viewState.logicalRange.from !== undefined && viewState.logicalRange.to !== undefined) {
validCharts.forEach(c => {
try {
c.timeScale().setVisibleLogicalRange(viewState.logicalRange);
restored = true;
} catch (e) {}
});
}
// 逻辑范围失败时,回退到时间可见范围
if (!restored && viewState.visibleRange && viewState.visibleRange.from !== undefined && viewState.visibleRange.to !== undefined) {
validCharts.forEach(c => {
try {
c.timeScale().setVisibleRange(viewState.visibleRange);
restored = true;
} catch (e) {}
});
}
// 最后回退到滚动位置
if (!restored && typeof viewState.scrollPosition === 'number') {
validCharts.forEach(c => {
try { c.timeScale().scrollToPosition(viewState.scrollPosition, false); } catch (e) {}
});
}
}
// 初始化图表
function initTradingView(symbol, timeframe) {
try {
@@ -6634,15 +6687,19 @@
// 首先同步时间轴设置
syncTimeScaleSettings();
// 显示最近 200 根K线而非全部挤压(避免K线过多时重叠)
// 仅在没有待恢复视图时,设置默认可见范围
const totalBars = candles ? candles.length : 0;
const visibleBarsCount = 200;
if (totalBars > visibleBarsCount) {
const rangeFrom = totalBars - visibleBarsCount;
const rangeTo = totalBars + 12;
mainChart.timeScale().setVisibleLogicalRange({ from: rangeFrom, to: rangeTo });
} else {
mainChart.timeScale().fitContent();
const hasPendingRestoreView = !!window._pendingRestoreView;
if (!hasPendingRestoreView) {
// 显示最近 200 根K线而非全部挤压(避免K线过多时重叠)
if (totalBars > visibleBarsCount) {
const rangeFrom = totalBars - visibleBarsCount;
const rangeTo = totalBars + 12;
mainChart.timeScale().setVisibleLogicalRange({ from: rangeFrom, to: rangeTo });
} else {
mainChart.timeScale().fitContent();
}
}
// 立即同步其他图表到主图表的范围
@@ -6760,19 +6817,14 @@
if (showMacd && macdChart) allCharts.push(macdChart);
if (showMacd && chanMacdChart) allCharts.push(chanMacdChart);
// 检查是否有待恢复的视图(barSpacing + scrollPosition
// 检查是否有待恢复的视图(缩放 + 位置
const pending = window._pendingRestoreView;
window._pendingRestoreView = null;
if (pending && pending.barSpacing) {
// 恢复刷新前的缩放和滚动位置
console.log('📌 恢复图表视图 - barSpacing:', pending.barSpacing, 'scrollPosition:', pending.scrollPosition);
allCharts.forEach(c => {
try {
c.timeScale().applyOptions({ barSpacing: pending.barSpacing });
c.timeScale().scrollToPosition(pending.scrollPosition, false);
} catch(e) {}
});
if (pending) {
// 恢复刷新前的缩放和位置(优先可见范围/逻辑范围,最后回退到滚动位置
console.log('📌 恢复图表视图:', JSON.stringify(pending));
restoreChartViewState(allCharts, pending);
} else {
// 无保存视图,正常同步主图到子图
const visibleRange = mainChart.timeScale().getVisibleRange();
@@ -8381,12 +8433,7 @@
// tvWidget 会在 initTradingView 内被重建,所以必须存到 window 上
if (tvWidget && tvWidget.mainChart) {
try {
const ts = tvWidget.mainChart.timeScale();
window._pendingRestoreView = {
barSpacing: ts.options().barSpacing,
scrollPosition: ts.scrollPosition(),
rightOffset: ts.options().rightOffset
};
window._pendingRestoreView = captureChartViewState(tvWidget.mainChart);
console.log('📌 保存图表视图:', JSON.stringify(window._pendingRestoreView));
} catch (e) {
console.warn('保存图表视图失败:', e);