I have the following graphviz code:
graph {
node[width = 0.6, height = 0.6, fixedsize=true, shape=circle];
a[label="22"];
b[label="22"];
c[label="34"];
d[label="22"];
e[label="99"];
f[label="34"];
g[label="40"];
h[label="37"];
i[label="22"];
j[label="99"];
k[label="135"];
l[label="129"];
m[label="40"];
edge[penwidth=3.0];
a -- b;
b -- d;
c -- f;
d -- i;
e -- j;
g -- m;
edge[penwidth=1.0];
a -- c;
b -- e;
c -- g;
d -- h;
e -- k;
g -- l;
}
This is meant to draw a binary tree with some edges highlighted. However, the tree doesn't look quite right - especially further-down the tree, the arrangement of parent and children looks like this:
parent
child child
whereas I would like it to look more like this:
parent
child child
(i.e. have the parent centred above its children, not sitting on top of one of them). Is this possible, and how would I do it if so?
I did play a lot and I think there is no perfect solution. There are some approaches.
The classic approach with additional invisible edges and nodes. This works out for small graphs but becomes very ugly on big ones. to ensure this is working out you have to fill the complete grid with invisible nodes. otherwise the dot engine will overrule you.
what I expected to work out was this approach
Unfortunately it did not. It seems that the dot layout engine tries to minimize not the edge length, but the horizontal part only i.e. any parent position between the child nodes is considered ideal.
Another one i tried is
which gives
It does seem to work out, the horizontal order depends on appearence. But clusters do not behave well with many other constructs, you have to try whether it works out for you.
If you omit the clusters the layout will be horizontally more compact. vertical edges are still prevented by the invisible middle nodes.
which gives
Finally there is one thing left, a gvpr script for tree layout by ERG. Details you find in marapets answer to this question.