echarts关系图动态增删节点及连线

首先,echarts的关系图有个非常坑的地方,就是节点的id必须连续,否则增删之后节点无法连接!

下面是简单的演示实现,实际要用动态增删的话,要复杂的多得多。

我是用的关系图是力引导图

更新后不会重新渲染,只是动态增加的效果

//假设你已经渲染了关系图
test() {
      let option = this.chart.getOption() //获取option配置项
 
      //START增加节点,假设根据id连线
      // option.series[0].data.push({name: '测试节点', category: 1, id: 6, des: '测试描述'})
      // option.series[0].links.push({source: 0, target: 6, name: '测试连线'})
      //END 
 
      //删除节点START
      let data = option.series[0].data //获取节点数据
      let link = option.series[0].links //获取边的数据
      let flag = -1
      for(let i = 0; i<data.length;i  ){//假设删除id为1的节点
        if (data[i].id===1){
          data.splice(i,1)
          link.splice(i-1,1)
          flag = i
          break
        }
      }
      for(let i = flag; i<data.length;i  ){
        data[i].id--
        if (i!==data.length){
          link[i-1].target--
        }
      }
      //删除节点END
 
      //更新关系图
      this.chart.setOption(option)
    },

echarts关系图vue完整代码

vue 使用echarts 实现关系图,效果如下:

说明: 关系图可以有两种,一种是指定坐标x,y。 另外一种就是通过设置series属性

layout: "force",
force: {
          repulsion: [-2, 100], //节点之间的斥力因子。支持数组表达斥力范围,值越大斥力越大。
          gravity: 0.03, //节点受到的向中心的引力因子。该值越大节点越往中心点靠拢。
          edgeLength: [20, 200], //边的两个节点之间的距离,这个距离也会受 repulsion:[10, 50]值越小则长度越长
          layoutAnimation: false,
        },

vue全部代码如下

<template>
  <div class="uni-chart-container">
    <div class="uni-bar-charts" :id="id"></div>
  </div>
</template>
<script>
import echarts from "echarts";
import resize from "../mixins/resize";
export default {
  name: "uniGraph",
  mixins: [resize],
  components: {},
  data() {
    return {
      options: {
        title: {
          text: "",
        },
        series: [],
      },
      barData: [],
      myChart: null,
      seriesName: "",
    };
  },
  props: {
    id: {
      type: String,
      require: true,
    },
    sortMethod: {
      type: String,
      default: "desc",
    },
    title: {
      type: String,
    },
    optionsSetup: {
      type: Object,
      default: () => {
        return {};
      },
    },
    isVertical: {
      type: Boolean,
      default: true,
    },
    chartsData: {
      type: Object,
      default: function () {
        return {
          nodes: [
            {
              name: "李志强",
              category: 0,
              symbolSize: 30,
              value: ["确诊"],
              color: "#F10F0F",
            },
            {
              name: "张亮",
              category: 2,
              symbolSize: 30,
              value: ["密接"],
              color: "#FFC001",
            },
            {
              name: "王飞",
              category: 1,
              symbolSize: 30,
              value: ["次密接"],
              color: "#1D84C6",
            },
            {
              name: "王丽",
              category: 2,
              symbolSize: 30,
              value: ["密接"],
              color: "#FFC001",
            },
            {
              name: "符华",
              category: 1,
              symbolSize: 30,
              value: ["次密接"],
              color: "#1D84C6",
            },
            {
              name: "钱峰",
              category: 1,
              symbolSize: 30,
              value: ["次密接"],
              color: "#1D84C6",
            },
            {
              name: "吴梦",
              category: 1,
              symbolSize: 30,
              color: "#1D84C6",
              value: ["次密接"],
            },
            {
              name: "杨月",
              category: 1,
              symbolSize: 30,
              color: "#1D84C6",
              value: ["次密接"],
            },
          ],
          links: [
            {
              source: "李志强",
              target: "张亮",
              linkTip: "聚餐",
            },
            {
              source: "张亮",
              target: "王飞",
              linkTip: "出现在同一场所",
            },
            {
              source: "李志强",
              target: "王丽",
              linkTip: "出现在同一场所",
            },
            {
              source: "张亮",
              target: "钱峰",
              linkTip: "聚餐",
            },
            {
              source: "张亮",
              target: "符华",
              linkTip: "家庭聚集",
            },
            {
              source: "张亮",
              target: "杨月",
              linkTip: "出现在同一场所",
            },
            {
              source: "张亮",
              target: "吴梦",
              linkTip: "出现在同一场所",
            },
          ],
          categories: [
            {
              name: "确诊",
            },
            {
              name: "次密接",
            },
            {
              name: "密接",
            },
          ],
        };
      },
    },
    customColor: {
      type: Array,
      default: function () {
        return ["#1890FF"];
      },
    },
    // 展示前5条 可传5
    maxL: {
      default: "auto",
    },
    codeStatus: {
      type: Array,
    },
  },
  watch: {
    chartsData: {
      deep: true,
      immediate: true,
      handler: function (v) {
        let _this = this;
        this.$nextTick(function () {
          _this.init();
        });
      },
    },
  },
  beforeDestroy() {
    if (!this.myChart) {
      return;
    }
    this.myChart.dispose();
    this.myChart = null;
  },
  methods: {
    init() {
      //构建3d饼状图
      if (this.myChart) this.myChart.dispose();
      this.myChart = echarts.init(document.getElementById(this.id));
      this.editorOptions(this.chartsData);
      // 传入数据生成 option
      this.myChart.setOption(this.options);
    },
    editorOptions(val) {
      let series = this.getSeries(val);
      var options = {
        tooltip: {
          // formatter: (e) => {
          //   console.log(e);
          //   return e.name   e.data.value;
          // },
        },
        animationDuration: 1500,
        animationEasingUpdate: "quinticInOut",
        color: this.customColor,
        grid: this.setOptionsMargin(),
        series: series,
      };
      this.options = options;
    },
    getSeries(newData) {
      const series = [];
      series.push({
        name: "关系图谱",
        type: "graph",
        hoverAnimation: true,
        layout: "force",
        force: {
          repulsion: [-2, 100], //节点之间的斥力因子。支持数组表达斥力范围,值越大斥力越大。
          gravity: 0.03, //节点受到的向中心的引力因子。该值越大节点越往中心点靠拢。
          edgeLength: [20, 200], //边的两个节点之间的距离,这个距离也会受 repulsion:[10, 50]值越小则长度越长
          layoutAnimation: false,
        },
        nodeScaleRatio: 0.6,
        draggable: true,
        roam: false, //鼠标缩放和平移
        symbol: "circle",
        edgeSymbol: ["circle", "arrow"],
        data: newData.nodes,
        links: newData.links,
        categories: newData.categories,
        cursor: "pointer",
        focusNodeAdjacency: true,
        scaleLimit: {
          //所属组件的z分层,z值小的图形会被z值大的图形覆盖
          min: 0, //最小的缩放值
          max: 9, //最大的缩放值
        },
        edgeLabel: {
          //连接线上文字
          normal: {
            show: true,
            textStyle: {
              fontSize: 10,
            },
            formatter: (e) => {
              return e.name;
            },
          },
        },
        label: {
          normal: {
            show: true,
          },
        },
        lineStyle: {
          normal: {
            width: 1.5,
            curveness: 0,
            type: "solid",
          },
        },
      });
      return series;
    },
    // 边距设置
    setOptionsMargin() {
      const optionsSetup = this.optionsSetup;
      const grid = {
        left: optionsSetup.marginLeft,
        right: optionsSetup.marginRight,
        bottom: optionsSetup.marginBottom,
        top: optionsSetup.marginTop,
        containLabel: true,
      };
      return grid;
    },
  },
};
</script>
<style lang="scss">
.uni-chart-container,
.uni-bar-charts {
  width: 100%;
  height: 100%;
}
</style>

resize文件如下:debounce可以自行实现

import {
  debounce
} from "@/utils/utils.js";
export default {
  data() {
    return {};
  },
  mounted() {
    this.initListener();
  },
  beforeDestroy() {
    this.destroyListener();
  },
  deactivated() {
    this.destroyListener();
  },
  methods: {
    initListener() {
      window.addEventListener("resize", debounce(this.resize, 100));
    },
    destroyListener() {
      window.removeEventListener("resize", this.resize);
    },
    resize() {
      const {
        myChart
      } = this;
      myChart && myChart.resize();
    },
  },
};

以上为个人经验,希望能给大家一个参考,也希望大家多多支持Devmax。 

vue中echarts关系图动态增删节点以及连线方式的更多相关文章

  1. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  2. vue自定义加载指令v-loading占位图指令v-showimg

    这篇文章主要为大家介绍了vue自定义加载指令和v-loading占位图指令v-showimg的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. vue使用动画实现滚动表格效果

    这篇文章主要为大家详细介绍了vue使用动画实现滚动表格效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  4. 关于Vue 监控数组的问题

    这篇文章主要介绍了Vue 监控数组的示例,主要包括Vue 是如何追踪数据发生变化,Vue 如何更新数组以及为什么有些数组的数据变更不能被 Vue 监测到,对vue监控数组知识是面试比较常见的问题,感兴趣的朋友一起看看吧

  5. Vue子组件props从父组件接收数据并存入data

    这篇文章主要介绍了Vue子组件props从父组件接收数据并存入data的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. Vue h函数的使用详解

    本文主要介绍了Vue h函数的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  7. VUE响应式原理的实现详解

    这篇文章主要为大家详细介绍了VUE响应式原理的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

  8. vue+Element ui实现照片墙效果

    这篇文章主要为大家详细介绍了vue+Element ui实现照片墙效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. vue+elemet实现表格手动合并行列

    这篇文章主要为大家详细介绍了vue+elemet实现表格手动合并行列,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. iview+vue实现导入EXCEL预览功能

    这篇文章主要为大家详细介绍了iview+vue实现导入EXCEL预览功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部