How To Create State Diagrams with Graphviz
I love software design documentation. There’s just something fulfilling about seeing a coherent and simplistic representation of the behavior of a software system that sets my mind at ease. State diagrams are an especially common method of documenting software design but they’re not always easy to generate. If you have money, you can buy Visio and lay everything out manually. If you don’t have money you can download Dia or some other free/open-source software to (hopefully) do the same work as Visio. My experience with Visio is mostly frustration: aligning, centering, copying, arranging, etc. I usually spend 80% of my time on picky detail work rather than useful software design. That’s why I found Graphviz.
Graphviz is a software package for visualizing directed graphs. It’s been around for at least 26 years and AT&T Labs developed it, so it has some gravitas. You can download it for Windows, Linux or (as I am using right now) Cygwin and many other operating systems. The idea behind it is that you write a text file that defines all of the nodes in the graph and the edges that connect them together. Then, you can dress those nodes up with colors, styles, labels, etc. You take this text file, pass it through a command-line utility and Graphviz will lay out the diagram and produce a graphic file (which can be many many different formats).
Here I’ll lay out the steps to generate a basic state diagram with Graphviz. These steps assume that you have a working installation. I may document the installation steps at some future point.
The directed graph/state diagram is defined entirely in a Graphviz file. Here is sample content for such a file - we’ll call it example.gv:
You can use the following command line to generate a PNG file from this code:
dot example.gv -Tpng -o example.png
And it produces this output:
All of the tedium of laying out the states, drawing connections, etc. is done for you. Trust me: it’s not always this pretty or easy. Sometimes you get some downright insane diagrams from this process - especially for complex diagrams with lots of states, transitions and labels. There are methods you can use to tame the madness but they’re all beyond the scope of this article. Additionally, there are plenty of options for prettying up the graphs with colors, different node and edge styles, etc. Those are similarly beyond the scope of this article. Check out the link to the offical documentation in the Resources section below for full (and I do mean FULL) documentation on Graphviz and the DOT language.
This section contains information on how to generate other constructs within GraphViz.
Clusters are groups of nodes that are all grouped, optionally with a border surrounding them and a label.
Here’s what a cluster looks like:
And how to create one:
Points With Labels
For entry and exits from my graphs, I like to use the ‘point’ style node. However, you can’t add a label to point nodes. You’ll have to do this:
Note the use of ‘xlabel’ on those nodes is due to the fact that a regular ‘label’ will attempt to place the label text inside of the node, which is not really possible for a point.
Sometimes the labels (especially on the points with labels above) can be in a bad place.
If the label is an xlabel, there’s really no good way to move it. You might have luck adding some newlines before or after the label, or some spaces, but that’s about it.
As per this SO answer, you can use a location command (labelloc) to change the location of the label: