vue+echarts实现桑吉图的效果

前言:

        在我们项目使用图形的情况下,桑吉图算是冷门的图形了,但是它可以实现我们对多级数据之间数据流向更好的展示的需求,比如,我们实际数据流向中,具有1对多,多对多的情况下,如果用tree是不合适,用思维导图的话,只能实现线路的展示,达不到我们想对数据可视化的需要。

实现效果:

实现代码:

1、初始化调用方法

echarts挂载点击事件: radarChart.getZr().on

echarts随着界面的变动自动适应:window.onresize

源码:

let chartDom = document.getElementById("radar")
let radarChart = echarts.init(chartDom)

//配置属性值
 radarChart.setOption(option.value)

//挂载点击事件
  radarChart.getZr().on("click", event=> {
    // 第三层文字点击事件
    if (event.topTarget?.type === "tspan") {
          const text = event.topTarget.style.text
          if(text.indexOf('/') !== -1){
            console.log(event);
            console.log(text);
          }
    }
  })

//让echarts随着界面的变动自动适应
window.onresize = () => {
    radarEcharts.resize()
  }

2、配置属性

注意1:echarts通用的用网格的方法添加内边距,在桑吉图是无效的

grid: {
  top: "0",
  left: "10%",
  right: "10%",
  bottom: "0",
  containLabel: true,
}

//  桑吉图中添加内边距的特殊方法

series: {
      type: "sankey",
      top: "1%",           // 距离上 距离
      bottom: "1%",      // 距离下 距离
      left: "0",                  // 距离左 距离
      right: "16.5%",          // 距离右 距离

...

注意2:桑吉图中文字内容是可以自定义的,但是排版是固定的,不会自定义生成距离

注意3:桑吉图的数据中通过  depth  这个字段来控制他是第几层

源码:

option.value = {
    tooltip: {
      trigger: "item",
      triggerOn: "mousemove",
      rich: {
        "a": {
          "fontSize": 14,
          "fontWeight": 500,
          'color':'#fff',
          padding: [0, 0, 5, 0],
        }
      },
    // 鼠标滑上去的展示信息
      formatter: function(params) {
        if (params.data.source) {
          return `${params.data.source}-${params.data.target}:${params.data.value}`;
        } else {
          return `${params.name}:${params.value}`;
        }
      }
    },
    series: {
      type: "sankey",
      layout: "none",
      top: "1%",
      bottom: "1%",
      left: "0",
      right: "16.5%",
      draggable: false,
      focusNodeAdjacency: 'allEdges', // 鼠标划上时高亮的节点和连线,allEdges表示鼠标划到节点上点亮节点上的连线及连线对应的节点
      lineStyle: {
        opacity: 0.3,
        color: "gradient",
        curveness: 0.7,
      },
      label: {
        color: "#000",
        fontSize: 15,
        formatter: function (params) {
          // 一级 硕士研究生 博士研究生
          if(params.data.depth === 0 && params.data.name==='本科生') return "{a|" + params.data.name + "\n}" +"{b|" + params.data.value+ "}";
          if(params.data.depth === 0 && params.data.name==='硕士研究生') return "{a2|" + params.data.name + "\n}" +"{b2|" + params.data.value+ "}";
          if(params.data.depth === 0 && params.data.name==='博士研究生') return "{a3|" + params.data.name + "\n}" +"{b3|" + params.data.value+ "}";
          // 二级
          if(params.data.depth === 1) return "{c|" + params.data.name + "}" +"{d|" + params.data.value+ "}";
          // 三级
          if(params.data.depth === 2){
            let str = ''
            params.data.typeArr.forEach(item=>{
              // str += "{e|" + params.data.name + "/"+ item.typeName +"\n}"+"{f|" + item.value+ "\n}"
              str += "{m|" + params.data.name + "/"+ item.typeName +"}"+"{n|" + item.value+ "\n}"
            })
            return str;
          }

        },
        rich: {
          "a": {
            "fontSize": 14,
            "fontWeight": 500,
            'color':'#7BA2DF',
            padding: [0, 0, 5, 0],
          },
          "b": {
            "fontSize": 24,
            "fontWeight": 600,
            'color':'#7BA2DF',
            padding: [0, 0, 0, 0],
          },
          "a2": {
            "fontSize": 14,
            "fontWeight": 500,
            'color':'#BA86ED',
            padding: [0, 0, 5, 0],
          },
          "b2": {
            "fontSize": 24,
            "fontWeight": 600,
            'color':'#BA86ED',
            padding: [0, 0, 0, 0],
          },
          "a3": {
            "fontSize": 14,
            "fontWeight": 500,
            'color':'#59DEC6',
            padding: [0, 0, 5, 0],
          },
          "b3": {
            "fontSize": 24,
            "fontWeight": 600,
            'color':'#59DEC6',
            padding: [0, 0, 0, 0],
          },
          "c": {
            "fontSize": 16,
            "color": "#332D2D",
            "lineHeight": 20,
          },
          "d": {
            "fontSize": 16,
            "fontWeight": 600,
            "lineHeight": 20,
            "color": "#332D2D ",
            padding: [0, 0, 0, 2],
          },
          "e": {
            "fontSize": 14,
            "fontWeight": 500,
            'color':'#332D2D',
            padding: [0, 0, 5, 0],
          },
          "f": {
            "fontSize": 16,
            "fontWeight": 600,
            'color':'#332D2D',
            padding: [0, 0, 20, 0],
          },
          "m": {
            "fontSize": 14,
            "fontWeight": 500,
            'color':'#332D2D',
            padding: [0, 0, 0, 0],
          },
          "n": {
            "fontSize": 16,
            "fontWeight": 600,
            'color':'#332D2D',
            padding: [0, 0, 0, 10],
          },
        },
      },
      // nodeWidth:100,
      nodeGap: 20, // 每一组之间的距离
      layoutIterations: 0,// 自动优化列表,尽量减少线的交叉,为0就是按照数据排列
      emphasis: {
        focus: "adjacency",
      },
      data: allData,
      links: allGuideData,
    },
  }

3、测试数据填入:

// 测试数据1
  let allData= [
    { name: "本科生",value:430, itemStyle: { color: "#7BA2DF" }, depth: 0 },
    { name: "硕士研究生",value:60, itemStyle: { color: "#BA86ED" }, depth: 0 },
    { name: "博士研究生",value:60, itemStyle: { color: '#59DEC6' }, depth: 0 },
    { name: "预防医学",value:60, itemStyle: { color: '#5FD981' }, depth: 1 },
    { name: "综合楼",value:60, itemStyle: { color: "#00baff" }, depth: 1 },
    { name: "2022级",typeArr:[{typeName:"本科",value:50},{typeName:"硕士研究生",value:30}], itemStyle: { color: "#f8b551" }, depth: 2 },
    { name: "2021级",typeArr:[{typeName:"硕士研究生",value:50}], itemStyle: { color: "#7ecef4" }, depth: 2 },
    { name: "2023级",typeArr:[{typeName:"博士研究生",value:50}], itemStyle: { color: "#7ecef4" }, depth: 2 },
  ]

  // 测试数据2,连线
  let allGuideData = [
    // L1→L3	 4509
    { source: "本科生", target: "预防医学", value: 800 },
    // L2→L3	 12196
    { source: "硕士研究生", target: "预防医学", value: 200 },
    // L1→L2→L3	 2404
    { source: "综合楼", target: "2022级", value: 200 },
    { source: "综合楼", target: "2023级", value: 200 },
    { source: "博士研究生", target: "2022级", value: 300 },
    { source: "预防医学", target: "2021级", value: 400 },
    { source: "预防医学", target: "2023级", value: 100 },
  ]

4、更多,官方api:

官方api有关桑吉图apiicon-default.png?t=N7T8https://echarts.apache.org/zh/option.html#series-sankey.type

更多桑吉图资料icon-default.png?t=N7T8https://www.ppchart.com/#/

猜你喜欢

转载自blog.csdn.net/weixin_44727080/article/details/134823323