方案 1:自定义 tooltip
自定义 tootip,加入逻辑将数据保存在一个变量中,监听 echarts 的双击事件,将变量中的数据添加到表格中。此方案简单有效,不用考虑 x 轴对齐问题,echarts 已经处理好了。太简单了就不贴代码了。
方案 2:自己计算
自己计算,以下代码只适用于多条曲线的 x 轴是对齐的情况,不对齐则需要额外的逻辑,本文未考虑这种情况。
myChart.getZr().on("dblclick", () => {
let pointInPixel = [params.offsetX, params.offsetY];
if (myChart.containPixel("grid", pointInPixel)) {
let xIndex = myChart.convertFromPixel(
{ seriesIndex: 0 },
pointInPixel
)[0];
let series: any = option.series;
series = series.filter((se: any) => {
let d = se.data;
if (d && d[0].name <= xIndex && d[d.length - 1].name >= xIndex) {
return true;
}
return false;
});
let data: any = series[0].data;
let end = data.length - 1;
let index = findIndex(xIndex, data, 0, end);
if (index == 0) {
index = 0;
} else if (index > end) {
index = end;
} else {
// 计算前后两个值和 xIndex 的差,选取最近的一个最为 index
let first = xIndex - data[index - 1].name;
let second = data[index].name - xIndex;
if (first < second) {
index = index - 1;
}
}
// 将数据添加到表格中
let time = data[index].name;
tableColumns.length = 0;
let row: any = { time: time };
series.forEach((se: any) => {
let value = findValue(time, se.data, 0, se.data.length);
if (value !== null) {
tableColumns.push({
label: se.name,
prop: se.name,
width: 0,
formatter: defaultFormatter,
});
row[se.name] = value;
}
});
pinTableData.value.push(row);
}
})
// 查找 x 轴的值,二分法
const findIndex = (
num: number,
nums: any[],
start: number,
end: number
): number => {
if (start == end) {
return start;
}
if (end - start == 1) {
if (nums[start].name >= num) {
return start;
}
if (nums[start].name <= num && num <= nums[end].name) {
return end;
}
return end + 1;
}
let index = Math.ceil((start + end) / 2);
let val = nums[index].name;
if (val == num || (val > num && nums[index - 1].name < num)) {
return index;
}
if (val > num) {
return findIndex(num, nums, start, index - 1);
}
return findIndex(num, nums, index + 1, end);
};
// 查找 y 轴的值,二分法
const findValue = (
num: number,
nums: any[],
start: number,
end: number
): any => {
if (start <= end) {
let index = Math.ceil((start + end) / 2);
let val = nums[index].name;
if (val == num) {
return nums[index].value[1];
}
if (val > num) {
return findValue(num, nums, start, index - 1);
}
return findValue(num, nums, index + 1, end);
}
return null;
};