I compile the following graph with: dot graph.dot -Tpdf -ograph.pdf
, producing:
The result is okay, but the state transition look a lot like a spagetthi monster and I have no clue what I could do to approach this problem. I tried other layouts: twopi, neato, etc.
Are there parameters which allow it to force the graph to look a little bit more symmetric? Because the overall picture is okay.
To me it seems like the edges use the minimal space available to frame the edge descriptions, maybe this is the problem?
Is my graph design flawed? Should I write the different state transitions on one edge, using \n to separate the different transitions?
digraph finite_state_machine {
rankdir=LR;
edge [fontsize=26];
node [shape = doublecircle, width=2.0, fontsize=24, fixedsize=true,style=filled, colorscheme=spectral5]; New [fillcolor=3] Terminated [fillcolor=5];
node [shape = circle, width=2.0, fontsize=24, fixedsize=true, colorscheme=spectral5]; Runnable [fillcolor=4] Waiting [fillcolor=2] "Timed\nWaiting" [fillcolor=2] Blocked [fillcolor=1];
New -> Runnable [ label = "Thread.start" ];
Runnable -> Waiting [ label = "Object.wait" ];
Runnable -> Waiting [ label = "Thread.sleep" ];
Runnable -> Waiting [ label = "LockSupport.park" ];
Waiting -> Blocked [ label = "Reacquire monitor lock after\nleaving Object.wait" ]
Waiting -> Blocked [label = "Spurious wake-up"]
"Timed\nWaiting" -> Blocked [ label = "Reaquire monitor lock after\n leaving Object.wait" ]
"Timed\nWaiting" -> Terminated [ label = "Exception" ]
"Timed\nWaiting" -> Blocked [ label = "Spurious wake-up" ]
Runnable -> "Timed\nWaiting" [ label = "Object.wait" ];
Runnable -> Blocked [ label = "Contended Monitor\nEnter" ];
Blocked -> Runnable [ label = "Contended Monitor\nEntered" ];
Runnable -> Terminated [ label = "Thread finishes\nexecution" ]
Runnable -> Terminated [ label = "Exception" ]
Waiting -> Runnable [ label = "Object.notify\nObject.notifyAll" ]
Waiting -> Terminated [ label = "Exception" ]
"Timed\nWaiting" -> Runnable [ label = "Object.notify\nObject.notifyAll" ]
}
What is Braille? Braille is a system of touch reading and writing for blind persons in which raised dots represent the letters of the alphabet. It also contains equivalents for punctuation marks and provides symbols to show letter groupings.
neato is a reasonable default tool to use for undirected graphs that aren't too large (about 100 nodes), when you don't know anything else about the graph. neato attempts to minimize a global energy function, which is equivalent to statistical multi-dimensional scaling.
Create a graph object, assemble the graph by adding nodes and edges, and retrieve its DOT source code string. Save the source code to a file and render it with the Graphviz installation of your system. Use the view option/method to directly inspect the resulting (PDF, PNG, SVG, etc.) file with its default application.
Graphviz is an open-source graph visualisation software. The graphviz package, which works under Python 3.7+ in Python, provides a pure-Python interface to this software. This package allows to create both undirected and directed graphs using the DOT language.
I don't think your design is flawed, I think it's ok. The dot syntax is readable and therefore maintainable, and the result is what an automatically generated graph looks typically alike.
Of course you can add small corrections to make this particular graph better (or at least different). Some of them may prove difficult to implement if for example the source for your graph is generated by an application. Here are some ideas:
To get the layout to be more symmetric, you may try to align the nodes Waiting and Terminated as well as Timed Waiting and Blocked by setting their group
attribute to the same value (group=a
and group=b
).
It worked fine for Waiting and Teminated, but not so well for Timed Waiting and Blocked - probably because there are two edges between those nodes.
You may try to straighten them out by picking one of the edges which links them and set its weight
attribute to a high value.
Other than that, I think the graph looks nicer over all because the edges are smoother and have less unnecessary curves, especially - but not only - between Runnable and Waiting.
The spaghetti effect is due to the splines - maybe it looks less spaghetti without splines? I tried by adding splines=compound
or splines=ortho
(same result):
The graph uses slightly less vertical space. It's not spaghetti, but it's not better in my opinion...
You may also try splines=compound
without the group attributes, this should make the graph a little more compact (bug not necessarily prettier). Or simply play around with the weight of the edges to straighten out particularly unpleasant edges.
In some cases, concentrate
can clear up graphs with lots of parallel edges - in this case it doesn't really help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With