当前位置: 首页 > article >正文

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/#/


http://www.kler.cn/news/161572.html

相关文章:

  • 策略模式终极解决方案之策略机
  • Jquery easyui异步提交表单的两种方式
  • Vue练习 v-model 指令在状态和表单输入之间创建双向绑定
  • Vue3集成ThreeJS实现3D效果,threejs+Vite+Vue3+TypeScript 实战课程【一篇文章精通系列】
  • stm32f103使用hal库函数读写内部flash
  • 【分布式微服务专题】从单体到分布式(二、SpringCloud整合Nacos)
  • TR转发路由器测评—云企业网实现跨地域跨VPC的网络互通测评实战【阿里云产品测评】
  • tomcat环境搭建
  • 深入理解Dubbo-1.初识Dubbo
  • Csharp(C#)无标题栏窗体拖动代码
  • 推荐5款很牛的Paas平台编译构建工具
  • .netcore 操作aspose.words导出pdf
  • selenium 执行js后拿不到返回值的原因
  • IT基础监控方案:5台服务器和20台网络设备监控
  • UnityShader自定义cginc文件
  • Intellij idea 快速定位到文件的开头或者结尾的几种方式
  • 预测:2024年的安防监控行业将迎来怎样的变化?
  • 使用postman请求x5接口
  • C语言指针详解上
  • 【推荐系统】了解推荐系统的生态(重点:推荐算法的主要分类)
  • 【Java基础篇 | 面向对象】—— 聊聊什么是接口(上篇)
  • 智能优化算法应用:基于鹰栖息算法无线传感器网络(WSN)覆盖优化 - 附代码
  • 2.HTML进阶
  • 为什么伦敦银交易中支撑和阻力位这么重要?
  • 展开说说:Android之广播接收者
  • 连接服务器的ssh终端自动断开解放方法
  • Comparator Comparators Comparable Collections排序源码解析
  • SRC挖掘漏洞XSS
  • uni-app实现返回刷新上一页
  • 基于selenium工具刷b站播放量(请谨慎使用)