一. 效果演示
二. 实现教程
接触jsPlumb也有一个星期了,刚开始的时候,每处理一个步骤马上保存起来(比如添加节点添加线条删除节点等),当做到移动节点时无法获取到移动之后的回调函数,然而获取不到移动之后的位置。经过查找前辈的资料,终于恍然大悟,我们可以把整个流程图画好之后再提供一个提交按钮,点击之后再保存起来,这样就避免反复操作复杂的节点线条事件了。因此,我们只要在点击保存时获取到所有节点线条数据即可。
三. 获取所有节点
想要获取所有节点,直接循环设计区域内的jnode-box元素即可
// 保存节点信息
var blocks = [];
// 遍历节点
$("#folwMain .jnode-box").each(function (idx,elem) {
var $elem = $(elem);
blocks.push({
BlockId: $elem.parent().attr('id'),
BlockJnode: $elem.parent().attr('jnode'),
BlockContent: $elem.html().replace(/"/g,"'").replace(/[\t\n]/g,""),
BlockClass: $elem.attr('class').replace("jnode-box ",""),
BlockX: parseInt($elem.parent().css("left"), 10),
BlockY: parseInt($elem.parent().css("top"), 10)
});
});
// 将多出来的 \ 去掉
let node = JSON.stringify(blocks).replace(/\\/g,"");
console.log("node:"+node);
// 测试直接存储到本地
localStorage.setItem('node',node);
四. 获取所有线条
利用jsPlumb提供的getAllConnections()方法获取所有线条,值得注意的是,新增的连线和原来的连线获取锚点位置有所不同
// 遍历线条
var connects = [];
$.each(jsPlumb.getAllConnections(), function (idx,connection) {
// 获取锚点位置
var sourceAnchor,targetAnchor;
if(connection.endpoints[0].anchor.type){
// 新增的连线
sourceAnchor = connection.endpoints[0].anchor.type;
targetAnchor = connection.endpoints[1].anchor.type;
}else{
// 原来的连线
sourceAnchor = connection.endpoints[0].anchor.anchors[0].type;
targetAnchor = connection.endpoints[0].anchor.anchors[1].type;
}
connects.push({
ConnectionId: connection.id,
PageSourceId: connection.sourceId,
PageSourceAnchor: sourceAnchor.replace("Middle","").replace("Center",""),
PageTargetId: connection.targetId,
PageTargetAnchor: targetAnchor.replace("Middle","").replace("Center","")
});
});
// 将数据转换格式后存储
let ligature = JSON.stringify(connects);
console.log("ligature:"+ligature)
// 测试直接存储到本地
localStorage.setItem('ligature',ligature);
五. 页面初始化
页面加载时需要初始化流程图
//页面加载时识别缓存JSON
window.onload = function(){
// 遍历节点
if(localStorage.getItem('node')){
// 获取存储到本地的节点数据
let node = JSON.parse(localStorage.getItem('node'));
console.log("node:", node);
for(let i = 0;i<node.length;i++){
var blockClass = node[i].BlockClass.replace("jnode-box ","");
var dataObj = { top: node[i].BlockY, left: node[i].BlockX, id: node[i].BlockId, jnode: node[i].BlockJnode, jnodeClass: blockClass, jnodeHtml: node[i].BlockContent }
var targetHtml = renderHtml("jnode-template", dataObj);
$('#folwMain').append(targetHtml); //追加元素
initSetNode(dataObj);
}
}
// 遍历线条
if(localStorage.getItem('ligature')){
// 获取存储到本地的线条数据
let ligature = JSON.parse(localStorage.getItem('ligature'));
console.log("ligature:", ligature);
// 将节点的连线还原
for(let i = 0;i<ligature.length;i++){
jsPlumb.ready(function (){
jsPlumb.connect(
{
source:ligature[i].PageSourceId,
target:ligature[i].PageTargetId,
anchor: [ligature[i].PageSourceAnchor, ligature[i].PageTargetAnchor],
paintStyle: { stroke: 'lightgray', strokeWidth: 3 },
endpointStyle: { fill: 'lightgray', outlineStroke: 'darkgray', outlineWidth: 2 },
overlays: [ ['Arrow', { width: 12, length: 12, location: 1 }] ]
},
visioConfig.hollowCircle
);
jsPlumb.draggable(ligature[i].PageSourceId);
jsPlumb.draggable(ligature[i].PageTargetId);
})
}
}
}
六. 大功告成
以上教程为测试案例,直接保存到本地,若实际应用请保存到服务器地址。因每次保存都是循环获取设计区域中所有节点和线条,因此每次保存之前都必须删除数据库原来的数据。
赠人玫瑰手留余香,若对您有帮助,来
点个赞
呗!