echart 桑基图的点击高亮

先上效果图

引入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

  1. 调整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;
  1. 调整高亮节点的
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
      }
    });
  }
}
相关推荐
梨子同志1 分钟前
ES6 let 和 const
前端·javascript
用户5806139393002 分钟前
超越 console.log():前端调试的 10 个神级技巧
前端
却尘3 分钟前
当全世界都在用 Rust 重写一切时,Prisma 却选择了反方向
前端·数据库·orm
这是个栗子3 分钟前
前端开发者常用网站
前端
前端小白佬19 分钟前
【JS】防抖(debounce)和节流(throttle)
前端·面试
GIS之路21 分钟前
OpenLayers 从后端服务加载 GeoJSON 数据
前端
前端小白佬28 分钟前
【JS】事件传播--事件捕获/冒泡
javascript·面试
开始编程吧28 分钟前
【HarmonyOS5】仓颉编程:当多范式统一成为智能时代的「通用语言」
前端
PasserbyX38 分钟前
ES6 WeakMap 生效的证明: FinalizationRegistry
前端·javascript
努力学习的小刘41 分钟前
如何使用react-router实现动态路由
前端·javascript