最近我司项目中需要加入流程图制作功能,于是乎百度各种找可视化绘制拓扑图的轮子,大部分都是国外的,看文档太吃力,不过好在最终让我发现了AntV G6流程图图表库,最新版为2.0,不过编辑器在2.0版本还没有进行开源,所以只能退而求其次,使用了1.2.8版本。希望2.0版本的编辑器尽早开源,在交互方面1.2.8版本还是差了一些。

该组件并非开箱即食,需要根据自己的业务进行修改,右侧属性表单部分如果有时间考虑改为插槽形式,方便以后复用~

如何将数据进行数据可视化展现?

技术栈

Vue v3.0.1

Sass

效果图

引入

在index.html中进行了全局引用

<script src="./static/plugin/g6.min.js"></script>

实例代码

仿照2.0版本的编辑器将G6作为了一个组件使用,代码:

<template>

<div id="flowChart">

<div class="operating">

<div class="btn-group">

<div class="btn" @click="addCircle" title="起始节点">

<i class="iconfont icon-circle-oeps"></i>

</div>

<div class="btn" @click="addRect" title="常规节点">

<i class="iconfont icon-square-oeps"></i>

</div>

<div class="btn" @click="addRhombus" title="条件节点">

<i class="iconfont icon-square-ling"></i>

</div>

</div>

<div class="btn-group">

<div class="btn" @click="addLine" title="直线">

<i class="iconfont icon-zhixian"></i>

</div>

<div class="btn" @click="addSmooth" title="曲线">

<i class="iconfont icon-quxian"></i>

</div>

<div class="btn" @click="addArrowLine" title="箭头直线">

<i class="iconfont icon-jiantouzhixian"></i>

</div>

<div class="btn" @click="addArrowSmooth" title="箭头曲线">

<i class="iconfont icon-jiantouquxian"></i>

</div>

</div>

<div class="btn-group">

<div class="btn" @click="changeMode('edit')" title="选择模式">

<i class="iconfont icon-chose"></i>

</div>

<div class="btn" @click="changeMode('drag')" title="拖拽模式">

<i class="iconfont icon-move"></i>

</div>

</div>

<div class="btn-group">

<div class="btn" @click="del" style="margin-top: 5px;" title="删除">

<i class="el-icon-delete"></i>

</div>

<div class="btn" @click="save" title="保存">

<i class="iconfont icon-baocun"></i>

</div>

</div>

<div class="btn-group">

<el-input size="mini" v-model="workflowName" placeholder="请输入流图名称..."></el-input>

</div>

</div>

<div class="info">

<div class="title">

<span>{{infoTitle}}属性</span>

</div>

<div class="content">

<el-checkbox v-if="isBlank === true" v-model="checked">网格对齐</el-checkbox>

<el-form v-else label-position="left" label-width="60px">

<el-form-item v-if="isNode !== true" label="动作">

<el-select v-model="action" size="mini" filterable placeholder="绑定动作" value="">

<el-option

v-for="item in actionList"

:key="item.id"

:label="item.label"

:value="item.id">

</el-option>

</el-select>

</el-form-item> <!-- 线-->

<el-form-item v-if="isNode === true" label="名称">

<el-input size="mini" v-model="name"></el-input>

</el-form-item>

<el-form-item v-if="isNode === true" label="功能">

<el-select v-model="func" size="mini" filterable placeholder="绑定功能" value="">

<el-option

v-for="item in funcList"

:key="item.id"

:label="item.label"

:value="item.id">

</el-option>

</el-select>

</el-form-item>

<el-form-item v-if="isNode === true" label="账号">

<el-select v-model="account" size="mini" filterable multiple

collapse-tags placeholder="绑定账号" value="">

<el-option

v-for="item in accountList"

:key="item.id"

:label="item.label"

:value="item.id">

</el-option>

</el-select>

</el-form-item>

<el-form-item v-if="isNode === true" label="流图">

<el-select v-model="workflow" size="mini" filterable clearable placeholder="绑定流图" value="">

<el-option

v-for="item in workflowList"

:key="item.id"

:label="item.label"

:value="item.id">

</el-option>

</el-select>

</el-form-item>

<el-form-item v-if="isNode === true" label="类型">

<el-select v-model="nodeType" size="mini" filterable placeholder="请选择类型" value="">

<el-option

v-for="item in nodeTypeList"

:key="item.id"

:label="item.label"

:value="item.id">

</el-option>

</el-select>

</el-form-item>

<el-form-item label="颜色">

<el-color-picker v-model="color"></el-color-picker>

</el-form-item>

</el-form>

</div>

</div>

</div>

</template>

<script>

export default {

name: "index",

components: {},

mounted() {

this.initG6();

},

props: {

actionList: {

type: Array, default: []

},

funcList: {

type: Array, default: []

},

accountList: {

type: Array, default: []

},

workflowList: {

type: Array, default: []

},

nodeTypeList: {

type: Array, default: () => {

return [

{id: 0, label: '普通节点'},

{id: 1, label: '入口节点'},

{id: 2, label: '出口节点'}

]

}

}

},

data() {

return {

action: '',

name: '',

func: '',

account: '',

workflow: '',

nodeType: 0,

color: '',

net: '',

Util: '',

workflowName: '',

activation: '', //当前激活的节点

isNode: false, //当前是节点

isBlank: true, //当前是空白区

checked: true, //网格对齐

infoTitle: '画布',//属性标题

oldColor: '', //获取节点本身颜色

type: '', //有值为编辑状态

}

},

methods: {

initG6() {

let self = this;

self.Util = G6.Util;

let grid;

if (self.checked) {

grid = {

forceAlign: true, // 是否支持网格对齐

cell: 25, // 网格大小

};

} else {

grid = null;

}

self.net = new G6.Net({

id: 'flowChart', // 容器ID

mode: 'edit',

grid: grid,

/*width: 500, // 画布宽*/

height: 800 // 画布高

});

/*self.net.tooltip({

title: '信息', // @type {String} 标题

split: ':', // @type {String} 分割符号

dx: 0, // @type {Number} 水平偏移

dy: 0 // @type {Number} 竖直偏移

});*/

/**

*点击空白处

*/

self.net.on('click', (ev) => {

if (!self.Util.isNull(ev.item)) {

self.isBlank = false

} else {

self.isBlank = true;

self.infoTitle = '画布'

}

});

/**

*点击节点

*/

self.net.on('itemclick', function (ev) {

self.isNode = self.Util.isNode(ev.item); //是否为Node

self.activation = ev.item;

if (self.isNode) {

/* 激活节点后节点名称input聚焦*/

self.$nextTick(()=>{

self.$refs.inputFocus.$el.querySelector('input').focus();

});

self.infoTitle = '节点';

self.name = ev.item.get('model').label;

self.func = ev.item.get('model').func;

self.account = ev.item.get('model').account || [];

self.workflow = ev.item.get('model').workflow;

self.nodeType = ev.item.get('model').nodeType;

} else {

self.infoTitle = '边';

self.action = ev.item.get('model').action;

}

self.color = self.oldColor;

});

/**

* 鼠标移入移出事件改变颜色

*/

self.net.on('itemmouseenter', ev => {

const item = ev.item;

self.oldColor = item.get('model').color; //获取节点颜色

self.net.update(item, {

color: '#108EE9',

});

self.net.refresh();

});

self.net.on('itemmouseleave', ev => {

const item = ev.item;

self.net.update(item, {

color: self.oldColor

});

self.net.refresh();

});

/**

* 提示信息

*/

/* self.net.node().tooltip(['label', 'func', 'role', 'color']);

self.net.edge().tooltip(['label', 'color']);*/

/**

* 渲染

*/

/*self.net.source(self.nodes, self.edges);*/ //加载资源数据

self.net.render();

},

addCircle() {

this.net.beginAdd('node', {

shape: 'circle',

nodeType: 0

})

},//添加起始节点

addRect() {

this.net.beginAdd('node', {

shape: 'rect',

nodeType: 0

})

},//添加常规节点

addRhombus() {

this.net.beginAdd('node', {

shape: 'rhombus',

nodeType: 0

})

}, //添加条件节点

addLine() {

this.net.beginAdd('edge', {

shape: 'line'

});

}, //添加直线

addSmooth() {

this.net.beginAdd('edge', {

shape: 'smooth'

})

}, //添加曲线

addArrowSmooth() {

this.net.beginAdd('edge', {

shape: 'smoothArrow'

})

}, //添加箭头曲线

addArrowLine() {

this.net.beginAdd('edge', {

shape: 'arrow'

});

}, //添加箭头直线

addPolyLine() {

this.net.beginAdd('edge', {

shape: 'polyLineFlow'

});

}, //添加折线

changeMode(mode) {

this.net.changeMode(mode)

}, //拖拽与编辑模式的切换

del() {

this.net.del()

},//删除

save() {

/* 验证流图名称*/

if (this.workflowName !== '') {

let data = this.net.save();

if (data.source.nodes.length === 0) {

this.$message({type: 'error', message: '流图内容不能为空'});

return false

}

/* 验证节点名称*/

for (let item of data.source.nodes) {

if (item.label === '' || item.label === null || item.label === undefined) {

this.$message({type: 'error', message: '节点名称不能为空'});

return false

}

}

data.source['name'] = this.workflowName;

/*let json = JSON.stringify(data, null, 2);*/

this.$emit('saveData', data.source, this.type);

} else {

this.$message({type: 'error', message: '流图名称不能为空'})

}

/*console.log(saveData, json);*/

},//保存

update() {

if (this.activation.get('type') === 'node') {

this.net.update(this.activation, {

label: this.name,

func: this.func,

account: this.account,

workflow: this.workflow,

nodeType: this.nodeType,

color: this.color

});

} else {

/* 根据ID取出label*/

let label = this.actionList.map(item => {

if (item.id === this.action) {

return item.label

}

}).join('');

this.net.update(this.activation, {

label: label,

color: this.color,

action: this.action

});

}

}, //更新节点

clearView() {

this.type = '';

this.workflowName = '';

this.net.changeData()

}, //清空视图

source(nodes, edges, name, type) {

this.type = type;

this.workflowName = name;

this.net.changeData(nodes, edges)

}, //更新数据

},

watch: {

/**

* 监听输入框

*/

action: function () {

this.update()

},

name: function () {

this.update()

},

func: function () {

this.update()

},

account: function () {

this.update()

},

workflow: function () {

this.update()

},

nodeType: function () {

this.update()

},

color: function () {

this.update()

},

/**

* 网格切换

*/

checked: function () {

let _saveData = this.net.save();

this.net.destroy(); //销毁画布

this.initG6();

this.net.read(_saveData);

this.net.render()

}

}

}

</script>

<style rel="stylesheet/scss" lang="scss" scoped>

#flowChart {

border: 1px solid #ebeef5;

position: relative;

overflow: hidden;

}

.operating {

position: absolute;

z-index: 99;

background-color: #ffffff;

padding: 20px 10px;

box-shadow: 1px 1px 4px 0 #0a0a0a2e;

}

.info {

position: absolute;

right: 0;

z-index: 99;

box-shadow: 1px 1px 4px 0 #0a0a0a2e;

.title {

height: 40px;

padding-left: 10px;

border-top: 1px solid #DCE3E8;

border-bottom: 1px solid #DCE3E8;

border-left: 1px solid #DCE3E8;

background: rgb(235, 238, 242);

line-height: 40px;

span {

font-size: 14px;

}

}

.content {

background: rgba(247, 249, 251, 0.45);

width: 200px;

height: 800px;

border-left: 1px solid #E6E9ED;

padding: 10px;

}

}

.btn-group {

border-right: 1px solid #efefef;

display: inline-block;

padding-left: 10px;

padding-right: 14px;

&:last-of-type {

border-right: 0;

}

.btn {

display: inline-block;

margin: 2px;

width: 30px;

height: 30px;

line-height: 30px;

text-align: center;

cursor: pointer;

border: 1px solid rgba(233, 233, 233, 0);

i {

font-size: 20px;

}

&:hover {

border: 1px solid #E9E9E9;

color: #767A85;

border-radius: 2px;

background: #FAFAFE;

}

}

.el-form-item {

margin-bottom: 0 !important;

}

}

</style>

流图属性

参数

说明

类型

可选值

默认值

actionList

动作数据

Array

——

[]

funcList

功能数据

Array

——

[]

accountList

账号数据

Array

——

[]

workflowList

流图数据

Array

——

[]

nodeTypeList

节点类型数据

Array

——

[{id: 0, label: '普通节点'},{id: 1, label: '入口节点'},{id: 2, label: '出口节点'}]

所有属性接收的数据格式需要与nodeTypeList的默认值相同

流图事件

事件名

说明

参数

saveData

当用户手动点击保存触发事件

source,type

参数type可为空,在此项目中主要用来区分新建与编辑

流图方法

方法名

说明

参数

clearView

清空当前视图

——

source

渲染数据

nodes, edges, name, type

参数type与事件中相同,参数name的作用是用来取流图名

参考文档

antv g6 禁止移动_antV G6流程图在Vue中的使用相关推荐

  1. vue中使用Antv g6构建简单流程图

    vue中使用Antv g6构建简单流程图 前端小白第一次使用,项目需要一个流程图,看了一些博客,简单的写了一个,但是还是没实现项目的需求,希望有会的人帮忙指点一下.项目需要实现的是:可以自定义添加节点 ...

  2. Vuex和antv/g6实现在线绘制分析流程图功能

    流程图绘制在项目中实际是一个复杂的应用,但是因为有很多算法都是和项目中业务相关不一定符合其他小伙伴的实际应用情况并且项目存在保密机制不方便全部分享出来,所以本文章仅抽取最基础的部分简单介绍流程图创建. ...

  3. vue中使用bpmn-js绘制流程图,并实现汉化、自定义Palette及ContextPad。

    一.认识bpmn-is bpmn-js是一个BPMN2.0渲染工具包和web建模器, 使得画流程图的功能在前端来完成. 效果图如下(改造后): 二.在vue基本使用 安装bpmn-js npm ins ...

  4. vue中使用antv/G6完成流程图

    目录 效果展示 后台数据 处理后台数据 安装 完整js代码 效果展示 自定义节点 G6.registerNode 根据后端返回数据生成流程图 后台数据 返回的类似数据,需要parentId数组即上级节 ...

  5. antv g6 禁止移动_十 AntV

    ← Highcharts AntV 是蚂蚁金服全新一代数据可视化解决方案,致力于提供一套简单方便.专业可靠.无限可能的数据可视化最佳实践. AntV 包括以下解决方案: G2:可视化引擎 G2Plot ...

  6. vue中使用antv/g6 绘制关系图、结构图

    使用antv/g6绘制关系图 效果图 代码实现 npm install @antv/g6 --save <template><div id="app">&l ...

  7. VUE中 用AntV G6 + element 实现关系图展示

    1.效果图 (我的需求是做字段血缘展示) 2.官方文档 :https://antv-g6.gitee.io/zh/examples/tree/mindmap#hCustomSideMindmap 3. ...

  8. vue中使用antv/g6 绘制关系图、结构图_高级图标绘制设计软件最新版 | MyDraw 4.1.2...

    THE START 更新高级图标绘制设计软件最新版,MyDraw 4.1.2.还有一些类似的软件Xmind.Xmind ZEN等,都可在小编的菜单栏找到.进入主题! MyDraw是先进的绘图软件和矢量 ...

  9. vue中使用antv/g6 绘制关系图、结构图_CAD小白必看!手把手教你如何看懂室内设计施工图图纸(平面立面剖面大样节点图)...

    号外!号外!你们心心念念的干货来了~ 室内设计施工图视频教程+CAD图库 可供大家学习研究,希望能对大家有所帮助.如果你喜欢请点赞收藏哦,谢谢~ 本期干货:室内设计施工图视频教程+CAD图库 领取方式 ...

最新文章

  1. Java关键字和保留字
  2. 当程序员的一个人无聊时,甚至用Python开发出机器人看他们聊天
  3. 以太坊开发 发行代币的增发功能 并实现转到钱包 和买卖的功能
  4. 2022年全球及中国户外电源产品行业容量前景与运营动态分析报告
  5. ES6一些新特性记录
  6. DefaulSqlSession 和SqlSessionTemplate 的区别是什么?
  7. 博鳌直击 | 区块链在互联网金融中扮演怎样的角色?
  8. asp.net Core 中间件Hello world
  9. DockOne微信分享(七十七):用Harbor实现容器镜像仓库的管理和运维
  10. 电脑大小写怎么切换_小白买了Mac pro电脑学会基本操作
  11. 一文带你斩杀Python之Numpy☀️Pandas全部操作【全网最详细】❗❗❗
  12. MATLAB统计签选课名单程序,关于2018级方向课程选择的通知(1.7选课名单公布)...
  13. 标准MIDI文件格式
  14. 用 Amazon Web Services 进行云计算,第 3 部分: 用 EC2 根据需要提供服务器
  15. java pfx_如何在Java中读取.pfx文件的内容?
  16. 日记20050930
  17. 2023年非证券类投资银行业研究报告
  18. 不用找,你想要的手抄报 小报印刷模板素材都在这里
  19. 云服务器可以虚拟内存吗,云服务器可以设置虚拟内存吗
  20. 智能门禁系统教程--人脸识别方案

热门文章

  1. 工具_SublimeText
  2. RNA-Seq Transcriptome Profiling Identifies CRISPLD2 as a Glucocorticoid Responsive Gene that Modulat
  3. SMRT测序技术及其在微生物研究中的应用
  4. html如何让列表呈直线排列,html – 列表分成多列
  5. Python局域网socket无法连接的问题解决
  6. 三、单链表增删改查原理和代码实现
  7. 语义分割--FCN 算法中的一些细节--特征怎么融合
  8. 分布式锁的使用与注意事项
  9. 在CentOS/Debian/Ubuntu上编译安装最新版 GCC 8 , cmake 3 和ninja
  10. ModuleNotFoundError: No module named 'sklearn.cross_validation'