# antv-x6-learn **Repository Path**: gitee_store/antv-x6-learn ## Basic Information - **Project Name**: antv-x6-learn - **Description**: antv-x6学习总结 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2021-09-08 - **Last Updated**: 2021-09-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AntV X6 技术分享 [TOC] ### 一、本文目的 对 AntV x6 知识点的一个总结,也为其他开发同学提供一个说明文档。 ### 二、知识要点 #### 1、简介 X6 是 AntV 旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建流程图、DAG 图、ER 图等图应用。 #### 2、安装 ``` npm i @antv/x6 -S yarn add @antv/6 ``` #### 3、实例代码 ``` import { Graph } from '@antv/x6'; const graph = new Graph({ container: document.getElementById('container'), width: 800, height: 600, }); ``` #### 4、画布 Graph 在 X6 中,Graph 是图的载体,它包含了图上的所有元素(节点、边等),同时挂载了图的相关操作(如交互监听、元素操作、渲染等)。 ##### a. 常用的方法: ``` graph.dispose() // 销毁画布 graph.centerContent() //内容居中,画布内容中心与视口中心对齐 graph.zoom() // 获取缩放级别 graph.zoom(0.2) // 在原来缩放级别上增加 0.2 graph.zoom(-0.2) // 在原来缩放级别上减少 0.2 graph.getCells() // 返回画布中所有节点和边 graph.getNodes() // 返回画布中所有节点 graph.getEdges() // 返回画布中所有边 graph.toJSON() // 导出图中的节点和边 graph.fromJSON() // 反序列化 按照指定的 JSON 数据渲染节点和边。 graph.clearCells() // 清空画布 graph.resetCells() // 清空画布并添加用指定的节点/边 graph.getCellById() 根据节点/边的 ID 获取节点/边。 ``` ##### b. 画布反序列化 ``` const data = { // 节点 nodes: [ { id: 'node1', x: 40, y: 40, width: 80, height: 40, label: 'Hello' }, { id: 'node2', x: 160, y: 180, width: 80, height: 40, label: 'World' } ], // 边 edges: [ { source: 'node1', target: 'node2' } ] } graph.fromJSON(data) ``` #### 5、节点 Node Node 是所有节点的基类,继承自 [Cell](https://x6.antv.vision/zh/docs/api/model/cell),并定义了节点的通用属性和方法。 ##### a. 常用方法: ``` node.isNode() // 判断是不是节点 node.getBBox() // 获取节点的包围盒 node.size() // 获取节点大小 node.resize() // 改变节点大小 node.scale() // 缩放节点 node.position() // 获取节点位置 node.position(30, 30) // 设置节点位置 ``` ##### b. 创建内置节点 ``` // 方式一:构造函数 import { Shape } from '@antv/x6' // 创建节点 const rect = new Shape.Rect({ x: 100, y: 200, width: 80, height: 40, angle: 30, attrs: { body: { fill: 'blue', }, label: { text: 'Hello', fill: 'white', }, }, }) graph.addNode(rect) // 方式二:graph.addNode const rect = graph.addNode({ shape: 'rect', // 指定使用何种图形,默认值为 'rect' x: 100, y: 200, width: 80, height: 40, angle: 30, attrs: { body: { fill: 'blue', }, label: { text: 'Hello', fill: 'white', }, }, }) // 方式三:graph.createNode const node = graph.createNode({ width: 75, height: 38, shape: 'html', attrs: { label: { text: '开始', // 文本 style: { visibility: 'hidden' } } }, ports: { groups, items: startGroupItems }, type: 'start', nodeDescription: '开始节点描述', html: 'start-html', ...startNodeSetting }); this.dnd.start(node, e); ``` ##### c. 注册自定义 HTML 节点 ``` registerHTMLComponent() { const startHtml = `
开始
`; const approvalHtml = `
审批节点
`; const aggregationHtml = `
聚合节点
`; const endHtml = `
结束
`; const branchHtml = `
`; Graph.registerHTMLComponent('start-html', startHtml, true); Graph.registerHTMLComponent('approval-html', approvalHtml, true); Graph.registerHTMLComponent('aggregation-html', aggregationHtml, true); Graph.registerHTMLComponent('end-html', endHtml, true); Graph.registerHTMLComponent('branch-html', branchHtml, true); } ``` ##### d. 渲染 Vue 节点 ``` npm install @antv/x6-vue-shape 在 vue2 下还需要安装 @vue/composition-api import { Graph } from '@antv/x6' import '@antv/x6-vue-shape' import ServiceNode from './service-node.vue' Graph.registerVueComponent( 'service-node', { template: '', components: { ServiceNode } }, true ) const graph = new Graph({ container: document.getElementById('graph') }) const node1 = graph.addNode({ shape: "vue-shape", x: 300, y: 250, component: "service-node" }); const node2 = graph.addNode({ shape: "vue-shape", x: 300, y: 550, component: "service-node" }); graph.addEdge({ source: node1, target: node2, vertices: [ { x: 300, y: 250 }, { x: 300, y: 550 } ] }); ``` #### 6、边 Edge Edge 是边的基类,继承自 [Cell](https://x6.antv.vision/zh/docs/api/model/cell),并定义了边的通用属性和方法。 ##### a. 连接到画布上的点 ``` const edge = new Shape.Edge({ source: { x: 40, y: 40 }, target: { x: 180, y: 80 }, }) ``` ##### b. 连接到节点/边 ``` const edge = new Shape.Edge({ source: { cell: 'source-cell-id' }, target: { cell: 'target-cell-id' }, }) ``` ##### c. 连接到节点上的链接桩 ``` const edge = new Shape.Edge({ source: { cell: 'source-cell-id', port: 'port-id' }, target: { cell: 'target-cell-id', port: 'port-id' }, }) ``` ##### d. 连接到节点上的某个元素 ``` const edge = new Shape.Edge({ source: { cell: 'source-cell-id', selector: 'some-selector' }, target: { cell: 'target-cell-id', selector: 'some-selector' }, }) ``` ##### e. 自定义边: ``` import { Shape } from '@antv/x6'; export class TreeEdge extends Shape.Edge { // ... } TreeEdge.config({ zIndex: 1 }); Edge.registry.register('tree-edge', TreeEdge, true); ``` ##### f. 常用的方法有 ``` edge.isEdge() // 判断是不是边 edge.getBBox() // 返回边的包围盒 edge.getSource() // 获取边的起始节点/起始点信息 edge.getTarget() // 获取边的终止节点/终止点信息 ``` ##### g. 箭头 ``` // 内置箭头:https://x6.antv.vision/zh/docs/tutorial/intermediate/marker#%E5%86%85%E7%BD%AE%E7%AE%AD%E5%A4%B4 const markers = [ ['block', { size: 6 }], ['classic', { size: 6 }], ['diamond', { size: 8 }], ['circle', { size: 6 }], ['circlePlus', { size: 6 }], ['ellipse', { rx: 6, ry: 4 }], ['cross', { size: 8, offset: 1 }], ['async', { size: 8, offset: 1 }], ] markers.forEach(([marker, args], i) => { graph.addEdge({ sourcePoint: [220, 30 + i * 40], targetPoint: [500, 30 + i * 40], label: marker, attrs: { line: { sourceMarker: { args, name: marker, }, targetMarker: { args, name: marker, }, strokeWidth: 1, }, }, }) }) ``` #### 7、基类 cell Cell 是 [Node](https://x6.antv.vision/zh/docs/api/model/node) 和 [Edge](https://x6.antv.vision/zh/docs/api/model/edge) 的基类,包含节点和边的通用属性和方法定义,如属性样式、可见性、业务数据等,并且在实例化、样式定制、默认选项、自定义选项等方面具有相同的行为。 ##### a. 常用的方法有: ``` cell.isNode() // 监测是否是Node实例 cell.isEdge() // 监测是否是Edge实例 cell.attr() // 获取全部属性值 cell.attr('body/fill') // 获取某一属性值 cell.attr('body/fill', '#f5f5f5') // 设置某一属性值 cell.getProp().type // 获取指定的属性值。 cell.setProp('name', val); // 设置属性 cell.removeProp('zIndex'); // 删除单个属性 ``` #### 8、辅助工具 ##### a. 自定义 tooltip 弹框 ``` import { ToolsView, Graph } from '@antv/x6'; import insertCss from 'insert-css'; insertCss(` .inner-box { box-sizing: border-box; width: 590px; z-index: 2; max-height: 175px; padding: 20px; color: rgba(255, 255, 255, 65); background-color: rgba(36, 40, 52, 1); box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.5); border: 1px solid rgba(255, 255, 255, 0.2); position: absolute; display: none; } .inner-box::before { width: 0; height: 0; content: ''; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 10px solid rgba(255, 255, 255, 0.2); position: absolute; top: -10px; left: 49px; } .inner-box::after { width: 0; height: 0; content: ''; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 8px solid rgba(36, 40, 52, 1); position: absolute; top: -8px; left: 50px; } .inner-box-main-title { font-size: 18px; font-weight: 600; color: rgba(65, 133, 255, 100); } .inner-box-main-text { font-size: 12px; line-height: 20px; } `); export class TooltipTool extends ToolsView.ToolItem { render() { const dom = `

`; this.knob = ToolsView.createElement('div', false); this.knob.setAttribute('class', 'inner-box'); this.knob.innerHTML = dom; this.container.appendChild(this.knob); this.updatePosition(); return this; } updatePosition() { const cell = this.cell; const { position, name, description } = cell.getProp(); if (description && name) { const style = this.knob.style; style.display = 'block'; style.left = `${position.x}px`; style.top = `${position.y + 70}px`; this.knob.querySelector('.inner-box-main-title').innerHTML = name; this.knob.querySelector('.inner-box-main-text').innerHTML = description; } } } TooltipTool.config({ tagName: 'div', isSVGElement: false }); Graph.registerNodeTool('tooltip', TooltipTool, true); // 页面实例化 new TooltipTool() cell.addTools([{ name: 'tooltip' }]); // 添加tooltip cell.removeTools(); // 删除tooltip ``` ### 三、参考阅读 ##### [官网](https://x6.antv.vision/zh) ##### [github](https://github.com/antvis/X6) ##### [国内镜像](https://antv-x6.gitee.io/zh) ##### [布局](https://x6.antv.vision/zh/docs/tutorial/advanced/layout)