• 【技术博客】基于JsPlumb和JQuery-UI的流程图的保存和再生成


    开发组在开发过程中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了。我们认为这样的经验是有必要记录下来的,因此就有了【技术博客】。


    基于JsPlumb和JQuery-UI的流程图的保存和再生成

    这篇技术博客基于软件工程课程的VisualPytorch之上,代码在一定程度上参考了https://www.cnblogs.com/sggx/p/3836432.html这篇博客。

    VisualPytorch项目链接如下:VisualPytorch

    前言-为什么要保存流程图

    对于这样一个类流程图或者模型图,用户会有保存、查看以及再编辑的需求,仅仅提供让用户拖拽连线的功能、让用户每次都从头搭建是会严重影响用户体验的,因此需要能够保存模型图。

    这篇博客主要用于提供思路,而非提供整套的解决方案,具体解决方案因人而异。

    如何保存流程图

    保存流程图是两方面的问题:

    (1)选定合适的保存格式

    (2)确保保存的信息足够来还原完整的图

    在保存时,我采用的是将整个图分为两个数组保存入数据库中。图主要由模块(开始、reshape层)和连线两部分组成,因此我选择将模块保存为一个json,而连线保存为数组。

    保存模块采用的主要方法

    $("#canvas").find(".node").each(function (index, element) {
            var id = $(element).attr('id');
            nets[id] = {
                "name": $(element).attr('name'),
                "attribute": eval('(' + window.localStorage.getItem(id) + ')'),
                "left": $(element).css('left'),
                "top": $(element).css('top')
            }
        });
    

    在画布中遍历所有的模块类,nets对象的标签为模块的id,而内容为需要保存的属性。需要注意的是,left与top属性必须保存,其相当于x,y坐标,用于还原时定位div的位置。

    保存连线采用的主要方法

    for (var i = 0; i < conn_list.length; i++) {
            var source_id = conn_list[i]["sourceId"];
            var target_id = conn_list[i]["targetId"];
            var conn = {
                "source": {
                    "id": source_id,
                    "anchor_position": conn_list[i]["endpoints"][0]["anchor"]["type"]
                },
                "target": {
                    "id": target_id,
                    "anchor_position": conn_list[i]["endpoints"][1]["anchor"]["type"]
                }
            };
            nets_conn.push(conn);
        }
    

    连线保存需要注意两个地方,首先是conn_list的获得,即如何得到目前的所有连线,这里我调用了JsPlumb中现有的接口

    conn_list = jsPlumb.getAllConnections()
    

    另一个地方时anchor_position。这里涉及到了JsPlumb的部分,在连线的时候,只有有anchor的地方才可以连线,为了复原整个图,我们需要记录下anchor的位置。

    如何复原流程图

    如何将保存的数据从数据库中取出不应该是本博客的内容,不多赘述。先贴上完整代码

     var structure = eval('(' + net_work["structure"] + ')');
                        var nets = structure['nets'];
                        var nets_conn = structure['nets_conn'];
                        var static_val = structure['static'];
                        var drop_function = $("#canvas").droppable('option', 'drop');
                        var event;
                        jQuery.each(nets, function (id, val) {
    
                            jsPlumb.ready(function () {
                                var ui = {
                                    'offset': {
                                        'left': parseInt(val['left'].split('px')) + $("#canvas").offset().left,
                                        'top': parseInt(val['top'].split('px')) + $("#canvas").offset().top
                                    },
                                    'draggable': [{
                                        "id": val['name'],
                                        "innerHTML": $("#" + val['name'])[0].innerHTML
                                    }],
                                    'id': id
                                };
                                drop_function(event, ui);
                            });
                            window.localStorage.setItem(id, JSON.stringify(val['attribute']));
                        });
                        jQuery.each(nets_conn, function (id, val) {
                            jsPlumb.ready(function () {
                                jsPlumb.connect({
                                    "source": val['source']['id'],
                                    "target": val['target']['id'],
                                    "anchors": [val['source']['anchor_position'], val['target']['anchor_position']],
                                    "endpoint": ["Dot", {radius: 5}],
                                    "paintStyle": {
                                        stroke: "#fc2f49",
                                        strokeWidth: 3,
    
                                    },
                                    "maxConnections": -1,
                                    "connector": ["Flowchart", {
                                        stub: [40, 60],
                                        gap: 5,
                                        cornerRadius: 5,
                                        alwaysRespectStubs: true
                                    }],
                                    "overlays": [["Arrow", { 10, length: 10, location: 1}]],
                                    "connectionsDetachable": true,
                                })
                            });
                        });
    

    代码看着很多,原理非常简单,就是把用户画图的操作再用js脚本做一遍。

    放置模块

    首先第一点,用户在拖拽div进入画布时,画布为droppable状态,会触发JQuery-UI 的drop事件。

    $("#canvas").droppable({
            scope: "ss",
            drop: function (event, ui) {
                .......
            }
    })
    

    第一段代码中的

     var drop_function = $("#canvas").droppable('option', 'drop')
    

    drop_function函数就对应了drop事件触发后执行的代码块。

    如此一来便很容易理解,只要让每个被保存的模块去触发drop事件即可,参数ui用保存的属性来自己构造,详情参照代码。

    重新连线

    重新连线部分,直接调用JsPlumb的连线方法

    jsPlumb.connect()
    

    即可。

    注意我们的anchor要选择之前保存的anchor。



  • 相关阅读:
    Java NIO -- 通道 Channel
    【RF库Collections测试】Convert To List
    【RF库Collections测试】Create Dictionary
    【RF库Collections测试】combine lists
    【RF库Collections库测试】关键字append to list
    【RF库测试】关键字get time
    【RF库测试】DateTime库
    linux 统计命令执行后的行数或者统计目录下文件数目
    grep 同时满足多个关键字和满足任意关键字
    【python】一次执行多个linux命令
  • 原文地址:https://www.cnblogs.com/1606-huluwa/p/10872754.html
Copyright © 2020-2023  润新知