修正了刷新图表缩放和位置不变的bug
This commit is contained in:
+76
-29
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user