# 流程图
# G6绘制的流程图
<template>
<div class="hello" ref="hello">
<div id="left">1</div>
<div id="canvas"></div>
<div id="right">
<div>
<div class="des">当前节点</div>
<el-input v-model="current.label" @input="changeCurrentName" class="elinput"></el-input>
<template v-for="item in nodeName">
<p class="des">当前节点与{{targetFilter(item)}}关联</p>
<el-input v-model="message[item]"
type="textarea"
placeholder="请输入节点间的关联信息"
class="elinput">
</el-input>
</template>
</div>
<el-select v-model="nodeName" multiple class="elselect">
<el-option
v-for="item in arr"
:key="item.id"
:label="item.label"
:value="item.id"
>
</el-option>
</el-select>
<el-button @click="changemes" type="primary" class="changemes">确定</el-button>
</div>
<div class="toolselect">
<div @click="add" class="add">添加节点</div>
<div @click="clear" class="clear">清空画布</div>
</div>
</div>
</template>
<script>
import G6 from"@antv/G6"
export default {
name: 'HelloWorld',
data(){
return{
graph:null,
data:null,
arr:[],
current:{},
nodeName:[],
message:[],
index:-1,
}
},
watch: {
nodeName(newValue, oldValue) {
console.log(newValue)
}
},
filters: {
},
mounted(){
const width = this.$refs.hello.clientWidth
const height = this.$refs.hello.clientHeight
this.data= {
nodes: [],
edges: []
}
const grid = new G6.Grid();
this.graph =new G6.Graph({
container:"canvas",
width:width-400,
height,
plugins:[grid],
modes:{
default:[
'drag-canvas',
'zoom-canvas',
'drag-node'
]
},
nodeStateStyles: {
// 鼠标 hover 上节点,即 hover 状态为 true 时的样式
hover: {
fill: 'orange',
cursor:"pointer"
},
// 鼠标点击节点,即 click 状态为 true 时的样式
click: {
stroke: '#000',
lineWidth: 3,
},
}
})
this.graph.data(this.data)
this.graph.render()
/**
* 删除节点和线段信息*/
this.graph.on("node:contextmenu",e=>{
e.preventDefault();
const _id=e.item._cfg.id;
this.$confirm('此操作将删除本节点, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.data.nodes.forEach((el,i)=>{
if(el.id==_id){
this.data.nodes.splice(i,1)
}
})
let digui=()=>{
this.data.edges.forEach((el,i)=>{
console.log(i)
if(el.source==_id||el.target==_id){
this.data.edges.splice(i,1)
digui()
}
})
}
digui()
// let arrlen=this.data.edges.length;
// for(let i=0;arrlen;){
// console.log(this.data.edges)
// if(this.data.edges.length==0){
// return
// }
// if(this.data.edges[i].source==_id||this.data.edges[i].target==_id){
// this.data.edges.splice(i,1);
// --arrlen;
// continue;
// }
// i++;
// }
this.graph.changeData(this.data)
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch((err) => {
console.log(err)
this.$message({
type: 'info',
message: '已取消删除'
});
});
//删除这个节点吗
// console.log(e)
})
/**
* 点击画布的节点,显示该节点的所有信息,包括连接*/
this.graph.on("node:click",e=>{
// console.log(e)
// console.log(this.data)
const elid =e.item.defaultCfg.id
this.arr=[];
this.nodeName=[]
this.message=[]
this.data.nodes.forEach((el,i)=>{
if(elid==el.id){
this.current=el;
this.index=i
}else{
this.arr.push(el)
}
})
this.data.edges.forEach((el,i)=>{
if(elid==el.source){
this.nodeName.push(el.target)
this.message[el.target]=el.message
}
})
})
this.graph.on('node:mouseenter', e => {
const nodeItem = e.item; // 获取鼠标进入的节点元素对象
this.graph.setItemState(nodeItem, 'hover', true); // 设置当前节点的 hover 状态为 true
});
this.graph.on('node:mouseleave', e => {
const nodeItem = e.item; // 获取鼠标进入的节点元素对象
this.graph.setItemState(nodeItem, 'hover', false); // 设置当前节点的 hover 状态为 true
});
// console.log(this.graph)
},
methods:{
/**
* 新增节点*/
add(){
console.log(this.data)
let len=-1;
if(this.data.nodes.length==0){
len=0;
}else{
len = Math.max(...this.data.nodes.map(el=>Number(el.id)))
}
const model = {
id: `${len+1}`,
label: `流程${len+1}`,
size:[80,30],
labelCfg:{
style:{
fill:"#FFF"
}
},
type:"ellipse",
x: 100,
y: 150,
style: {
fill: '#409EFF',
stroke:"#FFF"
},
};
this.graph.addItem('node', model);
this.data.nodes.push(model)
this.graph.refreshPositions()
console.log(this.data)
},
/**清空画布*/
clear(){
this.$confirm('此操作将清空整个画布, 是否继续?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.data.nodes=[]
this.data.edges=[]
this.nodeName=[]
this.current={}
this.arr=[]
this.graph.changeData(this.data)
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
/**
* 修改当前节点的连线,同时存储连线的逻辑关系,包括删除原有的移除掉的线段*/
changemes(){
console.log(this.nodeName)
if(this.nodeName.length){
this.nodeName.forEach(el=>{
//如果已有的情况下,则替换新message,没有的才增加整个新内容
let ishave=false
this.data.edges.forEach((e,i)=>{
if(e.source==this.current.id&&e.target==el){
e.message=this.message[el]
ishave= true
}
console.log("------")
console.log(e.target)
console.log(this.nodeName)
if((!this.nodeName.includes(e.target))&&e.source==this.current.id){
this.data.edges.splice(i,1)
}
})
//修改还是新增
if(!ishave){
this.data.edges.push({
source:this.current.id,
target:el,
style:{
stroke:"#409EFF",
endArrow:true
},
message:this.message[el]
})
}
//删除的节点
})
}
console.log(this.data.edges)
this.graph.changeData(this.data)
this.message=[]
this.nodeName=[]
this.current={}
this.arr=[]
},
/**
* 修改当前节点的名字*/
changeCurrentName(){
this.data.nodes[this.index].label=this.current.label;
this.graph.changeData(this.data)
},
targetFilter(value) {
let item;
this.data.nodes.forEach(el=>{
if(el.id==value){
item=el.label
}
})
return item
}
}
}
</script>
<style scoped lang="stylus">
.hello
display flex
height 100%
font-size 0
#left
width 200px
border-right 1px solid #F2F2F2
height 100%
font-size 12px
#right
width 200px
border-left 1px solid #F2F2F2
height 100%
font-size 12px
overflow-y auto
.changemes
width 100%
.des
color #13CE66
line-height 30px
height 30px
.elinput,.elselect
margin 4px 0
#canvas
flex:1
height 100%
position relative
.toolselect
width 140px
height 40px
border 1px solid palevioletred
position absolute
top 0
left 200px
font-size 14px
display flex
.add,.clear
flex 1
line-height 40px
text-align center
cursor pointer
.add
color:#409EFF
.clear
color:red
</style>