清空画布,简单粗暴的方法就是清空html
$('#delete').click(function(){
$('#flow-main').html('')
})
保存流程图是将流程图中的节点信息,连线信息和 label 信息序列化之后,利用 Ajax 传递到后台。节点和 label 可以利用 jQuery 直接获取 dom 信息,jsPlumb 提供了 jsPlumb.getAllConnections() 方法,可以获取连线信息。
$('#save').click(function () {
var connects = [];
$.each(jsPlumb.getAllConnections(), function (idx, connection) {
connects.push({
connectionId: connection.id,
pageSourceId: connection.sourceId,
pageTargetId: connection.targetId,
sourcePoint: connection.endpoints[0].anchor.type,
targetPoint: connection.endpoints[1].anchor.type,
});
});
var blocks = [];
$("#flow-main .node-common").each(function (idx, elem) {
var $elem = $(elem);
console.log($elem);
var blockId = $elem.attr('id');
var blockContent = $elem.children('.node-text').html();
blocks.push({
blockId: blockId,
blockContent: blockContent,
type: $elem.data("type"),
blockX: parseInt($elem.css("left"), 10),
blockY: parseInt($elem.css("top"), 10),
width: parseInt($elem.width(), 10) + 24,
height: parseInt($elem.height(), 10) + 16,
});
});
var lineDescs = [];
$("#flow-main .line-label").each(function (idx, elem) {
var $elem = $(elem);
var lineContent = $elem.children('.label-text').html();
lineDescs.push({
lineId: $elem.attr('id'),
lineContent: lineContent,
lineX: parseInt($elem.css("left"), 10),
lineY: parseInt($elem.css("top"), 10),
width: parseInt($elem.width(), 10) + 24,
height: parseInt($elem.height(), 10) + 16,
pathId: $elem.data("path")
});
});
var serliza = {
connects:connects,
blocks:blocks,
lineDescs:lineDescs
}
$.ajax({
type: "POST",
url: "test.json",
data: serliza,
success: function(data){
//保存成功之后的回调函数
}
});
})
流程图可以分为可编辑和不可编辑两种状态,利用变量 isNew 区分,true 为可编辑, false 为不可编辑。默认的流程图是只可以查看,如果想要修改流程图,除了节点 label 的信息可以修改以外,还需要支持可以修改连线信息。
$('#update').click(function(){
isNew = true;
$("#flow-main .node-common").each(function (idx, elem) {
var $elem = $(elem);
var id = $elem.attr('id')
jsPlumb.addEndpoint(id, { anchors: "BottomCenter" }, endpointStyle);
jsPlumb.addEndpoint(id, { anchors: "TopCenter" }, endpointStyle);
jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, endpointStyle);
jsPlumb.addEndpoint(id, { anchors: "LeftMiddle" }, endpointStyle);
jsPlumb.draggable(id);
$("#" + id).draggable({ containment: "parent",grid: [10, 10] });
that.nodeClick(id);
});
$("#flow-main .line-label").each(function (idx, elem) {
var $elem = $(elem);
var id = $elem.attr('id')
jsPlumb.draggable(id);
$elem.draggable({ containment: "parent" });
that.labelClick(id);
});
})
编辑的时候,因为页面中已经有了一部分节点,而 _index 变量的值,并没有变化。如果继续添加节点的时候,会出现 id 冲突的情况,所以,再添加节点之前,需要判断 id 是否存在。
判断节点是否存在的方法:
/**
* 防止节点id重复
* @params type Srting 节点类型
* @params num Number 当前顺序号
* @return id String 不重复的id
*/
judgeId: function(type,num){
var id = type + num;
var doms = $('#'+id)
if(doms.length != 0){
_index = num + 1;
return judgeId(type,_index);
}
return type + num;
},
除了保存编辑功能外,还需要支持根据已有的数据绘制流程图的功能。
/**
* 根据数据画流程图
* @params data Object 流程图数据
*/
draw:function(data){
var blockDoms = data.blocks;
blockDoms.forEach(function(item,index){
var dom = $(''+ item.blockContent +'')
dom.css("left", item.blockX).css("top",item.blockY);
dom.css("width", item.width).css("height",item.height);
var type = item.type;
switch (type) {
case "base":
dom.addClass('node-base');
break;
case "flow":
dom.addClass('node-flow');
break;
case "node":
dom.addClass('node-node');
break;
case "judge":
dom.addClass('node-judge');
break;
}
$('#flow-main').append(dom);
})
var connect = data.connects;
connect.forEach(function(item,index){
jsPlumb.ready(function(){
jsPlumb.connect({
source: item.pageSourceId,
target: item.pageTargetId,
anchor: [item.sourcePoint, item.targetPoint],
endpoint: ["Dot", { radius: 8 }],
connectorStyle: connectorPaintStyle,//连接线的颜色,大小样式
connectorHoverStyle: connectorHoverStyle,
paintStyle: { strokeStyle: "#000000",
fillStyle: "transparent",
radius: 2,
lineWidth: 2},
connector: ["Flowchart", { stub: [20, 30], gap: 5, cornerRadius: 3, alwaysRespectStubs: true }],
overlays: [["Arrow", { width: 10, length: 10, location: 1 }]],
endpointStyle: { fillStyle: 'transparent', strokeStyle: "#000000", lineWidth: 1 ,radius: 2,},
isSource: false,
isTarget: false
})
})
})
var lineDescs = data.lineDescs;
lineDescs.forEach(function(item,index){
var dom = $(''+ item.lineContent +'')
dom.css("left", item.lineX).css("top",item.lineY);
dom.css("width", item.width).css("height",item.height);
$('#flow-main').append(dom);
})
},
至此,流程图的基本功能已全部完成。
第一次写,基本功能实现,但是测试并不是十分充分,如果有问题,欢迎大家反馈,一起讨论。
项目地址:https://github.com/smile1828/demo-jsPlumb
基于 jsPlumb 的流程图编辑器的实现 (一,节点的操作)
基于 jsPlumb 的流程图编辑器的实现 (二,连接线的操作)
基于 jsPlumb 的流程图编辑器的实现 (三,document的操作)