Как внедрить XML-представление вершины в существующий граф mxgraph

У меня возникла проблема при вставке новой вершины в существующий граф mxgraph.

Я могу сериализовать/десериализовать всю графовую модель, используя кодек по умолчанию. Однако я также хотел бы иметь возможность вводить отдельные вершины в существующий граф. Вершина представлена ​​в виде JSON-массива XML-строк mxgraph, где первый элемент является главной вершиной, а все последующие элементы — портами.

["<mxCell id=\"47\" style=\"Zerply\" vertex=\"1\" connectable=\"0\" parent=\"1\">
  <Object type=\"component\" label=\"Zerply\" attribute1=\"value1\" as=\"value\"/>
  <mxGeometry x=\"573\" y=\"224\" width=\"150\" height=\"110\" as=\"geometry\"/>
</mxCell>",

"<mxCell id=\"48\" style=\"ZerplyInputLeft\" vertex=\"1\" parent=\"47\">
  <Object type=\"port\" label=\"label 2\" attribute1=\"value1\" as=\"value\"/>
  <mxGeometry y=\"0.5\" width=\"10\" height=\"10\" relative=\"1\" as=\"geometry\">
    <mxPoint x=\"-5\" y=\"-5\" as=\"offset\"/>
  </mxGeometry>
</mxCell>",

"<mxCell id=\"49\" style=\"ZerplyOutputRight\" vertex=\"1\" parent=\"47\">
  <Object type=\"port\" label=\"label 2\" attribute1=\"value1\" as=\"value\"/>
  <mxGeometry x=\"1\" y=\"0.25\" width=\"10\" height=\"10\" relative=\"1\" as=\"geometry\">
    <mxPoint x=\"-5\" y=\"-5\" as=\"offset\"/>
  </mxGeometry>
</mxCell>",

"<mxCell id=\"50\" style=\"ZerplyOutputRight\" vertex=\"1\" parent=\"47\">
  <Object type=\"port\" label=\"label 2\" attribute1=\"value1\" as=\"value\"/>
  <mxGeometry x=\"1\" y=\"0.75\" width=\"10\" height=\"10\" relative=\"1\" as=\"geometry\">
    <mxPoint x=\"-5\" y=\"-5\" as=\"offset\"/>
  </mxGeometry>
</mxCell>"]

А вот простой код, чтобы попытаться внедрить вершину в граф:

var componentNode;                      
for (var i = 0; i < xmlArray.length; i++) {

    var mxXML = xmlArray[i];
    var xmlDocument = mxUtils.parseXml(mxXML);
    var decoder = new mxCodec(xmlDocument);
    var node = xmlDocument.documentElement;
    var newCell = decoder.decode(node);

    if (i == 0) {
        vertex = graph.insertVertex(root, null, newCell, x, y, 150, 110,
                this.dragElement.id);
        componentNode = vertex;
    } else {
        componentNode.insert(newCell);
    }

    vertex.connectable = 0;
}

Это успешно внедряет вершину (и ее подвершины/порты) в существующий граф. Проблема возникает, когда мы затем пытаемся сериализовать новый граф — мы получаем лишний дочерний узел в первой вершине:

<mxGraphModel>
  <root>
    <mxCell id="0"/>
    <mxCell id="1" parent="0"/>
    <mxCell id="2" style="Zerply" vertex="1" connectable="0">
      <Object type="component" label="Zerply" attribute1="value1" as="value"/>
      <mxGeometry x="573" y="224" width="150" height="110" as="geometry"/>
      **<mxCell style="Zerply" vertex="1" parent="1">
        <mxGeometry x="615" y="252" width="150" height="110" as="geometry"/>
      </mxCell>**
    </mxCell>
    <mxCell id="48" style="ZerplyInputLeft" parent="2" vertex="1">
      <Object type="port" label="label 2" attribute1="value1" as="value"/>
      <mxGeometry y="0.5" width="10" height="10" relative="1" as="geometry">
        <mxPoint x="-5" y="-5" as="offset"/>
      </mxGeometry>
    </mxCell>
    <mxCell id="49" style="ZerplyOutputRight" parent="2" vertex="1">
      <Object type="port" label="label 2" attribute1="value1" as="value"/>
      <mxGeometry x="1" y="0.25" width="10" height="10" relative="1" as="geometry">
        <mxPoint x="-5" y="-5" as="offset"/>
      </mxGeometry>
    </mxCell>
    <mxCell id="50" style="ZerplyOutputRight" parent="2" vertex="1">
      <Object type="port" label="label 2" attribute1="value1" as="value"/>
      <mxGeometry x="1" y="0.75" width="10" height="10" relative="1" as="geometry">
        <mxPoint x="-5" y="-5" as="offset"/>
      </mxGeometry>
    </mxCell>
  </root>
</mxGraphModel>

Я подхожу к этому неправильно? .. или это похоже на ошибку?


person user2788873    schedule 17.09.2013    source источник


Ответы (2)


Вот моя функция «вставить», которая работает:

                                // deserialize cells
                                var doc = mxUtils.parseXml(decodeURIComponent(serializedCells));

                                var codec = new mxCodec(doc);

                                var cells = new Array();
                                for (var i = 0; i < doc.documentElement.childNodes.length; i++) {
                                    cells[i] = codec.decodeCell(doc.documentElement.childNodes[i]);
                                }

                                // import cells into the graph
                                var delta = mxClipboard.insertCount * mxClipboard.STEPSIZE;
                                var parent = graph.getDefaultParent();

                                graph.model.beginUpdate();
                                try
                                {
                                  for (var i = 0; i < cells.length; i++)
                                  {
                                    cells[i] = graph.importCells([cells[i]], delta, delta, parent)[0];
                                  }
                                }
                                finally
                                {
                                  graph.model.endUpdate();
                                }

                                // Increments the counter and selects the inserted cells
                                mxClipboard.insertCount++;
                                graph.setSelectionCells(cells);

Не обращайте внимания на mxClipboard.insertCount, я использую его для увеличения смещения вставки, когда пользователь нажимает «Вставить» несколько раз.

serializedCells — это закодированная в HTML строка XML (сериализованная из javascript Array() из mxCell).

К каждой из моих ячеек прикреплен пользовательский объект, поэтому я использую decodeCell() — эта функция выполняет инверсию узлов xml пользовательского объекта по сравнению с узлами mxCell.

Затем я импортирую каждую ячейку с помощью graph.importCells().

Я использую graph.model.beginUpdate() и .endUpdate(), так как разрешаю функцию "отменить".

setSelectionCells() выбирает вставленные ячейки.

person HuGo    schedule 02.10.2013

person    schedule
comment
Пожалуйста, хотя бы напишите несколько слов в своем ответе, а не просто публикуйте код. - person EluciusFTW; 18.01.2017