I have a graph which can be summarized in English as:
A -> [B -> C -> D] -> E
B -> A
E -> B
Where the square braces indicate a subgraph, with a box drawn around it.
I have implemented it in graphViz/dot as follows:
digraph {
rankdir = LR
graph [overlap = true, fontname = Helvetica]
A [shape="box", style="dashed", label="Alab"]
subgraph clusterx {
node [shape="box"]
B [label="Blab"]
C [label="Clab"]
D [label="Dlab"]
B -> C -> D
label = "Subgraph Box Label";
labeljust = "l";
}
E [shape="box", style="dashed", label="Elab"]
A -> B [label = " ", headport="nw", tailport="ne"]
B -> A [label = " ", headport="se", tailport="sw"]
D -> E
E -> B [tailport="s", headport="s"]
}
This renders in a valid way, but I would like to correct a few visual things.
A
and the subgraph, and less space between nodes of the subgraph.E
to be on the same vertical alignment as the other nodes. I want the D -> E
edge to be a flat line.E -> B
edge to bend in a more aesthetically pleasing way. I would prefer it come out of the 's' port of E
, take a rounded 90 left turn, continue left until it's reached node B
, and then take a rounded 90 degree turn up, and enter the 's' port of B
in a perpendicular way. I believe this occurs because of the way that graphViz spaces the spline points -- I guess what I actually want to do is drag every intermediate spline point down a little bit so that the left-traveling portion of the edge is flat.I have tried adjusting nodesep
and ranksep
parameters to solve the first two problems and not been able to consistently understand why the changes I make produce the changes they do. I have not been able to solve #3 at all.
Additionally, I am using diagrammeR in R to render this to PDF and HTML documents, so any answer here should be output format agnostic, in case it matters.
Any advice? I've tried scouring the graphViz documentation to no avail and I can't find any worked examples that exhibit these problems.
To improve the position of the nodes and the shape of the Edge (though this is not exactly what you imagined), use constraint=false
:
E -> B [tailport="s", headport="s", constraint=false]
The space between A
and B
is trickier - rank Separation is the same in the graph and in subgraph. You can insert an invisible node to increase the distance, though this may not be worth it:
ranksep=0.2;
invisnode[style=invis, shape=point, width=0.2];
A -> invisnode [style=invis];
invisnode -> B [style=invis];
and invert the direction of the edge going from B
to A
with dir=back
:
A -> B [label = " ", headport="sw", tailport="se", dir=back]