美文网首页
G6自定义节点样式配置

G6自定义节点样式配置

作者: 海豚先生的博客 | 来源:发表于2023-01-03 10:29 被阅读0次
<template>
    <div
      v-if="reRender"
      id="container"
      v-loading="loading"
      :element-loading-text="$t('public.please_wait')"
      element-loading-spinner="el-icon-loading"
    />
  </div>
</template>

<script>
import G6 from "@antv/g6";
import { getTopology } from "@/api/getTopology";
export default {
  data() {
    return {
      reRender: true,
      loading: false,
    };
  },
  watch: {
    // 切换到其他拓扑图时重新渲染
    $route(n) {
      this.reRender = false;
      this.$nextTick(() => {
        this.reRender = true;
      });
      this.getData(n.query.id);
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.getData(this.$route.query.id);
    });
  },
  methods: {
    async getData(id) {
      // 自定义节点
      G6.registerNode(
        // 自定义节点名称
        "rect-auto",
        {
          draw(cfg, group) {
            const { label, style } = cfg;
            // 画一个默认矩形
            const rect = group.addShape("rect", {
              attrs: {
                width: 1,
                height: 1,
                x: 0,
                y: 0,
                radius: 4,
                lineWidth: 1,
                stroke: "#409eff",
                fill: "#f0f7ff",
                // 来自实例配置defaultNode选项的style
                ...style,
              },
              name: "rect-shape",
            });
            // 画一个文本
            const text = group.addShape("text", {
              attrs: {
                x: 0,
                y: 0,
                text: label,
                textAlign: "left",
                textBaseline: "middle",
                ...style,
                ...style.labelCfg.style,
              },
              name: "text-shape",
            });
            const labelBox = text.getBBox();
            // 矩形左右留白各10px,上下留白各6px
            rect.attr({
              width: labelBox.width + 20,
              height: labelBox.height + 12,
            });
            // 文本位置,以矩形左上角为原点
            text.attr({
              x: 10,
              y: labelBox.height / 2 + 6,
            });
            // 返回该矩形
            return rect;
          },
        },
        // 继承自已有rect图形
        "rect"
      );
      this.loading = true;
      // 后端返回标准的数据格式
      const res = await getTopology(id);
      const data = res.data;
      const container = document.getElementById("container");
      const width = container.scrollWidth;
      const height = container.scrollHeight || 500;
      // 实例配置,搜索关键字查看具体释义
      const graph = new G6.Graph({
        container: "container",
        width,
        height,
        controlPoints: false,
        fitView: true,
        fitViewPadding: 10,
        modes: {
          default: [
            {
              type: "activate-relations",
              trigger: "click",
              activeState: "active",
              inactiveState: "inactive",
            },
            {
              type: "zoom-canvas",
            },
            {
              type: "drag-canvas",
            },
            {
              type: "click-select",
            },
          ],
        },
        layout: {
          type: "dagre",
          preventOverlap: true,
          nodeSize: 100,
          nodesep: 50,
          ranksep: 10,
        },
        animate: true,
        defaultNode: {
          type: "rect-auto",
          anchorPoints: [
            [0.5, 0],
            [0.5, 1],
          ],
          style: {
            cursor: "pointer",
            labelCfg: {
              style: {
                fill: "#000",
              },
            },
          },
        },
        defaultEdge: {
          size: 1,
          color: "#ccc",
          type: "line",
          style: {
            endArrow: {
              path: G6.Arrow.triangle(6, 6, 0),
              // path: "M 0,0 L 8,4 L 8,-4 Z",
              fill: "#ccc",
            },
          },
        },
        nodeStateStyles: {
          active: {
            fill: "#fff",
            stroke: "#409eff",
            lineWidth: 1,
            shadowColor: "#409eff",
            shadowBlur: 10,
            shadowOffsetX: 1,
            shadowOffsetY: 1,
            "text-shape": {
              fill: "#000",
            },
          },
          inactive: {
            opacity: 0.6,
          },
          hover: {
            fill: "#fff",
            lineWidth: 1,
            stroke: "#409eff",
            shadowColor: "#409eff",
            shadowBlur: 10,
            shadowOffsetX: 1,
            shadowOffsetY: 1,
            "text-shape": {
              fill: "#000",
            },
          },
          selected: {
            fill: "#fff",
            lineWidth: 1,
            stroke: "#f56c6c",
            shadowColor: "#f56c6c",
            shadowBlur: 10,
            shadowOffsetX: 1,
            shadowOffsetY: 1,
            "text-shape": {
              fill: "#000",
            },
          },
        },
        edgeStateStyles: {
          active: {
            stroke: "#409eff",
            endArrow: {
              path: G6.Arrow.triangle(6, 6, 0),
              fill: "#409eff",
            },
          },
          inactive: {
            opacity: 0.6,
            endArrow: {
              path: G6.Arrow.triangle(6, 6, 0),
              fill: "#ccc",
              opacity: 0.6,
            },
          },
        },
      });
      graph.data(data);
      graph.render();
      // 节点只有一个时太大,缩放一下
      graph.on("afterrender", () => {
        if (data.nodes.length === 1) {
          graph.zoom(0.2, { x: width / 2, y: height / 2 });
        }
      });
     // 双击节点进行跳转
      graph.on("dblclick", (evt) => {
        const itemData = evt.item._cfg.model;
        const { level, id } = itemData;
        this.$emit("changeState", [id]);
        if (level === 2) {
          this.$router.push({
            name: "groupDetail",
            query: {
              id,
            },
          });
        } else if (level === 3) {
          this.$router.push({
            name: "serviceInfo",
            query: {
              id,
            },
          });
        }
      });
      // 触发hover样式配置
      graph.on("node:mouseenter", (evt) => {
        const { item } = evt;
        graph.setItemState(item, "hover", true);
      });
      // 关闭hover样式
      graph.on("node:mouseleave", (evt) => {
        const { item } = evt;
        graph.setItemState(item, "hover", false);
      });
      this.$nextTick(() => {
        this.loading = false;
      });
      if (typeof window !== "undefined") {
        window.onresize = () => {
          if (!graph || graph.get("destroyed")) return;
          if (!container || !container.scrollWidth || !container.scrollHeight)
            return;
          graph.changeSize(container.scrollWidth, container.scrollHeight - 30);
        };
      }
    },
  },
};
</script>

<style lang="scss" scoped>
#container {
  height: calc(100vh - 310px);
}
</style>

相关文章

网友评论

      本文标题:G6自定义节点样式配置

      本文链接:https://www.haomeiwen.com/subject/zjflcdtx.html