Why does shape=record not draw the arrow? - graphviz

Note that I set the rank to same.
The code is:
digraph R {
rankdir = LR
node [shape=record];
{rank = same; rA sA}
rA -> sA;
}
The output is:

When I run this on a Mac with the same version I see the following error:
Warning: flat edge between adjacent nodes one of which has a record shape - replace records with HTML-like labels
Edge sA -> rA
Error: lost rA sA edge
I'm not sure why you don't see this error message. But based on the date of the code commit, it was added after 2.38.0 and is part of 2.40.1. The code change adds a return which is why you don't see an arrow.

Related

Add space between 2 connected nodes

I would like to add a little more horizontal space between the 2 nodes so the edge labels appear associated to their node (instead of in the middle of the edge):
The graphviz source:
digraph {
rankdir="LR";
node [shape=cylinder]
clone
initial
clone -> initial [headlabel="origin",taillabel="clone"]
}
Expected:
I tried using nodesep but it seems to only work when there are no edges.
nodesep was a good try, but your ranking is LR, so ranksep is the way to go
digraph {
rankdir="LR";
ranksep=1.2 // rank-to-rank in inches
node [shape=cylinder]
clone
initial
clone -> initial [headlabel="origin",taillabel="clone"]
}
Giving:

How do I force nodes to be drawn next to each other with Graphviz dot?

I'm looking to have a series of nodes in a row, joined by an edge. This works fine when the graph's rankdir is set to TB or BT, but it rearranges the nodes when I set it to LR or RL so they're no longer next to each other. Example images are included.
I've taken my code and stripped it down to it's minimum point for demonstration. The code is the same for both of the following graphs, aside from line 2 (which specifies rankdir):
digraph{
rankdir=LR;
node[shape=box,fontcolor=white,color=black,fillcolor=black,style=filled];
edge[dir=none,color=black];
Josh -> JoshParent;
JoshParent -> Hero;
JoshParent[shape=circle,label="",height=0.0001,width=0.0001];
{
rank=same;
Kae[label="Kae"];
Hero[label="Hero"];
Kae -> Hero;
}
Kae -> KaeParent;
Hero -> HeroParent;
KaeParent -> Liz;
KaeParent[shape=circle,label="",height=0.0001,width=0.0001];
HeroParent -> George;
HeroParent[shape=circle,label="",height=0.0001,width=0.0001];
{
rank=same;
George[label="George"];
Liz[label="Liz"];
Ocean[label="Ocean"];
Egg[label="Egg"];
Liz -> Ocean -> Egg;
}
}
This is what's shown with rankdir=TB:
This is what's shown with rankdir=LR:
As you can see, from the LR image, the nodes have been drawn in the order "Ocean, George, Egg", rather than "Ocean, Egg, George" as it is with the TB image.
You can force the order by adding an explicit but invisible edge from Egg to George:
Liz -> Ocean -> Egg; // last line of your code
Egg -> George[ style = invis ]; // additional edge
This produces
I don't have an explanation for the different behaviour between TB and LR, though.

How position elements with dot for a control system diagram?

I want control over the positioning of some elements in the following sample:
digraph {
graph [splines=ortho];
/* Node customization. */
node [shape=box];
join [shape=point];
set [label="set\npoint"];
/* Define node levels; driving elements on top, feed back below. */
{ rank = min; set; PID; P1; P2; join; OUT;}
{ rank = max; M1;}
/* Edges */
set -> PID -> P1 -> P2;
P2-> join [arrowhead=none];
join -> {OUT; M1};
PID -> M1 [dir=back];
}
If I add more elements to the M1 rank the edges connect to random points (north/top side). I would like to keep them connect horizontally. Can this be done?
How can I increase spacing (edge length) between PID/P1/P2?
It would be nice to align P1/M1 vertically. Can this be done?
Traditional control system diagrams don't have the join node and an edge just comes out of another edge. Is this possible? I removed the arrow head for this.
Maybe some of the questions are extraneous as proper positioning of one will make the others happen naturally.
Generally you can control the point where the arrow enters node with headport attribute. But with ortho splines this rarely works. Ortho splines live their own life and can cause a variety of different problems, including disappearing edge labels. So there's no definite answer to your first question, each situation has to be handled specifically.
You can increase distance between all nodes by setting a nodesep graph attribute. But if you need to increase distance only between specific nodes, you can use a trick: Add a label with big number of spaces for value.
You can accomplish it with invisible edges.
Points 2 and 3 illustrated in edited example below:
digraph {
graph [splines=ortho];
/* Node customization. */
node [shape=box];
join [shape=point];
set [label="set\npoint"];
/* Define node levels; driving elements on top, feed back below. */
{ rank = min; set; PID; P1; P2; join; OUT;}
{ rank = max; M1;}
/* Edges */
set -> PID;
P2-> join [arrowhead=none];
join -> {OUT; M1}
PID -> M1 [dir=back];
PID -> P1 -> P2 [label=" "] /* #2 increase space between specific nodes */
P1 -> M1 [style=invis] /* #3 align P1 an M1 */
}
result:

How to prevent edge labels from messing up the layout in graphviz?

I have a simple vertical graph that looks nice and symmetrical without any labels using the following code:
digraph test_alignment
{
{rank=same; a -> b;}
a -> c;
b -> c;
c -> d;
d -> e;
d -> f;
{rank=same; e -> f;}
}
I'd like to label the edge between A and B as well as the one between E and F, using the same string for each label. I'm expecting the same output, except with longer A->B and E->F edges bearing the same label.
Unfortunately, as soon as I add a label to one of these edges, the general layout looks slightly askew (the result is similar if I add a label to the E->F edge):
digraph test_alignment
{
{rank=same; a -> b [label="Label"];}
a -> c;
b -> c;
c -> d;
d -> e;
d -> f;
{rank=same; e -> f;}
}
I'm very new to graphviz and, following many questions on Stack Overflow, I have been experimenting with different combinations of rank and constraint, I tried using clusters to see if it would keep the top and bottom part properly aligned independently, and tried using a mix of dot, ccomp, gvpack and neato that produced similar results.
It always seems to boil down to the fact adding a label to the edge between nodes with the same rank affects how these nodes are positioned in a way I don't yet understand.
Am I missing something trivial, or am I attempting something I shouldn't instead of letting dot do its thing?
I'm using dot - graphviz version 2.36.0 (20140111.2315) and the linked pictures were produced with dot only (though I obtained similar results when using :
dot test_alignment.dot -Tpng -O
You may try to use the xlabel attribute, together with forcelabels if necessary. From the description:
... For edges, the label will be placed near the center of the edge. This
can be useful in dot to avoid the occasional problem when the use of
edge labels distorts the layout. ...

Can you join edges when they go to the same node?

See the line on the leftmost side of this image.
This isn't a perfect example because the lines don't end on a node, but imagine that there is a node on the bottom left corner of the image. Normally in graphviz if I have a graph like this:
digraph G {
a->c
b->c
}
Then I get two separate lines going into c. Is it possible to have these two lines join before they reach c?
Yes, it is possible to have two lines join before they reach c but, as far as I can see, it requires inserting an invisible node to do it. e.g.:
digraph G {
x [style=invis, height=0, label=""]
a->x [dir=none]
b->x [dir=none]
x->c
}
... which gives:

Resources