|
|
@@ -516,10 +516,10 @@
|
|
|
priceChart = echarts.init(container);
|
|
|
|
|
|
// 准备数据
|
|
|
- const timestamps = data.map(d => new Date(d.timestamp * 1000).toLocaleTimeString());
|
|
|
- const binancePrices = data.map(d => d.binance_price);
|
|
|
- const lighterBids = data.map(d => d.lighter_bid);
|
|
|
- const lighterAsks = data.map(d => d.lighter_ask);
|
|
|
+ // 对于时间类型的 X 轴,数据格式应该是 [[timestamp, value], ...]
|
|
|
+ const binancePrices = data.map(d => [d.timestamp * 1000, d.binance_price]);
|
|
|
+ const lighterBids = data.map(d => [d.timestamp * 1000, d.lighter_bid]);
|
|
|
+ const lighterAsks = data.map(d => [d.timestamp * 1000, d.lighter_ask]);
|
|
|
|
|
|
const option = {
|
|
|
title: {
|
|
|
@@ -544,8 +544,7 @@
|
|
|
containLabel: true
|
|
|
},
|
|
|
xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: timestamps,
|
|
|
+ type: 'time',
|
|
|
boundaryGap: false
|
|
|
},
|
|
|
yAxis: {
|
|
|
@@ -561,7 +560,8 @@
|
|
|
type: 'line',
|
|
|
smooth: true,
|
|
|
itemStyle: { color: '#ff6b6b' },
|
|
|
- areaStyle: { color: 'rgba(255, 107, 107, 0.1)' }
|
|
|
+ areaStyle: { color: 'rgba(255, 107, 107, 0.1)' },
|
|
|
+ showSymbol: false
|
|
|
},
|
|
|
{
|
|
|
name: 'Lighter买价',
|
|
|
@@ -569,7 +569,8 @@
|
|
|
type: 'line',
|
|
|
smooth: true,
|
|
|
itemStyle: { color: '#45b7d1' },
|
|
|
- lineStyle: { type: 'dashed' }
|
|
|
+ lineStyle: { type: 'dashed' },
|
|
|
+ showSymbol: false
|
|
|
},
|
|
|
{
|
|
|
name: 'Lighter卖价',
|
|
|
@@ -577,7 +578,8 @@
|
|
|
type: 'line',
|
|
|
smooth: true,
|
|
|
itemStyle: { color: '#f9ca24' },
|
|
|
- lineStyle: { type: 'dashed' }
|
|
|
+ lineStyle: { type: 'dashed' },
|
|
|
+ showSymbol: false
|
|
|
}
|
|
|
],
|
|
|
dataZoom: [
|
|
|
@@ -627,9 +629,9 @@
|
|
|
bpsChart = echarts.init(container);
|
|
|
|
|
|
// 准备数据
|
|
|
- const timestamps = data.map(d => new Date(d.timestamp * 1000).toLocaleTimeString());
|
|
|
- const askBps = data.map(d => d.ask_bps);
|
|
|
- const bidBps = data.map(d => d.bid_bps);
|
|
|
+ // 对于时间类型的 X 轴,数据格式应该是 [[timestamp, value], ...]
|
|
|
+ const askBps = data.map(d => [d.timestamp * 1000, d.ask_bps]);
|
|
|
+ const bidBps = data.map(d => [d.timestamp * 1000, d.bid_bps]);
|
|
|
|
|
|
const option = {
|
|
|
title: {
|
|
|
@@ -654,8 +656,7 @@
|
|
|
containLabel: true
|
|
|
},
|
|
|
xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: timestamps,
|
|
|
+ type: 'time',
|
|
|
boundaryGap: false
|
|
|
},
|
|
|
yAxis: {
|
|
|
@@ -669,7 +670,8 @@
|
|
|
type: 'line',
|
|
|
smooth: true,
|
|
|
itemStyle: { color: '#e74c3c' },
|
|
|
- areaStyle: { color: 'rgba(231, 76, 60, 0.1)' }
|
|
|
+ areaStyle: { color: 'rgba(231, 76, 60, 0.1)' },
|
|
|
+ showSymbol: false
|
|
|
},
|
|
|
{
|
|
|
name: 'Bid价差 (bps)',
|
|
|
@@ -677,7 +679,8 @@
|
|
|
type: 'line',
|
|
|
smooth: true,
|
|
|
itemStyle: { color: '#27ae60' },
|
|
|
- areaStyle: { color: 'rgba(39, 174, 96, 0.1)' }
|
|
|
+ areaStyle: { color: 'rgba(39, 174, 96, 0.1)' },
|
|
|
+ showSymbol: false
|
|
|
}
|
|
|
],
|
|
|
dataZoom: [
|
|
|
@@ -749,8 +752,8 @@
|
|
|
priceThumbnail = echarts.init(container);
|
|
|
|
|
|
// 准备数据
|
|
|
- const timestamps = data.map(d => new Date(d.timestamp * 1000).toLocaleTimeString());
|
|
|
- const binancePrices = data.map(d => d.binance_price);
|
|
|
+ // 对于时间类型的 X 轴,数据格式应该是 [[timestamp, value], ...]
|
|
|
+ const seriesData = data.map(d => [d.timestamp * 1000, d.binance_price]);
|
|
|
|
|
|
const option = {
|
|
|
tooltip: {
|
|
|
@@ -764,8 +767,7 @@
|
|
|
containLabel: true
|
|
|
},
|
|
|
xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: timestamps,
|
|
|
+ type: 'time',
|
|
|
boundaryGap: false,
|
|
|
axisLine: { show: true },
|
|
|
axisTick: { show: true },
|
|
|
@@ -783,12 +785,13 @@
|
|
|
series: [
|
|
|
{
|
|
|
name: 'Binance价格',
|
|
|
- data: binancePrices,
|
|
|
+ data: seriesData,
|
|
|
type: 'line',
|
|
|
smooth: true,
|
|
|
itemStyle: { color: '#ff6b6b' },
|
|
|
areaStyle: { color: 'rgba(255, 107, 107, 0.2)' },
|
|
|
- lineStyle: { width: 1.5 }
|
|
|
+ lineStyle: { width: 1.5 },
|
|
|
+ showSymbol: false
|
|
|
}
|
|
|
]
|
|
|
};
|
|
|
@@ -914,46 +917,40 @@
|
|
|
function setupThumbnailClickHandler(containerId, chart) {
|
|
|
const container = document.getElementById(containerId);
|
|
|
|
|
|
- // 直接在容器上添加点击事件
|
|
|
- container.addEventListener('click', function(event) {
|
|
|
+ // 使用 ECharts 的点击事件,而不是 DOM 点击事件
|
|
|
+ chart.on('click', function(params) {
|
|
|
if (!thumbnailData || thumbnailData.length === 0) {
|
|
|
console.log('缩略图数据为空');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 获取容器的位置和大小
|
|
|
- const rect = container.getBoundingClientRect();
|
|
|
- const x = event.clientX - rect.left;
|
|
|
- const containerWidth = rect.width;
|
|
|
-
|
|
|
- // 计算点击位置对应的数据索引
|
|
|
- const dataIndex = Math.floor((x / containerWidth) * thumbnailData.length);
|
|
|
- const clickedIndex = Math.min(dataIndex, thumbnailData.length - 1);
|
|
|
- const clickedDataPoint = thumbnailData[clickedIndex];
|
|
|
-
|
|
|
- if (clickedDataPoint) {
|
|
|
- // 选择前后10分钟的数据
|
|
|
- const clickedTime = clickedDataPoint.timestamp;
|
|
|
- const tenMinutes = 10 * 60; // 10分钟的秒数
|
|
|
+ // 从点击事件获取时间戳(ECharts 会自动处理时间轴的转换)
|
|
|
+ const clickedTime = params.value[0] / 1000; // 转换为秒
|
|
|
+ const tenMinutes = 10 * 60; // 10分钟的秒数
|
|
|
|
|
|
- console.log('点击的数据点:', clickedDataPoint);
|
|
|
- console.log('点击时间戳:', clickedTime);
|
|
|
- console.log('点击索引:', clickedIndex);
|
|
|
+ // 调试信息
|
|
|
+ const clickedDate = new Date(clickedTime * 1000);
|
|
|
+ console.log('点击的时间戳:', clickedTime);
|
|
|
+ console.log('点击时间(本地):', clickedDate.toLocaleString());
|
|
|
+ console.log('点击时间(UTC):', clickedDate.toUTCString());
|
|
|
|
|
|
- selectedTimeRange = {
|
|
|
- start: clickedTime - tenMinutes,
|
|
|
- end: clickedTime + tenMinutes,
|
|
|
- center: clickedTime
|
|
|
- };
|
|
|
+ selectedTimeRange = {
|
|
|
+ start: clickedTime - tenMinutes,
|
|
|
+ end: clickedTime + tenMinutes,
|
|
|
+ center: clickedTime
|
|
|
+ };
|
|
|
|
|
|
- console.log('选择的时间范围:', selectedTimeRange);
|
|
|
+ const startDate = new Date(selectedTimeRange.start * 1000);
|
|
|
+ const endDate = new Date(selectedTimeRange.end * 1000);
|
|
|
+ console.log('选择的时间范围:', selectedTimeRange);
|
|
|
+ console.log('选择范围(本地):', startDate.toLocaleString(), '-', endDate.toLocaleString());
|
|
|
+ console.log('选择范围(UTC):', startDate.toUTCString(), '-', endDate.toUTCString());
|
|
|
|
|
|
- // 更新主图表显示选中的时间范围数据
|
|
|
- updateMainChartsWithSelectedRange();
|
|
|
+ // 更新主图表显示选中的时间范围数据
|
|
|
+ updateMainChartsWithSelectedRange();
|
|
|
|
|
|
- // 显示选择区域
|
|
|
- showThumbnailSelection(containerId, clickedIndex);
|
|
|
- }
|
|
|
+ // 显示选择区域
|
|
|
+ showThumbnailSelection(containerId, clickedTime);
|
|
|
});
|
|
|
|
|
|
// 鼠标移动时改变光标
|
|
|
@@ -967,7 +964,7 @@
|
|
|
}
|
|
|
|
|
|
// 显示缩略图选择区域
|
|
|
- function showThumbnailSelection(canvasId, dataIndex) {
|
|
|
+ function showThumbnailSelection(canvasId, clickedTime) {
|
|
|
const thumbnailWrapper = document.getElementById(canvasId);
|
|
|
|
|
|
// 移除之前的选择区域
|
|
|
@@ -981,9 +978,16 @@
|
|
|
selection.className = 'thumbnail-selection';
|
|
|
|
|
|
// 计算选择区域的位置和宽度
|
|
|
- const totalDataPoints = thumbnailData.length;
|
|
|
- const selectionWidth = (20 / totalDataPoints) * 100; // 20分钟范围对应的百分比宽度
|
|
|
- const centerPosition = (dataIndex / totalDataPoints) * 100;
|
|
|
+ // 基于时间戳计算位置
|
|
|
+ const minTime = thumbnailData[0].timestamp;
|
|
|
+ const maxTime = thumbnailData[thumbnailData.length - 1].timestamp;
|
|
|
+ const totalTimeSpan = maxTime - minTime;
|
|
|
+
|
|
|
+ const tenMinutes = 10 * 60; // 10分钟的秒数
|
|
|
+ const selectionTimeSpan = tenMinutes * 2; // 前后各10分钟
|
|
|
+
|
|
|
+ const centerPosition = ((clickedTime - minTime) / totalTimeSpan) * 100;
|
|
|
+ const selectionWidth = (selectionTimeSpan / totalTimeSpan) * 100;
|
|
|
const leftPosition = Math.max(0, centerPosition - selectionWidth / 2);
|
|
|
const actualWidth = Math.min(selectionWidth, 100 - leftPosition);
|
|
|
|