桑基图-鼠标悬浮(选中)某一个节点和节点有关系的高亮v2

描述:当前是关于Echarts图表中的 桑基图 示例。
 
            let data = {
   "nodes": [
      { name: 'end', level: 3 },

      { name: 'one0', level: 0 },
      { name: 'one1', level: 0 },
      { name: 'one2', level: 0 },
      { name: 'one3', level: 0 },
      { name: 'one4', level: 0 },

      { name: 'two0', level: 1 },
      { name: 'two1', level: 1 },
      { name: 'two2', level: 1 },
      { name: 'two3', level: 1 },
      { name: 'two4', level: 1 },

      { name: 'three0', level: 3 },
      { name: 'three1', level: 3 },
      { name: 'three2', level: 3 },
      { name: 'three3', level: 3 },
      { name: 'three4', level: 1 },
      { name: 'three5', level: 1 },
      { name: 'three6', level: 1 },
      { name: 'three7', level: 1 },


      { name: 'four1' },
      { name: 'four2' },
   ],
   "links": [
      { source: 'one0', target: 'two0', value: 1 },
      { source: 'one1', target: 'two1', value: 1 },
      { source: 'one2', target: 'two2', value: 1 },
      { source: 'one3', target: 'two3', value: 1 },
      { source: 'one4', target: 'two4', value: 1 },

      { source: 'two0', target: 'three0', value: 1 },
      { source: 'two0', target: 'three1', value: 1 },
      { source: 'two0', target: 'three2', value: 1 },
      { source: 'two0', target: 'three3', value: 1 },
      { source: 'two0', target: 'three4', value: 1 },
      { source: 'two0', target: 'right0', value: 1 },
      { source: 'two0', target: 'right1', value: 1 },
      { source: 'two0', target: 'right2', value: 1 },
      { source: 'two0', target: 'right3', value: 1 },
      { source: 'two0', target: 'right4', value: 1 },

      { source: 'two1', target: 'three5', value: 1 },
      { source: 'two1', target: 'three4', value: 1 },
      { source: 'two2', target: 'three6', value: 1 },
      { source: 'two3', target: 'three7', value: 1 },
      { source: 'two4', target: 'three7', value: 1 },
      { source: 'three0', target: 'four1', value: 1 },
      { source: 'three1', target: 'four2', value: 1 },
      { source: 'three1', target: 'four1', value: 1 },
      { source: 'three2', target: 'four1', value: 1 },
      { source: 'three3', target: 'four1', value: 1 },
      { source: 'three4', target: 'four1', value: 1 },
      { source: 'three5', target: 'four2', value: 1 },
      { source: 'three6', target: 'four2', value: 1 },
      { source: 'three7', target: 'four2', value: 1 },
      { source: 'four1', target: 'end', value: 1 },
      { source: 'four2', target: 'end', value: 1 },
   ]
}

const dg = (name) => {
   data.links.map((v) => {
      if (v.source == name) {
         v['gx'] = 1;
         dg(v.target)
      }
   })
}

const dg2 = (name1, name2) => {
   data.links.map((v) => {
      if (v.target == name1) {
         v['gx'] = 1;
         dg2(v.source, v.target);
      }
   })
}

const dg3 = (name1) => {
   data.links.map((v) => {
      if (v.target == name1) {
         v['gx'] = 1;
         dg3(v.source);
      }
   })
}

let level_last = []
data.links.map((link) => {
   let link_ = data.links.filter((f) => f.source == link.target)[0];
   if (!link_) {
      level_last.push(link);
   }
})
// level 最低层级 label右对齐向左延申
let maxKey = 0;
let colors = ['#10d19c','#fdffab','#f6cd4f','#f9dd4b','#e7a398','#f1c27e','#e48936','#a76241','#77d2d3','#3d74b4','#3375cb','#b2cee4','#ec69d1','#9157a3','#c2e19d','#6eea88','#569d3f','#449680','#663f9a','#cd3729'];
data.nodes.map((node, key) => {
   let is_ = level_last.filter((v) => v.target == node.name)[0];
   if (is_) {
      node['label'] = {
         position: "right",
         width: 16 * (6 + 1),
         overflow: 'truncate',
         ellipsis: '...'
      }
   }
   let k = key;
   if (key > colors.length - 1) {
      if (maxKey > colors.length - 1) {
         maxKey = 0;
      }
      k = maxKey;
      maxKey++
   }
   node['itemStyle'] = {
      opacity: .2,
      color: colors[k]
   }
})
option = {
   title: {
      text: 'Sankey Diagram'
   },
   tooltip: {
      trigger: 'item',
      triggerOn: 'mousemove'
   },
   series: [
      {
         type: 'sankey',
         data: data.nodes,
         links: data.links,
         draggable: false,
         lineStyle: {
            curveness: 0.5,
            color: 'source',
         }
      }
   ]
}
myChart.setOption(option);
myChart.on('mouseover', (eventParam) => {
   data.links.forEach((link) => {
      link.gx = 0;
      link['lineStyle'] = {};
   })
   let activeNode = [];
   if (eventParam.dataType == "node") {
      let name1 = eventParam.data.id ? eventParam.data.id : eventParam.data.name;  //这里可能会变化
      let items = data.links.filter((v) => v.target == name1);
      if (items.length <= 0) {
         items = data.links.filter((v) => v.source == name1)
      }
      items.map((item) => {
         item['gx'] = 1;
         dg(item.target);
         dg3(item.source);
      })
      data.links.map((link) => {
         link['lineStyle'] = {
            opacity: .1
         }
         if (link.gx) {
            link['lineStyle'] = {
               opacity: .8
            }
            let nodes = data.links.filter((link_) => link_.source == link.target)
            activeNode.push(...nodes)
         }
      })
   } else {
      dg(eventParam.data.target);
      dg2(eventParam.data.source, eventParam.data.target);
      data.links.map((link) => {
         link['lineStyle'] = {
            opacity: .1
         }
         if (link.gx) {
            link['lineStyle'] = {
               opacity: .8
            }
            let nodes = data.links.filter((link_) => {
               if (link_.source == link.target) {
                  return link_;
               }
            });
            activeNode.push(...nodes);
         }
         if (link.source == eventParam.data.source && link.target == eventParam.data.target) {
            link.gx = 1;
            let nodes = data.links.filter((link_) => link_.source == link.target);
            activeNode.push(...nodes);
            link['lineStyle'] = {
               opacity: .8
            }
         }
      })
   }

   data.nodes.map((node) => {
      let is = activeNode.filter((isNode) => node.name == isNode.source)[0];
      if (is) {
         node['itemStyle']['opacity'] = 1
      }
      let lightLinks = data.links.filter((v) => v.gx);
      let isNodeGx = lightLinks.filter((v) => v.target == node.name || v.source == node.name)[0];
      if (isNodeGx) {
         node['itemStyle']['opacity'] = 1
      }
   })

   myChart.setOption({
      series: [
         {
            type: 'sankey',
            data: data.nodes,
            links: data.links,
         }
      ]
   });

})
myChart.on('mouseout', (eventParam) => {
   data.links.forEach((link) => {
      link.gx = 0;
      link.lineStyle = {};
   })
   data.nodes.forEach((node) => {
      node['itemStyle']['opacity'] = .2;
   })
   myChart.setOption({
      series: [
         {
            type: 'sankey',
            data: data.nodes,
            links: data.links,
         }
      ]
   });
})