vue2+antv/x6实现er图

效果图

安装依赖

bash 复制代码
npm install @antv/x6 --save

我目前的项目安装的版本是@antv/x6 2.18.1

人狠话不多,直接上代码

html 复制代码
<template>
  <div class="er-graph-container">
    <!-- 画布容器 -->
    <div ref="graphContainerRef" id="graphContainer"></div>
  </div>
</template>

<script>
import { Graph, Shape } from "@antv/x6";

const LINE_HEIGHT = 24;
const NODE_WIDTH = 150;

export default {
  name: "X6GraphComponent",
  data() {
    return {
      graph: null,
      // 画布数据
      graphData: [
        {
          id: "1",
          shape: "er-rect",
          label: "学生",
          width: 150,
          height: 24,
          position: {
            x: 24,
            y: 150,
          },
          ports: [
            {
              id: "1-1",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "ID",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
            {
              id: "1-2",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "Name",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
            {
              id: "1-3",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "Class",
                },
                portTypeLabel: {
                  text: "NUMBER",
                },
              },
            },
            {
              id: "1-4",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "Gender",
                },
                portTypeLabel: {
                  text: "BOOLEAN",
                },
              },
            },
          ],
        },
        {
          id: "2",
          shape: "er-rect",
          label: "课程",
          width: 150,
          height: 24,
          position: {
            x: 250,
            y: 210,
          },
          ports: [
            {
              id: "2-1",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "ID",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
            {
              id: "2-2",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "Name",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
            {
              id: "2-3",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "StudentID",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
            {
              id: "2-4",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "TeacherID",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
            {
              id: "2-5",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "Description",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
          ],
        },
        {
          id: "3",
          shape: "er-rect",
          label: "老师",
          width: 150,
          height: 24,
          position: {
            x: 480,
            y: 350,
          },
          ports: [
            {
              id: "3-1",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "ID",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
            {
              id: "3-2",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "Name",
                },
                portTypeLabel: {
                  text: "STRING",
                },
              },
            },
            {
              id: "3-3",
              group: "list",
              attrs: {
                portNameLabel: {
                  text: "Age",
                },
                portTypeLabel: {
                  text: "NUMBER",
                },
              },
            },
          ],
        },
        {
          id: "4",
          shape: "edge",
          source: {
            cell: "1",
            port: "1-1",
          },
          target: {
            cell: "2",
            port: "2-3",
          },
          attrs: {
            line: {
              stroke: "#A2B1C3",
              strokeWidth: 2,
            },
          },
          zIndex: 0,
        },
        {
          id: "5",
          shape: "edge",
          source: {
            cell: "3",
            port: "3-1",
          },
          target: {
            cell: "2",
            port: "2-4",
          },
          attrs: {
            line: {
              stroke: "#A2B1C3",
              strokeWidth: 2,
            },
          },
          zIndex: 0,
        },
      ],
    };
  },
  mounted() {
    this.initGraph();
  },
  methods: {
    initGraph() {
      Graph.registerPortLayout(
        "erPortPosition",
        (portsPositionArgs) => {
          return portsPositionArgs.map((_, index) => {
            return {
              position: {
                x: 0,
                y: (index + 1) * LINE_HEIGHT,
              },
              angle: 0,
            };
          });
        },
        true
      );

      Graph.registerNode(
        "er-rect",
        {
          inherit: "rect",
          markup: [
            {
              tagName: "rect",
              selector: "body",
            },
            {
              tagName: "text",
              selector: "label",
            },
          ],
          attrs: {
            rect: {
              strokeWidth: 1,
              stroke: "#5F95FF",
              fill: "#5F95FF",
            },
            label: {
              fontWeight: "bold",
              fill: "#ffffff",
              fontSize: 12,
            },
          },
          ports: {
            groups: {
              list: {
                markup: [
                  {
                    tagName: "rect",
                    selector: "portBody",
                  },
                  {
                    tagName: "text",
                    selector: "portNameLabel",
                  },
                  {
                    tagName: "text",
                    selector: "portTypeLabel",
                  },
                ],
                attrs: {
                  portBody: {
                    width: NODE_WIDTH,
                    height: LINE_HEIGHT,
                    strokeWidth: 1,
                    stroke: "#5F95FF",
                    fill: "#EFF4FF",
                    magnet: true,
                  },
                  portNameLabel: {
                    ref: "portBody",
                    refX: 6,
                    refY: 6,
                    fontSize: 10,
                  },
                  portTypeLabel: {
                    ref: "portBody",
                    refX: 95,
                    refY: 6,
                    fontSize: 10,
                  },
                },
                position: "erPortPosition",
              },
            },
          },
        },
        true
      );

      this.graph = new Graph({
        container: this.$refs.graphContainerRef,
        grid: true,
        connecting: {
          router: {
            name: "er",
            args: {
              offset: 25,
              direction: "H",
            },
          },
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  stroke: "#A2B1C3",
                  strokeWidth: 2,
                },
              },
            });
          },
        },
      });

      let cells = [];
      this.graphData.forEach((item) => {
        if (item.shape === "edge") {
          cells.push(this.graph.createEdge(item));
        } else {
          cells.push(this.graph.createNode(item));
        }
      });
      this.graph.resetCells(cells);
      this.graph.zoomToFit({ padding: 10, maxScale: 1 });
    },
  },
  beforeDestroy() {
    this.graph && this.graph.dispose();
  },
};
</script>

<style>
/* 确保图表可以在容器内正确显示 */
.er-graph-container {
  min-width: 300px;
  min-height: 200px;
}
.er-graph-container,
#graphContainer {
  width: 100%;
  height: 100%;
}
</style>

O了

相关推荐
用户28907942162711 小时前
Spec-Kit应用指南
前端
酸菜土狗1 小时前
🔥 手写 Vue 自定义指令:实现内容区拖拽调整大小(超实用)
前端
ohyeah1 小时前
深入理解 React Hooks:useState 与 useEffect 的核心原理与最佳实践
前端·react.js
Cache技术分享1 小时前
275. Java Stream API - flatMap 操作:展开一对多的关系,拉平你的流!
前端·后端
apollo_qwe1 小时前
前端缓存深度解析:从基础到进阶的实现方式与实践指南
前端
周星星日记1 小时前
vue中hash模式和history模式的区别
前端·面试
Light601 小时前
Vue 高阶优化术:v-bind 与 v-on 的实战妙用与思维跃迁
前端·低代码·vue3·v-bind·组件封装·v-on·ai辅助开发
周星星日记2 小时前
5.为什么vue中使用query可以保留参数
前端·vue.js
lebornjose2 小时前
javascript - webgl中绑定(bind)缓冲区的逻辑是什么?
前端·webgl
瘦的可以下饭了2 小时前
Day05- CSS 标准流、浮动、Flex布局
前端