16

I created a shape in draw.io and exported it to get its XML file, which looks like this:

<mxlibrary>[{"xml":"vZTNcoIwEMefJnckXjxarF7aXvoEKawk05Blwirap+8SooLa0XbaZoaZ7H8/sssPImRW7VZe1foZC7BCPgqZeUTqd9UuA2tFmphCyIVI04QfkS6/8E6CN6mVB0f3JKR9wlbZDfRKLzS0t1EoPW5qIR88kiL1FuSE7ZgJnmA3Oj1H5yA/hB5bGHUVQmNLK8AKyO85pDUF6Rgxi2kaTKkPaTKKqonNHXNPQ/Imznl9Znkx8wsSNBeD89yugCKO22pD8FqrvPO2DIw1TRUfspjwttGqwPZgkMd3yNCiD6VkFhZ71sbagT4Lq9PR0UBfhsW6sqZ0rFlYU1eYzzeufArWYtpRgcZ8DKhUuB1YUJghsjGZJNS32M69x7aJyt2YhzjTn+H8DZrT21/wX4A8A9O9H5MrO48yYX0V1xjPObz/5rMfY7j59yXf58Xm6TYLvtFl9wk=","w":190,"h":130,"aspect":"fixed","title":"notes"}]</mxlibrary>

Is it possible to insert a new vertex using this data? I don't even know where to begin on this one.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
dyarbrough
  • 771
  • 2
  • 8
  • 14

3 Answers3

18

You're looking at the XML compressed using the Deflate compression algorithm. Clearly you'll want to uncompress it prior to working with it.

JGraph, creators of the excellent Draw.io drawing/diagramming application, provide an online decompression conversion tool. Here's the mxGraphModel associated with your compressed data after uncompressing it with that tool:

<mxGraphModel>
  <root>
    <mxCell id="0"/>
    <mxCell id="1" parent="0"/>
    <mxCell id="2" value="" style="group;rotatable=0;" vertex="1" connectable="0" parent="1">
      <mxGeometry width="190" height="130" as="geometry"/>
    </mxCell>
    <mxCell id="3" value="Notes" style="rounded=0;whiteSpace=wrap;html=1;shadow=1;strokeColor=#CCCCCC;fillColor=#999999;fontColor=#FFFFFF;align=left;spacingLeft=4;resizable=0;movable=0;editable=0;connectable=0;allowArrows=0;rotatable=0;" vertex="1" parent="2">
      <mxGeometry width="190" height="30" as="geometry"/>
    </mxCell>
    <mxCell id="4" value="" style="rounded=0;whiteSpace=wrap;html=1;shadow=1;strokeColor=#CCCCCC;align=left;verticalAlign=top;spacingLeft=4;movable=0;resizable=0;connectable=0;allowArrows=0;rotatable=0;" vertex="1" parent="2">
      <mxGeometry y="30" width="190" height="100" as="geometry"/>
    </mxCell>
  </root>
</mxGraphModel>

See also Extracting the XML from mxfiles on the Draw.io site.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • Ok, but I'm still not sure how to use this. The documentation is pretty sparse; are there any examples out there? – dyarbrough Dec 19 '19 at 21:05
  • 1
    Just add a vertex manually in the program, save the XML, and compare the difference between the *before* and the *after* XML. That will tell you exactly how the XML must be changed to add the vertex you want. Then, write code to update the XML using your favorite programming language such as XSLT, JavaScript, Prolog, etc -- standard XML programming at that point. Recompress as needed. – kjhughes Dec 19 '19 at 21:10
  • Alternatively, use their JS API. A shape has an array of points into which you can add another: [`mxShape.prototype.points`](https://jgraph.github.io/mxgraph/docs/js-api/files/shape/mxShape-js.html#mxShape.points) – kjhughes Dec 19 '19 at 21:21
  • Is there not an API that just allows me to add a shape based on the XML? I haven't been able to find one. I don't know what you mean by your first comment. You mean using graph.insertVertex? I'm sorry I'm new to mxgraph and having a hard time :/ – dyarbrough Dec 20 '19 at 16:35
  • You can either write generic XML processing code (using whatever language suits you) against the XML outside of their API, or you can use their JS API against their JS structures. – kjhughes Dec 20 '19 at 17:13
7

I know the question has already been answered, but I'll pass the tip of what helped me. In draw.io you go to the File menu and then to Properties, you have the option to disable compression. So when saving the xml it will be more readable and easier to edit.

Gustavo Rossi Muller
  • 1,062
  • 14
  • 18
3

Finally got this working. Check out the mxCodec example here. So first, get the uncompressed xml for the node either as described by kjhughes or via the Extras -> Edit Diagram menu in Draw.io. Then you can add the node like so:

var xml = '<root><mxCell id="2" value="Hello," vertex="1"><mxGeometry x="20" y="20" width="80" height="30" as="geometry"/></mxCell><mxCell id="3" value="World!" vertex="1"><mxGeometry x="200" y="150" width="80" height="30" as="geometry"/></mxCell><mxCell id="4" value="" edge="1" source="2" target="3"><mxGeometry relative="1" as="geometry"/></mxCell></root>';
var doc = mxUtils.parseXml(xml);
var codec = new mxCodec(doc);
var elt = doc.documentElement.firstChild;
var cells = [];

while (elt != null)
{
  cells.push(codec.decode(elt));
  elt = elt.nextSibling;
}

graph.addCells(cells);

Replace xml with whatever the xml for your node is. Also, be sure not to include

<mxCell id="0"/>
<mxCell id="1" parent="0"/>

as these are the default parents and their inclusion will break the graph by causing infinite recursion.

dyarbrough
  • 771
  • 2
  • 8
  • 14