我正在绘制一个在 x 时间轴上具有多个布尔自定义系列的数字线系列。布尔自定义系列的渲染方式为每个布尔系列创建水平泳道,并且泳道的不透明度由值决定。因为工具提示触发器是轴,所以我只能看到数据点存在时的布尔值(自定义系列渲染项目的开始)。无论我将鼠标悬停在图表上的哪个位置,如何在工具提示中包含所有布尔系列的布尔值,以便我可以看到线条系列的数值以及与悬停位置相交的所有布尔系列值给定时间点?
Apache ECharts 自定义示例:链接
在上面链接的 Apache Echarts 自定义示例中悬停特定时间点的图像
期望:当我将鼠标悬停在特定时间点上时,我期望看到线系列中的数值以及与给定时间点的悬停位置相交的自定义系列中的布尔值。在我提供的图像中,我希望在工具提示中看到这些值:84.5、false、false。
我尝试过的:
我考虑过的:
我想到的最简单的解决方案是将所有线点添加到布尔数据数组中。由于这给出了多个布尔值的间隔相等,因此我稍微更改了渲染函数,仅从布尔值发生变化的点进行渲染。
示例:
const NUMBER_DATA = [
[new Date('2024-06-13T00:00:12.000Z'), 78.1],
[new Date('2024-06-13T00:04:45.000Z'), 76.3],
[new Date('2024-06-13T00:07:24.000Z'), 72.4],
[new Date('2024-06-13T00:12:13.000Z'), 73.3],
[new Date('2024-06-13T00:17:43.000Z'), 84.5],
[new Date('2024-06-13T00:21:56.000Z'), 81.0],
[new Date('2024-06-13T00:26:35.000Z'), 77.9],
[new Date('2024-06-13T00:29:32.000Z'), 65.4],
[new Date('2024-06-13T00:32:04.000Z'), 51.3],
[new Date('2024-06-13T00:35:27.000Z'), 44.2],
[new Date('2024-06-13T00:39:51.000Z'), 39.8]
];
const BOOLEAN_DATA1 = [
[new Date('2024-06-13T00:00:12.000Z'), true],
[new Date('2024-06-13T00:11:13.000Z'), false],
[new Date('2024-06-13T00:24:37.000Z'), true],
[new Date('2024-06-13T00:30:11.000Z'), false],
[new Date('2024-06-13T00:32:50.000Z'), true],
[new Date('2024-06-13T00:39:51.000Z'), false]
];
const BOOLEAN_DATA2 = [
[new Date('2024-06-13T00:00:12.000Z'), false],
[new Date('2024-06-13T00:07:52.000Z'), true],
[new Date('2024-06-13T00:13:48.000Z'), false],
[new Date('2024-06-13T00:20:11.000Z'), true],
[new Date('2024-06-13T00:33:23.000Z'), false],
[new Date('2024-06-13T00:39:51.000Z'), true]
];
function addPointsToBoolData(booldata) {
let index = 0;
for (let datapoint of NUMBER_DATA) {
if (booldata[index] === undefined) {
booldata.push([datapoint[0], booldata[-1][1]]);
continue;
}
while (booldata[index][0] < datapoint[0]) {
index++;
}
if (datapoint[0].getTime() === booldata[index][0].getTime()) {
index++;
continue;
}
if (index === 0) {
booldata.splice(index, 0, [datapoint[0], booldata[index][1]]);
} else {
booldata.splice(index, 0, [datapoint[0], booldata[index-1][1]]);
}
}
}
addPointsToBoolData(BOOLEAN_DATA1)
addPointsToBoolData(BOOLEAN_DATA2)
function getRenderItem(categoryIndex, data) {
return function renderItem(params, api) {
const date = api.value(0);
const val = api.value(1);
if (params.dataIndex === data.length - 1) {
return null;
}
if (data[params.dataIndex - 1] && data[params.dataIndex - 1][1] === val) {
return null;
}
let index = 0;
let nextVal = val;
while (data[params.dataIndex + index + 1] && val === nextVal) {
index++;
nextVal = data[params.dataIndex + index][1];
}
const nextDate = data[params.dataIndex + index][0];
const start = api.coord([date, categoryIndex]);
const end = api.coord([nextDate, categoryIndex]);
const height = api.size([0, 1])[1];
const opacity = val ? 1 : 0.75;
var rectShape = echarts.graphic.clipRectByRect(
{
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height
},
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
);
return (
rectShape && {
type: 'rect',
transition: ['shape'],
shape: rectShape,
style: {
fill: api.visual('color'),
opacity
}
}
);
};
}
option = {
tooltip: {
trigger: 'axis',
valueFormatter: (value) => (typeof value === 'number' ? value : value[1]),
axisPointer: {
axis: 'x'
}
},
xAxis: {
type: 'time'
},
yAxis: [
{
type: 'value'
},
{
type: 'category',
show: false,
data: ['Boolean Data 1', 'Boolean Data 2']
}
],
series: [
{
type: 'line',
yAxisIndex: 0,
data: NUMBER_DATA
},
{
type: 'custom',
yAxisIndex: 1,
renderItem: getRenderItem(0, BOOLEAN_DATA1),
data: BOOLEAN_DATA1
},
{
type: 'custom',
yAxisIndex: 1,
renderItem: getRenderItem(1, BOOLEAN_DATA2),
data: BOOLEAN_DATA2
}
]
};