我已经为 echarts 实现了自定义图例来调度图表操作。 它工作正常,但有时会隐藏折线图标签。 要实现该行为,您必须单击 line1 按钮,然后单击 line2 按钮以隐藏折线图。然后以任意顺序再次单击它们,在某些时候图表上的其中一条线将不会显示其标签。
<html lang="en">
<head>
<meta charset="utf-8">
<title>Basic Line Chart - Apache ECharts Demo</title>
</head>
<body>
<div id="chart-container"></div>
<div id="buttons">
<button id="line1">line1</button>
<button id="line2">line2</button>
</div>
<script src="https://fastly.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
</body>
</html>
<style>
* {
margin: 0;
padding: 0;
}
#chart-container {
position: relative;
height: 80vh;
overflow: hidden;
}
#buttons {
padding: 20px;
display: flex;
gap: 10px;
align-items: center;
justify-content: center;
}
</style>
<script>
var dom = document.getElementById('chart-container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
option = {
legend: {
show: false
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: 'line1',
emphasis: {
focus: 'self'
},
label: {
show: true
},
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
},
{
name: 'line2',
emphasis: {
focus: 'self'
},
label: {
show: true
},
data: [80, 150, 180, 250, 180, 160, 180],
type: 'line'
},
]
};
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
const dispatch = (line) => {
myChart.dispatchAction({
type: 'legendToggleSelect',
name: line,
});
};
const mouseOver = (index) => {
myChart.dispatchAction({
type: 'highlight',
seriesIndex: index,
});
};
const mouseOut = (index) => {
myChart.dispatchAction({
type: 'downplay',
seriesIndex: index,
});
};
['line1', 'line2'].forEach((line, index) => {
const item = document.getElementById(line);
item.addEventListener('click', () => dispatch(line));
item.addEventListener('mouseover', () => mouseOver(index));
item.addEventListener('mouseout', () => mouseOut(index));
});
</script>
如果从图表系列中删除强调选项,则它可以工作。但我需要强调图例悬停时的突出显示线。
这是您发现的意外且不稳定的行为。
通过在图表上记录事件并检查 真正的传奇是做什么的,经过一些调试后 源代码,我确定了问题所在: 突出显示、隐藏然后再次显示的系列 为标签生成两个相互冲突的动画,一个 为了正常渲染要显示的系列 以及一个用于将
emphasis
状态应用于相同的状态。
确实,禁用动画后问题不会显现。
解决方案是向 之前即将被图例选择隐藏的系列 调度
downplay
事件;这样所有
隐藏系列将处于正常状态。这个动作是
当突出显示的项目时也由真实图例执行
被点击。自从 legendToggleSelect
发送到隐藏系列
没有效果,解决方案可能很简单,只需更改您的
downplay
功能:dispatch
const dispatch = (line) => {
myChart.dispatchAction({
type: 'downplay',
seriesName: line
});
myChart.dispatchAction({
type: 'legendToggleSelect',
name: line,
});
};
const dom = document.getElementById('chart-container');
const myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
const option = {
legend: {
show: false
},
//animation: false,
animationDuration: 20,
animationDurationUpdate: 20,
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: 'line1',
emphasis: {
focus: 'self',
},
label: {
show: true
},
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
},
{
name: 'line2',
emphasis: {
focus: 'self',
},
label: {
show: true
},
data: [81, 150, 180, 250, 180, 160, 180],
type: 'line'
}
]
};
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
// myChart.on('legendselectchanged', data => console.warn('legend.select.changed', data));
// myChart.on('highlight', 'series.line', data => console.log('line.highlighted', data));
// myChart.on('downplay', 'series.line', data => console.log('line.downplayed', data));
const dispatch = (line) => {
myChart.dispatchAction({
type: 'downplay',
seriesName: line
});
myChart.dispatchAction({
type: 'legendToggleSelect',
name: line,
});
};
const mouseOver = (index) => {
myChart.dispatchAction({
type: 'highlight',
seriesIndex: index
});
};
const mouseOut = (index) => {
myChart.dispatchAction({
type: 'downplay',
seriesIndex: index
});
};
['line1', 'line2'].forEach((line, index) => {
const item = document.getElementById(line);
item.addEventListener('click', () => dispatch(line));
item.addEventListener('mouseover', () => mouseOver(index));
item.addEventListener('mouseout', () => mouseOut(index));
});
#chart-container {
position: relative;
height: 90vh;
overflow: hidden;
}
#buttons {
display: flex;
gap: 10px;
align-items: center;
justify-content: center;
}