I am trying to recreate in graphviz a diagram similar to the one taken from the CLR book:
I am using the following code in Python:
s = Digraph(node_attr={'shape': 'record'})
s.node('struct', '<f0> 3|<f1> 13|<f2> 1|<f3> 2|<f4> 8|<f5> 5')
s.edge("struct:f0", "struct:f1")
s.edge("struct:f0", "struct:f2")
s.edge("struct:f1", "struct:f3")
s.edge("struct:f1", "struct:f4")
s
Which is very close to what I want, except the edges overlap the nodes instead of going above/below them.
I couldn't find a way to modify edge behavior. Also, I have a feeling I am misusing the struct feature of graphviz, but I don't know how to force the graph elements to stick together in one row otherwise.
Can I avoid edge overlaps (except by modifying the SVG myself, of course) or use a different approach altogether?
You can use "ports" to set the points of connection.
I tried your graph on the online service, it seems your rendering is with dot http://dreampuf.github.io/GraphvizOnline
You can test with the others, Circo and the rest do not cross the cells, but by default they all draw on one side (bottom) and the edges are messy.
However there are "ports" properties which allow to solve that by specifying suffixes ":s", ":n" etc. n, s, e, w, nw, ne, sw, s. - i.e. south, north etc.... .
It seems that Dot has different default ports than Circo and Neato, the latter are fine with that:
digraph Structs {
node [shape=record];
s [label="<f0> 3|<f1> 13|<f2> 1|<f3>2|<f4>8|<f5>5"];
s:f0 -> s:f1;
s:f0 -> s:f2;
s:f1:n -> s:f3:n;
s:f1:n -> s:f4:n;
}
Dot needs to specify the ports of the first two nodes, too:
digraph Structs {
node [shape=record];
s [label="<f0> 3|<f1> 13|<f2> 1|<f3>2|<f4>8|<f5>5"];
s:f0:s -> s:f1:s;
s:f0:s -> s:f2:s;
s:f1:n -> s:f3:n;
s:f1:n -> s:f4:n;
}
So I guess, in your code:
s.edge("struct:f0:s", "struct:f1:s")
s.edge("struct:f0:s", "struct:f2:s")
s.edge("struct:f1:n", "struct:f3:n")
s.edge("struct:f1:n", "struct:f4:n")