web端进行优化,减少内存开销,data provider提供websocket服务
This commit is contained in:
+108
-253
@@ -1173,9 +1173,43 @@
|
||||
// 不在前端截断数据,保留完整历史,避免K线数量限制
|
||||
function trimDataInPlace(payload, maxLen = 2000) {
|
||||
if (!payload || typeof payload !== 'object') return;
|
||||
// 仅清理可能保留的旧快照引用
|
||||
delete payload.original_kline_data;
|
||||
delete payload.original_macd;
|
||||
|
||||
// 截断大型数组,只保留最新 maxLen 条数据
|
||||
const arrayKeys = [
|
||||
'kline_data', 'element_kline_data', 'sub_sub_kline_data',
|
||||
'bi_list', 'element_bi_list', 'sub_sub_bi_list',
|
||||
'seg_list', 'element_seg_list', 'sub_sub_seg_list',
|
||||
'zs_list', 'element_zs_list', 'sub_sub_zs_list',
|
||||
'uncompleted_bi_list', 'uncompleted_seg_list', 'uncompleted_zs_list',
|
||||
'element_uncompleted_bi_list', 'element_uncompleted_seg_list', 'element_uncompleted_zs_list',
|
||||
'bsp_list', 'element_bsp_list', 'sub_sub_bsp_list',
|
||||
'trade_points', 'element_trade_points'
|
||||
];
|
||||
for (const key of arrayKeys) {
|
||||
if (Array.isArray(payload[key]) && payload[key].length > maxLen) {
|
||||
payload[key] = payload[key].slice(-maxLen);
|
||||
}
|
||||
}
|
||||
// 截断 MACD 子数组
|
||||
const macdKeys = ['macd', 'element_macd', 'sub_sub_macd'];
|
||||
for (const mk of macdKeys) {
|
||||
const m = payload[mk];
|
||||
if (m && typeof m === 'object') {
|
||||
for (const sub of ['macd', 'signal', 'histogram']) {
|
||||
if (Array.isArray(m[sub]) && m[sub].length > maxLen) {
|
||||
m[sub] = m[sub].slice(-maxLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 截断 ATR 数组
|
||||
for (const ak of ['atr', 'element_atr', 'sub_sub_atr']) {
|
||||
if (Array.isArray(payload[ak]) && payload[ak].length > maxLen) {
|
||||
payload[ak] = payload[ak].slice(-maxLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
let trendDetailTable = null;
|
||||
let trendChart = null;
|
||||
@@ -2120,15 +2154,6 @@
|
||||
}
|
||||
currentData = data;
|
||||
|
||||
// 检查和记录服务器返回的时区
|
||||
console.log('服务器返回的时区:', data.timezone || '未指定');
|
||||
// BI中枢调试输出
|
||||
console.log('主周期BI中枢(完成):', Array.isArray(data.bi_zs_list) ? data.bi_zs_list.length : 0);
|
||||
console.log('主周期BI中枢(未完成):', Array.isArray(data.uncompleted_bi_zs_list) ? data.uncompleted_bi_zs_list.length : 0);
|
||||
console.log('次周期BI中枢(完成):', Array.isArray(data.element_bi_zs_list) ? data.element_bi_zs_list.length : 0);
|
||||
console.log('次周期BI中枢(未完成):', Array.isArray(data.element_uncompleted_bi_zs_list) ? data.element_uncompleted_bi_zs_list.length : 0);
|
||||
|
||||
// 刷新图表
|
||||
refreshChart(data);
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
@@ -7010,7 +7035,12 @@
|
||||
}
|
||||
}
|
||||
function bindSyncEvents(mainChartContainer, volumeChartContainer, atrChartContainer, macdChartContainer, chanMacdChartContainer, mainChart, volumeChart, atrChart, macdChart, chanMacdChart, showMacd) {
|
||||
// 防止同步过程中的无限循环
|
||||
// 清理上一轮绑定的事件监听器,防止累积
|
||||
if (window._bindSyncCleanups) {
|
||||
window._bindSyncCleanups.forEach(fn => { try { fn(); } catch(e) {} });
|
||||
}
|
||||
window._bindSyncCleanups = [];
|
||||
|
||||
let syncInProgress = false;
|
||||
|
||||
// 用于跟踪所有图表的拖动状态 - 在函数内部定义以确保作用域正确
|
||||
@@ -7024,161 +7054,70 @@
|
||||
|
||||
// 同步图表的时间范围
|
||||
function syncCharts(sourceChart, sourceContainer) {
|
||||
// 防止无限循环 - 使用更精确的检查
|
||||
if (syncInProgress) {
|
||||
console.log('🔄 同步正在进行中,跳过此次同步');
|
||||
return;
|
||||
}
|
||||
if (syncInProgress) return;
|
||||
|
||||
syncInProgress = true;
|
||||
console.log('🚀 开始同步图表,来源:',
|
||||
sourceChart === mainChart ? '主图' :
|
||||
sourceChart === volumeChart ? '成交量图' :
|
||||
sourceChart === atrChart ? 'ATR图' : 'MACD图');
|
||||
|
||||
try {
|
||||
if (sourceChart && sourceChart.timeScale) {
|
||||
const logicalRange = sourceChart.timeScale().getVisibleLogicalRange();
|
||||
|
||||
if (logicalRange && logicalRange.from !== undefined && logicalRange.to !== undefined) {
|
||||
console.log('📊 同步时间范围:', logicalRange);
|
||||
|
||||
// 同步主图
|
||||
if (sourceChart !== mainChart && mainChart && mainChart.timeScale) {
|
||||
try {
|
||||
mainChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
console.log('✅ 主图同步完成');
|
||||
} catch (e) {
|
||||
console.error('❌ 主图同步失败:', e);
|
||||
}
|
||||
try { mainChart.timeScale().setVisibleLogicalRange(logicalRange); } catch (e) {}
|
||||
}
|
||||
|
||||
// 同步成交量图
|
||||
if (sourceChart !== volumeChart && volumeChart && volumeChart.timeScale) {
|
||||
try {
|
||||
volumeChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
console.log('✅ 成交量图同步完成');
|
||||
} catch (e) {
|
||||
console.error('❌ 成交量图同步失败:', e);
|
||||
}
|
||||
try { volumeChart.timeScale().setVisibleLogicalRange(logicalRange); } catch (e) {}
|
||||
}
|
||||
|
||||
// 同步ATR图
|
||||
if (sourceChart !== atrChart && atrChart && atrChart.timeScale) {
|
||||
try {
|
||||
atrChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
console.log('✅ ATR图同步完成');
|
||||
} catch (e) {
|
||||
console.error('❌ ATR图同步失败:', e);
|
||||
}
|
||||
try { atrChart.timeScale().setVisibleLogicalRange(logicalRange); } catch (e) {}
|
||||
}
|
||||
|
||||
// 同步MACD图
|
||||
if (showMacd && macdChart && sourceChart !== macdChart && macdChart.timeScale) {
|
||||
try {
|
||||
macdChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
console.log('✅ MACD图同步完成');
|
||||
} catch (e) {
|
||||
console.error('❌ MACD图同步失败:', e);
|
||||
}
|
||||
try { macdChart.timeScale().setVisibleLogicalRange(logicalRange); } catch (e) {}
|
||||
}
|
||||
|
||||
// 同步ChanMACD图
|
||||
if (showMacd && chanMacdChart && sourceChart !== chanMacdChart && chanMacdChart.timeScale) {
|
||||
try {
|
||||
chanMacdChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
console.log('✅ ChanMACD图同步完成');
|
||||
} catch (e) {
|
||||
console.error('❌ ChanMACD图同步失败:', e);
|
||||
}
|
||||
try { chanMacdChart.timeScale().setVisibleLogicalRange(logicalRange); } catch (e) {}
|
||||
}
|
||||
|
||||
// 保存当前的可见范围到全局状态
|
||||
if (tvWidget && tvWidget.state) {
|
||||
tvWidget.state.logicalRange = logicalRange;
|
||||
// 同时保存可见范围以确保精确对齐
|
||||
try {
|
||||
const visibleRange = sourceChart.timeScale().getVisibleRange();
|
||||
tvWidget.state.visibleRange = visibleRange;
|
||||
console.log('💾 保存状态 - 逻辑范围:', logicalRange, '可见范围:', visibleRange);
|
||||
} catch (e) {
|
||||
console.warn('⚠️ 保存可见范围失败:', e);
|
||||
}
|
||||
try { tvWidget.state.visibleRange = sourceChart.timeScale().getVisibleRange(); } catch (e) {}
|
||||
}
|
||||
} else {
|
||||
console.warn('⚠️ 无效的逻辑范围:', logicalRange);
|
||||
}
|
||||
} else {
|
||||
console.warn('⚠️ 无效的源图表或时间刻度');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('💥 同步图表出错:', e);
|
||||
console.error('同步图表出错:', e);
|
||||
}
|
||||
|
||||
// 立即重置同步标志,提高响应速度
|
||||
setTimeout(() => {
|
||||
syncInProgress = false;
|
||||
console.log('🔓 同步标志已重置');
|
||||
}, 1);
|
||||
setTimeout(() => { syncInProgress = false; }, 1);
|
||||
}
|
||||
|
||||
// 为每个图表添加事件监听
|
||||
const addChartSyncEvents = (chartContainer, chart) => {
|
||||
console.log('为图表添加同步事件监听:',
|
||||
chart === mainChart ? '主图' :
|
||||
chart === volumeChart ? '成交量图' :
|
||||
chart === atrChart ? 'ATR图' :
|
||||
chart === macdChart ? 'MACD图' :
|
||||
chart === chanMacdChart ? 'ChanMACD图' : '未知图表');
|
||||
|
||||
// 确定当前图表类型
|
||||
const chartType = chart === mainChart ? 'main' :
|
||||
chart === volumeChart ? 'volume' :
|
||||
chart === atrChart ? 'atr' :
|
||||
chart === macdChart ? 'macd' :
|
||||
chart === chanMacdChart ? 'chanmacd' : 'unknown';
|
||||
|
||||
// 使用LightweightCharts内置的时间范围变化事件(这是最可靠的方法)
|
||||
chart.timeScale().subscribeVisibleTimeRangeChange(() => {
|
||||
// 使用图表特定的同步标志防止递归
|
||||
const timeRangeHandler = () => {
|
||||
if (!syncInProgress) {
|
||||
console.log('✅ 检测到时间范围变化,触发同步:', chartType, '当前范围:', chart.timeScale().getVisibleLogicalRange());
|
||||
syncCharts(chart, chartContainer);
|
||||
} else {
|
||||
console.log('⏸️ 同步进行中,跳过时间范围变化事件:', chartType);
|
||||
}
|
||||
};
|
||||
chart.timeScale().subscribeVisibleTimeRangeChange(timeRangeHandler);
|
||||
window._bindSyncCleanups.push(() => {
|
||||
try { chart.timeScale().unsubscribeVisibleTimeRangeChange(timeRangeHandler); } catch(e) {}
|
||||
});
|
||||
|
||||
// 备用的DOM事件监听(用于调试和额外保障)
|
||||
let isScrolling = false;
|
||||
|
||||
// 鼠标按下事件
|
||||
chartContainer.addEventListener('mousedown', (e) => {
|
||||
localDragStates[chartType] = true;
|
||||
console.log('鼠标按下开始拖动:', chartType);
|
||||
});
|
||||
|
||||
// 鼠标抬起事件
|
||||
chartContainer.addEventListener('mouseup', (e) => {
|
||||
if (localDragStates[chartType]) {
|
||||
localDragStates[chartType] = false;
|
||||
console.log('鼠标抬起,结束拖动:', chartType);
|
||||
}
|
||||
});
|
||||
|
||||
// 鼠标离开事件
|
||||
chartContainer.addEventListener('mouseleave', (e) => {
|
||||
if (localDragStates[chartType]) {
|
||||
localDragStates[chartType] = false;
|
||||
console.log('鼠标离开容器,结束拖动:', chartType);
|
||||
}
|
||||
});
|
||||
|
||||
// 滚轮缩放事件(保持原有逻辑)
|
||||
chartContainer.addEventListener('wheel', (e) => {
|
||||
const mousedownHandler = () => { localDragStates[chartType] = true; };
|
||||
const mouseupHandler = () => { localDragStates[chartType] = false; };
|
||||
const mouseleaveHandler = () => { localDragStates[chartType] = false; };
|
||||
const wheelHandler = () => {
|
||||
if (!isScrolling) {
|
||||
isScrolling = true;
|
||||
console.log('滚轮缩放:', chartType);
|
||||
setTimeout(() => {
|
||||
if (!syncInProgress) {
|
||||
syncCharts(chart, chartContainer);
|
||||
@@ -7186,6 +7125,17 @@
|
||||
isScrolling = false;
|
||||
}, 50);
|
||||
}
|
||||
};
|
||||
|
||||
chartContainer.addEventListener('mousedown', mousedownHandler);
|
||||
chartContainer.addEventListener('mouseup', mouseupHandler);
|
||||
chartContainer.addEventListener('mouseleave', mouseleaveHandler);
|
||||
chartContainer.addEventListener('wheel', wheelHandler);
|
||||
window._bindSyncCleanups.push(() => {
|
||||
chartContainer.removeEventListener('mousedown', mousedownHandler);
|
||||
chartContainer.removeEventListener('mouseup', mouseupHandler);
|
||||
chartContainer.removeEventListener('mouseleave', mouseleaveHandler);
|
||||
chartContainer.removeEventListener('wheel', wheelHandler);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -7206,58 +7156,35 @@
|
||||
addChartSyncEvents(chanMacdChartContainer, chanMacdChart);
|
||||
}
|
||||
|
||||
// 窗口大小变化时重绘图表
|
||||
window.addEventListener('resize', () => {
|
||||
// 调整主图大小
|
||||
// 窗口大小变化时重绘图表 — 使用可清理的方式注册
|
||||
const resizeHandler = () => {
|
||||
if (mainChart && mainChartContainer) {
|
||||
mainChart.applyOptions({
|
||||
width: mainChartContainer.clientWidth,
|
||||
height: mainChartContainer.clientHeight
|
||||
});
|
||||
mainChart.applyOptions({ width: mainChartContainer.clientWidth, height: mainChartContainer.clientHeight });
|
||||
}
|
||||
|
||||
// 调整成交量图大小
|
||||
if (volumeChart && volumeChartContainer) {
|
||||
volumeChart.applyOptions({
|
||||
width: volumeChartContainer.clientWidth,
|
||||
height: volumeChartContainer.clientHeight
|
||||
});
|
||||
volumeChart.applyOptions({ width: volumeChartContainer.clientWidth, height: volumeChartContainer.clientHeight });
|
||||
}
|
||||
|
||||
// 调整ATR图大小
|
||||
if (atrChart && atrChartContainer) {
|
||||
atrChart.applyOptions({
|
||||
width: atrChartContainer.clientWidth,
|
||||
height: atrChartContainer.clientHeight
|
||||
});
|
||||
atrChart.applyOptions({ width: atrChartContainer.clientWidth, height: atrChartContainer.clientHeight });
|
||||
}
|
||||
|
||||
// 调整MACD图大小
|
||||
if (showMacd && macdChart && macdChartContainer) {
|
||||
macdChart.applyOptions({
|
||||
width: macdChartContainer.clientWidth,
|
||||
height: macdChartContainer.clientHeight
|
||||
});
|
||||
macdChart.applyOptions({ width: macdChartContainer.clientWidth, height: macdChartContainer.clientHeight });
|
||||
}
|
||||
|
||||
// 调整ChanMACD图大小
|
||||
if (showMacd && chanMacdChart && chanMacdChartContainer) {
|
||||
chanMacdChart.applyOptions({
|
||||
width: chanMacdChartContainer.clientWidth,
|
||||
height: chanMacdChartContainer.clientHeight
|
||||
});
|
||||
chanMacdChart.applyOptions({ width: chanMacdChartContainer.clientWidth, height: chanMacdChartContainer.clientHeight });
|
||||
}
|
||||
|
||||
// 重新同步 - 使用主图作为同步源
|
||||
setTimeout(() => {
|
||||
if (mainChart) {
|
||||
syncCharts(mainChart, mainChartContainer);
|
||||
}
|
||||
}, 200);
|
||||
});
|
||||
setTimeout(() => { if (mainChart) syncCharts(mainChart, mainChartContainer); }, 200);
|
||||
};
|
||||
window.addEventListener('resize', resizeHandler);
|
||||
window._bindSyncCleanups.push(() => { window.removeEventListener('resize', resizeHandler); });
|
||||
}
|
||||
function setupTooltip(mainChart, buyMarkers = [], sellMarkers = [], mainChartContainer, volumeChartContainer, atrChartContainer, macdChartContainer, chanMacdChartContainer, volumeChart, atrChart, macdChart, chanMacdChart, showMacd) {
|
||||
// 调试变量
|
||||
// 清理上一轮 tooltip 的事件订阅
|
||||
if (window._tooltipCleanups) {
|
||||
window._tooltipCleanups.forEach(fn => { try { fn(); } catch(e) {} });
|
||||
}
|
||||
window._tooltipCleanups = [];
|
||||
|
||||
window.debugMode = true;
|
||||
// 初始化 U 显示状态(主/次周期分开控制)
|
||||
const isShowUMain = $('#toggleUOnMain').is(':checked');
|
||||
@@ -7295,7 +7222,7 @@
|
||||
|
||||
// 添加鼠标悬停事件显示提示
|
||||
if (mainChart) {
|
||||
mainChart.subscribeCrosshairMove(param => {
|
||||
const crosshairHandler = (param) => {
|
||||
// 十字线同步到其他图表 - 通过DOM元素绘制垂直线实现虚线延长效果
|
||||
if (param.time && param.point && volumeChart) {
|
||||
try {
|
||||
@@ -7378,13 +7305,6 @@
|
||||
const chanMacdTimeCoordinate = chanMacdChart.timeScale().timeToCoordinate(param.time);
|
||||
if (chanMacdTimeCoordinate !== null) {
|
||||
const chanMacdChartRect = chanMacdChartContainer.getBoundingClientRect();
|
||||
console.log('ChanMACD图表位置(第二个位置):', {
|
||||
left: chanMacdChartRect.left,
|
||||
top: chanMacdChartRect.top,
|
||||
width: chanMacdChartRect.width,
|
||||
height: chanMacdChartRect.height,
|
||||
timeCoordinate: chanMacdTimeCoordinate
|
||||
});
|
||||
const chanMacdLine = document.createElement('div');
|
||||
chanMacdLine.className = 'chanmacd-crosshair-line';
|
||||
chanMacdLine.style.position = 'fixed';
|
||||
@@ -7397,16 +7317,7 @@
|
||||
chanMacdLine.style.pointerEvents = 'none';
|
||||
chanMacdLine.style.zIndex = '1000';
|
||||
document.body.appendChild(chanMacdLine);
|
||||
console.log('ChanMACD垂直线已创建(第二个位置),位置:', chanMacdLine.style.left, chanMacdLine.style.top);
|
||||
} else {
|
||||
console.log('ChanMACD时间坐标为空(第二个位置)');
|
||||
}
|
||||
} else {
|
||||
console.log('ChanMACD图表条件不满足(第二个位置):', {
|
||||
showMacd: showMacd,
|
||||
hasChanMacdChart: !!chanMacdChart,
|
||||
hasChanMacdChartContainer: !!chanMacdChartContainer
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -7479,9 +7390,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 仅记录最简短的调试信息
|
||||
console.debug(`十字线: ${timeStr} -> ${formattedTime} (${timezone})`);
|
||||
|
||||
// 显示自定义时区工具提示,包含价格信息
|
||||
crosshairTooltip.innerHTML = `<div style="font-weight:bold">时间: ${formattedTime}</div>` +
|
||||
(priceInfo ? `<div>${priceInfo}</div>` : '');
|
||||
@@ -7506,12 +7414,20 @@
|
||||
tooltipElement.style.display = 'none';
|
||||
crosshairTooltip.style.display = 'none';
|
||||
}
|
||||
};
|
||||
mainChart.subscribeCrosshairMove(crosshairHandler);
|
||||
window._tooltipCleanups.push(() => {
|
||||
try { mainChart.unsubscribeCrosshairMove(crosshairHandler); } catch(e) {}
|
||||
});
|
||||
|
||||
// 处理图表缩放、平移等事件,隐藏提示
|
||||
mainChart.timeScale().subscribeVisibleTimeRangeChange(() => {
|
||||
const hideTooltipHandler = () => {
|
||||
tooltipElement.style.display = 'none';
|
||||
crosshairTooltip.style.display = 'none';
|
||||
};
|
||||
mainChart.timeScale().subscribeVisibleTimeRangeChange(hideTooltipHandler);
|
||||
window._tooltipCleanups.push(() => {
|
||||
try { mainChart.timeScale().unsubscribeVisibleTimeRangeChange(hideTooltipHandler); } catch(e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -8259,60 +8175,27 @@
|
||||
|
||||
// 只重绘分形元素(笔、线段、中枢),保留现有的K线、MACD和成交量
|
||||
function redrawFractalElements() {
|
||||
// 检查图表是否已初始化
|
||||
if (!tvWidget || !tvWidget.mainChart) {
|
||||
console.error('图表未初始化,无法重绘分形元素');
|
||||
return;
|
||||
}
|
||||
if (!tvWidget || !tvWidget.mainChart) return;
|
||||
|
||||
console.log('重绘分形元素 - 开始');
|
||||
console.log('- 显示笔:', $('#showMainBi').is(':checked'));
|
||||
console.log('- 显示线段:', $('#showMainSeg').is(':checked'));
|
||||
console.log('- 显示中枢:', $('#showMainZs').is(':checked'));
|
||||
|
||||
// 保存当前的图表可见范围
|
||||
const mainChart = tvWidget.mainChart;
|
||||
const visibleRange = mainChart.timeScale().getVisibleRange();
|
||||
const logicalRange = mainChart.timeScale().getVisibleLogicalRange();
|
||||
const visibleRange = mainChart.timeScale().getVisibleRange();
|
||||
|
||||
// 获取当前图表设置
|
||||
const showMacd = $('#showMacd').is(':checked');
|
||||
const showOriginalKline = $('#showOriginalKline').is(':checked');
|
||||
const showBi = $('#showMainBi').is(':checked');
|
||||
const showSeg = $('#showMainSeg').is(':checked');
|
||||
const showZs = $('#showMainZs').is(':checked');
|
||||
|
||||
// 保存原始K线和MACD数据,确保即使使用小级别,我们依然使用主周期的K线和MACD数据
|
||||
const originalKlineData = currentData.kline_data;
|
||||
const originalMacdData = currentData.macd;
|
||||
|
||||
// 重新初始化图表 - 这将清除所有系列并重新创建
|
||||
console.log('重新初始化图表...');
|
||||
|
||||
// 临时存储currentData中可能被修改的字段
|
||||
const tempCurrentData = {
|
||||
kline_data: originalKlineData,
|
||||
macd: originalMacdData
|
||||
};
|
||||
|
||||
// 在重绘前确保K线和MACD数据不变
|
||||
if (currentData.original_kline_data && currentData.original_macd) {
|
||||
// 如果已经保存了原始数据,恢复它们
|
||||
// 确保使用主周期的K线和MACD数据
|
||||
if (currentData.original_kline_data) {
|
||||
currentData.kline_data = currentData.original_kline_data;
|
||||
currentData.macd = currentData.original_macd;
|
||||
} else {
|
||||
// 首次运行 - 保存原始数据
|
||||
currentData.original_kline_data = originalKlineData;
|
||||
currentData.original_macd = originalMacdData;
|
||||
}
|
||||
if (currentData.original_macd) {
|
||||
currentData.macd = currentData.original_macd;
|
||||
}
|
||||
// 清除冗余引用,帮助GC回收
|
||||
delete currentData.original_kline_data;
|
||||
delete currentData.original_macd;
|
||||
|
||||
// 调用初始化函数
|
||||
initTradingView($('#symbol').val(), $('#timeframe').val());
|
||||
|
||||
// 恢复原始可见范围
|
||||
setTimeout(() => {
|
||||
if (tvWidget && tvWidget.mainChart) {
|
||||
console.log('恢复图表可见范围...');
|
||||
if (logicalRange) {
|
||||
tvWidget.mainChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
if (tvWidget.volumeChart) tvWidget.volumeChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||
@@ -8326,14 +8209,8 @@
|
||||
if (tvWidget.macdChart) tvWidget.macdChart.timeScale().setVisibleRange(visibleRange);
|
||||
if (tvWidget.chanMacdChart) tvWidget.chanMacdChart.timeScale().setVisibleRange(visibleRange);
|
||||
}
|
||||
|
||||
console.log('图表可见范围已恢复(包括ATR图表)');
|
||||
} else {
|
||||
console.error('恢复图表可见范围失败 - 图表未初始化');
|
||||
}
|
||||
}, 200);
|
||||
|
||||
console.log('重绘分形元素 - 完成');
|
||||
}
|
||||
// 只更新分形元素(笔、线段、中枢)的表格数据
|
||||
function updateFractalTables() {
|
||||
@@ -8424,33 +8301,11 @@
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('API返回数据:', data);
|
||||
console.log('K线数据点数:', data.kline_data ? data.kline_data.length : 0);
|
||||
|
||||
// 检查是否包含小周期数据
|
||||
if (data.element_timeframe) {
|
||||
console.log('小周期笔数据点数:', data.element_bi_list ? data.element_bi_list.length : 0);
|
||||
console.log('小周期线段数据点数:', data.element_seg_list ? data.element_seg_list.length : 0);
|
||||
console.log('小周期中枢数据点数:', data.element_zs_list ? data.element_zs_list.length : 0);
|
||||
|
||||
// 更新小周期选择器
|
||||
$('#elementTimeframe').val(data.element_timeframe);
|
||||
} else {
|
||||
console.log('未提供小周期数据,使用主周期数据');
|
||||
}
|
||||
|
||||
// 保存原始K线和MACD数据,用于后续参考
|
||||
data.original_kline_data = data.kline_data;
|
||||
data.original_macd = data.macd;
|
||||
|
||||
// 如果图表未初始化,则创建图表,否则更新图表数据
|
||||
if (!tvWidget.state.isInitialized) {
|
||||
console.log('图表尚未初始化,创建新图表');
|
||||
initTradingView($('#symbol').val(), $('#timeframe').val());
|
||||
} else {
|
||||
console.log('图表已初始化,进行增量更新');
|
||||
updateTradingViewData();
|
||||
}
|
||||
initTradingView($('#symbol').val(), $('#timeframe').val());
|
||||
|
||||
// 更新表格数据
|
||||
updateTables(data);
|
||||
|
||||
Reference in New Issue
Block a user