Graphviz
From Noah.org
Graphviz is a collection of tools for creating pictures from descriptions of graphs. It is not a GUI drawing tool. Instead, you write a description of a graph and Graphviz will draw it for you.
The main tool is `dot`. Without any options it doesn't do much. Usually you want to tell it to create a PNG.
dot -T png -o example.png example.dot
A dot script file is pretty simple. You pretty much just list nodes and denote connections between them with a '--' operator. You can repeat node names on different lines or you can list multiple connections on one line. Some special characters need quoting (note how I quote www.noah.org).
# This is simple, undirected graph of nodes. This just lists nodes. The edges have no labels.
graph example
{
user -- internet
internet -- "www.noah.org"
database -- "www.noah.org"
"Noah's home" -- "staging server" -- "www.noah.org"
}
You can also label the edges. Note how I broke the last two edges into two lines ("Noah's home" -- "staging server" -- "www.noah.org") so I could label each edge separately.
# This is simple, undirected graph of nodes. This adds labels to the edges.
graph example
{
user -- internet [label="ISP"]
internet -- "www.noah.org" [label="port 80"]
database -- "www.noah.org" [label="port 3306"]
"Noah's home" -- "staging server" [label="local"]
"staging server" -- "www.noah.org" [label="port 22"]
}
You can create directed graphs using digraph instead of graph. Note that edges always point left->right. If you want an edge to point both directions then add "dir=both" to the properties (database -> "www.noah.org" [dir=both, label = "port 3306"]).
# This creates a directed graph.
digraph example
{
user -> internet [label="ISP"]
internet -> "www.noah.org" [label="port 80"]
database -> "www.noah.org" [dir=both, label="port 3306"]
"Noah's home" -> "staging server" [label="local"]
"staging server" -> "www.noah.org" [label="port 22"]
}
More advanced work
digraph finite_state_machine {
graph[rankdir=LR size="8.5,11" dpi=300 ratio=fill center=1]
//graph[rankdir=LR dpi=300 ratio=fill center=1]
rankdir=LR
// graph[rankdir=LR size="18,10"]
// node [shape=box style=rounded color=black fontcolor=black fontsize=12];
node [shape=box style=rounded fontsize=12];
//node [shape=box style=rounded weight=bold fontsize=18 color=black fontcolor=black]
edge [color=black fontcolor=black fontsize=12]
{ rank=same
off_lm1970 [label = "power=OFF\nLastMount=1970"];
off_lm2011 [label = "power=OFF\nLastMount=2011"];
}
{ rank = same
lm2011_now2011 [style=bold,label = "System Running\nApp starts\nLastMount=2011\nnow=2011"];
lm1970_now1970 [style=bold,label = "System Running Crippled\nApp does not start\nStuck on white screen\nLastMount=1970\nnow=1970"];
lm2011_now1970 [style=bold,label = "System Crashing\nLastMount=2011\nnow=1970"];
lm1970_now2011 [style=bold,label = "System Running Unsteady\nApp starts\nLastMount=1970\nnow=2011"];
}
{ rank=same
halt_lm2011_now2011 [label = ":Halt kernel\nLastMount=2011\nnow=2011"];
halt_lm1970_now1970 [label = ":Halt kernel\nLastMount=1970\nnow=1970"];
}
{ rank=same
lm1970_now1970_boot_fsck [label = "boot: filesystem check\n:fsck rootfs\nLastMount=1970\nnow=1970"];
}
{ rank=same
lm1970_now1970_boot_ntp [label = "boot: start NTP update daemon\n:mount root filesystem\n:NTPD start"];
}
{ rank=same
lm2011_rtc_query_i2c [label=":query RTC via I2C bus"]
lm1970_rtc_query_i2c [label=":query RTC via I2C bus"]
}
{ rank=same
panic_unrelated [shape = doublecircle, label = "ERROR\nUnrelated\n:Halt kernel"];
panic_fs_error [shape = doublecircle, label = "ERROR\nFileSystem\nStuck on white screen\n:Halt kernel"];
}
// Transitions.
lm2011_now2011 -> halt_lm2011_now2011 [label="clean shutdown"];
lm2011_now2011 -> off_lm2011 [label="power off"];
lm2011_now1970 -> panic_fs_error [weight=bold fontsize=32 label="λ: fsck BAD"];
lm1970_now1970_boot_fsck -> lm1970_now1970_boot_ntp [label="fsck OK"];
lm1970_now1970_boot_fsck -> panic_unrelated [label="fsck BAD"];
lm1970_now2011 -> off_lm1970 [label="power off"];
lm1970_now2011 -> halt_lm2011_now2011 [label="clean shutdown"];
lm1970_now1970_boot_ntp -> lm1970_now1970 [label="NTP BAD"];
lm1970_now1970_boot_ntp -> lm1970_now2011 [label="NTP GOOD"];
halt_lm2011_now2011 -> off_lm2011 [label="power off"];
off_lm2011 -> lm2011_rtc_query_i2c [label="power on"] //lm2011_now1970 [label="power on,\nbad RTC"];
lm2011_rtc_query_i2c -> lm2011_now2011 [label="RTC OK"] //lm2011_now1970 [label="power on,\nbad RTC"];
lm2011_rtc_query_i2c -> lm2011_now1970 [label="RTC BAD"] //lm2011_now1970 [label="power on,\nbad RTC"];
//off_lm1970 -> lm1970_now1970_boot_fsck [label="power on,\nbad RTC"];
off_lm1970 -> lm1970_rtc_query_i2c [label="power on"];
lm1970_rtc_query_i2c -> lm1970_now1970_boot_fsck [label="RTC BAD"];
lm1970_rtc_query_i2c -> lm1970_now2011 [label="RTC GOOD"];
//lm1970_now1970_boot_fsck -> lm1970_now1970 [label="power on,\nbad RTC"];//->lm1970_now1970_boot_ntp
off_lm2011 -> lm2011_now2011 [label="power on,\ngood RTC"];
halt_lm1970_now1970 -> off_lm1970 [label="power off"];
lm1970_now1970 -> halt_lm1970_now1970 [label="clean shutdown\n(Unlikely exept by developers.)"];
}
// Makefile:
// all:
// @ dot -T png rtc.dot | display - 2>&1 >/dev/null &
// :map <F5> <CR>:silent !make<CR><CR>:redraw!<CR>