relation-graph implements enterprise architecture diagrams, relationship diagrams, etc.

Business needs

The length of the article may be too long, and focus on explaining how to configure the properties of the desired renderings, dynamically request the rendering of back-end interface data, and click the node or node expansion button to add data logic . If you want to directly realize the effect diagram, you can directly pull the code in all the code titles, communicate with the backend to return the data format, and just change the interface. There is an optimized code at the end of the article, which will be more perfect than the effect diagram, and you can also read it yourself.

1. The effect picture that the company wants

insert image description here
insert image description here

2. The dome effect diagram that comes with the relation-graph plug-in

insert image description here
insert image description here

3. Realize the rendering

insert image description here

Official document address

Official document address: http://www.relation-graph.com/#/docs/start
Need to configure attributes when initializing the relationship graph, refer to the document api

insert image description here

Implementation code

  1. Introduce relation-graph
npm install --save relation-graph
  1. Create a relationship graph dom node (must be wrapped in a div, height is set to fit the height of the node to the screen)
<div class="legalperson">
    <div style="height: calc(100vh - 50px)" v-loading="relationLoading">
      <SeeksRelationGraph
        ref="seeksRelationGraph"
        :options="graphOptions"
        :on-node-click="onNodeClick"
        :on-line-click="onLineClick"
        :on-node-expand="onNodeExpand"
      />
    </div>
  </div>
  1. Introduce the plug-in, configure the properties of the relationship graph, and initialize the root node (you can configure the properties you want according to different projects)
<script>
import SeeksRelationGraph from "relation-graph";   //引入插件
import {
    
     query_tree1 } from "@/api/affiliated";   //接口api

export default {
    
    
  name: "legalperson",
  components: {
    
     SeeksRelationGraph },
  data() {
    
    
    return {
    
    
      relationLoading: false,
      currentCase: "双向树",
	  //关系图属性配置(重要)
      graphOptions: {
    
    
        layouts: [
          {
    
    
            label: "中心",
            layoutName: "tree",   //布局方式(tree树状布局/center中心布局/force自动布局)
            layoutClassName: "seeks-layout-center",   //当使用这个布局时,会将此样式添加到图谱上
            defaultJunctionPoint: "border",   //默认的连线与节点接触的方式
            defaultNodeShape: 0,   //默认的节点形状,0:圆形;1:矩形
            defaultLineShape: 1,   //默认的线条样式(1:直线/2:样式2/3:样式3/4:折线/5:样式5/6:样式6)
            centerOffset_y: 130,   //根节点y坐标偏移量(针对项目配置单位为px)
            min_per_width: 150,   //节点距离限制:节点之间横向距离最小值
            min_per_height: 180,   //节点距离限制:节点之间纵向距离最小值
          },  
        ],
        defaultNodeShape: 1,    //默认的节点形状,0:圆形;1:矩形
        defaultExpandHolderPosition: "bottom",  //节点展开关闭的按钮位置
        defaultLineShape: 4,   //默认的线条样式(1:直线/2:样式2/3:样式3/4:折线/5:样式5/6:样式6)
        defaultJunctionPoint: "tb", //默认的连线与节点接触的方式(border:边缘/ltrb:上下左右/tb:上下/lr:左右)当布局为树状布局时应使用tb或者lr,这样才会好看
        defaultNodeBorderWidth: 0.2, //节点边框粗细
        defaultLineColor: "rgba(0, 186, 189, 1)",    //默认的线条颜色
        defaultNodeColor: "rgba(0, 206, 209, 1)",    //默认的节点背景颜色
        defaultNodeWidth: "130", //节点宽度
        defaultNodeHeight: "80", //节点高度
        defaultFocusRootNode: false,   //默认为根节点添加一个被选中的样式
        moveToCenterWhenResize: false,   //当图谱的大小发生变化时,是否重新让图谱的内容看起来居中
      },
      __graph_json_data: {
    
    },   //节点的数据
    };
  },
  mounted() {
    
    
    this.showSeeksGraph();
  },
  methods: {
    
    
    //初始化节点数据
    showSeeksGraph(query) {
    
    
      this.__graph_json_data = {
    
    
        rootId: "0",    //根节点唯一id
        nodes: [
          {
    
    
            id: "0",
            offset_x: -59,    //根节点位置偏移量
            text: "XXXXXX股份有限公司",  //节点文本
            width: 250,     //根节点宽度
            color: "#0084ff",   //根节点背景色
            fontColor: "#ffffff",   //根节点字体颜色
            childrenLoaded: true,   //配置标识,点击展开节点按钮时判断,不需要重复请求接口(懒加载数据)
          },
          //也可以在此添加静态子节点(展示效果图)
          {
    
    
            id: "101",
            text: "节点1",
            expandHolderPosition: "top",    //展开节点的显示位置,查看后续效果图
            expanded: false,
            childrenLoaded: false,   //节点重复展开标识
          },
          {
    
    
            id: "102",
            text: "节点2",
            expandHolderPosition: "bottom",
            expanded: false,
            childrenLoaded: false,   //节点重复展开标识
          },
        ],
        links: [
        //根节点上方侧的关系数据,注意关系的方向,是从 节点--->根节点:
          {
    
     from: "101", to: "0" },    //上方(从子节点出发到根节点)
          {
    
     from: "0", to: "102" },   //下方(从根节点出发到子节点)
        ],
      };
      //将根节点渲染进图谱中
      this.$refs.seeksRelationGraph.setJsonData(this.__graph_json_data,(seeksRGGraph) => {
    
    
          this.shareholdersData();
        }
      );
    },
  },
};
</script>

  1. The effect diagram realized now (static node value hard-coded at the front end);
    insert image description here

  2. Dynamically obtain interface data rendering

    It can be seen that the attributes in the data required by the structure tree must have their own requirements, so the company does not have many options to implement the case, so it can only hope that the back end cooperates with itself to process the returned data. If all data processing is placed on the front end, performance requirements may be problematic, and this operation is not recommended.

    There is no need to write more repetitive codes. Directly write the method of requesting the interface to obtain rendering data, and the attribute configuration remains unchanged.

 mounted() {
    
    
    this.showSeeksGraph();
  },
  methods: {
    
    
    //加载根节点数据后请求接口
    showSeeksGraph(query) {
    
    
      this.__graph_json_data = {
    
    
        rootId: "0",
        nodes: [
          {
    
    
            id: "0",
            offset_x: -59,
            text: "XXXXXX股份有限公司",
            width: 250,
            color: "#0084ff",
            fontColor: "#ffffff",
            childrenLoaded: false,
          },
          // { id: "102", text: "对外投资", color: '#83D942', expandHolderPosition: 'bottom', expanded: false, childrenLoaded: false, },
          // { id: "101", text: "股东",},
        ],
        links: [
          // { from: "101", to: "0", color: "#6d9bfd", },
        ],
      };
      //setJsonData初始化数据方法
      this.$refs.seeksRelationGraph.setJsonData(this.__graph_json_data,(seeksRGGraph) => {
    
    
        this.shareholdersData();
        }
      );
    },
    //加载接口数据
    shareholdersData() {
    
    
      let dictionary = {
    
    
        parentcodeName: "",
        relatedtypedetail: "101",
      };
      query_tree1(dictionary).then((res) => {
    
    
        this.__graph_json_data.nodes = res.data.nodes;
        this.__graph_json_data.links = res.data.links;
        //找到节点appendJsonData方法是追加数据
        this.$refs.seeksRelationGraph.appendJsonData(this.__graph_json_data,(seeksRGGraph) => {
    
    }
        );
      });
    },
    //点击展开节点按钮触发
    onNodeExpand(node, e) {
    
    
      this.additionalData(node);
    },
    //像图谱中追加数据
    additionalData(info) {
    
    
      let dictionary = {
    
    
        parentcodeName: info.text,
        parentcode: info.id,
      };
      //判断是否已经动态加载数据了
      if (info.data.childrenLoaded) {
    
    
        console.log("这个节点的子节点已经加载过了");
        // this.$refs.seeksRelationGraph.refresh()   //可以看官方文档,此方法可以刷新布局
        return;
      }
      info.data.expanded = true;
      info.data.childrenLoaded = true;
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.__graph_json_data.nodes = res.data.nodes;
          this.__graph_json_data.links = res.data.links;
          // this.$refs.seeksRelationGraph.refresh()
          this.$refs.seeksRelationGraph.appendJsonData(this.__graph_json_data,(seeksRGGraph) => {
    
    
            }
          );
        })
    },
    onNodeClick() {
    
    },
    onLineClick() {
    
    },
  },
  1. Dynamic loading of data is also simple, that is, after getting the data, call the appendJsonData method to append the data. You can directly use the __graph_json_data data of the relationship diagram to equal the return value of the interface.

Interface return data format (the most important point)

insert image description here
insert image description here
insert image description here
insert image description here

Dynamic renderings

insert image description here

all codes

<template>
  <div class="legalperson">
    <div style="height: calc(100vh - 50px)" v-loading="relationLoading">
      <SeeksRelationGraph
        ref="seeksRelationGraph"
        :options="graphOptions"
        :on-node-click="onNodeClick"
        :on-line-click="onLineClick"
        :on-node-expand="onNodeExpand"
      />
    </div>
  </div>
</template>
<script>
import SeeksRelationGraph from "relation-graph";
import {
    
     query_tree1 } from "@/api/affiliated";

export default {
    
    
  name: "legalperson",
  components: {
    
     SeeksRelationGraph },
  data() {
    
    
    return {
    
    
      dialogapproval: false,
      relationLoading: false,
      dialogLoading: false,
      currentCase: "双向树",
      isShowCodePanel: false,
      graphOptions: {
    
    
        layouts: [
          {
    
    
            label: "中心",
            layoutName: "tree",
            layoutClassName: "seeks-layout-center",
            defaultJunctionPoint: "border",
            defaultNodeShape: 0,
            defaultLineShape: 1,
            // min_per_height: "100",
            // centerOffset_x: -300,
            centerOffset_y: 130,
            min_per_width: 150,
            min_per_height: 180,
          },
        ],
        defaultNodeShape: 1,
        defaultExpandHolderPosition: "bottom", //节点展开关闭的按钮位置
        defaultLineShape: 4,
        defaultJunctionPoint: "tb", //
        defaultNodeBorderWidth: 0.2, //节点边框粗细
        defaultLineColor: "rgba(0, 186, 189, 1)",
        defaultNodeColor: "rgba(0, 206, 209, 1)",
        defaultNodeWidth: "130", //节点宽度
        defaultNodeHeight: "80", //节点高度
        defaultFocusRootNode: false,
        moveToCenterWhenResize: false,
      },
      __graph_json_data: {
    
    },
    };
  },
  mounted() {
    
    
    this.showSeeksGraph();
  },
  methods: {
    
    
    //查询中煤法人查询
    showSeeksGraph(query) {
    
    
      this.__graph_json_data = {
    
    
        rootId: "0",
        nodes: [
          {
    
    
            id: "0",
            offset_x: -59,
            text: "XXXXXXX股份有限公司",
            width: 250,
            color: "#0084ff",
            fontColor: "#ffffff",
            childrenLoaded: false,    //节点展开关闭标识
          },
          // { id: "102", text: "对外投资", color: '#83D942', expandHolderPosition: 'bottom', expanded: false, childrenLoaded: false, },
          // { id: "101", text: "股东",},
        ],
        links: [
          // { from: "101", to: "0", color: "#6d9bfd", },
        ],
      };
      this.$refs.seeksRelationGraph.setJsonData(
        this.__graph_json_data,
        (seeksRGGraph) => {
    
    
          this.shareholdersData();
        }
      );
    },
    //加载股东数据
    shareholdersData() {
    
    
      this.relationLoading = true;
      let dictionary = {
    
    
        parentcodeName: "XXXXXX股份有限公司",
        relatedtypedetail: "101",
      };
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.__graph_json_data.nodes = res.data.nodes;
          this.__graph_json_data.links = res.data.links;
          this.$refs.seeksRelationGraph.appendJsonData(
            this.__graph_json_data,
            (seeksRGGraph) => {
    
    
              this.foreignData();
            }
          );
        })
        .catch(() => {
    
    
          this.relationLoading = false;
        });
    },
    //加载对外投资数据
    foreignData() {
    
    
      let dictionary = {
    
    
        parentcodeName: "XXXXXX股份有限公司",
        relatedtypedetail: "102",
      };
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.__graph_json_data.nodes = res.data.nodes;
          this.__graph_json_data.links = res.data.links;
          // this.$refs.seeksRelationGraph.refresh()
          this.$refs.seeksRelationGraph.appendJsonData(
            this.__graph_json_data,
            (seeksRGGraph) => {
    
    
              this.relationLoading = false;
            }
          );
        })
        .catch(() => {
    
    
          this.relationLoading = false;
        });
    },
    //点击节点触发
    onNodeClick(node, $event) {
    
    },
    //点击展开节点按钮触发
    onNodeExpand(node, e) {
    
    
      this.additionalData(node);
    },
    //向图谱中追加数据
    additionalData(info) {
    
    
      let dictionary = {
    
    
        parentcodeName: info.text,
        parentcode: info.id,
      };
      //点击根节点上,下请求入参不同
      if (info.expandHolderPosition == "top") {
    
    
        dictionary.relatedtypedetail = "101";
      } else if (info.expandHolderPosition == "bottom") {
    
    
        dictionary.relatedtypedetail = "102";
      }
      //判断是否已经动态加载数据了
      if (info.data.childrenLoaded) {
    
    
        console.log("这个节点的子节点已经加载过了");
        // this.$refs.seeksRelationGraph.refresh()
        return;
      }
      info.data.expanded = true;
      info.data.childrenLoaded = true;
      this.relationLoading = true;
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.__graph_json_data.nodes = res.data.nodes;
          this.__graph_json_data.links = res.data.links;
          // this.$refs.seeksRelationGraph.refresh()
          this.$refs.seeksRelationGraph.appendJsonData(
            this.__graph_json_data,
            (seeksRGGraph) => {
    
    
              this.relationLoading = false;
            }
          );
        })
        .catch(() => {
    
    
          this.relationLoading = false;
        });
    },
    onLineClick(lineObject, $event) {
    
    
      console.log("onLineClick:", lineObject);
    },
  },
};
</script>
<style lang="scss">
</style>

Pity

Me: "Wow, leader, I wrote out the structure tree, which is great."
The leader: "What did you achieve? I gave you such a beautiful prototype, and you just built this one. Although it can't be exactly the same, but look at the two examples of other people's plug-in demos, it's also pretty good."
Me: "Leader, listen to my sophistry, listen to my explanation if it's not right, in fact, we wrote it according to the first demo, didn't he just add a little more color matching, and a little more text with connecting lines, as for the second one, look at how he explained it on the left navigation.Set coordinates manually, and then open the source code to take a look. This is a good old cow. Set the offset offset_x and offset_y node by node. But our sub-node levels are not sure, it would be best if we could do this.”

  1. Pointing arrow property of connector line does not work

The plug-in should be maintained by a boss personally. For this reason, I have contacted the QQ of the boss on the official website for special consultation. The boss is very patient and can really reply to the question, but it seems that because the boss has limited energy, the document is not being maintained in the future. Therefore, it does not matter where the arrow is facing when communicating with the leader. Add attribute in link (isReverse is the reverse arrow attribute does not take effect, isHideArrow hides the arrow so well)

 links: [
          {
    
     from: "101", to: "0", "isHideArrow": true,"isReverse": true,},
        ],

insert image description here
2. The connecting line text overlaps (bottom and right are compatible. Left and top are incompatible)
insert image description here

Me: "Let's not take the share ratio of the leadership connection line, it doesn't show how simple it is."
Of course, I look forward to the day when the plug-in boss can improve the optimization point.

  1. The effect achieved can only be one-sided loading of data, the upper node can only display its higher, and the lower node can only display its lower. Then if the upper node also has upper and lower child nodes, brainstorming must be optimized. After all, I can't bear to see this effect.

Effect optimization

Ideas:

The previous function remains the same, click the expand button to load the data on one side of the child node, click on the node itself, a dialog will pop up, and use it as the root node to load data on both sides of it.

Optimization renderings

insert image description here
insert image description here
insert image description here

Optimized code (all codes after effect optimization)

<template>
  <div class="legalperson">
    <div style="height: calc(100vh - 50px)" v-loading="relationLoading">
      <SeeksRelationGraph
        ref="seeksRelationGraph"
        :options="graphOptions"
        :on-node-click="onNodeClick"
        :on-line-click="onLineClick"
        :on-node-expand="onNodeExpand"
      />
    </div>
    <el-dialog :title="title" :visible.sync="dialogapproval" width="70%">
      <div style="height: calc(63vh)" v-loading="dialogLoading">
        <SeeksRelationGraph
          ref="other"
          :options="othergraphOptions"
          :on-node-click="otheronNodeClick"
          :on-node-expand="otheronNodeExpand"
        />
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button size="medium" @click="dialogapproval = false"
          >关闭</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>
<script>
import SeeksRelationGraph from "relation-graph";
import {
    
     query_tree1 } from "@/api/affiliated";

export default {
    
    
  name: "legalperson",
  components: {
    
     SeeksRelationGraph },
  data() {
    
    
    return {
    
    
      dialogapproval: false,
      relationLoading: false,
      dialogLoading: false,
      currentCase: "双向树",
      isShowCodePanel: false,
      graphOptions: {
    
    
        layouts: [
          {
    
    
            label: "中心",
            layoutName: "tree",
            layoutClassName: "seeks-layout-center",
            defaultJunctionPoint: "border",
            defaultNodeShape: 0,
            defaultLineShape: 1,
            // min_per_height: "100",
            // centerOffset_x: -300,
            centerOffset_y: 130,
            min_per_width: 150,
            min_per_height: 180,
          },
        ],
        defaultNodeShape: 1,
        defaultExpandHolderPosition: "bottom", //节点展开关闭的按钮位置
        defaultLineShape: 4,
        defaultJunctionPoint: "tb", //
        defaultNodeBorderWidth: 0.2, //节点边框粗细
        // defaultLineColor: "rgba(0, 186, 189, 1)",
        // defaultNodeBorderColor: "rgba(199, 199, 199, 1)",
        // defaultNodeFontColor: "rgba(67, 67, 67, 1)",
        // defaultNodeColor: "rgba(255, 255, 255, 1)",
        // defaultLineColor: "#c7c7c7",
        defaultLineColor: "rgba(0, 186, 189, 1)",
        defaultNodeColor: "rgba(0, 206, 209, 1)",
        defaultNodeWidth: "130", //节点宽度
        defaultNodeHeight: "80", //节点高度
        defaultFocusRootNode: false,
        moveToCenterWhenResize: false,
      },
      //弹窗dialog图配置
      othergraphOptions: {
    
    
        layouts: [
          {
    
    
            label: "中心",
            layoutName: "tree",
            layoutClassName: "seeks-layout-center",
            defaultJunctionPoint: "border",
            defaultNodeShape: 0,
            defaultLineShape: 1,
            // min_per_height: "100",
            centerOffset_x: 100,
            centerOffset_y: 70,
            min_per_width: 150,
            min_per_height: 180,
          },
        ],
        defaultNodeShape: 1,
        defaultExpandHolderPosition: "bottom", //节点展开关闭的按钮位置
        defaultLineShape: 4,
        defaultJunctionPoint: "tb", //
        defaultNodeBorderWidth: 0.2, //节点边框粗细
        // defaultLineColor: "rgba(0, 186, 189, 1)",
        // defaultNodeBorderColor: "rgba(199, 199, 199, 1)",
        // defaultNodeFontColor: "rgba(67, 67, 67, 1)",
        // defaultNodeColor: "rgba(255, 255, 255, 1)",
        // defaultLineColor: "#c7c7c7",
        defaultLineColor: "rgba(0, 186, 189, 1)",
        defaultNodeColor: "rgba(0, 206, 209, 1)",
        defaultNodeWidth: "130", //节点宽度
        defaultNodeHeight: "80", //节点高度
        defaultFocusRootNode: false,
        moveToCenterWhenResize: false,
      },
      title: "",
      __graph_json_data: {
    
    },
      otherData: {
    
    },
    };
  },
  mounted() {
    
    
    this.showSeeksGraph();
  },
  methods: {
    
    
    //查询根节点
    showSeeksGraph(query) {
    
    
      this.__graph_json_data = {
    
    
        rootId: "0",
        nodes: [
          {
    
    
            id: "0",
            offset_x: -59,
            text: "中煤财产保险股份有限公司",
            width: 250,
            color: "#0084ff",
            fontColor: "#ffffff",
            childrenLoaded: true,
          },
          // { id: "102", text: "对外投资", color: '#83D942', expandHolderPosition: 'bottom', expanded: false, childrenLoaded: false, },
          // { id: "101", text: "股东",},
        ],
        links: [
          // { from: "101", to: "0", color: "#6d9bfd", },
        ],
      };
      this.$refs.seeksRelationGraph.setJsonData(
        this.__graph_json_data,
        (seeksRGGraph) => {
    
    
          this.shareholdersData();
        }
      );
    },
    //加载股东数据
    shareholdersData() {
    
    
      this.relationLoading = true;
      let dictionary = {
    
    
        parentcodeName: "中煤财产保险股份有限公司",
        relatedtypedetail: "101",
      };
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.__graph_json_data.nodes = res.data.nodes;
          this.__graph_json_data.links = res.data.links;
          // Promise.all(
          //   this.__graph_json_data.links.map((item) => {
    
    
          //     //   item.color = '#c7c7c7';
          //   })
          // ).then(() => {
    
    
          // this.$refs.seeksRelationGraph.refresh()   //刷新布局
          this.$refs.seeksRelationGraph.appendJsonData(
            this.__graph_json_data,
            (seeksRGGraph) => {
    
    
              this.foreignData();
            }
          );
          // });
        })
        .catch(() => {
    
    
          this.relationLoading = false;
        });
    },
    //加载对外投资数据
    foreignData() {
    
    
      let dictionary = {
    
    
        parentcodeName: "中煤财产保险股份有限公司",
        relatedtypedetail: "102",
      };
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.__graph_json_data.nodes = res.data.nodes;
          this.__graph_json_data.links = res.data.links;
          // Promise.all(
          //   this.__graph_json_data.links.map((item) => {
    
    
          //     //   item.color = '#c7c7c7';
          //   })
          // ).then(() => {
    
    
          // this.$refs.seeksRelationGraph.refresh()
          this.$refs.seeksRelationGraph.appendJsonData(
            this.__graph_json_data,
            (seeksRGGraph) => {
    
    
              this.relationLoading = false;
            }
          );
          // });
        })
        .catch(() => {
    
    
          this.relationLoading = false;
        });
    },
    //点击节点触发
    onNodeClick(node, $event) {
    
    
      // this.additionalData(node);
      this.dialogapproval = true;
      this.$nextTick(() => {
    
    
        this.other(node);
      });
    },
    //点击展开节点按钮触发
    onNodeExpand(node, e) {
    
    
      if (node.id !== "0") {
    
    
        this.additionalData(node);
      }
    },
    //像图谱中追加数据
    additionalData(info) {
    
    
      console.log(info);
      let dictionary = {
    
    
        parentcodeName: info.text,
        parentcode: info.id,
      };
      if (info.expandHolderPosition == "top") {
    
    
        dictionary.relatedtypedetail = "101";
      } else if (info.expandHolderPosition == "bottom") {
    
    
        dictionary.relatedtypedetail = "102";
      }
      //判断是否已经动态加载数据了
      if (info.data.childrenLoaded) {
    
    
        console.log("这个节点的子节点已经加载过了");
        // this.$refs.seeksRelationGraph.refresh()
        return;
      }
      info.data.expanded = true;
      info.data.childrenLoaded = true;
      this.relationLoading = true;
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.__graph_json_data.nodes = res.data.nodes;
          this.__graph_json_data.links = res.data.links;
          // this.$refs.seeksRelationGraph.refresh()
          this.$refs.seeksRelationGraph.appendJsonData(
            this.__graph_json_data,
            (seeksRGGraph) => {
    
    
              this.relationLoading = false;
            }
          );
        })
        .catch(() => {
    
    
          this.relationLoading = false;
        });
    },
    onLineClick(lineObject, $event) {
    
    
      console.log("onLineClick:", lineObject);
    },
    //--------------------------------------------------弹框展示企业架构图
    //点击企业信息弹框,展示各个企业的架构图
    other(info) {
    
    
      console.log(info);
      this.title = info.text;
      this.otherData = {
    
    
        rootId: info.id,
        nodes: [
          {
    
    
            offset_x: -59,
            id: info.id,
            text: info.text,
            width: 250,
            color: "#0084ff",
            fontColor: "#ffffff",
            childrenLoaded: true,
          },
        ],
        links: [],
      };
      this.$nextTick(() => {
    
    
        // dom元素更新后执行,因此这里能正确打印更改之后的值
        this.$refs.other.setJsonData(this.otherData, (seeksRGGraph) => {
    
    
          this.othershareholdersData(info);
        });
      });
    },
    //加载股东数据
    othershareholdersData(info) {
    
    
      this.dialogLoading = true;
      let dictionary = {
    
    
        parentcodeName: info.text,
        relatedtypedetail: "101",
      };
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.otherData.nodes = res.data.nodes;
          this.otherData.links = res.data.links;
          this.$refs.other.appendJsonData(this.otherData, (seeksRGGraph) => {
    
    
            this.otherforeignData(info);
          });
        })
        .catch(() => {
    
    
          this.dialogLoading = false;
        });
    },
    //加载对外投资数据
    otherforeignData(info) {
    
    
      let dictionary = {
    
    
        parentcodeName: info.text,
        relatedtypedetail: "102",
      };
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.otherData.nodes = res.data.nodes;
          this.otherData.links = res.data.links;
          this.$refs.other.appendJsonData(this.otherData, (seeksRGGraph) => {
    
    
            this.dialogLoading = false;
          });
        })
        .catch(() => {
    
    
          this.dialogLoading = false;
        });
    },
    //点击节点触发
    otheronNodeClick(node, $event) {
    
    
      this.other(node);
    },
    //点击展开节点按钮触发
    otheronNodeExpand(node, e) {
    
    
      if (node.id !== "0") {
    
    
        this.otheradditionalData(node);
      }
    },
    //向图谱中追加数据
    otheradditionalData(info) {
    
    
      console.log(info);
      let dictionary = {
    
    
        parentcodeName: info.text,
        parentcode: info.id,
      };
      if (info.expandHolderPosition == "top") {
    
    
        dictionary.relatedtypedetail = "101";
      } else if (info.expandHolderPosition == "bottom") {
    
    
        dictionary.relatedtypedetail = "102";
      }
      //判断是否已经动态加载数据了
      if (info.data.childrenLoaded) {
    
    
        console.log("这个节点的子节点已经加载过了");
        // this.$refs.other.refresh()
        return;
      }
      info.data.expanded = true;
      info.data.childrenLoaded = true;
      this.dialogLoading = true;
      query_tree1(dictionary)
        .then((res) => {
    
    
          this.otherData.nodes = res.data.nodes;
          this.otherData.links = res.data.links;
          this.$refs.other.appendJsonData(this.otherData, (seeksRGGraph) => {
    
    
            this.dialogLoading = false;
          });
        })
        .catch(() => {
    
    
          this.dialogLoading = false;
        });
    },
  },
};
</script>

<style lang="scss">
</style>

Message:
1: There are a lot of demos on the official website, if github cannot be opened, you can copy the address and send it to WeChat, and click on the address directly on WeChat to view the source code
2: Although there are many codes, a simple sentence summary is the methodsetJsonDataLoad initial data, methodappendJsonDataAdditional data,
3: After reviewing the data, the plan that meets the company's requirements is finally selected. Welcome everyone to communicate with each other for better implementation plans

The second method is implemented ( d3.js realizes the penetration diagram ) and the connecting line can display text

Article address: https://blog.csdn.net/wangjiecsdn/article/details/130488425?spm=1001.2014.3001.5501

insert image description here

Guess you like

Origin blog.csdn.net/wangjiecsdn/article/details/127570749