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
      }
    });
  }
}
相关推荐
工业甲酰苯胺3 小时前
TypeScript枚举类型应用:前后端状态码映射的最简方案
javascript·typescript·状态模式
brzhang3 小时前
我操,终于有人把 AI 大佬们 PUA 程序员的套路给讲明白了!
前端·后端·架构
止观止4 小时前
React虚拟DOM的进化之路
前端·react.js·前端框架·reactjs·react
goms4 小时前
前端项目集成lint-staged
前端·vue·lint-staged
谢尔登4 小时前
【React Natve】NetworkError 和 TouchableOpacity 组件
前端·react.js·前端框架
Lin Hsüeh-ch'in4 小时前
如何彻底禁用 Chrome 自动更新
前端·chrome
augenstern4166 小时前
HTML面试题
前端·html
张可6 小时前
一个KMP/CMP项目的组织结构和集成方式
android·前端·kotlin
G等你下课6 小时前
React 路由懒加载入门:提升首屏性能的第一步
前端·react.js·前端框架
谢尔登7 小时前
【React Native】ScrollView 和 FlatList 组件
javascript·react native·react.js