vue中D3树形图

<template>
  <div class="header">
    <!-- <div id="container"></div> -->
    <div>Tree Id:0&nbsp;Tree Size: 15</div>
    <div class="main-content-box">
    <svg id="svg-canvas" width=850 height=400>
      <g />
      <rect />
    </svg>
    </div>
  </div>
</template>

<script>
import G6 from "@antv/g6";
import dagreD3 from "dagre-d3";
import * as d3 from "d3";
export default {
  name: "nodeByDiy",
  data() {
    return {
      state: [],
      edg: [],
      g,
      listData: null,
    };
  },
  mounted() {
    // this.getInit()
    this.fn();
    //获取D3
    this.$nextTick(() => {});
  },
  methods: {
    fn() {
      this.state = [
        { label: "ppppppppp\n节点1", class: "type-suss" },
        { label: "ppppppppp\n节点2", class: "type-TOP" },
        { label: "ppppppppp\n节点3111", class: "type-TOP" },
        { label: "ppppppppp\n节点5111", class: "type-TOP" },
        { label: "ppppppppp\n节点6", class: "type-TOP" },
        { label: "ppppppppp\n节点7", class: "type-TOP" },
        { label: "ppppppppp\n节点8", class: "type-TOP" },
      ];
      this.edg = [
        { start: 0, end: 1, option: {} },
        { start: 0, end: 2, option: {} },
        { start: 1, end: 4, option: {} },
        { start: 1, end: 5, option: {} },
        { start: 2, end: 6, option: {} },
        { start: 2, end: 3, option: {} },
      ];
      this.g = new dagreD3.graphlib.Graph()
        .setGraph({})
        .setDefaultEdgeLabel(function () {
          return {};
        });
      var render = new dagreD3.render();
      var svg = d3.select("#svgCanvas"); //声明节点
      svg.select("g").remove(); //删除以前的节点,清空画面
      var svgGroup = svg.append("g");
      var inner = svg.select("g");
      var zoom = d3.zoom().on("zoom", function () {
        //添加鼠标滚轮放大缩小事件
        inner.attr("transform", d3.event.transform);
      });
      svg.call(zoom);
      this.drawNode(); //画点
      this.drawEdg(); // 画连线
      render(d3.select("svg g"), this.g); //渲染节点
      let max =
        svg._groups[0][0].clientWidth > svg._groups[0][0].clientHeight
          ? svg._groups[0][0].clientWidth
          : svg._groups[0][0].clientHeight;
      var initialScale = max / 779; //initialScale元素放大倍数,随着父元素宽高发生变化时改变初始渲染大小
      var tWidth =
        (svg._groups[0][0].clientWidth - this.g.graph().width * initialScale) /
        2; //水平居中
      var tHeight =
        (svg._groups[0][0].clientHeight -
          this.g.graph().height * initialScale) /
        2; //垂直居中
      svg.call(
        zoom.transform,
        d3.zoomIdentity.translate(tWidth, tHeight).scale(initialScale)
      ); //元素水平垂直居中
    },
    drawNode() {
      for (let i in this.state) {
        //画点
        let el = this.state[i];
        this.g.setNode(i, {
          rx : 5,
          ry: 5,
          width: 150,
          height:60,
          id: i,
          label: el.label,
          class: el.class,
          style: "fill: #3c79f2;",
        });
      }
    },
    drawEdg() {
      for (let i in this.edg) {
        // 画连线
        let el = this.edg[i];
        this.g.setEdge(el.start, el.end, {
          style: "stroke: #0fb2cc; fill: none;",
          arrowheadStyle: "fill: #0fb2cc;stroke: #0fb2cc;",
          arrowhead: "vee",
        });
      }
    },
    getInit() {
      var g = new dagreD3.graphlib.Graph();
      console.log(g, "ggg");
      // 注册节点。类型为开始或者结束类型
      G6.registerNode(
        "start-or-end",
        {
          drawShape: function (_cfg, group) {
            let width = cfg.size[0];
            let height = cfg.size[1];
            let stroke = cfg.style.stroke; // 样式属性,元素的描边色
            let fill = cfg.style.fill; // 样式属性,元素的填充色
            let rect = group.addShape("rect", {
              attrs: {
                x: -width / 2,
                y: -height / 2,
                width,
                height,
                radius: height / 2,
                stroke,
                fill,
                lineWidth: 1,
              },
              name: "start-or-end",
            });
            return rect;
          },
        },
        "single-node"
      );
      console.log(G6.registerNode, "G6.registerNode");
      // 注册节点。类型为子流程类型节点
      G6.registerNode(
        "sub-process",
        {
          drawShape: function (cfg, group) {
            console.log(cfg, "---", group, "gr");
            let width = cfg.size[0];
            let height = cfg.size[1];
            let stroke = cfg.style.stroke;
            let fill = cfg.style.fill;
            //大的矩形
            let subProcess = group.addShape("rect", {
              attrs: {
                x: -width / 2,
                y: -height / 2,
                height,
                width,
                fill,
                stroke,
              },
              name: "sub-process",
            });
            // 左边
            group.addShape("rect", {
              attrs: {
                x: -(width / 2 - 20),
                y: -height / 2,
                height,
                width: 1,
                fill: "#fff",
                stroke: "#fff",
              },
            });
            // 右边
            group.addShape("rect", {
              attrs: {
                x: width / 2 - 20,
                y: -height / 2,
                height,
                width: 1,
                fill: "#fff",
                stroke: "#fff",
              },
            });

            return subProcess;
          },
        },
        "rect"
      );
      // 注册节点。类型为文档类型节点
      G6.registerNode(
        "document-node",
        {
          drawShape: function (cfg, group) {
            let width = cfg.size[0];
            let height = cfg.size[1];
            let stroke = cfg.style.stroke;
            let fill = cfg.style.fill;
            let documentNodes = group.addShape("path", {
              attrs: {
                path: [
                  ["M", -width / 2, 0 - height / 2], // 坐上
                  ["L", width / 2, -height / 2], // 右上
                  ["L", width / 2, height / 3], // 右下
                  [
                    "C",
                    width / 4,
                    -height / 8,
                    -width / 4,
                    (height * 6) / 8,
                    -width / 2,
                    height / 2,
                  ], // 弧线
                  ["Z"],
                ],
                fill,
                stroke,
              },
              name: "document-node",
            });
            return documentNodes;
          },
        },
        "single-node"
      );
      // 注册边。继承polyline,添加流动效果
      G6.registerEdge(
        "cus-polyline",
        {
          afterDraw(cfg, group) {
            let shape = group.get("children")[0];
            let index = 0;
            shape.animate(
              () => {
                index++;
                if (index > 9) {
                  index = 0;
                }
                let animateLine = {
                  lineDash: [4, 5, 1, 2],
                  lineDashOffset: -index,
                };
                return animateLine;
              },
              {
                repeat: true,
                duration: 5000,
              }
            );
          },
        },
        "polyline"
      );
      const width = document.getElementById("container").scrollWidth * 0.95;
      // console.log(width, 'width-node');
      const height = document.getElementById("container").scrollHeight || 800;
      // console.log(height, 'height-node');

      const graph = new G6.Graph({
        container: "container",
        width,
        height,
        modes: {
          default: [
            "drag-canvas",
            // 'drag-node',  // 拖动元素
            // 'zoom-canvas'   //画面缩放
          ],
        },
        // 节点在默认状态下的样式配置(style)和其他配置
        defaultNode: {
          type: "rect",
          // type: 'circle',
          size: [80, 75], // 节点大小
          color: "#3e62ae",
          // 节点样式配置
          style: {
            fill: "#DEE9FF", // 节点填充色
            stroke: "#5B8FF9", // 节点描边色
            // lineWidth: 1, // 节点描边粗细
          },
          // 节点上的标签文本配置
          labelCfg: {
            style: {
              fill: "#ffffff", // 节点标签文字颜色
              fontSize: 16,
            },
          },
          F: [
            [0, 0.5],
            [0.5, 0],
            [1, 0.5],
            [0.5, 1],
          ],
        },
        // 边在默认状态下的样式配置(style)和其他配置
        defaultEdge: {
          type: "cus-polyline",
          // 边样式配置
          style: {
            offset: 30,
            endArrow: true,
            stroke: "blue", // 边描边颜色
            //  opacity: 0.6, // 边透明度
          },
        },
        layout: {
          // type: 'force', // 设置布局算法为 force
          linkDistance: 100, // 设置边长为 100
          preventOverlap: true, // 设置防止重叠
        },
      });
      graph.data(this.gDatas);
      console.log(graph, "graph- datanode11");
      graph.render();
      graph.fitView();
    },
  },
};
</script>

<style lang='scss' scoped>
.main-content-box {
  border: solid 1px #000;
}
#svg-canvas {
  padding-top: 20px;
  margin-left: 25%;
  // width: 100%;
  // height: 100%;
}
</style>
posted @ 2022-04-07 18:17  xiaoxiao95  阅读(929)  评论(0编辑  收藏  举报