AntV/G6图-force力导向布局案例

/**
*
* Author: me
* CreatDate: 2024-08-10
*
* Description: G6
*
*/
<template>
  <div class="antvG6-wapper">
    <div :id="idName" :ref="refName" class="graph-content"></div>
  </div>
</template>

<script>
import G6 from "@antv/g6";

export default {
  name: "antvG6",
  components: {},
  props: {
    idName: {
      type: String,
      default() {
        return "graphContainer";
      },
    },
    refName: {
      type: String,
      default() {
        return "graphRef";
      },
    },
    graphData: {
      type: Object,
      default() {
        return {
          // 节点
          nodes: [
            {
              id: "1", // 节点id,字符串类型
              label: "1", // 节点内容,字符串类型
            },
            {
              id: "2",
              label: "2",
            },
            {
              id: "3",
              label: "3",
            },
            {
              id: "4",
              label: "4",
            },
            {
              id: "5",
              label: "5",
            },
            {
              id: "6",
              label: "6",
            },
            {
              id: "7",
              label: "7",
            },
            {
              id: "8",
              label: "8",
            },
            {
              id: "9",
              label: "9",
            },
            {
              id: "10",
              label: "10",
            },
          ],
          // 边
          edges: [
            {
              source: "1", // 起始点id
              target: "2", // 目标点id
            },
            {
              source: "1",
              target: "3",
            },
            {
              source: "1",
              target: "4",
            },
            {
              source: "1",
              target: "5",
            },
            {
              source: "1",
              target: "6",
            },
            {
              source: "1",
              target: "7",
            },
            {
              source: "1",
              target: "8",
            },
            {
              source: "1",
              target: "9",
            },
            {
              source: "2",
              target: "4",
            },
            {
              source: "10",
              target: "2",
            },
            {
              source: "10",
              target: "5",
            },
            {
              source: "3",
              target: "9",
            },
            {
              source: "9",
              target: "3",
            },
          ],
        };
      },
    },
  },
  data() {
    return {
      graph: null, // G6 实例
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.initGraph();
      this.drawGraph();
    });
  },
  methods: {
    /**
     * 初始化graph实例
     */
    initGraph() {
      // 容器节点
      const dom = this.$refs[this.refName];
      // 配置参数
      const options = {
        container: this.idName, // 画布的容器id
        with: dom.offsetWidth, // 画布宽度
        height: dom.offsetHeight, // 画布高度
        // fitView: true, // 画布自适应,开启后图自动适配画布大小
        // fitViewPadding: 20, // 图适应画布时,指定四周的留白
        // fitCenter: true, // 居中,这里不需要,因为resizeView方法里写了居中,这里再有的话,会有突然变化一下的效果
        modes: {
          default: ["drag-canvas", "zoom-canvas", "drag-node"], // 允许拖拽画布、缩放画布、拖拽节点
        },
        // 布局
        layout: {
          type: "force", // 布局类型,力导向布局
          linkDistance: 160, // 边长
          preventOverlap: true, // 是否防止节点重叠
          preventOverlapPadding: 10,
          nodeSize: 80, // 节点距离调整参数,防止近距离重叠
          nodeSpacing: 40, // 节点边缘间距的最小值
          alpha: 1, // 当前的迭代收敛阈值,取值0-1
          alphaDecay: 0.028, // 迭代阈值的衰减率
        },
        // 节点样式
        defaultNode: {
          size: [30, 30],
          color: "#7dd0fc",
          style: {
            lineWidth: 2,
            fill: "#7dd0fc",
          },
          labelCfg: {
            positions: "center", // 标签在元素中的位置
            style: {
              fill: "#ffffff", // 填充色,这里是文字颜色
              fontSize: 16,
              fontFamily: "黑体",
            },
          },
        },
        nodeStateStyles: {
          hover: {
            color: "#ffff00",
          },
        },
        // 边样式
        defaultEdge: {
          size: 1,
          color: "#526c79",
          style: {
            // endArrow: true,
            endArrow: {
              fill: "#526c79",
              path: G6.Arrow.triangle(10, 10, 0), // 内置箭头,参数为箭头宽度、长度、偏移量 d(默认为 0)
            },
          },
        },
      };
      // 实例化
      this.graph = new G6.Graph(options);
      // 自适应
      this.resizeView();
      // 监听窗口大小变化
      window.addEventListener("resize", this.resizeView);
    },
    /**
     * 画图
     */
    drawGraph() {
      // 清除画布元素
      this.graph.clear();
      // 数据源
      this.graph.data(this.graphData);
      // 渲染
      this.graph.render();
      // 鼠标事件
      this.mouseEvent();
    },
    /**
     * 鼠标事件
     */
    mouseEvent() {
      const that = this;
      // 节点-鼠标进入
      this.graph.on("node:mouseenter", (evt) => {
        let node = evt.item;
        // let model = node.getModel();
        // model.oriLabel = model.label;
        that.graph.setItemState(node, "hover", true);
        that.graph.updateItem(node, {
          color: "#ffff00",
        });
      });
      // 节点-鼠标离开
      this.graph.on("node:mouseleave", function (evt) {
        let node = evt.item;
        // let model = node.getModel();
        that.graph.setItemState(node, "hover", false);
        that.graph.updateItem(node, {
          // label: model.oriLabel,
          color: "#7dd0fc",
        });
      });
      // 鼠标进入
      this.graph.on("edge:mouseenter", (evt) => {
        let edge = evt.item;
        that.graph.setItemState(edge, "hover", true);
        that.graph.updateItem(edge, {
          size: 4,
        });
      });
      // 鼠标离开
      this.graph.on("edge:mouseleave", function (evt) {
        let edge = evt.item;
        that.graph.setItemState(edge, "hover", false);
        that.graph.updateItem(edge, {
          size: 1,
        });
      });
    },
    /**
     * 自适应
     */
    resizeView() {
      const dom = this.$refs[this.refName];
      if (dom && this.graph) {
        this.graph.changeSize(dom.offsetWidth, dom.offsetHeight); // 修改画布大小
        this.graph.fitCenter(); // 移至中心
      }
    },
  },
  beforeDestroy() {
    this.graph && this.graph.destroy();
  },
  watch: {},
};
</script>

<style lang='scss' scoped>
.antvG6-wapper {
  height: 100%;
  background: #0b1e4c;
  .graph-content {
    width: 100%;
    height: 90%;
  }
}
</style>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值