最近一直在研究流程图相关的技术,一次在逛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完整流程图的更多相关文章

  1. FastAPI实践项目:SayHello(FastAPI + vue.js + axios + element ui)

    目录 简介 翻版 VS 本尊 后端服务 源码 接下来 简介 这次带来的是FastAPI + vue.js + axios + element ui (一个html文件里使用的) 实现的<Flas ...

  2. vue项目使用element ui的Checkbox

    最近使用到element ui的下拉多选框Checkbox Checkbox用法可参考与于 http://element.eleme.io/#/zh-CN/component/checkbox Che ...

  3. vue同时安装element ui跟 vant

    记一个卡了我比较久的问题,之前弄的心态爆炸各种问题. 现在来记录一下,首先我vant是已经安装成功了的. 然后引入element ui npm i element-ui -S 接着按需引入,安装插件 ...

  4. vue + antV G6 实现流程图完整代码 (antv G6 流程图)

    效果如下: 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  5. 在vue中关于element UI 中表格实现下载功能,表头添加按钮,和点击事件失效的解决办法。

    因为在element 中表格是使用el-table的形式通过数据来支撑结构,所以,表格的样式没有自己写的灵活,所以有了没法添加按钮的烦恼.下面是解决的方法. 准备工作: 一.下载npm安装包两个 1. ...

  6. vue中修改Element ui样式不起作用

    公司做的一个后台系统,由于Elemen ui是响应式的,在小屏笔记本中,一行两列的表单会自动变成一行一列,这样就很不美观了,由于是后台系统,当时也没考虑适配问题. 老总 地表最强的电脑 运行了一下,当 ...

  7. vue加载Element ui地址省市区插件-- element-china-area-data

    1.安装 npm install element-china-area-data -S 2.使用(引入) import { provinceAndCityData, regionData, provi ...

  8. antV G6流程图在Vue中的使用

    最近我司项目中需要加入流程图制作功能,于是乎百度各种找可视化绘制拓扑图的轮子,大部分都是国外的,看文档太吃力,不过好在最终让我发现了AntV G6流程图图表库,最新版为2.0,不过编辑器在2.0版本还 ...

  9. vue Cli 按需引入Element UI 和全局引用Element UI

    全局引用: 一.安装 Element UI npm i element-ui -S 二.在main.js 中引入 element UI import ElementUI from 'element-u ...

  10. 🎉 Element UI for Vue 3.0 来了!

    第一个使用 TypeScript + Vue 3.0 Composition API 重构的组件库 Element Plus 发布了 ~ 2016 年 3 月 13 日 Element 悄然诞生,经历 ...

随机推荐

  1. 【转帖】磁盘IOPS的计算

    计算磁盘IOPS的三个因素: 1.RAID类型的读写比 不同RAID类型的IOPS计算公式: RAID类型 公式 RAID5.RAID3 Drive IOPS=Read IOPS + 4*Write ...

  2. 【转帖】关于网卡特性TSO、UFO、GSO、LRO、GRO

    https://www.cnblogs.com/larrypeng/p/12496810.html 我们来看下关于网卡特性的解释,不过记住GSO和GRO两个特性就好. TSO(TCP Segmenta ...

  3. [转帖]超线程 Smt 究竟可以快多少?

    https://www.51cto.com/article/686171.html 刚才我们关闭SMT是把CPU10-CPU19全关了,只留下每对里面的1个CPU,也就是留下了CPU0-CPU9. 默 ...

  4. [转帖]INTEL MLC(Memory Latency Checker)介绍

    https://zhuanlan.zhihu.com/p/359823092 在定位机器性能问题的时候,有时会觉得机器莫名其妙地跑的慢,怎么也看不出来问题.CPU频率也正常,程序热点也没问题,可就是慢 ...

  5. [转帖]iostat相关参数说明——await:平均每次设备I/O操作的等待时间 (毫秒),如果%util接近 100%,说明产生的I/O请求太多

    https://www.cnblogs.com/bonelee/p/6323587.html iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动 ...

  6. [转帖]引人入胜,实战讲解“Java性能调优六大工具”之linux命令行工具

    Java性能调优六大工具之Linux命令行工具 为了能准确获得程序的性能信息,需要使用各种辅助工具.本章将着重介绍用于系统性能分析的各种工具.熟练掌握这些工具,对性能瓶颈定位和系统故障排查都很有帮助. ...

  7. [翻译]-hugePage的简要说明--部分内容

    hugePage的简要说明 本篇文档的主旨给linux内核支持的大页内存做一个简要的概述. 大页内存的实现是建立在大多数现代架构所都支持的多级页大小的特性之上的. 举例: x86架构下大部署CPU 的 ...

  8. mysql8 CentOS7 简要安装说明

    1. 卸载mariadb rpm -qa |grep mariadb |xargs yum remove -y比较简单的卸载办法. 2. 安装所有的rpm包. yum localinstall *.r ...

  9. React中useEffect、useCallBack、useLayoutEffect

    在函数中使用定时器 import { useEffect, useState } from "react"; export default function Funcom() { ...

  10. Ant Design Vue数字输入框InputNumber 有值但是验证却不能够通过

    InputNumber 有值但是验证却不能够通过 今天遇见这样一个问题,InputNumber 输入框中有值 但是却却提示验证不能够通过 后来经过分析,怀疑是数据类型不正确, 后面经过验证,果然是数据 ...