Flow charts in code: enter graphviz and the “dot” language

If you’re like me, you like gui’s as long as they don’t push you in a direction other than your train of thought. Whenever the tool tends to distract you from the task you are performing, you get annoyed. Stuff like “why am I searching for such an over-obvious functionality”, or “why didn’t they think of making the clickable area a bit bigger”, or simply “aaaarggghhh, it crashed on me again”.

I like typing code. It says what it is. I even considered writing graphs such as flow charts or database models in SVG once, but that’s a bridge too far. What is pretty helpful though, is graphviz, and the “dot” language.

In essence, DOT1 is a declarative language in which you express nodes and their relations in a graph. You can label the nodes and their edges (links between nodes) and you have an array of styling and shaping tools at hand. I have never more quickly drawn a flow chart for some documenting work than with this tool. So I decided I’d use it for my database model too, and behold, it helped me focusing on just the content and logic in stead of any other crap.

I’ll focus just on the flow chart here, but I hope it’ll get you enthusiastic to apply it to other types of graphs.

Installing graphviz

Graphviz is oooold. It should be available in your distro’s package repository, or you can download binaries from the graphviz website.

The tools

Graphviz comes with a set of layout engines which have different command line tools. I have only used dot so far, tried a bit of fdp and neato, but as long as I do not really understand how they differ, I can’t really tell you anything about them.

So, you’ll only need dot for now.

How to get started

There are two basic structures you can use, a graph and a digraph which stand for a graph and a directed graph respectively. The difference is that a directed graph always has edges with a “value”, i.e., you’d speak of a “parent”-“child” type of relationship. A regular graph is just nodes that are somehow connected, but there is no direction or value to their relationship. For example, synonyms are synonyms either way.

In practice, most of the graphs or charts you’ll do are directed graphs. For now it suffices to say that a directed graph connects nodes by arrows (->) and regular graphs by a line (--).

My first graph

digraph {
    A -> B;
}

Using the dot utility, you can render the graph as an image or many other output formats:

dot -Tpng -o graph.png graph.dot


We declare a relationship between the parent and the child. By declaring the relationship, we also declare the nodes. So if we’d output this graph, we’d see the relationship.

We can continue declaring relationships and nodes like this, in this declarative form:

digraph {
    A -> B -> C -> D;
    C -> E -> F;
    F -> B;
}

As you can see, it is pretty darn easy. There is absolutely no way you could have done this faster, and have the advantages of easily editing the graph structure, be able to version control it, insert comments, etc.


How to start writing a flow chart

Flow charts are a typically good example for using graphviz. You’ll usually only need a few different shapes, layout of the resulting graph isn’t overly important, and specifying relationships between the different nodes really is all you need.

digraph {
    label="How to make sure 'input' is valid"
 
    start[shape="box", style=rounded];
    end[shape="box", style=rounded];
    if_valid[shape="diamond", style=""];
    message[shape="parallelogram", style=""]
    input[shape="parallelogram", style=""]
 
    start -> input;
    input -> if_valid;
    if_valid -> message[label="no"];
    if_valid -> end[label="yes"];
    message -> input;
}


Since all node mentioning is declarative, you can easily put labels in a different section than the structure of your graph:

digraph {
    label="How to make sure 'input' is valid"
 
    start[shape="box", style=rounded];
    end[shape="box", style=rounded];
    if_valid[shape="diamond", style=""];
    message[shape="parallelogram", style=""]
    input[shape="parallelogram", style=""]
 
    start -> input;
    input -> if_valid;
    if_valid -> message[label="no"];
    if_valid -> end[label="yes"];
    message -> input;
 
    if_valid[label="Is input\nvalid?"]
    message[label="Show\nmessage"]
    input[label="Prompt\nfor input"]
}


Moreover, you can use the node keyword to declare attributes for sets of nodes:

digraph {
    label="How to make sure 'input' is valid";
 
    node[shape="box", style="rounded"]
       start; end;
    node[shape="parallelogram", style=""]
       message; input;
    node[shape="diamond", style=""]
       if_valid;
 
    start -> input;
    input -> if_valid;
    if_valid -> message[label="no"];
    if_valid -> end[label="yes"];
    message -> input;     
 
    if_valid[label="Is input\nvalid?"]
    message[label="Show\nmessage"]
    input[label="Prompt\nfor input"]
}


This can add so much productivity to drawing graphs that it is silly not to use it. If you’re not happy about the layout, you can use ranking of nodes to make sure nodes are ranked equally so they are put next to each other:

digraph {
    label="How to make sure 'input' is valid";
 
    node[shape="box", style="rounded"]
       start; end;
    node[shape="parallelogram", style=""]
       message; input;
    node[shape="diamond", style=""]
       if_valid;
 
    start -> input;
    input -> if_valid;
    if_valid -> message[label="no"];
    if_valid -> end[label="yes"];
    message -> input;     
 
    {rank=same; message input}
}


But if I’m honest, you shouldn’t bother too much. If you want the layout more presentable, you should just output any of the vector-based output formats and tweak it yourself with any drawing program out there, or even better: output SVG and an XSL transformation to do that for you ;). The essence of it all is that you are productive in documenting something, not in making beautifully laid out graphs. Be focused on that rather than having people “ooh” and “aah” your handywork.

Summarizing

Keep focus on the structure and decisions in your chart, in stead of how stuff should be placed and how it is laid out. You should be worrying about the concept behind the chart in stead of the chart it self. What better way just to be concerning yourself with the nodes, their relations and their type?

The key is that you are documenting domain logic, which is expressed in a logical sense rather than some graphical visualization. You have many possibilities here: for example, generate these charts from static code analysis, generate model relationships from your domain model, class diagrams, etc, etc. I’d say the possibilities are endless, but that seems tautologic.

Have fun, and let me know if you have any tips regarding graphviz or the DOT language!


  1. Don’t worry, you don’t need to be able to read the BNF syntax description. There’s more docs out there. 

This entry was posted in Development, Linux & BSD and tagged , , . Bookmark the permalink. Trackbacks are closed, but you can post a comment.

7 Comments

  1. Marlin Forbes
    Posted July 20, 2016 at 06:36 | Permalink

    This package is especially useful for mapping out state changes and event flows in a workflow system. Instead of having a separate .dot file with your graphic defined in it, use a PHP package like this https://github.com/graphp/graphviz to generate a graphic from the runtime state of your application. You could also use PHP to generate the .dot file based on internal application state. Then you don’t have to worry about keeping the .dot file up-to-date, it’s live. 🙂

  2. Tom Newton
    Posted September 30, 2016 at 11:10 | Permalink

    Thanks – really useful primer.

  3. Mayank Jain
    Posted October 6, 2016 at 13:34 | Permalink

    Exactly what I was looking for.. Thanks!

  4. Chris Dowey
    Posted January 4, 2017 at 18:14 | Permalink

    Very useful overview, thanks!

  5. Jay
    Posted January 10, 2017 at 07:26 | Permalink

    Great intro, thanks!

  6. Posted June 7, 2018 at 09:56 | Permalink

    Once making a new kitchen or renovating an existing kitchen, it is a good idea and a good idea to keep an open mind and pay attention to everything possible – towards the end of the process, it will definitely pay off. Here are some common myths about the design process as well as results:

    “You can certainly add later” -the best planning is to take into account and add all the characteristics of the kitchen at the planning and as well as or renewal stages, and not at a later stage. For example, although you may are not thinking about putting in a flat screen TELEVISION in the kitchen space or if you do not currently have a water dispenser, the best thing is to make for future installation of these and plan power, communication and water factors and keep the alternatives wide open. Also, since the kitchen is supposed to provide us for quite some time, it is highly recommended to measure all existing ergonomic solutions such as drawer drawers, cabinet style dishwashers, and so forth Even if you are young and fit at the moment, these additions will prove themselves Mobility in the future.

    Either way, if you prefer to deal with kitchen planning in stages – one aspect or specific area at a time – be certain to plan carefully so that everything will fit in stylistic and functional harmony when the kitchen will finally be complete.

    ” I do not have so many things” – whether we like it or not, your kitchen has tremendous potential for ruining due to multitude of items kept in it, which is why space is plenty to store, This means that there is a relative absence of overhead storage units, so it is important to balance function and style.

    “Bigger Better” – Your kitchen space is large and you need a sizable kitchen, but then you will find yourself going back and out from one machine to another, in addition to this situation, preferably in the look stages, consider adding a job sink beside the refrigerator or Reduce the need to cross these distances, and there is certainly that these enhancements mean additional costs, and if your budget is limited, it is unquestionably worthwhile considering a compact kitchen.

    “I do not desire a designer ” -not every kitchen design project requires a designer, but many people need someone to help us see the overall picture and regulate the work. Renting consult with an architect or designer does involve quite a lot of cost, but in the long run it is all about conserving money and time. Although you may have a very clear picture of what you want, do not save the expense of a designer since it can best fulfill ideal. Proper and efficient planning of your kitchen and coordination between all the many professionals engaged in building your kitchen by a designer can keep your project within their as well as budget, save you unnecessary money and unneeded problems and particularly keep your sanity.

  7. James
    Posted September 28, 2018 at 20:58 | Permalink

    This is the first graphviz walk-through I’ve found that’s been helpful to really understanding what’s going on. Thanks!

Post a Comment

Your email is never published nor shared.

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Subscribe without commenting