Pre-release - MIT - your file stays local
Any SVG, a diagram you can edit.
draw.io opens an SVG file as one flat image. accent-draw opens it as a diagram. Each box is a box, each label is in its box, and each arrow connects the two shapes at its ends. Open the demo, select a file, and edit the result.
$
accent-draw board.svg board.drawio
The pipeline
Five stages, each with one job
It is easy to show a drawing again. It is difficult to find the diagram in it. An SVG file says "a rectangle here, some text there, a path with an arrowhead". draw.io must know "this box, with this label, and an arrow from it to that box". A usual SVG file does not tell which text is the label of which box. One stage finds this, and you can test that stage alone.
-
recognise
Some sources give names to their parts: Miro, Mermaid, Graphviz, PlantUML, D2, Excalidraw and Inkscape. accent-draw reads these names. An SVG file that contains a draw.io diagram goes back without a change.
-
parse
The parser reads all other parts of the SVG: the style rules, the transforms, the viewBox, nested svg elements, use and defs, and the units. A rectangle stays a rectangle, and an arrowhead stays an arrowhead.
-
scene
The scene is a list of shapes, text, arrows, frames and groups. It contains no draw.io data. A test checks each file in the corpus against the rules of the scene.
-
layout
The layout finds what the source did not tell. It finds the label of each box, the frame around other shapes, and the shapes at the ends of each arrow. It adds only the data that the source did not give. It does not change what a profile read.
-
emit
The emitter writes the scene as an mxGraphModel. The cell ids are stable and all numbers have one format. Thus the same input gives the same bytes, and a change gives a diff that you can read.
Measured
Four numbers that support this page
We took each number from this repository. We did not make the numbers larger for this page. The numbers are the profiles and the tests that run for each change. They are also the size of the file that your browser downloads, and the data that the page sends.
What you get
What the conversion does
The list is short. We made the code around each item on it.
Each box keeps its label, and each arrow keeps its boxes
When you move a box in draw.io, its label moves with it. The label is part of the cell, not a separate text box on top of it. The arrows also move with the box. Each connected arrow has the fixed points exitX/exitY and entryX/entryY. Without these points, draw.io gives the arrow a new route, and the arrow loses its route from the source.
Eight sources, read by name
When a source gives names to its parts, accent-draw reads the names and does not guess. It reads a Miro board item by item. It reads a Mermaid flowchart and a Graphviz drawing by the names on their nodes and edges. It reads an Excalidraw file from the scene in the file, not from the sketch. The parser reads the parts that a profile does not name.
Each change is in a note
Some parts cannot become a draw.io cell: a filter, a mask or a pattern. Each of these parts becomes an image, and a note in the result tells you about it. An SVG file that contains no shape, text or arrow causes an error. You do not get an empty diagram that looks correct.
The second round trip loses nothing
The first conversion is an approximation, and it will always be one. But draw.io can export a .drawio.svg file, which contains the diagram. accent-draw does not convert the image in such a file. It gives back the diagram in the file, compressed or not. Thus each round trip after the first is exact.
It runs where you are
The library does not use files, the clock, random numbers or threads. Thus the same code is a command for a shell script and a WebAssembly module in a web page. The demo on this site uses the WebAssembly module. Your browser downloads the converter one time, and your file stays in the browser tab.
The same bytes each time
The cell ids are stable and all numbers have one format. Thus two conversions of the same SVG file give the same file, and a diff shows a real change. The browser and the command line give the same result. For each change, a test converts the corpus with both and compares the bytes.
Why this is difficult
A Miro export gives the structure to the reader. Each item on the board is a group, and each group has the id of its item. Thus a Miro reader can be exact. But for the same reason, a Miro reader does not work on other files. The Miro reader in this repository read a plain SVG file with a rectangle, a circle and some text. It wrote an empty diagram and told you that the conversion was correct.
For other files, accent-draw must find the structure from the positions of the parts. Some shapes are on top of other shapes: which shape is the box, and which is its border? An outline has no fill: is it a frame, or only a line in the drawing? The stroke of an arrow stops before its arrowhead: which of two near boxes does the arrow touch?
These decisions cause most errors. Thus one stage makes all of them. Each limit in that stage changes with the font size or the stroke width. No limit is a fixed number of pixels. A corpus of real exports tests the stage.
draw.io has its own rules. A <b> tag in a label removes the color of the label.
draw.io moves a connected arrow to a new route if the arrow has no fixed points.
A label is at the center if the style does not tell a different position. A
label also has two units of space on each side.
You cannot see these problems in the XML, but you can see them in an image. Thus for each change, we look at the source SVG file and the diagram side by side.
Try it on your drawing
The demo has nine samples. Seven come from the sources that accent-draw reads by name, and two name no parts. You can also use your own file. The converter runs in the page, and the page sends no data.