Center last node of a graph - graphviz

digraph {
1 -> 2 -> 3;
2 -> { rank = sink; end};
}
How can I force the "end" node to be centered horizontally (in the same column as the first node)?

You may use the group attribute of the nodes:
digraph {
3[group=b];
node[group=a]
1 -> 2 -> end;
2 -> 3;
}
See also this and this answer.

Related

Draw a program dependence graph with graphviz

I'm trying to draw a PDG, but when I add the data dependencies it gets malformed.
What I have
When I only draw the control dependencies the graph looks fine:
digraph {
4[label="4. int x=1"];
5[label="5. int y=2"];
6[label="6. while(x>0)"];
8[label="8. x=(y+x)"];
10[label="10. z=x+y"];
ENTRY -> 4[rank=same, splines=line];
ENTRY -> 5[rank=same, splines=line];
ENTRY -> 6[rank=same, splines=line];
ENTRY -> 10[rank=same, splines=line];
6 -> 8[splines=line];
}
When I try to add the data dependencies the graph gets malformed:
digraph {
4[label="4. int x=1"];
5[label="5. int y=2"];
6[label="6. while(x>0)"];
8[label="8. x=(y+x)"];
10[label="10. z=x+y"];
ENTRY -> 4[rank=same, splines=line];
ENTRY -> 5[rank=same, splines=line];
ENTRY -> 6[rank=same, splines=line];
ENTRY -> 10[rank=same, splines=line];
6 -> 8[splines=line];
4 -> 6[style=dashed, splines=curved, color=red];
8 -> 6[style=dashed, splines=curved, color=red];
4 -> 8[style=dashed, splines=curved, color=red];
5 -> 8[style=dashed, splines=curved, color=red];
4 -> 10[style=dashed, splines=curved, color=red];
5 -> 10[style=dashed, splines=curved, color=red];
8 -> 10[style=dashed, splines=curved, color=red];
}
I tried to add the attribute "splines=line" to draw straight lines (control dep.), but it doesnt't worked like expected. I also experimented with the attribute "weight" and "rank"...
Can someone give me a hint? Is it possible to set an order for the nodes?
Like:
Entry = first row and first element
Node 4 = second row and first element
...
Node 8 = third row and first element
Expected
Using rank = same properly, plus invisible edges to keep the order of the nodes in the middle should help:
digraph so
{
splines=true;
4[label="4. int x=1"];
5[label="5. int y=2"];
6[label="6. while(x>0)"];
8[label="8. x=(y+x)"];
10[label="10. z=x+y"];
{ rank = same; 4 5 6 10 }
ENTRY -> { 4 5 6 10 }
6 -> 8;
edge[style=dashed, color=red];
{ 4 8 } -> 6;
{ 4 5 } -> 8;
{ 4 5 8 } -> 10;
// keep graphViz from re-ordering these nodes:
4 -> 5 -> 6 -> 10[ style = invis ];
}
yields

Graphviz: Layout multiple clusters

digraph G {
rankdir=LR;
subgraph cluster_one {
one_x -> one_y -> one_z;
}
subgraph cluster_two {
two_x -> two_y;
}
subgraph cluster_three {
three_x -> three_y;
}
}
The order of the clusters is reversed. They should be in the order they appear in the source file.
I want all clusters to be of the same width (determined by the largest sub-graph) and aligned.
The order of the clusters is reversed. They should be in the order they appear in the source file.
The following code should work:
digraph G {
rankdir=LR;
subgraph cluster_one {
shape=rect;
one_x -> one_y -> one_z;
}
subgraph cluster_two {
two_x -> two_y;
}
subgraph cluster_three {
three_x -> three_y;
}
one_x->two_y[style=invis];
two_x->three_y[style=invis];
}
I want all clusters to be of the same width (determined by the largest sub-graph) and aligned.
I have found this answer. It is a bad solution, but I can't give a better one.

Graphviz .dot node ordering

I'm building a epsilon NFA to recognize a regular expression using the canonical construction. I'm using subgraphs to group various parts of the regular expression. The * operator is giving me particular trouble since dot has decided to move the order of the nodes around. I've tried adding edge weights to force particular edges to be short to keep the order of the edges in line but that does not seem to be working.
What I would like to do is force the nodes in a subgraph in to be placed in a particular order so that the output graph is recognizable as a particular type of (well known) construction. In the example below I would like edges 3, 4, 5 and 6 placed in that order, however the dot places them in the order 6, 3, 4, 5. Any pointers appreciated.
Note that the current weight parameter produces no difference than no weight parameter at all.
I have the following
digraph G {
rankdir = LR;
node [shape = none];
0 [label = "start"];
node [shape = circle];
1 [label = "q1"];
2 [label = "q2"];
3 [label = "q3"];
4 [label = "q4"];
5 [label = "q5"];
node [shape = doublecircle];
6 [label = "q6"];
subgraph re1 {
rank = same;
edge[label = "0"];
1 -> 2;
};
subgraph re2 {
rank = same;
edge[label = "ε"];
3 -> 4 [weight = 10];
edge[label = "1"];
4 -> 5 [weight = 10];
edge[label = "ε"];
5 -> 6 [weight = 10];
5 -> 4 [weight = 1];
6 -> 3 [weight = 1];
};
edge[color=black];
0 -> 1
edge[label = "ε"];
2 -> 3;
}
Here's how I'd write that graph:
First of all, to me this is a graph which goes from top to bottom, not left to right, therefore I removed the rankdir=LR and added rank=same only for nodes 0/1 and nodes 2/3.
I removed all the weights
Most importantly, I added constraint=false to the edges going against the direction of the graph - the one going from node 4 to node 5, and the one from node 6 to node 3.
Here the source:
digraph G {
0 [label = "start", shape = none];
node [shape = circle];
1 [label = "q1"];
2 [label = "q2"];
3 [label = "q3"];
4 [label = "q4"];
5 [label = "q5"];
6 [label = "q6", shape = doublecircle];
{rank = same; 0 -> 1; }
1 -> 2 [label = "0"];
{rank = same; 2 -> 3 [label = "ε"]; }
4 -> 5 [label = "1"];
edge [label = "ε"];
3 -> 4;
5 -> 6;
5 -> 4 [constraint = false];
6 -> 3 [constraint = false];
}
And here's the result:
Now if you want to, you could keep rankdir=LR, just take the markup you posted, remove the weights and add constraint=false to the same edges as I did, it works, too.

Graphviz: how to set 'default' arrow style?

Consider this dot language code:
digraph graphname {
subgraph clusterA {
node [shape=plaintext,style=filled];
1 -> 2 [arrowhead=normal,arrowtail=dot];
2 -> 3 -> X2 -> 5;
6;
7;
label = "A";
color=blue
}
}
In the above example, only the 1 -> 2 connection will have the arrowhead=normal,arrowtail=dot style applied; all the other arrows will be of the "default" style.
My question is - how do I set the arrow style (for the entire subgraph - or for the entire graph), without having to copy paste "[arrowhead=normal,arrowtail=dot];" next to each edge connection?
EDIT: Just for reference - the answer from Jesse didn't contain any code; I wrote that snippet and had it in this space here - for unknown reasons, a moderator cut it off from here and pasted it into Jesse's answer.
Use the edge attribute statement, as stated in the DOT Language documentation.
digraph graphname {
subgraph clusterA {
node [shape=plaintext,style=filled];
edge [arrowhead=normal,arrowtail=dot];
1 -> 2 ;
2 -> 3 -> X2 -> 5;
6;
7;
label = "A";
color=blue
}
}
Just like you did for nodes, but using edge, e.g. edge[style=dashed]

graphviz: minor tweaks to make the graph look nicer

I have a test graph here that I would like to tweak to make it look nicer.
Here is the graphviz (dot) source, test6.dot:
digraph G {
ranksep=0.3; size="6.0,6.0";
node [fontsize=11];
subgraph clusterA {
X2 [shape=box];
node [style=filled];
1 -> 2 -> 3 -> X2 -> 5;
6;
7;
label = "A";
color=blue
}
X1 [shape=box];
subgraph clusterB {
node [style=filled];
8;
9;
10 -> 11 -> 12;
12 -> 9;
12 -> 8 -> 13;
13 -> 14;
label = "B";
color=blue
}
subgraph clusterC {
label = "C";
{
node [style="invis"];
gap;
}
node [shape=box];
edge [style="invis"];
X3 -> gap -> X4;
}
14 -> X4 -> 3;
6 -> X1 -> 10;
{ edge [dir="both"];
8 -> X3 -> 7;
}
9 -> X3
}
Questions / changes I would like to make:
I want the flow of nodes 10 -> 11 -> 12 -> 8 -> 13 -> 14 to be in a vertical line (swap 8 and 9 horizontally). How can I do this? (same with 1 -> 2 -> 3 -> X2 -> 5; swap 6 and 1)
I want X1 to be at the same vertical position as 10, and the same horizontal position as 6. How can I do this?
I want 8 and X3 and 7 to be at the same vertical position, also with 14 and X4 and 3. How can I do this?
The ranksep=0.3; statement works great except note that 8 -> 13 -> 14 has a larger gap, as does X3 -> gap -> X4. Why doesn't it obey the ranksep=0.3 rule, and how do I fix this?
Below is the best I can do: phantom nodes and edges help. But I can't seem to encourage a particular ordering in the transverse direction (the other direction from rankdir).
digraph G {
ranksep=0.3; size="6.0,6.0";
rankdir=TB;
node [fontsize=11];
subgraph clusterA {
X2 [shape=box];
label = "A";
color=blue;
node [style=filled];
/* force 1, 6, and 7 to be at the top together,
add enough phantoms to keep things in nice columns */
{
node [style="invis", label=""];
phantom3;
phantom4;
phantom5;
phantom6;
}
rank = same;
1 -> 2 -> 3 -> X2 -> 5;
edge [style="invis"];
6 -> phantom3 -> phantom5;
7 -> phantom4 -> phantom6;
}
subgraph clusterB {
node [style=filled];
label = "B";
color=blue;
/* create an invisible phantom node
to take up space */
{
node [style="invis",label=""];
phantom1;
phantom1b;
}
{ rank=same; 11;
phantom1;
}
10 -> 11 -> 12 -> 8 -> 13 -> 14;
12 -> 9;
phantom1 -> 9 -> phantom1b [style="invis"];
}
/* force X1 to be at the same vertical pos as 10
(this yields a warning though) */
{ rank = same;
X1 [shape=box];
10;
}
6 -> X1;
X1 -> 10 [weight=0.5];
subgraph clusterC {
label = "C";
phantom2 [style="invis", label=""];
node [shape=box];
edge [style="invis"];
X3 -> phantom2 -> X4;
}
9 -> X3 [weight=0.5];
{
edge [weight=20];
14 -> X4 -> 3;
3 -> X4 -> 14 [style="invis"];
/* add a reverse path so graphviz doesn't force 14 above X4 above 3 */
}
{
edge [dir="both", weight=20];
8 -> X3 -> 7;
7 -> X3 -> 8 [style="invis"];
edge [style="invis"];
X4 -> phantom6;
1 -> phantom2;
8 -> phantom2;
}
}

Resources