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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM