GraphViz creating regular edges - graphviz

I'm using GraphViz inside a Mediawiki site, that means that I cannot work on the svg file (unluckily).
I created this graph
digraph GPPubProcess{
rankdir="TB";
node [shape = box fontsize=10];
edge [fontsize=10];
graph[size="7.75,10.25" overlap = false];
subgraph c2 {
rank="same";
N02 [label="Two?" shape=hexagon margin=0];
N03 [label="Three"];
}
subgraph c4 {
rank="same";
N07 [label="Seven"];
N06 [label="Six?" shape=hexagon margin=0];
N05 [label="Five"];
}
subgraph c8 {
rank="same";
N11 [label="Eleven)" shape=hexagon margin=0];
N12 [label="Twelve"];
}
subgraph c9 {
rank="same";
N13 [label="Thirteen?" shape=hexagon margin=0]];
N14 [label="Fourteen"];
N17 [label="COMPLETED"];
}
N00 [shape=point];
N01 [label="One"];
N02 [label="Two?" shape=hexagon margin=0];
N04 [label="Four?" shape=hexagon margin=0];
N08 [label="Eight"];
N09 [label="Nine"];
N10 [label="Ten?" shape=hexagon margin=0];
N99 [shape=point];
N00->N01:n;
N01:s->N02:n;
N02:s->N04:n [label=" yes"];
N04:s->N05:n [label=" no" weight=30];
N05:s->N08:n [weight=30];
N08:s->N09:n [weight=30];
N09:s->N10:n [weight=30];
N10:s->N11:n [label=" no" weight=30];
N11:s->N17:n [label=" no"];
N17:s->N99;
N02 -> N03 [weight=0];
N04:e -> N06:n [label=" yes"];
N06 -> N05 [label=" no"] [weight=0];
N06 -> N07 [label=" yes"];
N10:e -> N06:s [label=" yes" weight=5];
N03:s -> N07:n;
N07:e -> N09:e [weight=0];
N11:e -> N12:w;
N15 [label="Fifteen"];
N16 [label="Sixteen"];
N12:s->N13:n [weight=5];
N13:s->N15:n [label=" no"];
N15:s->N16:n;
N13:e->N14:w [label=" yes" weight=5];
N14:n->N07:s;
N16:w->N05:w [weight=0];
}
that produces almost what I like, but links sixteen->five, ten->six and thirteen->fourteen make a lot of slalom between nodes. Is there a way to regularize them?
Also the link between six and five goes in the wrong direction but I wasn't able to make it right? Is there any trick?
Thank you very much.
Giorgio

I would start by removing the weight and compass point instructions (:n, :e, :s, :w). Those are forcing dot to make some weird decisions, especially the compass points. If you need to make changes to the default version, make one small change at a time. Unfortunately, the more you try to force dot to make a specific graph, the weirder it tends to get.
Since you can't work with an SVG, at some point you have to give up getting exactly the graph you want and accept the graph that dot creates. There's a limit to how much you can coerce dot.
The link between six and five (N06 -> N05) should have the arrowhead going from six to five. If you're seeing the arrowhead pointing at six, I think that's a bug in an earlier version of Graphviz. Try updating to the most recent release.
This code:
digraph GPPubProcess{
rankdir="TB";
node [shape = box fontsize=10];
edge [fontsize=10];
graph[size="7.75,10.25" overlap = false];
subgraph c2 {
rank="same";
N02 [label="Two?" shape=hexagon margin=0];
N03 [label="Three"];
}
subgraph c4 {
rank="same";
N07 [label="Seven"];
N06 [label="Six?" shape=hexagon margin=0];
N05 [label="Five"];
}
subgraph c8 {
rank="same";
N11 [label="Eleven)" shape=hexagon margin=0];
N12 [label="Twelve"];
}
subgraph c9 {
rank="same";
N13 [label="Thirteen?" shape=hexagon margin=0];
N14 [label="Fourteen"];
N17 [label="COMPLETED"];
}
N00 [shape=point];
N01 [label="One"];
N02 [label="Two?" shape=hexagon margin=0];
N04 [label="Four?" shape=hexagon margin=0];
N08 [label="Eight"];
N09 [label="Nine"];
N10 [label="Ten?" shape=hexagon margin=0];
N99 [shape=point];
N00->N01;
N01->N02;
N02->N04 [label=" yes"];
N04->N05 [label=" no"];
N05->N08;
N08->N09;
N09->N10;
N10->N11 [label=" no"];
N11->N17 [label=" no"];
N17->N99;
N02 -> N03;
N04 -> N06 [label=" yes"];
N06 -> N05 [label=" no"];
N06 -> N07 [label=" yes"];
N10 -> N06 [label=" yes"];
N03 -> N07;
N07 -> N09;
N11 -> N12;
N15 [label="Fifteen"];
N16 [label="Sixteen"];
N12->N13;
N13->N15 [label=" no"];
N15->N16;
N13->N14 [label=" yes"];
N14->N07;
N16->N05;
}
created this graph:
adding [constraint=false] to N06 -> N05 helps eliminate intersections around N06, but then pushes N11 and N17 way off to the left:

Related

When rankdir is LR, why are the nodes in the same rank ordered bottom to top instead of top to bottom?

In the following example, the nodes in the subgraphs are ordered from the bottom to the top instead of from top to bottom. How can that be reversed, so that the start is top-left and the nodes in the subgraphs are ordered from top to bottom (A1-A4 and B1-B4)?
digraph ab
{
rankdir=LR
splines=ortho
ranksep=1
node[shape = record]
subgraph cluster_0
{
label="A"
{
rank = "same"
state0_anchor [label="", style=invis, width=0]
state0_step0 [label="A1"]
state0_step1 [label="A2"]
state0_step2 [label="A3"]
state0_step3 [label="A4"]
}
state0_anchor->state0_step0[style = invis]
state0_step0 -> state0_step1 -> state0_step2 -> state0_step3
}
state0_step3 -> state0_step0 [constraint=false]
state0_step3 -> state1_step0 [constraint=false]
subgraph cluster_state1
{
label="B"
{
rank = "same"
state1_anchor [label="", style=invis, width=0, height=0]
state1_step0 [label="B1"]
state1_step1 [label="B2"]
state1_step2 [label="B3"]
state1_step3 [label="B4"]
}
state1_anchor->state1_step0[style = invis]
state1_step0 -> state1_step1 -> state1_step2 -> state1_step3
}
state1_step3 -> state0_step0 [constraint=false]
state0_anchor -> state1_anchor[style = invis]
start -> state0_step0
}
In your example, when direction of the edges within the subgraphs are reversed, the nodes will be ordered the way you'd like. Something like this:
state0_step3 -> state0_step2 [dir=rev]
state0_step2 -> state0_step1 [dir=rev]
state0_step1 -> state0_step0 [dir=rev]
state0_step0 -> state0_anchor [style = invis]
The same for state1-nodes.
Details about transformations when going LR can be found in https://stackoverflow.com/a/9592856/63733

Edge crossing each other

is there a way to eliminate the crossing of edges?
I tried many ways, nothing helped.
digraph graphname {
graph [splines=ortho,];
node [shape=box,];
l;
l_a [shape=diamond,label="",height=0.20,width=0.20];
l_a_s [shape=point];
l_a_i [shape=point];
l_a_ii [shape=point];
l_a -> l_a_s;
{rank=same; a -> l_a -> l}
{rank=same; l_a_i -> l_a_s -> l_a_ii}
l_a_i -> i;
l_a_ii -> ii;
l_c [shape=diamond,label="",height=0.20,width=0.20];
l_c_s [shape=point];
l_c_t [shape=point];
l_c_n [shape=point];
l_c -> l_c_s;
{rank=same; l -> l_c -> c}
{rank=same; l_c_t -> l_c_s -> l_c_n}
l_c_t -> t;
l_c_n -> n;
}
some more details:
All you need to do is to reorganize your node/edge definitions a little bit, no additional edges needed.
for example:
digraph graphname {
graph [splines=ortho,];
node [shape=box,];
a;
l_a [shape=diamond,label="",height=0.20,width=0.20];
l;
l_c [shape=diamond,label="",height=0.20,width=0.20];
c;
{rank=same; a -> l_a -> l -> l_c -> c}
l_a_s [shape=point];
l_c_s [shape=point];
l_a -> l_a_s;
l_c -> l_c_s;
l_a_i [shape=point];
l_a_ii [shape=point];
l_c_t [shape=point];
l_c_n [shape=point];
{rank=same;
l_a_i -> l_a_s -> l_a_ii;
l_c_t -> l_c_s -> l_c_n;}
l_a_i -> i;
l_a_ii -> ii;
l_c_t -> t;
l_c_n -> n;
}
Adding this invisible edge solves your problem:
l_a_i -> l_c_s [constraint=false style=invis]
I can't prove mathematically why this works, but in such situation it usually helps to play with order in which nodes/edges are defined, or try adding invisible adges to nudge the layout in the direction you need

Graphviz/DOT: How to have arrow "redirected"

This is what I want to produce in a DOT graph:
I have the following code:
\digraph
[scale=0.7]{g1}
{
margin="0 0 0 0";
rankdir="TB";
"X" [shape=invhouse];
" " [shape=house];
"100" [shape=cylinder];
"X" -> "100"
"X" -> "+";
"100" -> "+"
"+" -> " ";
}
I also have the following code, which is closer in a sense but visually looks nothing like what I want:
digraph {
node[ shape = plaintext ];
a [label="X", shape = invhouse]
b [label="+", shape = ellipse]
ab1 [label="dummy", style=invis, shape=point]
ab2 [label="dummy", style=invis, shape=point]
c [label="100", shape = cylinder]
d [label=" ", shape=house]
subgraph cluster_0 {
style=invis
a -> ab1 [arrowhead=none];
ab1 -> c;
c -> ab2;
ab1 -> ab2 [arrowhead=none];
ab2 -> b;
b -> d;
}
}
How can I change my code(s) appropriately? Any help would be greatly appreciated.
the group attribute helps to bring nodes in line.
digraph {
node[ shape = plaintext group=abd];
a [label="X", shape = invhouse]
b [label="+", shape = ellipse]
ab1 [label="dummy", style=invis, shape=point]
ab2 [label="dummy", style=invis, shape=point]
c [label="100", shape = cylinder, group=c]
d [label=" ", shape=house]
subgraph cluster_0 {
style=invis
a -> ab1 [arrowhead=none];
ab1 -> c;
c -> ab2;
ab1 -> ab2 [arrowhead=none];
ab2 -> b;
b -> d;
}
}

Clusters squeeze nodes in GraphViz

I have several related sub-graphs that I want to draw together in GraphViz. When I draw simple nodes it looks quite pretty:
Source:
digraph {
rankdir=LR;
A1 -> A21;
A1 -> A22;
A1 -> A23;
A1 -> A24;
B1 -> B21;
B1 -> B22;
B1 -> B23;
B1 -> B24;
A21 -> A31;
A22 -> A31;
A23 -> A31;
A23 -> A32;
B21 -> B31;
B21 -> B32;
B22 -> B32;
B21 -> B33;
B23 -> B33;
}
As the nodes in the same level across the several sub-graphs are related, I want to group them and give it a label.
I tried to do it using clusters, but it "squeezes" the nodes:
Source:
digraph {
rankdir=LR;
subgraph cluster_level1 {
label = "Level 1";
style=filled;
color=lightgrey;
A1;
B1;
}
subgraph cluster_level2 {
label = "Level 2";
style=filled;
color=lightgrey;
A21;
A22;
A23;
A24;
B21;
B22;
B23;
B24;
}
subgraph cluster_level3 {
label = "Level 3";
style=filled;
color=lightgrey;
A31;
A32;
B31;
B32;
B33;
}
A1 -> A21;
A1 -> A22;
A1 -> A23;
A1 -> A24;
B1 -> B21;
B1 -> B22;
B1 -> B23;
B1 -> B24;
A21 -> A31;
A22 -> A31;
A23 -> A31;
A23 -> A32;
B21 -> B31;
B21 -> B32;
B22 -> B32;
B21 -> B33;
B23 -> B33;
}
With just two sub-graphs, it's bad, but still not horrible. However, if I add more sub-graphs, it becomes uglier and uglier.
Is there a way to group nodes with some shadowing and labels, while keeping the original nodes layout using GraphViz?
This is probably not a good answer since it implies a lot of trial and error but at least you get what you want (I guess) with invisible nodes:
digraph {
rankdir=LR;
subgraph cluster_level1 {
label = "Level 1";
style=filled;
color=lightgrey;
A01[ style = invis ];
A1;
A02[ style = invis ];
A03[ style = invis ];
A06[ style = invis ];
A05[ style = invis ];
B1;
A04[ style = invis ];
}
subgraph cluster_level2 {
label = "Level 2";
style=filled;
color=lightgrey;
A21;
A22;
A23;
A24;
B21;
B22;
B23;
B24;
}
subgraph cluster_level3 {
label = "Level 3";
style=filled;
color=lightgrey;
A07[ style = invis ];
A31;
A32;
A08[ style = invis ];
B31;
B32;
B33;
A01[ style = invis ];
A09[ style = invis ];
}
A1 -> A21;
A1 -> A22;
A1 -> A23;
A1 -> A24;
B1 -> B21;
B1 -> B22;
B1 -> B23;
B1 -> B24;
A21 -> A31;
A22 -> A31;
A23 -> A31;
A23 -> A32;
B21 -> B31;
B21 -> B32;
B22 -> B32;
B21 -> B33;
B23 -> B33;
}
yields

Optimize label position in Graphviz

The following dotfile is creating a massive output :
digraph G {
"Bob"->"A" [label=" A very long label"]
"Bob"->"B" [label=" A very long label"]
"Bob"->"C" [label=" A very long label"]
"Bob"->"D" [label=" A very long label"]
"Bob"->"E" [label=" A very long label"]
"Bob"->"F" [label=" A very long label"]
"Bob"->"G" [label=" A very long label"]
}
Outputs something like this :
Is there a way to change the label positions to reduce the graph size ?
Labels can be positioned with lp. You could change the labelangle. There are also headlabel and taillabel labels.
Search for 'label' in the documentation.
Very simple \n solution
digraph G {
"Bob"->"A" [label=" A very\nlong\nlabel"]
"Bob"->"B" [label=" A very\nlong\nlabel"]
"Bob"->"C" [label=" A very\nlong\nlabel"]
"Bob"->"D" [label=" A very\nlong\nlabel"]
"Bob"->"E" [label=" A very\nlong\nlabel"]
"Bob"->"F" [label=" A very\nlong\nlabel"]
"Bob"->"G" [label=" A very\nlong\nlabel"]
}

Resources