|
|
@@ -415,15 +415,19 @@
|
|
|
console.log('没有选择数据库文件');
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
const timeRange = document.getElementById('timeRange').value;
|
|
|
const symbol = document.getElementById('symbolFilter').value.trim();
|
|
|
-
|
|
|
+
|
|
|
try {
|
|
|
+ // ⚠️ 重要:先加载交易事件,再加载价格数据
|
|
|
+ // 因为 displayPriceChart 会读取 tradingEventsData
|
|
|
+ await loadTradingEvents(timeRange, symbol);
|
|
|
+
|
|
|
+ // 然后并行加载其他数据
|
|
|
await Promise.all([
|
|
|
loadStats(timeRange, symbol),
|
|
|
loadPriceData(timeRange, symbol),
|
|
|
- loadTradingEvents(timeRange, symbol),
|
|
|
loadThumbnailData(symbol)
|
|
|
]);
|
|
|
} catch (error) {
|
|
|
@@ -524,6 +528,9 @@
|
|
|
|
|
|
// 显示价格图表
|
|
|
function displayPriceChart(data) {
|
|
|
+ console.log('📈 displayPriceChart 被调用, 数据点数:', data.length);
|
|
|
+ console.log(' tradingEventsData:', tradingEventsData?.length);
|
|
|
+
|
|
|
const container = document.getElementById('priceChart');
|
|
|
|
|
|
// 销毁旧图表实例
|
|
|
@@ -541,6 +548,73 @@
|
|
|
const lighterBids = data.map(d => [d.timestamp * 1000, d.lighter_bid]);
|
|
|
const lighterAsks = data.map(d => [d.timestamp * 1000, d.lighter_ask]);
|
|
|
|
|
|
+ // 准备事件标记数据
|
|
|
+ const priceMarkLines = [];
|
|
|
+ const priceMarkPoints = [];
|
|
|
+
|
|
|
+ if (tradingEventsData && tradingEventsData.length > 0) {
|
|
|
+ console.log(' 准备添加', tradingEventsData.length, '个事件标记到价格图表');
|
|
|
+ tradingEventsData.forEach(event => {
|
|
|
+ const timestamp = event.timestamp * 1000;
|
|
|
+ const side = event.side;
|
|
|
+ const eventType = event.event_type;
|
|
|
+
|
|
|
+ let color, symbol, symbolSize, label, symbolRotate = 0;
|
|
|
+
|
|
|
+ if (side === 'long') {
|
|
|
+ symbol = 'arrow';
|
|
|
+ symbolSize = 15;
|
|
|
+ symbolRotate = 0;
|
|
|
+ color = '#28a745';
|
|
|
+ label = '买入';
|
|
|
+ } else if (side === 'short') {
|
|
|
+ symbol = 'arrow';
|
|
|
+ symbolSize = 15;
|
|
|
+ symbolRotate = 180;
|
|
|
+ color = '#dc3545';
|
|
|
+ label = '卖出';
|
|
|
+ } else {
|
|
|
+ color = '#6c757d';
|
|
|
+ symbol = 'circle';
|
|
|
+ symbolSize = 10;
|
|
|
+ label = '其他';
|
|
|
+ }
|
|
|
+
|
|
|
+ priceMarkLines.push({
|
|
|
+ xAxis: timestamp,
|
|
|
+ lineStyle: {
|
|
|
+ color: color,
|
|
|
+ type: 'dashed',
|
|
|
+ width: 1,
|
|
|
+ opacity: 0.6
|
|
|
+ },
|
|
|
+ label: { show: false }
|
|
|
+ });
|
|
|
+
|
|
|
+ priceMarkPoints.push({
|
|
|
+ coord: [timestamp, event.price || 0],
|
|
|
+ value: label,
|
|
|
+ symbol: symbol,
|
|
|
+ symbolSize: symbolSize,
|
|
|
+ symbolRotate: symbolRotate,
|
|
|
+ itemStyle: {
|
|
|
+ color: color,
|
|
|
+ borderColor: '#fff',
|
|
|
+ borderWidth: 2
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'top',
|
|
|
+ formatter: label,
|
|
|
+ fontSize: 10,
|
|
|
+ color: color,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ },
|
|
|
+ eventData: event
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
const option = {
|
|
|
title: {
|
|
|
text: '',
|
|
|
@@ -623,7 +697,18 @@
|
|
|
type: 'line',
|
|
|
smooth: true,
|
|
|
itemStyle: { color: '#ff6b6b' },
|
|
|
- showSymbol: false
|
|
|
+ showSymbol: false,
|
|
|
+ // 添加事件标记
|
|
|
+ markLine: priceMarkLines.length > 0 ? {
|
|
|
+ silent: false,
|
|
|
+ data: priceMarkLines,
|
|
|
+ animation: false
|
|
|
+ } : undefined,
|
|
|
+ markPoint: priceMarkPoints.length > 0 ? {
|
|
|
+ silent: false,
|
|
|
+ data: priceMarkPoints,
|
|
|
+ animation: false
|
|
|
+ } : undefined
|
|
|
},
|
|
|
{
|
|
|
name: 'Lighter买价',
|
|
|
@@ -673,6 +758,18 @@
|
|
|
|
|
|
priceChart.setOption(option);
|
|
|
|
|
|
+ // 添加点击事件监听
|
|
|
+ if (priceMarkPoints.length > 0) {
|
|
|
+ console.log(' 添加价格图表点击事件监听');
|
|
|
+ priceChart.off('click');
|
|
|
+ priceChart.on('click', function(params) {
|
|
|
+ console.log(' 价格图表被点击:', params);
|
|
|
+ if (params.componentType === 'markPoint' && params.data.eventData) {
|
|
|
+ showEventDetails(params.data.eventData);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
// 创建BPS图表
|
|
|
displayBpsChart(data);
|
|
|
|
|
|
@@ -687,6 +784,9 @@
|
|
|
|
|
|
// 显示BPS图表
|
|
|
function displayBpsChart(data) {
|
|
|
+ console.log('📊 displayBpsChart 被调用, 数据点数:', data.length);
|
|
|
+ console.log(' tradingEventsData:', tradingEventsData?.length);
|
|
|
+
|
|
|
const container = document.getElementById('bpsChart');
|
|
|
|
|
|
// 销毁旧图表实例
|
|
|
@@ -703,6 +803,74 @@
|
|
|
const askBps = data.map(d => [d.timestamp * 1000, d.ask_bps]);
|
|
|
const bidBps = data.map(d => [d.timestamp * 1000, d.bid_bps]);
|
|
|
|
|
|
+ // 准备事件标记数据
|
|
|
+ const bpsMarkLines = [];
|
|
|
+ const bpsMarkPoints = [];
|
|
|
+
|
|
|
+ if (tradingEventsData && tradingEventsData.length > 0) {
|
|
|
+ console.log(' 准备添加', tradingEventsData.length, '个事件标记到BPS图表');
|
|
|
+ tradingEventsData.forEach(event => {
|
|
|
+ const timestamp = event.timestamp * 1000;
|
|
|
+ const side = event.side;
|
|
|
+ const eventType = event.event_type;
|
|
|
+
|
|
|
+ let color, symbol, symbolSize, label, symbolRotate = 0;
|
|
|
+
|
|
|
+ if (side === 'long') {
|
|
|
+ symbol = 'arrow';
|
|
|
+ symbolSize = 15;
|
|
|
+ symbolRotate = 0;
|
|
|
+ color = '#28a745';
|
|
|
+ label = '买入';
|
|
|
+ } else if (side === 'short') {
|
|
|
+ symbol = 'arrow';
|
|
|
+ symbolSize = 15;
|
|
|
+ symbolRotate = 180;
|
|
|
+ color = '#dc3545';
|
|
|
+ label = '卖出';
|
|
|
+ } else {
|
|
|
+ color = '#6c757d';
|
|
|
+ symbol = 'circle';
|
|
|
+ symbolSize = 10;
|
|
|
+ label = '其他';
|
|
|
+ }
|
|
|
+
|
|
|
+ bpsMarkLines.push({
|
|
|
+ xAxis: timestamp,
|
|
|
+ lineStyle: {
|
|
|
+ color: color,
|
|
|
+ type: 'dashed',
|
|
|
+ width: 1,
|
|
|
+ opacity: 0.6
|
|
|
+ },
|
|
|
+ label: { show: false }
|
|
|
+ });
|
|
|
+
|
|
|
+ const bpsValue = event.ask_bps || event.bid_bps || 0;
|
|
|
+ bpsMarkPoints.push({
|
|
|
+ coord: [timestamp, bpsValue],
|
|
|
+ value: label,
|
|
|
+ symbol: symbol,
|
|
|
+ symbolSize: symbolSize,
|
|
|
+ symbolRotate: symbolRotate,
|
|
|
+ itemStyle: {
|
|
|
+ color: color,
|
|
|
+ borderColor: '#fff',
|
|
|
+ borderWidth: 2
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'top',
|
|
|
+ formatter: label,
|
|
|
+ fontSize: 10,
|
|
|
+ color: color,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ },
|
|
|
+ eventData: event
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
const option = {
|
|
|
title: {
|
|
|
text: '',
|
|
|
@@ -783,7 +951,18 @@
|
|
|
type: 'line',
|
|
|
smooth: true,
|
|
|
itemStyle: { color: '#e74c3c' },
|
|
|
- showSymbol: false
|
|
|
+ showSymbol: false,
|
|
|
+ // 添加事件标记
|
|
|
+ markLine: bpsMarkLines.length > 0 ? {
|
|
|
+ silent: false,
|
|
|
+ data: bpsMarkLines,
|
|
|
+ animation: false
|
|
|
+ } : undefined,
|
|
|
+ markPoint: bpsMarkPoints.length > 0 ? {
|
|
|
+ silent: false,
|
|
|
+ data: bpsMarkPoints,
|
|
|
+ animation: false
|
|
|
+ } : undefined
|
|
|
},
|
|
|
{
|
|
|
name: 'Bid价差 (bps)',
|
|
|
@@ -823,12 +1002,16 @@
|
|
|
|
|
|
bpsChart.setOption(option);
|
|
|
|
|
|
- // 如果有交易事件数据,添加标记
|
|
|
- if (tradingEventsData && tradingEventsData.length > 0) {
|
|
|
- // 延迟添加标记,确保图表已完全渲染
|
|
|
- setTimeout(() => {
|
|
|
- addEventMarkersToCharts();
|
|
|
- }, 100);
|
|
|
+ // 添加点击事件监听
|
|
|
+ if (bpsMarkPoints.length > 0) {
|
|
|
+ console.log(' 添加BPS图表点击事件监听');
|
|
|
+ bpsChart.off('click');
|
|
|
+ bpsChart.on('click', function(params) {
|
|
|
+ console.log(' BPS图表被点击:', params);
|
|
|
+ if (params.componentType === 'markPoint' && params.data.eventData) {
|
|
|
+ showEventDetails(params.data.eventData);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -889,10 +1072,19 @@
|
|
|
|
|
|
// 添加交易事件标记到图表
|
|
|
function addEventMarkersToCharts() {
|
|
|
+ console.log('🎯 addEventMarkersToCharts 被调用');
|
|
|
+ console.log(' - priceChart:', !!priceChart);
|
|
|
+ console.log(' - bpsChart:', !!bpsChart);
|
|
|
+ console.log(' - tradingEventsData:', tradingEventsData);
|
|
|
+ console.log(' - tradingEventsData.length:', tradingEventsData?.length);
|
|
|
+
|
|
|
if (!priceChart || !bpsChart || !tradingEventsData || tradingEventsData.length === 0) {
|
|
|
+ console.warn('⚠️ 无法添加事件标记 - 缺少必要数据');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ console.log('✅ 开始添加', tradingEventsData.length, '个事件标记');
|
|
|
+
|
|
|
// 准备标记线数据
|
|
|
const priceMarkLines = [];
|
|
|
const priceMarkPoints = [];
|
|
|
@@ -990,8 +1182,16 @@
|
|
|
bpsMarkPoints.push(bpsMarkPoint);
|
|
|
});
|
|
|
|
|
|
+ console.log('📊 准备更新图表:');
|
|
|
+ console.log(' - priceMarkLines:', priceMarkLines.length);
|
|
|
+ console.log(' - priceMarkPoints:', priceMarkPoints.length);
|
|
|
+ console.log(' - bpsMarkLines:', bpsMarkLines.length);
|
|
|
+ console.log(' - bpsMarkPoints:', bpsMarkPoints.length);
|
|
|
+
|
|
|
// 更新价格图表,添加标记
|
|
|
const priceOption = priceChart.getOption();
|
|
|
+ console.log(' - priceOption.series:', priceOption.series?.length);
|
|
|
+
|
|
|
if (priceOption.series && priceOption.series.length > 0) {
|
|
|
// 在第一个系列(Binance价格)上添加标记
|
|
|
priceOption.series[0].markLine = {
|
|
|
@@ -1005,11 +1205,14 @@
|
|
|
animation: false
|
|
|
};
|
|
|
|
|
|
+ console.log('✅ 更新价格图表标记');
|
|
|
priceChart.setOption(priceOption);
|
|
|
}
|
|
|
|
|
|
// 更新BPS图表,添加标记
|
|
|
const bpsOption = bpsChart.getOption();
|
|
|
+ console.log(' - bpsOption.series:', bpsOption.series?.length);
|
|
|
+
|
|
|
if (bpsOption.series && bpsOption.series.length > 0) {
|
|
|
// 在第一个系列(Ask BPS)上添加标记
|
|
|
bpsOption.series[0].markLine = {
|
|
|
@@ -1023,9 +1226,12 @@
|
|
|
animation: false
|
|
|
};
|
|
|
|
|
|
+ console.log('✅ 更新BPS图表标记');
|
|
|
bpsChart.setOption(bpsOption);
|
|
|
}
|
|
|
|
|
|
+ console.log('🎉 事件标记添加完成');
|
|
|
+
|
|
|
// 添加点击事件监听
|
|
|
priceChart.off('click'); // 移除旧的监听器
|
|
|
priceChart.on('click', function(params) {
|
|
|
@@ -1249,10 +1455,9 @@
|
|
|
if (result.success) {
|
|
|
tradingEventsData = result.data; // 保存事件数据
|
|
|
displayTradingEvents(result.data);
|
|
|
- // 重新绘制图表以添加事件标记
|
|
|
- if (priceChart && bpsChart) {
|
|
|
- addEventMarkersToCharts();
|
|
|
- }
|
|
|
+ console.log('✅ 已加载交易事件:', tradingEventsData.length, '个');
|
|
|
+ // 注意:不需要调用 addEventMarkersToCharts()
|
|
|
+ // 因为标记会在 displayPriceChart 和 displayBpsChart 中自动添加
|
|
|
} else {
|
|
|
throw new Error(result.error);
|
|
|
}
|
|
|
@@ -1518,26 +1723,24 @@
|
|
|
);
|
|
|
|
|
|
if (filteredData.length > 0) {
|
|
|
- // 更新价格图表
|
|
|
- displayPriceChart(filteredData);
|
|
|
- // 更新BPS图表
|
|
|
- displayBpsChart(filteredData);
|
|
|
-
|
|
|
- // 更新时间范围显示
|
|
|
- updateTimeRangeDisplay();
|
|
|
-
|
|
|
- // 更新交易事件数据
|
|
|
+ // ⚠️ 重要:先更新交易事件数据,再创建图表
|
|
|
+ // 因为 displayPriceChart 和 displayBpsChart 会读取 tradingEventsData
|
|
|
if (eventsResult.success && eventsResult.data) {
|
|
|
tradingEventsData = eventsResult.data;
|
|
|
displayTradingEvents(tradingEventsData);
|
|
|
+ console.log('✅ 已设置交易事件数据:', tradingEventsData.length, '个事件');
|
|
|
+ } else {
|
|
|
+ tradingEventsData = [];
|
|
|
+ console.log('⚠️ 没有交易事件数据');
|
|
|
+ }
|
|
|
|
|
|
- console.log('显示交易事件数量:', tradingEventsData.length);
|
|
|
+ // 更新价格图表(会自动包含事件标记)
|
|
|
+ displayPriceChart(filteredData);
|
|
|
+ // 更新BPS图表(会自动包含事件标记)
|
|
|
+ displayBpsChart(filteredData);
|
|
|
|
|
|
- // 重新添加事件标记
|
|
|
- setTimeout(() => {
|
|
|
- addEventMarkersToCharts();
|
|
|
- }, 200);
|
|
|
- }
|
|
|
+ // 更新时间范围显示
|
|
|
+ updateTimeRangeDisplay();
|
|
|
} else {
|
|
|
console.log('过滤后没有数据');
|
|
|
}
|