最近在使用jsplumb做了一个流程图绘制的实现,因为本身不是搞前端出身,布局有点丑,不过大致达到了自己想要的功能效果,具体效果如下:
期间遇到一些问题和自己想要的一些效果,现在记录下来和大家分享一下:
1、监听画图区域组件的拖拽事件,以获取组件的位置,注册stop方法,从event中获取组件ID,从ui获取事件的位置
jsPlumb.draggable(id, {
containment: 'parent',
stop:function (event,ui) {
let dragNodeId = event.target.id;
let dragNode = flowData.stepMap[dragNodeId];
dragNode.top = ui.position.top;
dragNode.left = ui.position.left;
updateFlag = true;
}
})
2、绘制连接线,这里注册了两个监听事件‘beforeDrop’和‘connection’ 。beforeDrop事件用于做绘制前检查,connenction用于监听,连接线连上后的动作,添加了connection监听事件后,发现初始化创建连接线的时候也会触发,这里可以加一个标识,初始化和非初始化时执行不同的方法。
//我这里绑定connection事件主要是为了获取jsplumb自动生成的连接线ID
//info是连接线对象
//flowData.stepMap保存的是我要提交到后来的组件信息,其中的targetMap保存了连接线的信息,即下一个节点的信息
//以下代码中有部分是业务代码,尽供参考
jsPlumb.bind("connection", function (info) {
let sourceId = info.sourceId;
let connId = info.connection.id;
let nodeSource = flowData.stepMap[sourceId];
let targets = nodeSource.targetMap;
let index = 0;
if (targets) {
for (let i = 0; i < targets.length; i++) {
let target = targets[i];
//初始化的时候target还没有赋值,或者已经赋值,该连接线已存在,则直接退出
if (!target.connId || target.connId === connId) {
return;
}
let temp = parseInt(target.id.substr(target.id.length - 1, 1));
if (temp >= index) {
index = temp + 1;
}
}
} else {
flowData.stepMap[info.sourceId].targetMap = [];
}
flowData.stepMap[info.sourceId].targetMap.push({
"id" : "target" + index,
"value" : info.targetId,
"connId" :connId
});
});
3、删除连接线,使用 jsPlumb.detach() 方法,参数是connection对象,前提是先获取connction对象,双击连接线 可以conn对象
jsPlumb.bind('dblclick', function (conn, originalEvent) {
if (confirm('确定删除所点击的链接吗?')) {
jsPlumb.detach(editConn);
}
});
4、在连接线上添加文字
//conn为连接线对象 ,desc文字的内容
conn.addOverlay(['Custom', {
create: function (component) {
return $('<span style="background-color: white; padding: 5px;">' + desc + '</span>');
},
location: 0.5 //文字的位置
}]);
5、双击节点可以编辑文字(解决办法是网上查找的)
//areaId为整个画图区域
$(areaId).on('dblclick',function (event) {
//判断双击事件是否在节点组件上
if (event.target.dataset.type === 'action') {
let element = event.target;
let oldhtml = $.trim(element.innerHTML);
//如果已经双击过,内容已经存在input,不做任何操作
if(oldhtml.indexOf('type="text"') > 0){
return;
}
//创建新的input元素
let newobj = document.createElement('input');
//为新增元素添加类型
newobj.type = 'text';
//为新增元素添加value值
newobj.value = oldhtml;
//为新增元素添加光标离开事件
newobj.onblur = function() {
//当触发时判断新增元素值是否为空,为空则不修改,并返回原有值
if(this.value && this.value.trim()!==""){
element.innerHTML = this.value === oldhtml ? oldhtml : this.value;
let stepNode = flowData.stepMap[_deNode.id];
stepNode.desc = element.innerHTML;
jsPlumb.setSuspendDrawing(false,true); //文字修改后,节点的宽度可能会改变,这里设置进行重绘
} else {
element.innerHTML = oldhtml;
}
};
//设置该标签的子节点为空
element.innerHTML = '';
//添加该标签的子节点,input对象
element.appendChild(newobj);
//设置选择文本的内容或设置光标位置(两个参数:start,end;start为开始位置,end为结束位置;如果开始位置和结束位置相同则就是光标位置)
newobj.setSelectionRange(0, oldhtml.length);
//设置获得光标
newobj.focus();
}
});
6、删除节点,执行remove方法后,及诶但和相关联的连接线都会一并被删除
//id为节点的 ID,即添加节点时设置的ID
//执行remove方法后,节点和相关联的连接线都会一并删除
function emptyNode (id) {
jsPlumb.remove(id);
}
7、添加节点,添加节点需要几个步骤:设置节点可拖动、添加入口点、添加出口点
function initSetNode (template, position) {
addDraggable(position.id);
setEnterPoint(position.id);
setExitPoint(position.id);
}
// 让元素可拖动
function addDraggable (id) {
jsPlumb.draggable(id, {
containment: 'parent',
stop:function (event,ui) {
let dragNodeId = event.target.id;
let dragNode = flowData.stepMap[dragNodeId];
dragNode.top = ui.position.top;
dragNode.left = ui.position.left;
updateFlag = true;
}
})
}
// 设置入口点
function setEnterPoint (id) {
let config = getBaseNodeConfig();
config.isSource = true;
config.maxConnections = -1;
config.allowLoopback = false ;//禁止回环
jsPlumb.addEndpoint(id, {
// anchors: ['Top'],
anchor:'AutoDefault',
uuid: id + '-in'
}, config)
}
// 设置出口点
function setExitPoint (id, position) {
let config = getBaseNodeConfig();
config.isTarget = true;
config.maxConnections = -1;
config.allowLoopback = false ;//禁止回环
jsPlumb.addEndpoint(id, {
// anchors: position || 'Bottom',
anchor:'AutoDefault',
uuid: id + '-out'
}, config)
}
不和后台交互的源码:
github下载链接:https://github.com/wongxl/jsplumb-flow-editor
csdn下载链接:https://download.youkuaiyun.com/download/wzl19870309/11103445