在jsPlumb上保存并加载流程图
在jsPlumb上保存和加载流程图的最佳方法是什么?
我设法通过简单地将所有元素放在一个对象数组中来保存图表,其中每个对象都有源 节点和目标节点,x,y坐标 。
保存时,只需执行JSON.stringify(whole_object)
,如果加载,只需JSON.parse()
并手动定位节点并连接它们。
我的解决方案保存并加载jsPlumb:
function Save() { $(".node").resizable("destroy"); Objs = []; $('.node').each(function() { Objs.push({id:$(this).attr('id'), html:$(this).html(),left:$(this).css('left'),top:$(this).css('top'),width:$(this).css('width'),height:$(this).css('height')}); }); console.log(Objs); } function Load() { var s=""; for(var i in Objs) { var o = Objs[i]; console.log(o); s+=' '+ o.html+''; } $('#main').html(s); }
UPD演示: http : //jsfiddle.net/Rra6Y/137/
注意:如果demo在JsFiddle中不起作用,请确保它指向现有的jsPlumb链接(链接列在“外部资源”JsFiddle菜单项中
我的保存function不仅仅是保存元素及其连接的x,y位置。 我还添加了保存连接标签覆盖以及每个元素的自定义文本。 您可以根据您的要求定制此解决方案,但这里基本上是:
//save functionality function IterateDrawnElements(){ //part of save var dict = {}; $('#id_diagram_container').children('div.window').each(function () { var pos = $(this).position() var diagram_label = $(this).children('div.asset-label').children('div.asset-diagram-label').text() if (diagram_label == null || diagram_label == ''){ diagram_label=''; } dict[this.id] = [pos.left, pos.top, diagram_label]; }); return dict; } function IterateConnections(){ //part of save var list = []; var conns = jsPlumb.getConnections() for (var i = 0; i < conns.length; i++) { var source = conns[i].source.id; var target = conns[i].target.id; try{ var label = conns[i].getOverlay("label-overlay").labelText; } catch(err) { label = null } //list.push([source, target]) if (source != null && target != null){ list.push([source, target, label]); }; } return list; }
当用户点击保存按钮时,我启动所有这一切,ajax调用返回到服务器,在这种情况下,Django拦截ajax请求并将数据保存到数据库。
//按下保存按钮时调用ajax $ save_btn.click(function(){
//drawn elements var d_elements = IterateDrawnElements(); var d_conns = IterateConnections(); var d_name =$('#id_diagram_name').val(); $.ajax({ url : ".", type : "POST", dataType: "json", data : { drawn_elements: JSON.stringify(d_elements), conns: JSON.stringify(d_conns), diagram_name: d_name, csrfmiddlewaretoken: '{{ csrf_token }}' }, success: function (result) { if (result.success == true){ save_status.html(result.message) } //console.log(JSON.stringify(result)); $save_btn.attr('disabled','disabled'); if (result.old_name != false){ //alert() $('#id_diagram_name').val(result.old_name) } }, error: function(xhr, textStatus, errorThrown) { alert("Please report this error: "+errorThrown+xhr.status+xhr.responseText); } }); //return false; // always return error?
});
加载所有这些更容易,有很多方法可以做到这一点。 在Django中,您可以直接在模板中生成html以及连接的js,或者您可以在javascript中为所有内容创建JSON对象,然后让javascript根据数组绘制它。 我用jquery这个。
//js & connections load var asset_conns = [ {% for conn in diagram_conns %} [ {{ conn.source.id }}, {{ conn.target.id }}, '{{ conn.name }}' ], {% endfor %} ] // Takes loaded connections and connects them for (var i = 0; i< asset_conns.length; i++){ var source = asset_conns[i][0].toString(); var target = asset_conns[i][1].toString(); var label = asset_conns[i][2]; var c = jsPlumb.connect({source: source, target: target, detachable:true, reattach: true }); //on init already know what kind of anchor to use! if (label != null && label != 'None'){ c.addOverlay([ "Label", { label: label, id:"label-overlay"} ]); } } //html right into django template to draw elements, asset element interchangeable terms {% for element in drawn_elements %} {#{{ element.asset }}#}{{ element.asset }} {% if element.asset.diagram_label %}{{ element.asset.diagram_label }}{% endif %} {% endfor %}
你可以大大简化这个,但我也得到了元素的背景,以及用于周边锚点的元素的标签和形状。 该解决方案有效并经过测试。 我将很快在PyPi上发布一个开源的Djago应用程序。
我最近写了这篇博文,讲述为什么jsPlumb没有保存function(我建议你这样做):
http://jsplumb.tumblr.com/post/11297005239/why-doesnt-jsplumb-offer-a-save-function
……也许有人会发现它很有用。
我正在使用YUI。 我正在保存表格中连接的每个箱子项目的位置。 我他们有一个单独的表存储父项与子项之间的关系,这用于确定jsPlumb应该绘制的行。 我使用选择过程确定这一点,其中选择的第一个项目是父项目,所有其他项目是子项目。 单击“连接”按钮时,将清除项目的父/子选择。 如果您单击所选父项,我也会切换此项 – 它也会清除子项选择。