开源库relation-graph的使用总结

概述

最近项目里面有用到血缘图、企业图谱、关系图相关的业务开发,综合考虑最终采用开源库relation-graph,内置vue组件和react组件,使用起来很方便,由于部分示例代码在官网需要开会员才能看到,所以,想要实现对应的复杂功能,需要自己去看源码,要不就自己掏钱去购买会员,综合考虑,本着能白嫖绝不花钱的原则,还是看源码,这里主要总结常用的几个功能点。

最终效果

工具栏的相关的功能官网需要会员才能看到,我这直接把源码里面的对应功能找出来,这里做一期小总结,其他更加详细的配置项可以自行查看官网。

实现代码

js 复制代码
<template>
  <div>
    <el-button type="primary" @click="handleClickFullScreen">全屏</el-button>
    <el-button type="primary" @click="handleClickZoomAdd">+</el-button>
    <el-button type="primary">{{ zoomNumber }}</el-button>
    <el-button type="primary" @click="handleClickZoomDecrease">-</el-button>
    <el-button type="primary" @click="handleClickRefresh">刷新</el-button>
    <el-button type="primary" @click="handleClickDownLoad">下载</el-button>
    <div
      v-loading="g_loading"
      style="
        margin-top: 50px;
        width: calc(100% - 10px);
        height: calc(100vh - 140px);
      "
    >
      <RelationGraph
        ref="graphRef"
        :options="graphOptions"
        :on-node-expand="onNodeExpand"
        :on-node-collapse="onNodeCollapse"
      >
      </RelationGraph>
    </div>
  </div>
</template>

<script>
export default {
  name: "RelationGraphDemo",
  components: {},
  data() {
    return {
      g_loading: true,
      zoomNumber: 100,
      demoname: "---",
      graphOptions: {
        layout: {
          label: "中心",
          layoutName: "tree",
          layoutClassName: "seeks-layout-center",
          defaultJunctionPoint: "border",
          defaultNodeShape: 0,
          defaultLineShape: 1,
          from: "left",
          max_per_width: 400,
          min_per_height: 10,
        },
        defaultLineMarker: {
          markerWidth: 12,
          markerHeight: 12,
          refX: 6,
          refY: 6,
          data: "M2,2 L10,6 L2,10 L6,6 L2,2",
        },
        moveToCenterWhenRefresh: false,
        defaultExpandHolderPosition: "right",
        defaultNodeShape: 1,
        defaultNodeWidth: 100,
        defaultLineShape: 4,
        defaultJunctionPoint: "lr",
        defaultNodeBorderWidth: 0,
        defaultLineColor: "rgba(0, 186, 189, 1)",
        defaultNodeColor: "rgba(0, 206, 209, 1)",
      },
    };
  },
  created() {},
  mounted() {
    this.demoname = this.$route.params.demoname;
    this.setGraphData();
  },
  methods: {
    setGraphData() {
      // 使用要点:通过节点属性expandHolderPosition: 'right' 和 expanded: false 可以让节点在没有子节点的情况下展示一个"展开"按钮
      //         通过onNodeExpand事件监听节点,在被展开的时候有选择的去从后台获取数据,如果已经从后台加载过数据,则让当前图谱根据当前的节点重新布局
      const __graph_json_data = {
        rootId: "a",
        nodes: [
          { id: "a", text: "a" },
          { id: "b", text: "b-固定数据展开/关闭" },
          { id: "b1", text: "b1" },
          { id: "b1-1", text: "b1-1" },
          { id: "b1-2", text: "b1-2" },
          { id: "b1-3", text: "b1-3" },
          { id: "b1-4", text: "b1-4" },
          { id: "b1-5", text: "b1-5" },
          { id: "b1-6", text: "b1-6" },
          { id: "b2", text: "b2" },
          { id: "b2-1", text: "b2-1" },
          { id: "b2-2", text: "b2-2" },
          { id: "c", text: "c-动态数据展开/关闭" },
          {
            id: "c1",
            text: "c1-动态获取子节点",
            expandHolderPosition: "right",
            expanded: false,
            data: {
              isNeedLoadDataFromRemoteServer: true,
              childrenLoaded: false,
            },
          },
          {
            id: "c2",
            text: "c2-动态获取子节点",
            expandHolderPosition: "right",
            expanded: false,
            data: {
              isNeedLoadDataFromRemoteServer: true,
              childrenLoaded: false,
            },
          },
          {
            id: "c3",
            text: "c3-动态获取子节点",
            expandHolderPosition: "right",
            expanded: false,
            data: {
              isNeedLoadDataFromRemoteServer: true,
              childrenLoaded: false,
            },
          },
        ],
        lines: [
          { from: "a", to: "b" },
          { from: "b", to: "b1" },
          { from: "b1", to: "b1-1" },
          { from: "b1", to: "b1-2" },
          { from: "b1", to: "b1-3" },
          { from: "b1", to: "b1-4" },
          { from: "b1", to: "b1-5" },
          { from: "b1", to: "b1-6" },
          { from: "b", to: "b2" },
          { from: "b2", to: "b2-1" },
          { from: "b2", to: "b2-2" },
          { from: "a", to: "c" },
          { from: "c", to: "c1" },
          { from: "c", to: "c2" },
          { from: "c", to: "c3" },
        ],
      };

      console.log(JSON.stringify(__graph_json_data));
      setTimeout(() => {
        this.g_loading = false;
        this.$refs.graphRef.setJsonData(__graph_json_data, (graphInstance) => {
          // 这些写上当图谱初始化完成后需要执行的代码
        });
      }, 1000);
    },
    onNodeCollapse(node, e) {
      this.$refs.graphRef.refresh();
    },
    // 通过onNodeExpand事件监听节点的展开事件,在被展开的时候有选择的去从后台获取数据,如果已经从后台加载过数据,则让当前图谱根据当前的节点重新布局
    onNodeExpand(node, e) {
      console.log("onNodeExpand:", node);
      // 根据具体的业务需要决定是否需要从后台加载数据
      if (!node.data.isNeedLoadDataFromRemoteServer) {
        console.log("这个节点的子节点已经加载过了");
        this.$refs.graphRef.refresh();
        return;
      }
      // 判断是否已经动态加载数据了
      if (node.data.childrenLoaded) {
        console.log("这个节点的子节点已经加载过了");
        this.$refs.graphRef.refresh();
        return;
      }
      this.g_loading = true;
      node.data.childrenLoaded = true;
      this.loadChildNodesFromRemoteServer(node, (new_data) => {
        this.g_loading = false;
        this.$refs.graphRef
          .getInstance()
          .appendJsonData(new_data, (graphInstance) => {
            // 这些写上当图谱初始化完成后需要执行的代码
          });
      });
    },
    loadChildNodesFromRemoteServer(node, callback) {
      setTimeout(function () {
        const _new_json_data = {
          nodes: [
            {
              id: node.id + "-child-1",
              text: node.id + "-的动态子节点1",
              width: 150,
              expanded: false,
              expandHolderPosition: "right",
              data: {
                isNeedLoadDataFromRemoteServer: true,
                childrenLoaded: false,
              },
            },
            {
              id: node.id + "-child-2",
              text: node.id + "-的动态子节点2",
              width: 150,
              expandHolderPosition: "right",
              expanded: false,
              data: {
                isNeedLoadDataFromRemoteServer: true,
                childrenLoaded: false,
              },
            },
            {
              id: node.id + "-child-3",
              text: node.id + "-的动态子节点3",
              width: 150,
              isNeedLoadDataFromRemoteServer: true,
              expanded: false,//是否已经展开(用于懒加载子节点数据)
              data: {
                isNeedLoadDataFromRemoteServer: true,//是否需要远程接口获取数据
                childrenLoaded: false,//节点是否已经加载过
              },
            },
          ],
          lines: [
            {
              from: node.id,
              to: node.id + "-child-1",
              text: "动态子节点",
              useTextPath: true,
              styleClass: "self-line",
            },
            {
              from: node.id,
              to: node.id + "-child-2",
              text: "动态子节点",
              useTextPath: true,//最好加上,避免展开节点样式不对称
              styleClass: "self-line",//展开折叠节点的样式名
              lineWidth: 3,
            },
            {
              from: node.id,
              to: node.id + "-child-3",
              text: "动态子节点",
              useTextPath: true,
              styleClass: "self-line",
              lineWidth: 3,
            },
          ],
        };
        callback(_new_json_data);
      }, 300);
    },
    handleClickFullScreen() {
      this.$refs.graphRef.getInstance().fullscreen();
    },
    handleClickZoomAdd() {
      this.$refs.graphRef.getInstance().zoom(10);
      this.zoomNumber = this.$refs.graphRef.getInstance().options.canvasZoom;
    },
    handleClickZoomDecrease() {
      this.$refs.graphRef.getInstance().zoom(-10);
      this.zoomNumber = this.$refs.graphRef.getInstance().options.canvasZoom;
    },
    handleClickRefresh() {
      this.$refs.graphRef.getInstance().refresh();
      this.zoomNumber = this.$refs.graphRef.getInstance().options.canvasZoom;
    },
    handleClickDownLoad() {
      this.$refs.graphRef.getInstance().downloadAsImage("png");
    },
  },
};
</script>
相关推荐
吃杠碰小鸡16 分钟前
commitlint校验git提交信息
前端
天天进步201536 分钟前
Vue+Springboot用Websocket实现协同编辑
vue.js·spring boot·websocket
虾球xz1 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇1 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒1 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员1 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐1 小时前
前端图像处理(一)
前端
程序猿阿伟1 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒1 小时前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪2 小时前
AJAX的基本使用
前端·javascript·ajax