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
      }
    });
  }
}
相关推荐
理想不理想v18 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我19 分钟前
浏览器交互事件汇总
前端·交互
小阮的学习笔记32 分钟前
Vue3中使用LogicFlow实现简单流程图
javascript·vue.js·流程图
YBN娜33 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=33 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck38 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript