Javascript 保存并加载jsPlumb流程图,包括精确的锚固件和连接件

Javascript 保存并加载jsPlumb流程图,包括精确的锚固件和连接件,javascript,json,save,flowchart,jsplumb,Javascript,Json,Save,Flowchart,Jsplumb,这是我正在构建的流程图编辑器的最新版本 这是一个通过“添加决策”+“添加任务”、连接和移动元素可以轻松创建的示例 现在来看最难的部分:我希望能够保存并加载准确的流程图。为此,我从Stackoverflow的一个网站开始 为此,我添加了“保存”和“加载”按钮,用于将流程图导出到JSON或从JSON导入流程图(保存后以JSFIDLE中的文本形式显示-加载时可以使用相同的文本形式) 保存功能: function saveFlowchart(){ var nodes = []

这是我正在构建的流程图编辑器的最新版本

这是一个通过“添加决策”+“添加任务”、连接和移动元素可以轻松创建的示例

现在来看最难的部分:我希望能够保存并加载准确的流程图。为此,我从Stackoverflow的一个网站开始

为此,我添加了“保存”和“加载”按钮,用于将流程图导出到JSON或从JSON导入流程图(保存后以JSFIDLE中的文本形式显示-加载时可以使用相同的文本形式)

保存功能

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);
        }
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:

{“nodes”:[{“blockId”:“startpoint”,“nodetype”:“startpoint”,“positionX”:273,“positionY”:8},{“blockId”:“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”:“decisioncontainer2”,“pageTargetId”:“endpoint”},{“connectionId”:“con 46”,“pageSourceId”:“startpoint”,“pageTargetId”:”:“decisioncontainer2”}],“numberOfElements”:2}

这样我就可以保存元素的位置以及连接的部分信息。 这里是加载功能:

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);
        }
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中提取(再次加载)锚/连接器位置?

请参见此以获取解决方案

您需要按如下方式保存锚定细节。这符合定义的锚定表示。请注意双重嵌套以避免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
    });

  });

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

非常感谢,效果非常好。我接受此答案,并在此处进行了快速编辑,其中包括端点的绘制样式,以便也保留格式。何时开始您保存并加载,未附加的重复项也会出现?@hbit我找不到您为保存和恢复端点的绘制和样式所做的编辑。请共享代码好吗?我尝试过,但我想我遗漏了一些内容。这对我不起作用。您获得上面的getConnections()了吗要工作吗?如果有一个好的
jsPlumb.jsonify()
函数就太棒了,但这是第二个最好的东西。