在jsPlumb上保存和加载流程图

11

如何在jsPlumb中保存和加载流程图的最佳方法是什么?


1
https://dev59.com/xmIj5IYBdhLWcg3wHhpX - Amit Kumar Gupta
5个回答

9
我成功地保存了这个图表,只需将所有元素放入一个对象数组中,每个对象具有源节点和目标节点、x和y坐标
要保存,请使用JSON.stringify(whole_object),如果要加载,请使用JSON.parse()并手动定位节点以及连接它们。

你能分享一些代码吗?我对如何加载和连接它们感到困惑。 - coding_idiot
哦..那是很久以前的事了,但据我所记,只需通过JSON.stringify(objectCollection)保存数据即可。其中包括关系、位置等信息。现在当您想要加载时,使用JSON.parse(generatedStrnig),然后手动遍历对象中的每个节点并定位它们(使用CSS),并连接它们(使用jsPlumb API)。抱歉,我记不太清楚了 :) - lukas.pukenis

7

我的解决方案是保存和加载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+='<div id="'+ o.id+'" class="node" style="left:'+ o.left+'; top:'+ o.top+'; width:'+ o.width +'; height:'+ o.height +' "> '+ o.html+'</div>';
    }
    $('#main').html(s);
}

UPD演示:http://jsfiddle.net/Rra6Y/137/

注意:如果演示在JsFiddle中无法工作,请确保它指向一个现有的jsPlumb链接(链接列在“外部资源”JsFiddle菜单项中)。


你好,感谢这些提示。我正在尝试使用jsplumb创建一个在线有限状态机设计师,并且为了正确保存/加载,我需要传递比您添加到我的数组中的html更多的数据。例如“状态名称”,“连接到”等等。你知道,一些东西可以实际保存我的“状态机”,而不仅仅是我的“绘图”。您是否对如何实现此功能有提示?那太棒了! - Dominik
1
jsfiddle链接无法使用。无法拖动,也无法创建连接。保存、加载和清除时控制台中出现了错误。 - coding_idiot

4

我的保存功能不仅保存元素的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对象来处理所有内容,然后根据数组绘制所有内容。我使用了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 %}
    <div id="{{ element.asset.id }}" class="window" style="left:{{ element.left }}px;top:{{ element.top }}px;background-image: url('{% static element.asset.asset_mold.image.url %}'); width: {{ element.asset.asset_mold.image.width }}px;height: {{ element.asset.asset_mold.image.height }}px;">
        <div class="asset-label" id="label-{{ element.asset.id }}">
            {#{{ element.asset }}#}<a class="lbl-link" id="lbl-link-{{ element.asset.id }}" href="{{ element.asset.get_absolute_url }}">{{ element.asset }}</a>
            <div class='asset-diagram-label' id="lbl-{{ element.asset.id }}">{% if element.asset.diagram_label  %}{{ element.asset.diagram_label }}{% endif %}</div>
        </div>
        <div class='ep' id="ep-{{ element.asset.id }}"></div>
    </div>
{% endfor %}

你可以大大简化这个过程,但我的方法还会为元素提供背景、标签和形状,以便与周长锚一起使用。这个解决方案已经经过测试并且可行。我很快就会在PyPi上发布一个开源的Django应用程序。


0

6
人们想要的是一种简单的方法来表示:将这个图表持久化为XML/JSON,或以其他易于解析和映射到数据模型的方式保存它... 这似乎是一个很明显的可用性需求。看起来你在这里概述的内容会使我需要采取很多烦人的额外步骤才能按照自己的方式实现这个目标。 - Brian MacKay

0

我正在使用YUI。我将每个连接的盒子项的位置保存在一个表中。然后,我有一个单独的表格,用于存储项目之间的父子关系,这用于确定jsPlumb应绘制的线条。我使用选择过程来确定这一点,在该过程中,选择的第一项是父项,所有其他项都是子项。当单击“连接”按钮时,清除项目的父/子选择。如果单击所选父项,则也会切换此选项-它还会清除子项选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接