vue office在线编辑_VUE和Antv G6实现在线拓扑图编辑

7015da482a671846a02fe1d252e2f7a7.png

我使用的是G6 2.0,也可以使用 G6 3.0,3.0的拓扑图单独作为一个编辑器使用,使用更加方便。不过2.0的比较简单,容易上手。

1.首先在Antv官网上找到蚂蚁Antv G6插件,引入插件。


<script src="static/antv/g6.js"</script>

也可以npm 方式引入。

2.写组件

<template>
<div class="car-list-container">
<div id="flowChart">
<div class="operating">
<div class="btn-group">
<div class="btn1" @click="addCircle" title="圆形">
<i class="iconfont icon-circle-oeps"></i>
</div>
</div>
<div class="btn-group">
<div class="btn1" @click="addArrowLine" title="箭头直线">
<i class="iconfont icon-icon-jiantouzhixian"></i>
</div>
</div>
<div class="btn-group">
<div class="btn1" @click="changeMode('edit')" title="选择模式">
<i class="iconfont icon-icon-chose"></i>
</div>
<div class="btn1" @click="changeMode('drag')" title="拖拽模式">
<i class="iconfont icon-zui28x28icon77"></i>
</div>
</div>
<div class="btn-group">
<div class="btn1" @click="del" style="margin-top: 5px;" title="删除">
<i class="el-icon-delete"></i>
</div>
<div class="btn1" @click="save" title="保存">
<i class="iconfont icon-baocun"></i>
</div>
</div>
<div class="btn-group">
<el-input size="mini" v-model="workflowName" placeholder="请输入拓扑图名称..." ref="inputFocus"></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="nodeType" size="mini" filterable placeholder="请选择类型">
<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 id="knowledge">
</div>
</div>
</div>
<script>export default {
name: "index",
components: {},
mounted() {this.initG6();
},
data() {return {
action: '',
name: '',
func: '',
account: '',
workflow: '',
nodeType: 0,
color: '',
net: '',
Util: '',
workflowName: '',
activation: '', //当前激活的节点
isNode: false, //当前是节点
isBlank: true, //当前是空白区
checked: true, //网格对齐
infoTitle: '画布',//属性标题
oldColor: '', //获取节点本身颜色
type: '', //有值为编辑状态
actionList:[],
nodeTypeList: [
{id: 0, label: '普通节点'}]
}
},
methods: {
initG6() {
let self = this;
self.Util = G6.Util;
let grid;if (self.checked) {
grid = {
forceAlign: true, // 是否支持网格对齐
cell: 25, // 网格大小
};
} else {
grid = null;
} // 生成度量 . . . . . . // 工具方法 . . . . . .var sourcesData={ }; //后台返回的数据var trainScale = function(dim, scale){var max = -Infinity;var min = Infinity;
sourcesData.source.nodes.map(function(node){
max =30;
min =25;
});
scale.domain([min, max]);
};var colors = ['#007AE7', '#40BCD2', '#81D6C3', '#C1E4BC', '#FFDD9B', '#FEAC4C', '#FF7C01', '#C4201D'];
. . . . . .
// 生成图http://self.net = new http://G6.Net({
id: 'knowledge', // 容器ID
height: canvasHeight, // 画布高
mode: 'edit'
});
G6.Global.nodeLabelStyle = {
fill: '#fff',
textAlign: 'left',
textBaseline: 'bottom',
fontSize:24
};
self.net.tooltip(true);
self.net.node()
.size(function(model){return sizeScale(model.weight)*2;
})
;
self.net.source(sourcesData.source.nodes, sourcesData.source.edges);
self.net.removeBehaviour(['dragCanvas', 'dragHideEdges', 'dragHideTexts']);
self.net.addBehaviour(['dragBlank']);
self.net.read(sourcesData);
self.net.render();
self.net.zoomAt(graphCenterX, graphCenterY, 0.7);
// 生成布局var layoutNodes = sourcesData.source.nodes;var layoutEdges = Util.clone(sourcesData.source.edges);var ticked = function(){
self.net.updateNodesPosition();
}; ................./** *点击空白处 */
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;
} 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.tooltip({
title: '信息', // @type {String} 标题
split: ':', // @type {String} 分割符号
dx: 0, // @type {Number} 水平偏移
dy: 0 // @type {Number} 竖直偏移
});
self.net.edge().tooltip() .size('val', function(val){return 3;
});/** * 渲染 */
/*self.net.source(self.nodes, self.edges);*/ //加载资源数据
// self.net.render();
},
addCircle() {
},//添加起始节点
addRect() {
},//添加常规节点
addRhombus() {
}, //添加条件节点
addLine() {
}, //添加直线
addSmooth() {
}, //添加曲线
addArrowSmooth() {
}, //添加箭头曲线
addArrowLine() {
}, //添加箭头直线
addPolyLine() {
}, //添加折线
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() {
}, //更新节点
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>

3.注意:

  1. 在实现过程中,我采用了度量的生成方法使节点均匀分布,否则需要指定节点的位置。不指定位置页面不会显示任何东西。
  2. 以上代码只写了重要的部分,需要理解后在写,如果有不明白的可以关注我的知乎文章。 谢谢观看!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值