web-dev-qa-db-ja.com

正確なアンカーと接続を含む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:

{"nodes":[{"blockId": "startpoint"、 "nodetype": "startpoint"、 "positionX":273、 "positionY":8}、{"blockId": "endpoint"、 "nodetype": "エンドポイント "、" 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}

これにより、要素の位置と接続の情報の一部を保存することができます。ここでload関数

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再びそれに)jsPlumb?

20
hbit

解決策については、これを参照してください JSFiddle

次のようにアンカーの詳細を保存する必要があります。これは、定義されたアンカー表現 ここ に準拠しています。マップ上で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
    });

  });

このソリューションでは、エンドポイントの形状やタイプなどのエンドポイントの詳細は保持されないことに注意してください。要求されたとおり、アンカーの詳細のみが保持されます。

23
Greg Ross