vue+antv g6+element-ui完整流程图
最近一直在研究流程图相关的技术,一次在逛GitHub时发现了一个技术栈为vue+g6+element-ui的项目,基础功能完好,如node与edge的托拉拽,主界面如下:
GitHub链接为:https://github.com/caoyu48/vue-g6-editor
线上访问地址为:http://62.234.69.136/
g6官方API文档:https://antv-g6.gitee.io/zh/docs/manual/introduction
但由于作者没有写代码的说明文档,本文仅仅只是我本人对读该源码的一些理解,如有不同理解还希望各位朋友指出订正。
一、本地运行
首先从上面的GitHub网址下载该项目,下载该项目需要的依赖包。这里很多人下载完依赖包之后发现启动报错无法运行,需要注意的是这里
不要使用cnpm install,一定要使用npm install!!!具体为什么cnpm不行,我也不知道。
二、给连线加上文字[本人自己增加]
1、修改src/components/DetailPanel/index.vue
<template>
<div class="detailpannel">
<div>
<div v-if="status=='node-selected'" class="pannel" id="node_detailpannel">
<div class="pannel-title">模型详情</div>
<div class="block-container">
<el-row :gutter="10">
<el-col :span="8">名称</el-col>
<el-col :span="16">
<el-input v-model="node.label" @change="handleChangeName" />
</el-col>
<el-col :span="8">任意属性</el-col>
<el-col :span="16">
<el-input v-model="node.xxx" />
</el-col>
</el-row>
</div>
</div>
<div v-if="status==='canvas-selected'" class="pannel" id="canvas_detailpannel">
<div class="pannel-title">画布</div>
<div class="block-container">
<el-checkbox v-model="showGrid" @change="changeGridState">网格对齐</el-checkbox>
</div>
</div>
<!--我添加的-->
<div v-if="status === 'edge-selected'" id="edge_detailpannel" class="pannel">
<div class="pannel-title">连线</div>
<div class="block-container">
<el-col :span="8">内容</el-col>
<el-col :span="16">
<el-input v-model="edge.label" @change="handleChange" />
</el-col>
<el-col :span="8">文字颜色</el-col>
<el-col :span="16">
<el-color-picker v-model="textColor" @change="handleChangeColor" />
</el-col>
</div>
</div>
<!-- <div v-if="status==='group-selected'" class="pannel" id="node_detailpannel">
<div class="pannel-title">群组详情</div>
<div class="block-container">
<div class="p">
名称:
<el-input v-model="name" />
</div>
<div class="p">
任意属性:
<el-input v-model="color" />
</div>
</div>
</div>
-->
</div>
</div>
</template> <script>
import eventBus from "@/utils/eventBus";
import Grid from "@antv/g6/build/grid";
export default {
data() {
return {
status: "canvas-selected",
showGrid: false,
page: {},
graph: {},
item: {},
node: {},
//【我添加的】
edge:{},
grid: null,
//【我添加的】
textColor: 'rgba(19, 206, 102, 0.8)'
};
},
created() {
this.init();
this.bindEvent();
},
methods: {
init() {},
bindEvent() {
let self = this;
eventBus.$on("afterAddPage", page => {
self.page = page;
self.graph = self.page.graph;
eventBus.$on("nodeselectchange", item => {
if (item.select === true && item.target.getType() === "node") {
self.status = "node-selected";
self.item = item.target;
self.node = item.target.getModel();
}
//【我添加的】
else if (item.select === true && item.target.getType() === "edge") {
self.status = "edge-selected";
self.item = item.target;
self.edge = item.target.getModel();
}
else {
self.status = "canvas-selected";
self.item = null;
self.node = null;
}
});
});
},
handleChangeName(e) {
const model = {
label: e
};
this.graph.update(this.item, model);
},
changeGridState(value) {
if (value) {
this.grid = new Grid();
this.graph.addPlugin(this.grid);
} else {
this.graph.removePlugin(this.grid);
}
},
//【我添加的】
handleChange(e) {
const model = {
label: e
};
console.log(model)
this.graph.update(this.item, model);
},
handleChangeColor(e) {
const model = {
textColor: e
};
this.graph.update(this.item, model);
}
}
};
</script> <style scoped>
.detailpannel {
height: 100%;
position: absolute;
right: 0px;
z-index: 2;
background: #f7f9fb;
width: 200px;
border-left: 1px solid #e6e9ed;
}
.detailpannel .block-container {
padding: 16px 8px;
}
.block-container .el-col {
height: 28px;
display: flex;
align-items: center;
margin-bottom: 10px;
}
.pannel-title {
height: 32px;
border-top: 1px solid #dce3e8;
border-bottom: 1px solid #dce3e8;
background: #ebeef2;
color: #000;
line-height: 28px;
padding-left: 12px;
}
</style>
2、修改src/components/Flow/customEdge.js
import G6 from "@antv/g6/build/g6";
import { uniqueId } from '@/utils'
const MIN_ARROW_SIZE = 3 const customEdge = {
init() {
const dashArray = [
[0, 1],
[0, 2],
[1, 2],
[0, 1, 1, 2],
[0, 2, 1, 2],
[1, 2, 1, 2],
[2, 2, 1, 2],
[3, 2, 1, 2],
[4, 2, 1, 2]
]; const lineDash = [4,2,1,2];
const interval = 9;
G6.registerEdge('customEdge', {
draw(cfg, group) {
let sourceNode, targetNode, start, end
if (typeof (cfg.souxrce) === 'string') {
cfg.source = cfg.sourceNode
}
if(!cfg.start){
cfg.start={
x:0,
y:17
}
}
if(!cfg.end){
cfg.end={
x:0,
y:-17
}
}
if (!cfg.source.x) {
sourceNode = cfg.source.getModel()
start = { x: sourceNode.x + cfg.start.x, y: sourceNode.y + cfg.start.y }
} else {
start = cfg.source
}
if (typeof (cfg.target) === 'string') {
cfg.target = cfg.targetNode
}
if (!cfg.target.x) { targetNode = cfg.target.getModel()
end = { x: targetNode.x + cfg.end.x, y: targetNode.y + cfg.end.y }
} else {
end = cfg.target
} let path = []
let hgap = Math.abs(end.x - start.x)
if (end.x > start.x) {
path = [
['M', start.x, start.y],
[
'C',
start.x,
start.y + hgap / (hgap / 50),
end.x,
end.y - hgap / (hgap / 50),
end.x,
end.y - 4
],
[
'L',
end.x,
end.y
]
]
} else {
path = [
['M', start.x, start.y],
[
'C',
start.x,
start.y + hgap / (hgap / 50),
end.x,
end.y - hgap / (hgap / 50),
end.x,
end.y - 4
],
[
'L',
end.x,
end.y
]
]
}
let lineWidth = 1;
lineWidth = lineWidth > MIN_ARROW_SIZE ? lineWidth : MIN_ARROW_SIZE;
const width = lineWidth * 10 / 3;
const halfHeight = lineWidth * 4 / 3;
const radius = lineWidth * 4;
const endArrowPath = [
['M', -width, halfHeight],
['L', 0, 0],
['L', -width, -halfHeight],
['A', radius, radius, 0, 0, 1, -width, halfHeight],
['Z']
];
const keyShape = group.addShape('path', {
attrs: {
id: 'edge' + uniqueId(),
path: path,
stroke: '#b8c3ce',
lineAppendWidth: 10,
endArrow: {
path: endArrowPath,
}
}
});
//此处是我修改的,增加连线的样式即线上文本
if (cfg.label) {
group.addShape('text', {
attrs: {
id: 'edgeText' + uniqueId(),
x: end.x - (end.x - start.x) / 2,
y: end.y - (end.y - start.y) / 2,
text: cfg.label,
fill: cfg.textColor ? cfg.textColor : '#000000'
}
})
}
return keyShape
},
afterDraw(cfg, group) {
if (cfg.source.getModel().isDoingStart && cfg.target.getModel().isDoingEnd) {
const shape = group.get('children')[0];
const length = shape.getTotalLength(); // G 增加了 totalLength 的接口
let totalArray = [];
for (var i = 0; i < length; i += interval) {
totalArray = totalArray.concat(lineDash);
}
let index = 0;
shape.animate({
onFrame() {
const cfg = {
lineDash: dashArray[index].concat(totalArray)
};
index = (index + 1) % interval;
return cfg;
},
repeat: true
}, 3000);
}
},
setState(name, value, item) {
const group = item.getContainer();
const shape = group.get("children")[0];
const selectStyles = () => {
shape.attr("stroke", "#6ab7ff");
};
const unSelectStyles = () => {
shape.attr("stroke", "#b8c3ce");
}; switch (name) {
case "selected":
case "hover":
if (value) {
selectStyles()
} else {
unSelectStyles()
}
break;
}
}
});
G6.registerEdge('link-edge', {
draw(cfg, group) {
let sourceNode, targetNode, start, end
if (!cfg.source.x) {
sourceNode = cfg.source.getModel()
start = { x: sourceNode.x + cfg.start.x, y: sourceNode.y + cfg.start.y }
} else {
start = cfg.source
}
if (!cfg.target.x) {
targetNode = cfg.target.getModel()
end = { x: targetNode.x + cfg.end.x, y: targetNode.y + cfg.end.y }
} else {
end = cfg.target
} let path = []
path = [
['M', start.x, start.y],
['L', end.x, end.y]
]
const keyShape = group.addShape('path', {
attrs: {
id: 'edge' + uniqueId(),
path: path,
stroke: '#1890FF',
strokeOpacity: 0.9,
lineDash: [5, 5]
}
});
return keyShape
},
});
}
} export default customEdge
三、发现的BUG
当删除文本框中的内容时,会发现连节点也删除了,解决办法就是修改src/behavior/keyboard.js
vue+antv g6+element-ui完整流程图的更多相关文章
- FastAPI实践项目:SayHello(FastAPI + vue.js + axios + element ui)
目录 简介 翻版 VS 本尊 后端服务 源码 接下来 简介 这次带来的是FastAPI + vue.js + axios + element ui (一个html文件里使用的) 实现的<Flas ...
- vue项目使用element ui的Checkbox
最近使用到element ui的下拉多选框Checkbox Checkbox用法可参考与于 http://element.eleme.io/#/zh-CN/component/checkbox Che ...
- vue同时安装element ui跟 vant
记一个卡了我比较久的问题,之前弄的心态爆炸各种问题. 现在来记录一下,首先我vant是已经安装成功了的. 然后引入element ui npm i element-ui -S 接着按需引入,安装插件 ...
- vue + antV G6 实现流程图完整代码 (antv G6 流程图)
效果如下: 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- 在vue中关于element UI 中表格实现下载功能,表头添加按钮,和点击事件失效的解决办法。
因为在element 中表格是使用el-table的形式通过数据来支撑结构,所以,表格的样式没有自己写的灵活,所以有了没法添加按钮的烦恼.下面是解决的方法. 准备工作: 一.下载npm安装包两个 1. ...
- vue中修改Element ui样式不起作用
公司做的一个后台系统,由于Elemen ui是响应式的,在小屏笔记本中,一行两列的表单会自动变成一行一列,这样就很不美观了,由于是后台系统,当时也没考虑适配问题. 老总 地表最强的电脑 运行了一下,当 ...
- vue加载Element ui地址省市区插件-- element-china-area-data
1.安装 npm install element-china-area-data -S 2.使用(引入) import { provinceAndCityData, regionData, provi ...
- antV G6流程图在Vue中的使用
最近我司项目中需要加入流程图制作功能,于是乎百度各种找可视化绘制拓扑图的轮子,大部分都是国外的,看文档太吃力,不过好在最终让我发现了AntV G6流程图图表库,最新版为2.0,不过编辑器在2.0版本还 ...
- vue Cli 按需引入Element UI 和全局引用Element UI
全局引用: 一.安装 Element UI npm i element-ui -S 二.在main.js 中引入 element UI import ElementUI from 'element-u ...
- 🎉 Element UI for Vue 3.0 来了!
第一个使用 TypeScript + Vue 3.0 Composition API 重构的组件库 Element Plus 发布了 ~ 2016 年 3 月 13 日 Element 悄然诞生,经历 ...
随机推荐
- [转帖]高性能分布式对象存储——MinIO实战操作(MinIO扩容)
https://juejin.cn/post/7132852449244610574 一.前言 MinIO的基础概念和环境部署可以参考我之前的文章:高性能分布式对象存储--MinIO(环境部署) 二. ...
- [转帖]比较不同CPU下的分支预测
https://plantegg.github.io/2023/04/16/%E6%AF%94%E8%BE%83%E4%B8%8D%E5%90%8CCPU%E4%B8%8B%E7%9A%84%E5%8 ...
- [转帖]Innodb存储引擎-锁(数据库锁的查看、快照读&当前读、MVCC、自增长与锁、外键与锁、行锁、并发事务的问题、阻塞、死锁、锁升级、锁的实现)
文章目录 锁 lock 与latch 读锁/写锁/意向锁 INNODB_TRX/INNODB_LOCKS/INNODB_LOCK_WAITS 一致性非锁定读(快照读) 一致性锁定读(当前读) MVCC ...
- 使用buildx在x86机器上面编译arm64架构的Docker镜像
buildx 多架构编译 安装docker 下载docker 下载buildx 安装架构支持 docker run --privileged --rm tonistiigi/binfmt --inst ...
- [转帖]Java 平台调试体系
https://www.cnblogs.com/xiaojiesir/p/15652619.html Java 平台调试体系(Java Platform Debugger Architecture,J ...
- [1036]kvm虚拟机访问时提示no route to host分析
环境 宿主机: IP: 10.110.136.43 版本:Kylin Linux Advanced Server release V10 (Sword) KVM vm: IP: 10.110.136. ...
- consul系列文章01---docker安装consul
1.下载镜像 2.运行容器 docker run --name consul -d -p 8500:8500 --restart=always consul agent -server -boots ...
- [1] HEVD 学习笔记:HEVD 环境搭建
1. HEVD 概述 + 环境搭建 HEVD作为一个优秀的内核漏洞靶场受到大家的喜欢,这里选择x86的驱动来学习内核漏洞,作为学习笔记记录下来 实验环境 环境 备注 调试主机操作系统 Window ...
- 从python3到python2的踩坑
为什么要从py3到py2 背景:之前自学写过一些py3,而且我写的工具是基于python3来写的,但是公司项目是使用python2版本,希望已有工具或者新写的工具能同时在py2和py3上执行,所以记录 ...
- 深度学习应用篇-计算机视觉-语义分割综述[5]:FCN、SegNet、Deeplab等分割算法、常用二维三维半立体数据集汇总、前景展望等
深度学习应用篇-计算机视觉-语义分割综述[5]:FCN.SegNet.Deeplab等分割算法.常用二维三维半立体数据集汇总.前景展望等 语义分割综述(semantic segmentation) 1 ...