XML as images
When writing for the web, an excellent diagram format is a Scalar Vector Graphic, or SVG.
While a picture may not replace literally a thousand words, it is true that images and diagrams can replace large amounts of text. A chart or diagram can represent information very effectively as visual aids.
Technical writers can use tools to create these kinds of images. A spreadsheet can generate charts. A photo editor can crop images so they can be placed into documents more effectively. A drawing application can create line diagrams.
Why SVG for diagrams
When writing for the web, an excellent de facto diagram format is a Scalar Vector Graphic, or SVG. An SVG file is a special form of an XML file, developed by the World Wide Web Consortium since the late 1990s.
SVG files provide two key benefits to writing for the web: SVG files are very small, and they provide high fidelity of images when scaled to different sizes. The second point is the most significant:
When you "size up" a raster image such as a PNG file, you end up with "jagged" or "fuzzy" edges on curves. This is because raster images are essentially bitmap files; the image is represented by an arrangement of pixels of a certain size.
However, SVG files are vector images, which means they contain descriptions of shapes that can be rendered at any size. The web browser or other display system interprets the SVG files and draws the shapes on screen using mathematics. A curved shape like an ellipse remains clear and sharp when drawn at the "original" size or when "sized up" to twice its original size.
As an example, note these two images of an ellipse. The "original" or intended size is 400 pixels wide by 200 pixels tall, but the images have been resized to fit the width of this web page. The PNG image has slightly fuzzy edges because it has been resized, while the SVG file remains sharp:
A sample diagram in SVG
Creating an SVG file to represent a diagram requires some understanding of XML. An XML file contains a single parent data block that may contain other child data blocks. Each data element may have attributes to further define the data.
SVG files are XML files, and the parent data block is <svg>
. The typical attributes for the <svg>
definition are the namespace (a reference to the SVG definition) and the view box. The view box is a pair of x,y coordinates: the first pair defines the upper-left origin of the SVG display area; the second pair defines the width and height of the image. A view box of "0 0 100 100"
defines the origin at 0,0 and a width and height of 100. A view box of "-10 -5 20 15"
defines the upper-left origin at -10,-5 and an image that is 20 pixels wide and 15 pixels tall; this means x,y coordinates for the SVG image elements can be anywhere from -10,-5 to 10,10.
Let's create a version of the "double diamond" diagram, often used in project management to define a process where ideas are expanded then focused to a few good ideas, and the top ideas are further explored before they are focused to a few recommendations. If we want each diamond to be 200 pixels wide and high, we need to define the SVG view box as 400 pixels wide and 200 pixels tall:
<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
</svg>
Drawing shapes with paths
To start the diagram, we need to define two "diamond" shapes. We can do this with the <path>
element, which defines a shape using a series of outlines. We can draw a diamond with four lines, using a path definition with the d
attribute:
<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
<path
d="M 100,0 L 200,100 L 100,200 L 0,100 L 100,0"
fill="lightblue" />
<path
d="M 300,0 l 100,100 l -100,100 l -100,-100 l 100,-100"
fill="pink" />
</svg>
Let's examine each component of the path:
The M statement says to move to an x,y coordinate without drawing a line; the first diamond starts at 100,0 and the second diamond starts at 300,0.
You can define paths in two different ways: Using a capital L
will create a line to an absolute coordinate, while using a lowercase l
will draw a line to a relative coordinate. The path definition "M 100,0 L 200,100"
starts the drawing at 100,0 and creates a line ending at 200,100. The second coordinate is 100 pixels to the right and 100 pixels down, which is a relative distance. The path definition "M 300,0 l 100,100"
starts the second diamond at 300,0 and draws a line 100 pixels to the right and 100 pixels down.
Successive L
and l
statements will further define the path. In each diamond, I ended the final path segment at the origin.
If you want the shape to have a specific color, you need to indicate the fill color using the fill
attribute. The first diamond is filled with light blue, and the second diamond is pink.
Adding lines
Let's represent many ideas in the initial phase of the double diamond diagram with a series of lines. Each line should use the same origin at 0,100 (the leftmost vertex of the blue diamond) but should end at different points along the midline of the diagram. To draw lines, we use the <line>
element.
<line>
requires the starting x1,y1 coordinates and the ending x2,y2 coordinates. These are provided as separate attributes:
<line x1='0' y1='100' x2='100' y2='0' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='25' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='50' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='75' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='100' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='125' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='150' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='175' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='200' stroke='royalblue' />
These separate <line>
elements define nine lines, each with origin 0,100 but ending at equally spaced points halfway into the diagram. Each uses a dark blue ("royalblue
") for the line stroke. For the second half of the diamond, we can use a similar method to create four lines that end at the same 200,100 point but start at equally spaced points along the midline of the diagram:
<line x1='100' y1='1' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='67' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='133' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='199' x2='200' y2='100' stroke='royalblue' />
SVG elements are drawn in order. To draw the dark blue lines "on top" of the light blue diamond, we need to include the <line>
elements after the first <path>
element:
<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
<path
d="M 100,0 L 200,100 L 100,200 L 0,100 L 100,0"
fill="lightblue" />
<line x1='0' y1='100' x2='100' y2='0' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='25' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='50' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='75' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='100' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='125' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='150' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='175' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='200' stroke='royalblue' />
<line x1='100' y1='1' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='67' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='133' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='199' x2='200' y2='100' stroke='royalblue' />
<path
d="M 300,0 l 100,100 l -100,100 l -100,-100 l 100,-100"
fill="pink" />
</svg>
Adding shapes
Let's add to the double diamond diagram by drawing several ideas identified in the first phase, but explored further in the second phase. To represent these as "expanded" ideas, we might draw lines that "expand" or grow bigger as they reach the midpoint of the pink diamond. This requires drawing an arbitrary shape.
We can draw these "wedge" shapes using the <path>
element. To simplify the shape, we only need to know the starting and ending coordinates; the "height" of the wedge can remain a constant 5 pixels. This is an excellent opportunity to leverage the lowercase l
attribute of the <path>
shape:
<path d='M 200,100 L 300,0 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,36 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,72 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,108 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,144 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,180 l 0,5 L 200,100' fill='hotpink' />
This draws six separate shapes, each with their origin at 200,100. The wedges have an initial endpoint that is equally spaced along the midline of the pink diamond, but 5 pixels "tall." The l 0,5
instruction creates an individual line segment at the same x level and 5 pixels down. Each wedge is filled with a darker pink ("hotpink
").
To represent these six ideas being condensed to a few strong ideas and focused to a single set of recommendations (the last phase of the double diamond) we can use a similar set of <path>
shapes:
<path d='M 300,0 l 0,10 L 400,100 L 300,0' fill='hotpink' />
<path d='M 300,75 l 0,10 L 400,100 L 300,75' fill='hotpink' />
<path d='M 300,150 l 0,10 L 400,100 L 300,150' fill='hotpink' />
These wedges are slightly taller, at 10 pixels each, using the l 0,10
instruction.
<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
<path
d="M 100,0 L 200,100 L 100,200 L 0,100 L 100,0"
fill="lightblue" />
<line x1='0' y1='100' x2='100' y2='0' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='25' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='50' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='75' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='100' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='125' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='150' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='175' stroke='royalblue' />
<line x1='0' y1='100' x2='100' y2='200' stroke='royalblue' />
<line x1='100' y1='1' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='67' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='133' x2='200' y2='100' stroke='royalblue' />
<line x1='100' y1='199' x2='200' y2='100' stroke='royalblue' />
<path
d="M 300,0 l 100,100 l -100,100 l -100,-100 l 100,-100"
fill="pink" />
<path d='M 200,100 L 300,0 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,36 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,72 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,108 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,144 l 0,5 L 200,100' fill='hotpink' />
<path d='M 200,100 L 300,180 l 0,5 L 200,100' fill='hotpink' />
<path d='M 300,0 l 0,10 L 400,100 L 300,0' fill='hotpink' />
<path d='M 300,75 l 0,10 L 400,100 L 300,75' fill='hotpink' />
<path d='M 300,150 l 0,10 L 400,100 L 300,150' fill='hotpink' />
</svg>
The completed diagram
The final diagram is a pair of diamonds: one light blue diamond and one pink diamond. The blue diamond includes lines radiating from the leftmost origin to represent the "ideation" phase, and several converting lines to the rightmost point to represent the "focus" phase.
The pink diamond represents how these ideas might be further developed into a set of recommendations. To show the expansion of several ideas, we use thin wedges from the left, and slightly thicker wedges that converge to the right.
The double diamond is a relatively simple diagram to describe using lines and shapes, which makes for an excellent demonstration using SVG. Also, the completed diagram is much smaller as a vector drawing than if the same diagram were created (or converted) as a raster image; the SVG is 1.6 kB while the PNG requires over 12 kB. A small difference for a small diagram, but the size difference becomes much greater for more complex or larger diagrams.
To learn more about how to create SVG diagrams, read the SVG: Scalable Vector Graphics guide at the Mozilla Developer website.