保存并加载jsPlumb流程图,包括精确的锚点和连接 [英] Save and Load jsPlumb flowchart including exact anchors and connections

查看:2962
本文介绍了保存并加载jsPlumb流程图,包括精确的锚点和连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我正在构建的流程图编辑器的。



为此,我添加了保存和加载按钮,用于将流程图导出/导入JSON(保存后显示在jsFiddle中的textform中 - 相同textform可用于加载)。



保存功能

  function saveFlowchart(){
var nodes = []
$(。node)。each(function(idx,elem){
var $ elem = $(elem);
var endpoints = jsPlumb.getEndpoints($ elem.attr('id'));
console.log('+ $ elem.attr('id')的端点);
console。 log(端点);
nodes.push({
blockId:$ elem.attr('id'),
nodetype:$ elem.attr('data-nodetype'),
positionX:parseInt($ elem.css(left),10),
positionY:parseInt($ elem.css(top),10)
});
});
var connections = [];
$ .each(jsPlumb.getConnections(),function(idx,connection){
connections.push({
connectionId:connection.id,
pageSourceId:connection.sourceId,
pageTargetId:connection.targetId
});
});

var flowChart = {};
flowChart.nodes = nodes;
flowChart.connections = connections;
flowChart.numberOfElements = numberOfElements;

var flowChartJson = JSON.stringify(flowChart);
//console.log(flowChartJson);

$('#jsonOutput')。val(flowChartJson);
}

以上示例生成的JSON:


{nodes:[{blockId:startpoint,nodetype:startpoint,positionX:273,positionY:8}, { 块标识: 终点, NODETYPE: 终点, 位X:310, 位置▲:385},{ 块标识: taskcontainer1, NODETYPE: 任务, 位X :381, 位置▲:208},{ BLOCKID: decisioncontainer2, NODETYPE: 决定, 位X:261, 位置▲:103}], 连接:[{ 的ConnectionId : con_18, pageSourceId: decisioncontainer2, pageTargetId: taskcontainer1},{ 的ConnectionId: con_25, pageSourceId: taskcontainer1, pageTargetId: 端点},{的ConnectionId : con_32\" , pageSourceId: decisioncontainer2, pageTargetId: 端点},{ 的ConnectionId: con_46, pageSourceId: 起始点, pageTargetId: decisioncontainer2}] ,numberOfElements:2}


凭借这一点,我可以保存元素的位置以及部分信息。连接纳秒。
这里的加载函数

  function loadFlowchart(){
var flowChartJson = $('#jsonOutput')。val();
var flowChart = JSON.parse(flowChartJson);
var nodes = flowChart.nodes;
$ .each(nodes,function(index,elem){
if(elem.nodetype ==='startpoint'){
repositionElement('startpoint',elem.positionX,elem。 positionY);
} else if(elem.nodetype ==='endpoint'){
repositionElement('endpoint',elem.positionX,elem.positionY);
} else if(elem) .nodetype ==='task'){
var id = addTask(elem.blockId);
repositionElement(id,elem.positionX,elem.positionY);
} else if(elem) .nodetype ==='decision'){
var id = addDecision(elem.blockId);
repositionElement(id,elem.positionX,elem.positionY);
} else {

}
});

var connections = flowChart.connections;
$ .each(connections,function(index,elem){
var connection1 = jsPlumb.connect({
source:elem.pageSourceId,
target:elem.pageTargetId,
anchors:[BottomCenter,[0.75,0,0,-1]]

});
});

numberOfElements = flowChart.numberOfElements;
}

但是,锚点和连接的确切位置会丢失。同样的例子,删除元素然后加载导出的JSON后的结果:





由于我还没有存储信息,这并不是一个大惊喜。但我现在陷入困境。



我的问题是:我需要存储哪些关于锚点/连接器位置的信息流程图设计以及我如何从中提取它(并再次加载到它中)jsPlumb?

解决方案

看到这个JSFiddle 获得解决方案。



您需要按如下方式保存锚点详细信息。这符合此处定义的Anchor表示。注意双嵌套以避免JQuery在地图上自动展平。

  $ .each(jsPlumb.getConnections(),function (idx,connection){
connections.push({
connectionId:connection.id,
pageSourceId:connection.sourceId,
pageTargetId:connection.targetId,
anchors :$ .map(connection.endpoints,function(endpoint){

return [[endpoint.anchor.x,
endpoint.anchor.y,
endpoint.anchor.orientation [0],
endpoint.anchor.orientation [1],
endpoint.anchor.offsets [0],
endpoint.anchor.offsets [1]]];

})
});
});

...并加载它们,如下所示:

  $ .each(connections,function(index,elem){
var connection1 = jsPlumb.connect({
source:elem.pageSourceId,
target:elem.pageTargetId,
anchors:elem.anchors
});

});

请注意,此解决方案不会保留端点详细信息,包括端点的形状和类型。它只根据您的要求保留锚点详细信息。


This is the jsFiddle of the flowchart editor I am building.

This is an example of what can be easily created with "Add Decision" + "Add Task", connecting and moving the elements.

Now for the hard part: I want to be able to save and load the exact flowchart. For this I got started based with a similar thread here at Stackoverflow.

For this I added the "Save" and "Load" buttons that export/import the flowchart to/from JSON (shown in a textform in the jsFiddle after save - same textform can be used for loading).

The save function:

function saveFlowchart(){
            var nodes = []
            $(".node").each(function (idx, elem) {
            var $elem = $(elem);
            var endpoints = jsPlumb.getEndpoints($elem.attr('id'));
            console.log('endpoints of '+$elem.attr('id'));
            console.log(endpoints);
                nodes.push({
                    blockId: $elem.attr('id'),
                    nodetype: $elem.attr('data-nodetype'),
                    positionX: parseInt($elem.css("left"), 10),
                    positionY: parseInt($elem.css("top"), 10)
                });
            });
            var connections = [];
            $.each(jsPlumb.getConnections(), function (idx, connection) {
                connections.push({
                    connectionId: connection.id,
                    pageSourceId: connection.sourceId,
                    pageTargetId: connection.targetId
                });
            });

            var flowChart = {};
            flowChart.nodes = nodes;
            flowChart.connections = connections;
            flowChart.numberOfElements = numberOfElements;

            var flowChartJson = JSON.stringify(flowChart);
            //console.log(flowChartJson);

            $('#jsonOutput').val(flowChartJson);
        }

The resulting JSON of the example above:

{"nodes":[{"blockId":"startpoint","nodetype":"startpoint","positionX":273,"positionY":8},{"blockId":"endpoint","nodetype":"endpoint","positionX":310,"positionY":385},{"blockId":"taskcontainer1","nodetype":"task","positionX":381,"positionY":208},{"blockId":"decisioncontainer2","nodetype":"decision","positionX":261,"positionY":103}],"connections":[{"connectionId":"con_18","pageSourceId":"decisioncontainer2","pageTargetId":"taskcontainer1"},{"connectionId":"con_25","pageSourceId":"taskcontainer1","pageTargetId":"endpoint"},{"connectionId":"con_32","pageSourceId":"decisioncontainer2","pageTargetId":"endpoint"},{"connectionId":"con_46","pageSourceId":"startpoint","pageTargetId":"decisioncontainer2"}],"numberOfElements":2}

With that I am able to save the position of the elements as well as part of the information of the connections. Here the load function:

function loadFlowchart(){
            var flowChartJson = $('#jsonOutput').val();
            var flowChart = JSON.parse(flowChartJson);
            var nodes = flowChart.nodes;
            $.each(nodes, function( index, elem ) {
                if(elem.nodetype === 'startpoint'){
                    repositionElement('startpoint', elem.positionX, elem.positionY);
                }else if(elem.nodetype === 'endpoint'){
                    repositionElement('endpoint', elem.positionX, elem.positionY);
                }else if(elem.nodetype === 'task'){
                    var id = addTask(elem.blockId);
                    repositionElement(id, elem.positionX, elem.positionY);
                }else if(elem.nodetype === 'decision'){
                    var id = addDecision(elem.blockId);
                    repositionElement(id, elem.positionX, elem.positionY);
                }else{

                }
            });

            var connections = flowChart.connections;
            $.each(connections, function( index, elem ) {
                 var connection1 = jsPlumb.connect({
                    source: elem.pageSourceId,
                    target: elem.pageTargetId,
                    anchors: ["BottomCenter", [0.75, 0, 0, -1]]

                });
            });

            numberOfElements = flowChart.numberOfElements;
        }

However, the exact position of the anchors and connections are lost. Same example again, the result after deleting the elements and then loading the exported JSON:

This comes not as a big surprise as I have not yet stored the information. But I am stuck at this point.

My question is: which information regarding the anchors/connectors position do I need to store for the whole flowchart design and how I can extract it from (& load into it again) jsPlumb?

解决方案

See this JSFiddle for a solution.

You need to save the anchor details as follows. This conforms to the Anchor representation defined here. Note the double nesting to avoid the JQuery auto-flatten on the map.

    $.each(jsPlumb.getConnections(), function (idx, connection) {
      connections.push({
      connectionId: connection.id,
      pageSourceId: connection.sourceId,
      pageTargetId: connection.targetId,
      anchors: $.map(connection.endpoints, function(endpoint) {

        return [[endpoint.anchor.x, 
        endpoint.anchor.y, 
        endpoint.anchor.orientation[0], 
        endpoint.anchor.orientation[1],
        endpoint.anchor.offsets[0],
        endpoint.anchor.offsets[1]]];

      })
    });
  });

...and load them, as follows:

    $.each(connections, function( index, elem ) {
     var connection1 = jsPlumb.connect({
      source: elem.pageSourceId,
      target: elem.pageTargetId,
      anchors: elem.anchors
    });

  });

Note that this solution does not preserve end-point details including the shape and type of end-points. It only preserves the anchor details, as you requested.

这篇关于保存并加载jsPlumb流程图,包括精确的锚点和连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆