In one graph I have longer edge label (conditions of state change). I would like to put these edge labels in a box and keep their position roughly where edge labels normally are drawn. How can I do this?
Example: In a simple graph like this
digraph finite_state_machine {
rankdir=LR
{
node [shape=record,style=rounded]
A B
}
A -> B [label=<This should <br/>be in a box>]
}
Here I would like to put the edge label text “This should be in a box” in a box. Is there a “label style” for this?
Great question, unfortunately I don’t think there is any simple way to do this. If you look at the styles page (style | Graphviz), you’ll note there are no label styles.
I guess the expectation was that text formatting was all that was needed.
However, below is a small gvpr program that seems to do what you want. It post-processes your result (in dot output format - DOT | Graphviz) and replaces the label with a node that contains the label.
You have to add a new attribute boxit=1 to all appropriate edges. Like so:
digraph finite_state_machine {
rankdir=LR
{
node [shape=record,style=rounded]
A B
}
A -> B [label=<This should <br/>be in a box> boxit=1]
}
and this gvpr program, named boxIt.gvpr:
BEG_G{
string tmpS, newName="___NewNode_";
int I=0;
node_t aNode;
}
E{
if (hasAttr($,"boxit") && $.boxit=="1"){
I++;
tmpS=newName+(string)I;
aNode=node($G,tmpS);
// whoops, we need to slide thex text "up" a little bit
//aNode.pos=$.lp;
aNode.pos=xOf($.lp) + "," + (string) (7. + (float)yOf($.lp));
aNode.label=$.label;
aNode.shape="rect";
aNode.margin=".04,.0";
$.label="";
$.lp="";
}
}
and then use this command line: dot myFile.gv |gvpr -cf boxIt.gvpr |neato -n2 -Tpng > myFile.png
Giving:
This scheme is not industrial-strength, but seems to work.
Maybe this is a silly suggestion, but why not just use a degenerate table:
digraph finite_state_machine {
rankdir=LR
{
node [shape=record,style=rounded]
A B
}
A -> B [label=<<table border="0"><tr><td border="1">This should <br/>be in a box</td></tr></table>>]
}
It might be very obvious toanswer, but I don’t undertsand why do you pipe the resulting gv stream to neato -Tpng and not to dot -Tpng?
ps: I followed you suggestion and submitted for this a feature request. Maybe somebody thinks this could be fun to implement - may be not. (It might not fit into the way Graphviz internally works…)
gvpr is quite powerful. [note that you could probably do the same using the Python interface to Graphviz - or other language interfaces]
The result is piped into neato -n (or neato -n2) because dot will ignore any pos (positioning X,Y) values and will completely re-layout the graph. Neato will accept the pos values & use accordingly (FAQ | Graphviz)
Hi again, I wanted to follow up on this topic. I have generated a small “real world” state diagram with the different methods discussed. I wanted to share their output and visually compare them here. – Maybe someone is interested in this. The diagrams show always the same states and transitions.
Diagrams
First the state diagram with plain labels on the transitions:
I think I will go with the last version (transition text as nodes), despite the fact that in this version nodes are not anymore only for states reserved. IMHO it is still a bit cleaner than the other options.
Runner up is the first version (plain label style) which, I guess, Graphviz itself suggests. The other two versions appear to me to busy and distracting.