Submitted by Aldon Hynes on Thu, 01/29/2009 - 12:52

Yesterday, I wrote a blog post about installing GraphViz on Drupal. Today, I will describe a little bit about how to create interesting images using GraphViz. This is a bit of a long and geeky post, so I’ll spare my less geeky friends the details. Click on read more to see the full blog post.

Before I start, I should note that you don’t need to install GraphViz on Drupal. For the longest time, I’ve used it from the command line in Linux. For those that like working in Windows, GVedit, which comes as part of the Windows install provides a wonderful environment to create images.

Within GraphViz, a graph is made up of nodes and edges that connect them. The graph can be a plain graph or a directed graph. A directed graph has arrows, and it matters which way the arrows are pointing. Here are a couple examples:

Plain graph

graph g {
a – b ;
a – c ;
a – d ;
}

digraph g {
a -> b ;
a -> c ;
a -> d ;
a -> e;
a -> f;
}

Pretty much the same, except that the directed graph starts off with digraph and uses ‘->’ instead of ‘–‘. The images look pretty similar as well.

A second thing to look at is how you want the graph laid out. When I first starting using GraphViz, all that I used was the ‘dot’ command. ‘dot’ makes a hierarchical graph. Other programs, like neato, fdp, twopi and circo use other algorithms to arrange the nodes and edges.

Here is a simple illustration of what I mean. Take the directed graph above. If you run it with dot, you gat a graphic that looks like this:
clip_image002

If you run it with neato, you get a graphic that looks like this:
clip_image003

Not only is ‘dot’ the first program that I used, it is also the default for the GraphViz filter in Drupal. However, you can over ride this by adding a GraphViz comment. e.g.

/*
* @command = neato
*
*/
digraph g {
a -> b ;
a -> c ;
a -> d ;
a -> e;
a -> f;
}

Back to hierarchical graphs for a moment. You can change the direction that the hierarchical graph points by adding a command rankdir. Rankdir takes four possible options LR, RL, TB, and BT, for Left to Right, Right to Left, Top to Bottom and Bottom to Top, respectively. So,

/*
* @command = dot
*
*/
digraph g {
rankdir = LR
a -> b ;
a -> c ;
a -> d ;
a -> e;
a -> f;
}

produces
clip_image004

In these examples, a through f are nodes. You can change the characteristics of nodes by adding different attributes. You can see some of the attributes on theNode, Edge and Graph Attributes page.

As an illustration, take a look at

/*
* @command = dot
*
*/
digraph g {
rankdir = LR
bgcolor = grey
a [color = blue; fontcolor = red]
b [shape = box]
c [shape = diamond]

a -> b [color = green] ;
a -> c ;
a -> d ;
a -> e;
a -> f;
}

This produces an image like this:
clip_image005

You’ll notice that I define the nodes ‘a’, ‘b’, and ‘c’ with its attributes on separate lines now, instead of taking the default that gets generated with the edge. When you add attributes, you should add them to the graph, as I did with the bgcolor of grey, to a node line, like how I added the color blue to the ‘a’ node, or to an edge, like how I specified that the arrow from a to b should be green.

One final tip for now. If you use GraphViz from Drupal, you can easily embed links into the graph. You need to add the directive @imagemap = TRUE to the DOT comment section, and then you need to and the URL attribute to whatever object you want. As an aside, when I’ve done this, if I only have one URL attribute, has seemed to apply it to the whole graph instead of just the node or the edge. I haven’t found any nice way of using this from the GVedit program in Windows, but that would probably get a bit messy anyway.

So, for the last example, let me show you the file with the URL attributes. I should note that this blog is currently not set up with the GraphViz filter, so it won’t work here, but you’ll get the idea

/*
* @command = dot
* @imageurl = TRUE
*
*/
digraph g {
rankdir = LR
bgcolor = grey
a [color = blue fontcolor = red URL=”/node/3105”]
b [shape = box URL=”/node/3407”]
c [shape = diamond]

a -> b [color = green] ;
a -> c ;
a -> d ;
a -> e;
a -> f;
}