「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」
前言
流程图在线编辑器是信息系统中常用的功能,公司新的项目中有这样的需求,查阅资料后发现AntV X6 可以实现项目需求,让我们一起来学习如何使用AntV X6 来打造一个流程图在线编辑器吧!
项目代码: vue-antvx6
整体布局
整体布局可以分为三个区域:
- 头部区域:工具栏。
- 中部区域:流程面板。
- 右侧区域:画布/节点/线条操作配置,可拓展更多的配置项。
编辑器实现的功能:
- 在工具栏中选择不同的图形节点,拖拽至流程面板中;
- 可以选择不同的线条样式连接节点;
- 选中节点/线条,可对其挂载的内容进行修改;
- 可删除指定节点或清空面板所有内容;
- 将流程及其节点以Json格式输出。
安装
vue 安装流程不再详细记录,安装 antv x6 时建议使用 yarn 命令安装,否则 x6-vue-shape 会出现安装失败的问题。
# yarn
$ yarn add @antv/x6
# yarn
yarn add @antv/x6-vue-shape
# 在 vue2 下还需要安装 @vue/composition-api
yarn add @vue/composition-api --dev
开始使用
1. 创建容器
创建一个用于容纳X6绘图的容器,主要内容就在这里面显示
<div id="containerChart"></div>
2. 创建画布
- history.undo() 撤销。
options将被传递到事件回调中。 - history.redo() 重做。
options将被传递到事件回调中。 - enablePanning() 启用画布平移。
- enableMouseWheel() 启用鼠标滚轮缩放画布。
import '@antv/x6-vue-shape'
import { Graph, Shape, Addon, FunctionExt, DataUri } from '@antv/x6'
const data = {}
export default {
data() {
return {
graph:'',
connectEdgeType:{ //连线方式
connector: 'normal',
shape: 'custom-edge-label',
router: {
name: ''
}
},
grid:{ // 网格设置
size: 20, // 网格大小 10px
visible: true, // 渲染网格背景
type: 'mesh',
args: {
color: '#D0D0D0',
thickness: 1, // 网格线宽度/网格点大小
factor: 10
}
}
}
},
mounted () {
this.initX6()
},
methods: {
initX6(){
var _that = this
this.graph = new Graph({
container: document.getElementById('containerChart'),
width: 1700,
height: '100%',
grid: _that.grid,
resizing: { // 调整节点宽高
enabled: true,
orthogonal:false,
},
selecting: true, // 可选
snapline: true,
interacting: {
edgeLabelMovable: true
},
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
})
}
},
highlighting: {
magnetAvailable: {
name: 'stroke',
args: {
padding: 4,
attrs: {
strokeWidth: 4,
stroke: '#6a6c8a'
}
}
}
},
});
insertCss(`
@keyframes ant-line {
to {
stroke-dashoffset: -1000
}
}
`)
this.graph.fromJSON(data)
this.graph.history.redo()
this.graph.history.undo()
this.graph.enablePanning()
this.graph.enableMouseWheel()
// 鼠标移入移出节点
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('blank:click', () => {
this.type = 'grid'
})
this.graph.on('cell:click', ({ cell }) => {
this.type = cell.isNode() ? 'node' : 'edge'
})
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()
})
})
}
}
}
以上,画布就已经创建完毕,在页面上就可以看到画布的样式啦~ 注意:初始化的方法需要放在mounted内,放在 created 内会加载不出来样式。
结语
画布已经创建好了,明天让我们继续学习关于节点的内容吧(ง •_•)ง