antv g6收缩树绘图

本文档展示了如何在Vue项目中利用AntV G6库来绘制关系图。代码示例包括设置节点样式、监听节点点击事件、自定义布局以及响应窗口大小变化时的图表调整。通过获取服务数据并渲染到图表上,实现了动态更新和交互功能。

最近工作需要,用了antv g6绘图,参照了官网的例子

<template>
  <div id="container"></div>
</template>
<script>
import { defineComponent, onMounted, ref, watch } from "vue";
import { getKinship } from "@/services/study.js";
import G6 from "@antv/g6";
import { message } from "ant-design-vue";

export default defineComponent({
  props: {
    selectedId: {
      type: Object,
      default: null,
    },
  },
  setup(props) {
    watch(props, (newProps) => {
      if (newProps.selectedId) {
        chooseId.value = newProps.selectedId.id;
      }
    });
    const chooseId = ref(props.selectedId.id);
    const data = ref([]);
    const relations = ref([]);
    const graphs = ref(null);
    const container = ref();
    const resolution = ref(document.documentElement.clientWidth / 1920);

    const refresh = () => {
      getKinship(chooseId.value).then((res) => {
        if (res.data.success) {
          relations.value = res.data.data.relations[0];
          data.value = res.data.data.tables;
          graphs.value.data(relations.value);
          graphs.value.render();
          // graphs.value.translate(150, 100);
          graphs.value.fitCenter(true);
          graphs.value.zoom(resolution.value);
        } else {
          message.error(res.data.msg);
        }
      });
    };

    const init = () => {
      G6.registerNode("card-node", {
        draw: function drawShape(cfg, group) {
          const r = 2;
          const color = "#5B8FF9";
          const w = cfg.size[0];
          const h = cfg.size[1];
          const shape = group.addShape("rect", {
            attrs: {
              x: -w / 2,
              y: -h / 2,
              width: w, //200,
              height: 1.5 * h, // 60
              stroke: color,
              radius: r,
              fill: "#fff",
            },
            name: "main-box",
            draggable: true,
          });

          group.addShape("rect", {
            attrs: {
              x: -w / 2,
              y: -h / 2,
              width: w, //200,
              height: h / 2, // 60
              fill: color,
              radius: [r, r, 0, 0],
            },
            name: "title-box",
            draggable: true,
          });

          // title text
          group.addShape("text", {
            attrs: {
              textBaseline: "top",
              x: -w / 2 + 8,
              y: -h / 2 + 2,
              lineHeight: 20,
              text: cfg.name,
              fill: "#fff",
            },
            name: "title",
          });
          cfg.children &&
            group.addShape("marker", {
              attrs: {
                x: w / 2,
                y: 0,
                r: 6,
                cursor: "pointer",
                symbol: cfg.collapsed ? G6.Marker.expand : G6.Marker.collapse,
                stroke: "#666",
                lineWidth: 1,
                fill: "#fff",
              },
              name: "collapse-icon",
            });
          group.addShape("text", {
            attrs: {
              textBaseline: "top",
              x: -w / 2 + 8,
              y: -h / 2 + 24,
              lineHeight: 20,
              text: cfg.tips,
              fill: "rgba(0,0,0, 1)",
            },
            name: `description`,
          });
          return shape;
        },
        setState(name, value, item) {
          if (name === "collapsed") {
            const marker = item.get("group").find((ele) => ele.get("name") === "collapse-icon");
            const icon = value ? G6.Marker.expand : G6.Marker.collapse;
            marker.attr("symbol", icon);
          }
        },
      });

      container.value = document.getElementById("container");
      const width = container.value.scrollWidth;
      const height = container.value.scrollHeight || 500;
      graphs.value = new G6.TreeGraph({
        container: "container",
        width,
        height,
        modes: {
          default: ["drag-canvas"],
        },
        defaultNode: {
          type: "card-node",
          size: [225, 40],
        },
        defaultEdge: {
          type: "cubic-horizontal",
          style: {
            startArrow: true,
          },
        },
        layout: {
          type: "indented",
          direction: "RL",
          dropCap: false,
          indent: 275,
          getHeight: () => {
            return 80;
          },
        },
      });
      graphs.value.on("node:click", (e) => {
        if (e.target.get("name") === "collapse-icon") {
          e.item.getModel().collapsed = !e.item.getModel().collapsed;
          graphs.value.setItemState(e.item, "collapsed", e.item.getModel().collapsed);
          graphs.value.layout();
        }
      });
      if (typeof window !== "undefined")
        window.onresize = () => {
          if (!graphs.value || graphs.value.get("destroyed")) return;
          if (!container.value || !container.value.scrollWidth || !container.value.scrollHeight) return;
          graphs.value.changeSize(container.value.scrollWidth, container.value.scrollHeight);
        };
      refresh();
    };

    onMounted(() => {
      init();
    });
    return {
      data,
      chooseId,
      relations,
      refresh,
      graphs,
      container,
      resolution,
    };
  },
});
</script>
<style lang="less" scoped>
#container {
  width: 100%;
  height: 100%;
  padding: 20px;
}
</style>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值