Сохраните и загрузите блок-схему jsPlumb, включая точные привязки и соединения

Это jsFiddle редактора блок-схем, который я создаю.

Это пример того, что можно легко создать с помощью "Добавить решение" + "Добавить задачу", соединяя и перемещая элементы.

Example flowchart - user configured

Теперь для жесткой части: я хочу иметь возможность сохранять и загружать точную блок-схему. Для этого я начал работать с подобным потоком здесь, в Stackoverflow.

Для этого я добавил кнопки "Сохранить" и "Загрузить", которые экспортируют/импортируют блок-схему в/из JSON (отображается в текстовой форме в jsFiddle после сохранения - для загрузки может использоваться тот же текстовый формат).

Функция сохранить:

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

Полученный JSON примера выше:

{ "узлы": [{ "blockId": "StartPoint" , "NodeType" : "StartPoint" , "Позиция X": 273, "Позиция Y": 8}, { "blockId": "конечной точки" , "NodeType" : "конечная точка", "Позиция X": 310, "Позиция Y": 385}, { "blockId": "taskcontainer1" , "NodeType" : "задача", "Позиция X": 381, "Позиция Y": 208}, { "blockId": "decisioncontainer2" , "NodeType" : "решение", "Позиция X": 261, "Позиция Y": 103}], "соединение": [{ "ConnectionID": "con_18", "pageSourceId": "decisioncontainer2" , "pageTargetId": "taskcontainer1" }, { "ConnectionID": "con_25", "pageSourceId": "taskcontainer1" , "pageTargetId": "конечной точки" }, { "ConnectionID": "con_32", "pageSourceId": "decisioncontainer2" , "pageTargetId": "конечной точки" }, { "ConnectionID": "con_46", "pageSourceId": "StartPoint" , "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:

Flowchart after loading JSON

Это не является большим сюрпризом, поскольку я еще не сохранил информацию. Но я застрял в этой точке.

Мой вопрос:, какую информацию относительно положения якорей/коннекторов нужно сохранить для всего проекта блок-схемы и как я могу извлечь его из (& load in it again) jsPlumb?

Ответы

Ответ 1

См. 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
    });

  });

Обратите внимание, что это решение не сохраняет детали конечной точки, включая форму и тип конечных точек. Он только сохраняет анкеры, как вы просили.