How it works
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". Five stages change the first into the second.
The five stages
Recognise. Some sources give names to their parts. accent-draw reads these names, not the drawing, because the names are more exact. A profile does this work. An SVG file that contains a draw.io diagram does not go through the other stages. accent-draw gives back the diagram in the file without a change.
Parse. The parser reads all parts that a profile did not read. It applies
the full style rules: first the presentation attributes, then the style sheet
rules, then style="". It also applies inheritance and custom properties
through var(). It reads 2D transforms, viewBox, nested <svg>, <use>,
<symbol>, and lengths in all units.
A rectangle stays a rectangle, and an arrowhead stays an arrowhead. A renderer changes both into paths. But a diagram needs exactly the data that a path loses.
Scene. The parser makes a scene: shapes, text, arrows, frames and groups, in page coordinates. The scene contains no draw.io data. The scene has its own rules, and a test checks each file in the test corpus against these rules.
Layout. The layout finds what the source did not tell. Only this stage finds such data, so you can test it alone. It adds only the data that the source did not give. It does not change what a profile read. For example, if a profile read the two shapes at the ends of an arrow, the layout keeps them.
Emit. The emitter changes the scene into an mxGraphModel. The cell ids are
stable, and all numbers have one format. Thus two conversions of the same file
give the same bytes, and a diff shows a real change.
What the layout finds
Labels. Text in a box, in an ellipse, or in a closed outline becomes the label of that shape. The label stays where the SVG file shows it. Thus when you move the shape in draw.io, its text moves with it. A box that has only an outline and no fill is a box too.
A stroke that does not close gets no label, for example an underline or a bracket. The bounding box of such a stroke can contain text that is not its label.
Borders. Often, two or more elements show one part. For example, a filled body has a separate outline with no fill on top of it. The outline is the border of the body. The layout does not give the border the text, the end of an arrow, or the role of the frame around the body.
Arrows. A line, a polyline without fill, or an open path becomes an arrow. Its markers become arrowheads, with their tips at its ends. Some programs draw an arrowhead as a triangle after the line. A triangle in the color of the line, at one of its ends, is an arrowhead too.
Each end connects to the shape that it touches, within a few stroke widths. If a box and its frame are both near, the end connects to the box.
Frames. A shape that contains other shapes is a frame. Each shape, text and line in the frame becomes a child of the frame, with a position from the corner of the frame. Thus when you move the frame, all its contents move with it. A line is a child of a frame only if the shapes at its ends are in the frame too.
The title of a frame stays a separate text. It does not become the label of the frame.
Each limit in the layout changes with the font size or the stroke width. No limit is a fixed number of pixels. A diagram that you export at two times the scale is the same diagram.
What becomes a note
draw.io cannot show some parts. Each of these parts becomes an image cell with an SVG of that part only, at the position of the part. The result also gives a note for each of these parts:
- masks, filters, patterns, text along a path, and HTML in a
<foreignObject>. - a gradient that is not two colors across the shape or out from its center. The shape gets the first color of the gradient, and a note.
- an image with a skew or a mirror transform. A cell can turn, but it cannot skew or mirror.
- a clip path. accent-draw shows the part without the clip path and gives a note. Most clip paths do not remove a part that a diagram needs.
- a reference that accent-draw cannot find: to nothing, to a different file, or to itself. Also a reference with too many levels, or one that shows too many parts.
accent-draw does not remove a part without a note. Each element that shows
something becomes a cell, a part of a cell, or a note. If an element becomes
none of these, accent-draw gives the note unaccounted. This note is a bug in
accent-draw, not a property of your file.
Why we look at each result
A style string can look correct in the XML and show incorrectly in draw.io. We found many problems in this project that we did not see in the XML. We saw them immediately in an image. Thus for each change, we convert the full corpus. Then we look at each source SVG file next to its diagram.
If you write .drawio files yourself, know these draw.io rules:
- A
<b>tag in an HTML label removes thefontColorof the label. For a label that is fully bold, usefontStyle=1. - draw.io moves a connected edge to the perimeter of its shape if the edge has
no fixed points. The edge then loses its real route. Thus each connected edge
that accent-draw writes has
exitX/exitYandentryX/entryY. - A label is at the center in both directions if
alignandverticalAligndo not tell a different position. A label also has two units of space on each side ifspacing=0does not remove it. - If two cells have the same id, draw.io does not open the document.