vue实战篇记录--如何使用eacharts制作一个族谱

本文介绍了如何在Vue项目中利用eacharts库创建一个具有头像、点击添加子代、缩放和拖拽功能的族谱关系图,包括了图表的配置和事件处理的详细代码片段。
摘要由CSDN通过智能技术生成

记录一个需求,做一个族谱,就想到了eacharts的关系图,不用自己写canvas,适当配置就可以达到还不错的效果。比如添加头像,点击添加子代,缩放,拖拽(后来我关闭了),移动等话不多说了,上代码

1、下载eacharts (eacharts官方文档Apache ECharts

npm install echarts

2、项目里引入eacharts(我这是vue2的项目,因为项目用图标比较多,所以使用的全局引入,有需要的可以单独引入或者按需引入,都在官方文档里了我就不多说了)

// 引入echarts
import echarts from 'echarts'
Vue.prototype.$echarts = echarts

3、html部分

<template>
    <div id="family-tree" style="width: 100%; height: 600px;"></div>
</template>

4、js(methods)部分 eacharts配置文档(Documentation - Apache ECharts

renderFamilyTree() {
      const chart = this.$echarts.init(document.getElementById('family-tree'))
      const option = {
        tooltip: {
        },
        xAxis: {
          type: 'category',
          splitLine: {
            show: false
          }
        },
        yAxis: {
          type: 'category',
          data: ["第一代", "第二代", "第三代", "第四代", "第五代"],
          splitLine: {
            show: true
          }
        },
        series: [
          {
            type: 'graph',//关系图
            layout: 'none',
            xAxisIndex:0,
            yAxisIndex:0,
            symbolSize: 50,
            edgeSymbol: ['circle', 'arrow'],
            center: [130, 160],
            label:{
              position: "bottom"
            },
            emphasis: {
              focus: 'adjacency',
              blurScope: 'coordinateSystem',
              lineStyle: {
                width: 2,
              },
              itemStyle: {
              borderWidth: 10,
              borderType: [5, 10],
              borderDashOffset: 5
            },
            },
            // draggable: true,//拖拽
            edgeLabel:{
              // show:true //标签显示
            },
            roam:'move',//移动
            // 缩放比例
            scaleLimit:{
              min:0.4,
              max:2,
            },
            edgeSymbolSize: [4, 10],
            data: [
              { name: '张爷爷', value:100,x: 50, y: 100 , label: { show: true },symbol: 'image://https://backupfie.empowerchint.com/1687876059-compressed-IMG_00901700556145090.JPG'},
              { name: '代奶奶',value:98, x: 70, y: 100 , itemStyle: { color: 'lightblue' }, label: { show: true } },
              { name: '张爸爸',value:66, x: 50, y: 130 , label: { show: true },},
              { name: '张叔叔',value:65, x: 150, y: 130 ,label: { show: true }},
              { name: '何大婶',value:64, x: 170, y: 130 , itemStyle: { color: 'lightblue' }, label: { show: true } },
              { name: '何二婶',value:63, x: 190, y: 130 , itemStyle: { color: 'lightblue' }, label: { show: true } },
              { name: '张亲姐',value:40, x: 20, y: 160 ,label: { show: true }},
              { name: '张自己',value:39, x: 50, y: 160 ,label: { show: true }},
              { name: '张大婶弟', value:34,x: 150, y: 160 ,label: { show: true }},
              { name: '张二婶妹', value:32,x: 250, y: 160 ,label: { show: true }},
              { name: '张二婶弟', value:31,x: 300, y: 160 ,label: { show: true }},
              { name: '张二婶弟媳', value:31,x: 320, y: 160 ,label: { show: true },itemStyle: { color: 'lightblue' }},
              { name: '张二婶妹亲侄',value:18, x: 250, y: 190 ,label: { show: true }},
              { name: '张儿子', x: 50,value:18, y: 190,label: { show: true }},
              { name: '赵儿媳', x: 70,value:17, y: 190 , itemStyle: { color: 'lightblue' }, label: { show: true } },
              { name: '张大婶弟侄女',value:16, x: 150, y: 190 ,label: { show: true }},
              { name: '张孙子', x: 50,value:1, y: 220 ,label: { show: true }},
            ],
            links: [
              { 
                source: '张爷爷', 
                target: '张爸爸' ,
                label:{
                  show:false,
                  formatter: ['{11111111}',].join('\n')
                }
              },
              { source: '代奶奶', target: '张爸爸' },
              { source: '张爷爷', target: '张叔叔' },
              { source: '代奶奶', target: '张叔叔' },
              { source: '张爸爸', target: '张亲姐' },
              { source: '张爸爸', target: '张自己' },
              { source: '张叔叔', target: '张大婶弟' },
              { source: '何大婶', target: '张大婶弟' },
              { source: '张叔叔', target: '张二婶妹' },
              { source: '何二婶', target: '张二婶妹' },
              { source: '张自己', target: '张儿子' },
              { source: '张二婶妹', target: '张二婶妹亲侄' },
              { source: '张大婶弟', target: '张大婶弟侄女' },
              { source: '张儿子', target: '张孙子' },
              { source: '赵儿媳', target: '张孙子' },

            ],
          },
        ],
      };

      chart.setOption(option);

      chart.on('dblclick', (params) => {
        if (params.dataType === 'node') {
          // 在此处处理双击节点弹出提示框的逻辑
          console.log('双击了节点:', params.data.name);
        }
      });
      chart.on('click', (params) => {
        if (params.dataType === 'edge') {
            const source = params.data.source;
            const target = params.data.target;
            console.log(chart.getOption().series[0].links)
            // 弹出输入框让用户输入标签
            const label = prompt('请输入连线的标签:');

            // 将标签信息保存到连线的数据中
            const allData = chart.getOption().series[0].links
            const edgeData = allData.find((link) => link.source === source && link.target === target);
            const edgeIndex = allData.findIndex((link) => link.source === source && link.target === target);
            
            if (edgeData&&edgeIndex>-1) {
              edgeData.label = {
                show:true,
                formatter :[label].join('\n')
              }
              allData[edgeIndex] = edgeData
              chart.setOption({ series: [{ links:allData}] });
              console.log(chart.getOption().series[0].links)
            }
          }
      });
      chart.on('click', (params) => {
        if (params.dataType === 'node') {
          const node = params.data.name;

          // 弹出菜单让用户选择增加子节点还是删除子节点
          const choice = confirm(`您想要对节点 ${node} 进行什么操作?\n\n1. 增加子节点\n2. 删除子节点`);

          if (choice) {
            // 用户选择增加子节点
            const newName = prompt('请输入新节点的名称:');
            const allData = chart.getOption().series[0].data
            const nodeIndex = allData.findIndex((data) => data.name === node);
            const newNode = { name: newName, x: params.data.x, y: params.data.y+30, label: { show: true } }
            const allLinks = chart.getOption().series[0].links
            const newAllLinks= [...allLinks,{source: node, target: newName }]
            allData.splice(nodeIndex,0,newNode)
            chart.setOption({ series: [{ data:allData}] });
            chart.setOption({ series: [{links:newAllLinks}] });

            
          } else {
            // 用户选择删除子节点
            const allData = chart.getOption().series[0].data
            const nodeData = allData.find((data) => data.name === node);
            const nodeIndex = allData.findIndex((data) => data.name === node);
            const allLinks = chart.getOption().series[0].links
            allData.splice(nodeIndex,1)
            console.log(allData,nodeData,nodeIndex)
            chart.setOption({ series: [{ data:allData}] });
            // const links = chart.getOption().series[0].links.filter((link) => link.source === node || link.target === node);
            // const data = chart.getOption().series[0].data.filter((item) => item.name !== node);
            // chart.setOption({ series: [{ data, links }] });
          }
        }
      });
    },

还有很多需要优化的,不过大概是这样子

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值