先上效果图
引入echarts-for-react
js
import ReactEcharts from 'echarts-for-react';
增加点击事件, 这里需要注意的是当用的是setState时,在onChartReady里获取的state的值一直是空值,所以增加useRef来临时存放curHighLight的值;
js
const [curHighLight, setCurHighLight] = useState(null);
const curHighLightRef = useRef(null);
<ReactEcharts
notMerge={true}
option={chartOption}
onChartReady={(EChartsInstance) => {
ChartsInstance.current = EChartsInstance;
// 双击高亮
ChartsInstance.current.on('click', (params) => {
console.log('点击高亮', params);
if (isHighlighted(params, curHighLightRef.current)) {
setCurHighLight(null);
curHighLightRef.current = null;
} else {
const cur = {
dataType: params?.dataType,
name: params?.data?.name,
source: params?.data?.source,
target: params?.data?.target
}
setCurHighLight(cur);
curHighLightRef.current = cur;
}
return false;
});
}}
/>
判断是否已经被点击过
js
const isHighlighted = (params, curHighLight) => {
if (params.dataType === 'node') {
return params?.data?.name === curHighLight?.name;
}
if (params.dataType === 'edge') {
return params?.data?.source === curHighLight?.source && params?.data?.target === curHighLight?.target;
}
return false;
}
点击事件增加后,把当前点击节点或连接线存起来后,再通过useEffect更新option
- 调整lineStyle和itemStyle里 opacity 值
js
const temp = cloneDeep(chartOption);
temp.series[0].lineStyle.opacity = curHighLight === null ? lineOpacity / 100 : 0.1;
temp.series[0].itemStyle.opacity = curHighLight === null ? 1 : 0.1;
temp.series[0].emphasis.disabled = curHighLight !== null;
- 调整高亮节点的
js
// 获取高亮详情
const getHighLightInfo = ({ curHighLight, links, nodes }) => {
// 当取消高亮时,文字颜色恢复正常
if (curHighLight === null) {
const isHighLight = false;
links?.forEach(item => {
item.isHighLight = isHighLight;
item.lineStyle.opacity = null;
});
nodes.forEach(item => {
item.isHighLight = isHighLight;
item.itemStyle.opacity = null;
item.label = {
color: null
}
});
}
// 节点
if (curHighLight?.dataType === 'node') {
const selectList = [];
links.forEach(item => {
const isHighLight = item.source === curHighLight.name || item.target === curHighLight.name;
item.isHighLight = isHighLight;
item.lineStyle.opacity = isHighLight ? opacityHL_link : 0.1;
if (isHighLight) {
selectList.push(item);
}
});
nodes.forEach(item => {
const isIn = selectList.find(v => v.source === item.name || v.target === item.name);
const isHighLight = !!isIn;
item.isHighLight = isHighLight;
item.itemStyle.opacity = isHighLight ? opacityHL_node : 0.1;
item.label = {
color: !isHighLight ? 'rgba(0, 0, 0, 0.35)' : null
}
});
}
// 连线
if (curHighLight?.dataType === 'edge') {
links?.forEach(item => {
const isHighLight = item.source === curHighLight?.source && item.target === curHighLight?.target;
item.isHighLight = isHighLight;
item.lineStyle.opacity = isHighLight ? opacityHL_link : 0.1;
});
nodes.forEach(item => {
const isHighLight = item.name === curHighLight.source || item.name === curHighLight.target;
item.isHighLight = isHighLight;
item.itemStyle.opacity = isHighLight ? opacityHL_node : 0.1;
item.label = {
color: !isHighLight ? 'rgba(0, 0, 0, 0.35)' : null
}
});
}
}