在 jsPlumb 上保存和加载流程图

发布于 2024-12-04 04:12:57 字数 68 浏览 1 评论 0 原文

jsPlumb 上保存和加载流程图的最佳方法是什么?

What's the best approach to save and load an flowchart on jsPlumb?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

单调的奢华 2024-12-11 04:12:57

我设法通过简单地将所有元素放在对象数组中来保存图表,其中每个对象都有目标节点、x、y 坐标

保存时,只需执行 JSON.stringify(whole_object),如果加载,只需 JSON.parse() 并手动定位节点并连接它们。

I managed to save the chart by simply having all the elements inside an array of objects, where each object has source and target nodes, x, y coordinates.

When saving, simply do JSON.stringify(whole_object), and if loading, simply JSON.parse() and manually position the nodes as well as connect them.

半夏半凉 2024-12-11 04:12:57

我的解决方案保存并加载 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 菜单项中列出)

My solution save and load 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 Demo: http://jsfiddle.net/Rra6Y/137/

Note: if demo does not work in JsFiddle, make sure it points to an existing jsPlumb link (links are listed in "External Resources" JsFiddle menu item

你不是我要的菜∠ 2024-12-11 04:12:57

我的保存功能不仅仅保存元素的 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 %}
    <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 上为此发布一个开源 Djago 应用程序。

My save functionality does a bit more than just save the x, y position of the element and its connections. I also added saving a connection Label overlay as well as custom text for each element. You can tailor this solution as per your requirements but here it is basically:

   //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;
    }

I initiate all this when the user hits the save button, an ajax call is made back to the server, in this case Django is intercepting the ajax request and saves the data to the database.

//ajax call when save button pressed
$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?

});

To load all this up is even easier and there are many ways you can do this. In Django you can just generate the html straight in your template as well as the js for the connections or you can create a JSON object in javascript for everything and then have javascript draw it all based on the array. I used jquery for this.

//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 %}

You can greatly simplify this but mine also gets a background for the element, as well as label and the shape of the element to use with perimeter anchors. This solution works and is tested. I'll release an open source Djago application for this soon on PyPi.

千里故人稀 2024-12-11 04:12:57

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

I'm using YUI with it. I'm saving the position of each box item being connected in a table. I them have a separate table the stores a parent to child relationship between the items, which is used to determine the lines jsPlumb should draw. I determine this using a selection process in which the first item selected is the parent, and all other items are children. When the "connect" button is clicked, the parent/child selection of the items is cleared. I also toggle this if you click the selected parent - it clear the child selections as well.

七秒鱼° 2024-12-11 04:12:57

我最近写了一篇关于为什么 jsPlumb 没有保存功能(以及我建议您做什么)的博客文章:

http://jsplumb.tumblr.com/post/11297005239/why-doesnt-jsplumb-offer-a-save-function

...也许有人会发现它有用。

I recently wrote this blog post about why jsPlumb doesn't have a save function (and what I recommend you do):

http://jsplumb.tumblr.com/post/11297005239/why-doesnt-jsplumb-offer-a-save-function

...maybe someone will find it useful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文