go.js收费;JointJS有社区版和收费版(Rappid),开源的中文文档相对较少;
jsPlumb有两种版本社区版和收费版,它的中文的开源文档相对多一点。
拖拽的功能不建议使用jQuery和JQuery-ui容易出现问题(例如版本不兼容等),并且要安装两个文件,比较笨重;
1 参考文档
1.1 参考网站
(1)jsPlumb文档
大神中文地址:https://wdd.js.org/jsplumb-chinese-tutorial/#/
大神中文GitHub地址:https://github.com/wangduanduan/jsplumb-chinese-tutorial
社区版官方社区文档(2.X):https://docs.jsplumbtoolkit.com/community-2.x/current/
项目Github地址: https://github.com/jsplumb/jsplumb
(2)vuedraggable文档
npm上的开发文档: https://www.npmjs.com/package/vuedraggable
中文开发文档(版本有点老):https://www.itxst.com/vue-draggable/tutorial.html
(3)参考的项目
VUE+JsPlumb+vuedraggable实现的开源项目:https://gitee.com/xiaoka2017/easy-flow
1.2 安装文件
# 安装jsplumb
cnpm install jsplumb@2.15.6 --save
# 安装vuedraggable
cnpm install vuedraggable@2.24.3 --save
2 结果图
3 源代码
<template>
<div class="my_jsplumb">
<draggable class="mj_left" v-on:end="dragWidget">
<div v-for="(item, index) in navArr" v-bind:key="index">{{item}}</div>
</draggable>
<div class="mj_right" id="region_id" ref="region">
<div v-for="(item, index) in conArr" v-bind:key="index" v-bind:id="item.id" v-bind:style="{'left':item.left, 'top':item.top}">{{item.label}}</div>
</div>
</div>
</template>
<script>
import draggable from "vuedraggable"
import { jsPlumb } from 'jsplumb'
export default {
name: 'MyJsplumb',
components:{
draggable
},
data: function(){
return{
regionId:"#region_id",
plumbIns: null,
navArr: new Array(),
conArr: new Array()
}
},
created: function(){
},
mounted: function(){
this.initData();
this.initJsplumb();
},
methods:{
initData: function(){
this.navArr = ["河南大学", "软件学院", "Mason"];
this.conArr.push({
id:"con_id_0",
label: "Mason",
top: "100px",
left: "400px"
});
},
initJsplumb: function(){
this.plumbIns = jsPlumb.getInstance();
this.$nextTick(() => {
this.plumbIns.ready(()=>{
this.addOneAnchor('con_id_0');
});
});
},
addOneAnchor: function(idStr){
let anchorStyle = {
isSource: true,
isTarget: true,
maxConnections: -1,
// Set the type of endpoint
endpoint: 'Dot',
// Set the style of anchor
paintStyle: {
fill: 'pink',
radius: 8
},
hoverPaintStyle: {
strokeWidth: 2,
stroke: 'lightblue'
},
// Set connection line
connector: 'StateMachine',
// The following styles apply only to type flowchart
// connector: ['Flowchart', {gap: 10, cornerRadius: 5, alwaysRespectStubs: true}],
// Set the style of line
connectorStyle: {
strokeWidth: 2,
stroke: 'green'
},
connectorHoverStyle: {
strokeWidth: 2,
stroke: 'red'
},
// Set the style of arrow
connectorOverlays: [ ['Arrow', { width: 14, length: 14, location: 1 }]],
}
// Add the anchor of component
this.plumbIns.addEndpoint(idStr, {anchor: 'Top'}, anchorStyle);
this.plumbIns.addEndpoint(idStr, {anchor: 'Right'}, anchorStyle);
this.plumbIns.addEndpoint(idStr, {anchor: 'Bottom'}, anchorStyle);
this.plumbIns.addEndpoint(idStr, {anchor: 'Left'}, anchorStyle);
// Set drag and the region
this.plumbIns.draggable(idStr, {containment: this.regionId});
},
dragWidget: function(event){
// Get position of widget
var widgetX = event.originalEvent.clientX;
let widgetY = event.originalEvent.clientY;
var regionRect = this.$refs.region.getBoundingClientRect();
// Judge the widget in the region
if(widgetX>regionRect.left && widgetX<regionRect.left+regionRect.width && widgetY>regionRect.top && widgetY<regionRect.top+regionRect.height){
// Set the parameter
let curConId = "new_con_id_"+this.conArr.length;
let left = widgetX - regionRect.left;
let top = widgetY - regionRect.top;
this.conArr.push({
id: curConId,
label: event.item.innerText,
top:top+"px",
left:left+"px"
});
// After delaying DOM updates
this.$nextTick(()=>{
this.addOneAnchor(curConId);
});
}else{
alert("请拖拽到内容框中");
}
}
}
}
</script>
<style scoped>
.my_jsplumb{
position: relative;
width: 100%;
}
.my_jsplumb>div{
display: inline-block;
vertical-align: top;
position: relative;
height: 600px;
}
.mj_left{
width: 10%;
}
.mj_left>div{
width: 100%;
height: 40px;
line-height: 40px;
margin: 8px 0px;
background-color: #EBEEF5;
cursor: pointer;
}
.mj_right{
width: 88%;
border: solid 1px #E6A23C;
}
.mj_right>div{
min-width: 100px;
position: absolute;
padding: 8px 10px;
background-color: #EBEEF5;
display: inline-block;
border-radius: 8px;
cursor: pointer;
}
</style>