200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > VUE+antv/x6实现拖拽自定义流程图

VUE+antv/x6实现拖拽自定义流程图

时间:2020-02-01 15:32:18

相关推荐

VUE+antv/x6实现拖拽自定义流程图

最近公司需要做一个流程图, 看了看antv/X6感觉挺合适,就研究了半个月。 网上也没什么资料,又怕自己忘,就自己记录一下用到得一些事件方法,方便以后再用到可以查阅。

一:实现流程图最重要得就是画布了,官网上都有文档可以轻松实现画布。下面放一下我用VUE写得画布代码。

首先最重要得就是下载依赖了, x6在vue中下载得话需要下载两个依赖;

npm install @antv/x6 --savenpm install @antv/x6-vue-shape把这两个依赖下载好就可以在vue中使用X6了 首先在页面引入依赖import "@antv/x6-vue-shape";import { Graph } from '@antv/x6';下面开始写代码

在methods里定义一个initX6方法, 然后拿到mounted里调用initX6() {this.graph = new Graph({container: document.getElementById("containerChart"), //这是画布需要挂载得ID名字width:1000, //画布宽度height: 500, //画布高度grid: this.grid, //画布样式, 在modou层自己定义用this调用autoResize: true, //跟随窗口自动变化大小}); },

需要定义画布背景网格得话可以自己定义, 下面是我自己定义得一个背景网格,直接在grid后面使用this.名字调用就可以。

data(){return{grid: {// 网格设置size: 20, // 网格大小 10pxvisible: true, // 渲染网格背景type: "mesh",args: {color: "#D0D0D0",thickness: 1, // 网格线宽度/网格点大小factor: 10,},},}}

这个时候在css里给你的挂载容器定义一个宽高你就可以在页面上看到一个画布了。 给他调整一个位置就开始写节点吧。

新建一个JS文件, 用来定义节点和写拖拽代码。

import '@antv/x6-vue-shape';import { Addon} from '@antv/x6';// 拖拽生成四边形export const startDragToGraph = (graph,type,e) =>{const node = graph.createNode({width: 100, //节点的宽度height: 60, //节点的高度attrs: {label: {text: type, fill: '#000000',fontSize: 14,textWrap: {width: -10 ,height: -10,ellipsis: true,},},body: {stroke: '#000000',strokeWidth: 1,fill: '#ffffff',}},ports: ports})const dnd = new Addon.Dnd({target:graph})dnd.start(node,e)}//下面是锚点的代码。 知道就行了 我就不一一写了。const ports = {groups: {// 输入链接桩群组定义top: {position: 'top',attrs: {circle: {r: 4,magnet: true,stroke: '#2D8CF0',strokeWidth: 2,fill: '#fff',},},},// 输出链接桩群组定义bottom: {position: 'bottom',attrs: {circle: {r: 4,magnet: true,stroke: '#2D8CF0',strokeWidth: 2,fill: '#fff',},},},left: {position: 'left',attrs: {circle: {r: 4,magnet: true,stroke: '#2D8CF0',strokeWidth: 2,fill: '#fff',},},},right: {position: 'right',attrs: {circle: {r: 4,magnet: true,stroke: '#2D8CF0',strokeWidth: 2,fill: '#fff',},},},},items: [{id: 'port1',group: 'top',},{id: 'port2',group: 'bottom',},{id: 'port3',group: 'left',},{id: 'port4',group: 'right',}],}

定义完节点和锚点以后回到vue页面引入JS文件

import { startDragToGraph } from "../methods.js"; //引入定义好的JS文件去HTML层加入手动拖拽的节点内容。<template><div class="warp"><div id="containerchart"></div><divv-for="(item, index) in List":key="index"class="btn":title="item"@mousedown="startDrag(item, $event)"><span>{{ item }}</span></div></div></template>//循环的list是自己写的data() {return {List: ["内置节点"],grid: {// 网格设置size: 20, // 网格大小 10pxvisible: true, // 渲染网格背景type: "mesh",args: {color: "#D0D0D0",thickness: 1, // 网格线宽度/网格点大小factor: 10,},},};},然后在methods里定义方法,把type传到js文件里。 startDrag(type, e) {startDragToGraph(this.graph, type, e);},

完成以上你就可以得到如下效果,从右侧拖拽节点到画布上就可以展示了。

只不过现在拖拽和线条还是有问题的。 接下来解决一下连线的问题。

data() {return {List: ["内置节点"],grid: {// 网格设置size: 20, // 网格大小 10pxvisible: true, // 渲染网格背景type: "mesh",args: {color: "#D0D0D0",thickness: 1, // 网格线宽度/网格点大小factor: 10,},},connectEdgeType: {//连线方式connector: "normal",router: {name: "",},},//首先在data里定义下面三个内容,下面需要用到graph: "",type: "grid",selectCell: "",};},//然后在methods里的initX6方法里加上下面的方法connecting: {// 节点连接anchor: "center",connectionPoint: "anchor",allowBlank: false,snap: true,},createEdge() {return new Shape.Edge({attrs: {line: {stroke: "#1890ff",strokeWidth: 1,targetMarker: {name: "classic",size: 8,},strokeDasharray: 0, //虚线style: {animation: "ant-line 30s infinite linear",},},},label: {text: "",},connector: _that.connectEdgeType.connector,router: {name: _that.connectEdgeType.router.name || "",},zIndex: 0,});},//注意 这两个方法写到new的Graph实例里面。//然后给节点写上拖拽事件,这个方法写到initX6方法里,new的Graph实例外。this.graph.on("selection:changed", (args) => {args.added.forEach((cell) => {this.selectCell = cell;if (cell.isEdge()) {cell.isEdge() && cell.attr("line/strokeDasharray", 5); //虚线蚂蚁线cell.addTools([{name: "vertices",args: {padding: 4,attrs: {strokeWidth: 0.1,stroke: "#2d8cf0",fill: "#ffffff",},},},]);}});args.removed.forEach((cell) => {cell.isEdge() && cell.attr("line/strokeDasharray", 0); //正常线cell.removeTools();});});

现在就看到画布上面的内置节点上面的锚点是处于一直显示的状态。 下面给他处理一下。

//需要先在引入的X6方法里添加一个方法import { Graph,FunctionExt } from "@antv/x6";在methods里定义一个遍历方法在鼠标移入移出里调用。。showPorts(ports, show) {for (let i = 0, len = ports.length; i < len; i = i + 1) {ports[i].style.visibility = show ? "visible" : "hidden";}},然后在方法里给this.garph.on()添加两个鼠标移入移出事件。 移入让锚点显示,移出让锚点隐藏。 这样就可以让画布的节点好看一点了。//鼠标移入this.graph.on("node:mouseenter",FunctionExt.debounce(() => {const container = document.getElementById("containerchart");const ports = container.querySelectorAll(".x6-port-body");this.showPorts(ports, true);}),500);//鼠标移出this.graph.on("node:mouseleave", () => {const container = document.getElementById("containerchart");const ports = container.querySelectorAll(".x6-port-body");this.showPorts(ports, false);});

下面是全部的代码

<template><div class="container_warp"><div id="containerChart"></div><divv-for="(item, index) in List":key="index"class="btn":title="item"@mousedown="startDrag(item, $event)"><span>{{ item }}</span></div></div></template><script>import "@antv/x6-vue-shape";import { Graph, Shape, FunctionExt } from "@antv/x6";import { startDragToGraph } from "../methods.js";export default {data() {return {List: ["目录监听","数据组织","影像发布","目标检测","变化检测","地物分类","专家候审","样本入库","影像入库","目标入库","图幅整饰","打包下载",],graph: "",type: "grid",selectCell: "",connectEdgeType: {//连线方式connector: "normal",router: {name: "",},},grid: {// 网格设置size: 20, // 网格大小 10pxvisible: true, // 渲染网格背景type: "mesh",args: {color: "#D0D0D0",thickness: 1, // 网格线宽度/网格点大小factor: 10,},},};},methods: {initX6() {this.graph = new Graph({container: document.getElementById("containerChart"),width: 1000,height: 500,grid: this.grid,connecting: {// 节点连接anchor: "center",connectionPoint: "anchor",allowBlank: false,snap: true,},createEdge() {return new Shape.Edge({attrs: {line: {stroke: "#1890ff",strokeWidth: 1,targetMarker: {name: "classic",size: 8,},strokeDasharray: 0, //虚线style: {animation: "ant-line 30s infinite linear",},},},label: {text: "",},connector: _that.connectEdgeType.connector,router: {name: _that.connectEdgeType.router.name || "",},zIndex: 0,});},});// 鼠标移入移出节点this.graph.on("node:mouseenter",FunctionExt.debounce(() => {const container = document.getElementById("containerChart");const ports = container.querySelectorAll(".x6-port-body");this.showPorts(ports, true);}),500);this.graph.on("node:mouseleave", () => {const container = document.getElementById("containerChart");const ports = container.querySelectorAll(".x6-port-body");this.showPorts(ports, false);});this.graph.on("selection:changed", (args) => {args.added.forEach((cell) => {this.selectCell = cell;if (cell.isEdge()) {cell.isEdge() && cell.attr("line/strokeDasharray", 5); //虚线蚂蚁线cell.addTools([{name: "vertices",args: {padding: 4,attrs: {strokeWidth: 0.1,stroke: "#2d8cf0",fill: "#ffffff",},},},]);}});args.removed.forEach((cell) => {cell.isEdge() && cell.attr("line/strokeDasharray", 0); //正常线cell.removeTools();});});},showPorts(ports, show) {for (let i = 0, len = ports.length; i < len; i = i + 1) {ports[i].style.visibility = show ? "visible" : "hidden";}},// 拖拽生成正方形或者圆形startDrag(type, e) {console.log(type, e);console.log(this.graph);startDragToGraph(this.graph, type, e);},},mounted() {this.initX6();},};</script><style lang="less">#containerChart {width: 1000px;height: 500px;border: 1px solid red;float: left;}.btn {width: 400px;float: right;margin-right: 500px;}</style>

这样就完成了一个手动生成节点到画布的X6了 剩下的就是一些CSS的问题了。 下面写几个X6的事件。方便以后用到或者查阅

this.garph.on('node:click',()=>{//这是点击节点事件})this.graph.on("blank:click", () => {//这是点击画布背景事件});this.graph.on("cell:click", () => {//这是点击连接线事件});// 删除节点deleteNode() {const cell = this.graph.getSelectedCells();this.graph.removeCells(cell);this.type = "grid";},//清空画布deleteAll() {this.graph.clearCells();},//销毁画布GraphDelete() {this.graph.dispose();},// 保存pngsaveToPNG() {//下面保存图片this.$nextTick(() => {this.graph.toPNG((dataUri) => {console.log(dataUri);// 下载DataUri.downloadDataUri(dataUri, "资产拓扑图.png");},{backgroundColor: "white",padding: {top: 50,right: 50,bottom: 50,left: 50,},quality: 1,copyStyles: false,});});},this.graph.toJSON()获取当前画布里的节点所有内容JSON.stringify(this.graph.toJSON())可以把当前画布的所有节点内容转成JSON串存到本地或者后台JSON.parse(json); 把json数据整形成数据格式 然后通过fromJSON方法再渲染到画布上。this.graph.fromJSON(json); 可以把从后台或者本地获取到的json数据整形后渲染到画布上。

下面是个人写的一些经验, 由于网上资料有限,记录一下供以后方便查阅, 写的不好各位大神别喷。 有什么问题的也可以留言私信我。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。