I'm a newbie with Graphviz, and I'm trying to draw a tree centered in an entity (I'm using the twopi command).
If I put overlap=true it overlaps even if it has a lot of space aroud the overlapped labels.
If I put overlap=false, labels become too small.
How can I have the first situation without overlapping?
Complete code:
digraph g {
graph [ fontname = "Helvetica",
fontsize = 10,
size = "500,500",
splines=true,
overlap=false,
ratio=.5 ];
node [ shape = plaintext,
fontname = "Helvetica" ];
root="owl:Thing";
"owl:Thing" -> "Work";
"Work" -> "WrittenWork";
"Work" -> "Software";
"Work" -> "Website";
"Work" -> "Film";
"owl:Thing" -> "Agent";
"Agent" -> "Organisation";
"Organisation" -> "Non-ProfitOrganisation";
"Organisation" -> "GeopoliticalOrganisation";
"Organisation" -> "SambaSchool";
"Agent" -> "Person";
"Person" -> "Athlete";
"Person" -> "OfficeHolder";
"Person" -> "Astronaut";
"Person" -> "Philosopher";
"Person" -> "Architect";
"owl:Thing" -> "Drug";
"owl:Thing" -> "Place";
"Place" -> "SiteOfSpecialScientificInterest";
"Place" -> "PopulatedPlace";
"PopulatedPlace" -> "Country";
"PopulatedPlace" -> "Continent";
"PopulatedPlace" -> "Atoll";
"Place" -> "ProtectedArea";
"Place" -> "ArchitecturalStructure";
"Place" -> "HistoricPlace";
"Place" -> "NaturalPlace";
"NaturalPlace" -> "Mountain";
"NaturalPlace" -> "Volcano";
"NaturalPlace" -> "MountainRange";
}
Thank you,
Alessio
For this particular graph, you may use overlap=true and then increment ranksep until no labels overlap anymore. ranksep=1.3 seems to be a good value.
Related
I'm not really sure how to describe what my client wants, so I'll let a picture do most of the talking. I'm using DOT to produce graphs for what is more or less the bill of materials problem. (Show an incoming lot and all the outgoing lots, at all levels, that were created from the material in the incoming lot.) I've got the code to create a graph that contains the data structured appropriately. For example, I generate this GV file:
digraph LotTrc {
rankdir=LR;
graph[label="Lot #AD626", labelloc=top, labeljust=left, fontsize=24];
PO_AD626_0000003333[shape=triangle,color=greenyellow,style=filled,label=AD626];
AJ_AD626_SJ00000099[shape=circle,color=red2,style=filled,label=AD626];
PO_AD626_0000003333 -> AJ_AD626_SJ00000099;
AJ_AD626_SJ00000103[shape=circle,color=red2,style=filled,label=AD626];
PO_AD626_0000003333 -> AJ_AD626_SJ00000103;
WO_AD627_RE00002230[shape=ellipse,color=lemonchiffon,style=filled,label=AD627];
PO_AD626_0000003333 -> WO_AD627_RE00002230;
SO_AD627_OZ00025429[shape=box,color=cyan3,style=filled,label=AD627];
WO_AD627_RE00002230 -> SO_AD627_OZ00025429;
SO_AD627_OZ00025434[shape=box,color=cyan3,style=filled,label=AD627];
WO_AD627_RE00002230 -> SO_AD627_OZ00025434;
SO_AD627_OZ00025439[shape=box,color=cyan3,style=filled,label=AD627];
WO_AD627_RE00002230 -> SO_AD627_OZ00025439;
SO_AD627_OZ00025444[shape=box,color=cyan3,style=filled,label=AD627];
WO_AD627_RE00002230 -> SO_AD627_OZ00025444;
WO_AD628_RE00002231[shape=ellipse,color=lemonchiffon,style=filled,label=AD628];
PO_AD626_0000003333 -> WO_AD628_RE00002231;
SO_AD628_OZ00025430[shape=box,color=cyan3,style=filled,label=AD628];
WO_AD628_RE00002231 -> SO_AD628_OZ00025430;
SO_AD628_OZ00025435[shape=box,color=cyan3,style=filled,label=AD628];
WO_AD628_RE00002231 -> SO_AD628_OZ00025435;
SO_AD628_OZ00025440[shape=box,color=cyan3,style=filled,label=AD628];
WO_AD628_RE00002231 -> SO_AD628_OZ00025440;
SO_AD628_OZ00025445[shape=box,color=cyan3,style=filled,label=AD628];
WO_AD628_RE00002231 -> SO_AD628_OZ00025445;
WO_AD629_RE00002232[shape=ellipse,color=lemonchiffon,style=filled,label=AD629];
PO_AD626_0000003333 -> WO_AD629_RE00002232;
SO_AD629_OZ00025431[shape=box,color=cyan3,style=filled,label=AD629];
WO_AD629_RE00002232 -> SO_AD629_OZ00025431;
SO_AD629_OZ00025436[shape=box,color=cyan3,style=filled,label=AD629];
WO_AD629_RE00002232 -> SO_AD629_OZ00025436;
SO_AD629_OZ00025441[shape=box,color=cyan3,style=filled,label=AD629];
WO_AD629_RE00002232 -> SO_AD629_OZ00025441;
SO_AD629_OZ00025446[shape=box,color=cyan3,style=filled,label=AD629];
WO_AD629_RE00002232 -> SO_AD629_OZ00025446;
WO_AD630_RE00002233[shape=ellipse,color=lemonchiffon,style=filled,label=AD630];
PO_AD626_0000003333 -> WO_AD630_RE00002233;
SO_AD630_OZ00025432[shape=box,color=cyan3,style=filled,label=AD630];
WO_AD630_RE00002233 -> SO_AD630_OZ00025432;
SO_AD630_OZ00025437[shape=box,color=cyan3,style=filled,label=AD630];
WO_AD630_RE00002233 -> SO_AD630_OZ00025437;
SO_AD630_OZ00025442[shape=box,color=cyan3,style=filled,label=AD630];
WO_AD630_RE00002233 -> SO_AD630_OZ00025442;
SO_AD630_OZ00025447[shape=box,color=cyan3,style=filled,label=AD630];
WO_AD630_RE00002233 -> SO_AD630_OZ00025447;
WO_AD631_RE00002234[shape=ellipse,color=lemonchiffon,style=filled,label=AD631];
PO_AD626_0000003333 -> WO_AD631_RE00002234;
SO_AD631_OZ00025433[shape=box,color=cyan3,style=filled,label=AD631];
WO_AD631_RE00002234 -> SO_AD631_OZ00025433;
SO_AD631_OZ00025438[shape=box,color=cyan3,style=filled,label=AD631];
WO_AD631_RE00002234 -> SO_AD631_OZ00025438;
SO_AD631_OZ00025443[shape=box,color=cyan3,style=filled,label=AD631];
WO_AD631_RE00002234 -> SO_AD631_OZ00025443;
SO_AD631_OZ00025448[shape=box,color=cyan3,style=filled,label=AD631];
WO_AD631_RE00002234 -> SO_AD631_OZ00025448;
}
and it produces this graph:
But what my client really wants is something that looks more like this, where the edges are straight lines, using 90 degree angles as needed. (Note that this is generic, not based on the example above.)
Is there a way to use DOT to produce something like that?
You can experiment with splines=ortho graph attibute. It makes the very straight connections with 90 degree angles.
But I won't recommend it. It's almost impossible to control them, port specification often doesn't work with them, and also, ortho splines may eat up some of the edge lables.
Possible solution would be using dummy nodes with point shape (this shape is convenient because it removes node lable by default) and width=0. Use these dummy nodes in places where the 90 degree turn is needed. You will have to group them with main nodes in subgraphs and add rank=same attribute to force these nodes to stay at the same level.
You would probably also need to add weight to some edges to prevent them from being bent (edges with higher weight tend to be straight).
Example
I've implemented part of your example graph using mentioned techniques, the code and image are below:
digraph {
rankdir=LR
ranksep=1
nodesep=0.5
LOT1 [shape=rect]
LOT2 [shape=rect]
LOT3 [shape=rect]
LOT4 [shape=rect]
LOT5 [shape=rect]
{rank=same
PO
dot1 [shape=point width=0]
dot2 [shape=point width=0]
PO -> dot1 -> dot2 [arrowhead=none]
}
dot1 -> WO1 [weight=20]
{
rank=same
WO1
dot21 [shape=point width=0]
dot22 [shape=point width=0]
WO1 -> dot21 -> dot22 [arrowhead=none]
}
dot21 -> LOT1 [weight=20]
dot22 -> LOT2 [weight=20]
{
rank=same
dot31 [shape=point width=0]
dot32 [shape=point width=0]
dot33 [shape=point width=0]
dot31 -> dot32 -> dot33 [arrowhead=none]
}
dot2 -> WO2 [weight=20]
{
WO2
rank=same
dot23 [shape=point width=0]
dot24 [shape=point width=0]
dot25 [shape=point width=0]
WO2 -> dot23 -> dot24 -> dot25 [arrowhead=none]
}
dot23 -> LOT3 [weight=20]
dot24 -> LOT4 [weight=20]
dot25 -> LOT5 [weight=20]
dot31 -> SO1
dot33 -> SO2
LOT1 -> dot32
}
Result:
I have a digraph made up to draw a skiplist, which it does fairly well, but the alignment needs to be improved.
digraph {
rankdir=LR
node [shape=record,weight=4]
edge [weight=10000]
X [label="<f0>•|<f1>•|<f2>•|<f3>•|<f4>Head"]
A [label="<f3>•|<f4>4"]
B [label="<f1>•|<f2>•|<f3>•|<f4>8"]
C [label="<f3>•|<f4>15"]
D [label="<f0>•|<f1>•|<f2>•|<f3>•|<f4>16"]
E [label="<f2>•|<f3>•|<f4>23"]
F [label="<f2>•|<f3>•|<f4>42"]
Y [label="<f0>•|<f1>•|<f2>•|<f3>•|<f4>Tail"]
X:f0 -> D:f0
X:f1 -> B:f1
X:f2 -> B:f2
X:f3 -> A:f3
X:f4 -> A:f4
A:f3 -> B:f3
A:f4 -> B:f4
B:f1 -> D:f1
B:f2 -> D:f2
B:f3 -> C:f3
B:f4 -> C:f4
C:f3 -> D:f3
C:f4 -> D:f4
D:f0 -> Y:f0
D:f1 -> Y:f1
D:f2 -> E:f2
D:f3 -> E:f3
D:f4 -> E:f4
E:f3 -> F:f3
E:f4 -> F:f4
F:f2 -> Y:f2
F:f3 -> Y:f3
F:f4 -> Y:f4
}
This produces:
I would like to produce something more like this:
How do I make the edges be straight? And how do align the nodes to be all on the same baseline?
For this graph, all that needs to be done is to add this to the graph:
nodesep=0
(You then may also remove the weight attributes)
nodesep: specifies the minimum space between two adjacent nodes
in the same rank
The way I imagine it works, is that nodesep adds some padding to the sides of the nodes. If there is a nearby edge, the node will be moved to respect the padding.
You will need to play around with the height of each individual node. Here is what I have done so far, gets close but you may want to further improve:
digraph so
{
splines = line;
rankdir = LR;
node [ shape = record ];
edge[ minlen = 2 ];
X [label="<f0>•|<f1>•|<f2>•|<f3>•|<f4>Head", height = 5.5 ]
A [label="<f3>•|<f4>4", height = 2.25 ]
B [label="<f1>•|<f2>•|<f3>•|<f4>8", height = 4.5 ]
C [label="<f3>•|<f4>15", height = 2.25 ]
D [label="<f0>•|<f1>•|<f2>•|<f3>•|<f4>16", height = 5.5 ]
E [label="<f2>•|<f3>•|<f4>23", height = 3.25 ]
F [label="<f2>•|<f3>•|<f4>42", height = 3.25 ]
Y [label="<f0>•|<f1>•|<f2>•|<f3>•|<f4>Tail", height = 5.5 ]
X:f0 -> D:f0
X:f1 -> B:f1
X:f2 -> B:f2
X:f3 -> A:f3:w
X:f4 -> A:f4
A:f3 -> B:f3
A:f4 -> B:f4
B:f1 -> D:f1
B:f2 -> D:f2
B:f3 -> C:f3
B:f4 -> C:f4
C:f3:e -> D:f3
C:f4 -> D:f4
D:f0 -> Y:f0
D:f1 -> Y:f1
D:f2 -> E:f2
D:f3 -> E:f3
D:f4 -> E:f4
E:f3 -> F:f3
E:f4 -> F:f4
F:f2 -> Y:f2
F:f3 -> Y:f3
F:f4 -> Y:f4
}
yields
I have a graph that represents one large process made up of two smaller processes. Each of the smaller processes is represented by a subgraph. But when I connect the end of one of those subprocesses (let's say "one") to the start of the other ("two"), the starting shape for the other process ("two") ends up in the same cluster as the ending of "one". How can I get the arrow from the end of one to point to the start of two, but keep the starting shape of two within its cluster?
digraph BigProcess {
graph [ label="Some big process" ]
subgraph clusterSubProcess1 {
graph [ label="Subprocess one", color="red" ]
start1_1 -> start1_2;
start1_2 -> start1_3a;
start1_2 -> start1_3b;
start1_3a -> start1_4;
start1_3b -> start1_5;
start1_4 -> start1_1;
start1_5 -> start2_1;
}
subgraph clusterSubProcess2 {
graph [ label="Subprocess two", color="blue" ]
start2_1 -> start2_2;
start2_2 -> start2_3a;
start2_2 -> start2_3b;
start2_3a -> start2_4;
start2_3b -> start2_5;
start2_4 -> start2_1;
start2_5 -> end1;
}
}
This results in the following, where I really want start2_1 to be the top node within the blue bounded box.
That's happening because the line start1_5 -> start2_1; in the first subgraph is defining start2_1 in that subgraph. You need to define start1_5 in the first subgraph but leave it unconnected until after you define start2_1 in the second subgraph.
digraph BigProcess {
graph [ label="Some big process" ]
subgraph clusterSubProcess1 {
graph [ label="Subprocess one", color="red" ]
start1_1 -> start1_2;
start1_2 -> start1_3a;
start1_2 -> start1_3b;
start1_3a -> start1_4;
start1_3b -> start1_5;
start1_4 -> start1_1;
start1_5;
}
subgraph clusterSubProcess2 {
graph [ label="Subprocess two", color="blue" ]
start2_1 -> start2_2;
start2_2 -> start2_3a;
start2_2 -> start2_3b;
start2_3a -> start2_4;
start2_3b -> start2_5;
start2_4 -> start2_1;
start2_5 -> end1;
}
//Now connect the nodes in the two different subgraphs
start1_5 -> start2_1;
}
I'm using dot to compile. So I have two nodes in cluster0 (MATH1036 and MATH1034). When I try to make an edge from MATH1034 to a node outside the cluster (n1), it freaks out and removes MATH1034 from cluster0.
digraph G {
labelloc="t";
label="";
graph [splines=spline, nodesep=1]
compound=true;
subgraph cluster0{
label="Math 1";
MATH1034[label="MATH1034\nAlgebra"];
MATH1036[label="MATH1036\nCalculus"];
{rank=same;MATH1036->MATH1034;}
}
COMS1015[label="COMS1015\nBCO"];
COMS1017[label="COMS1017\nALG"];
COMS1016[label="COMS1016\nDCS"];
COMS1018[label="COMS1018\nADS"];
subgraph cluster1{
label="Math 2";
MATH2007[label="MATH2007\nMC"];
MATH2018[label="MATH2018\nGT"];
MATH2019[label="MATH2019\nLA"];
STAT2XXX[label="STAT2XXX\nIntro to MS\nor\nSTAT1003\nStats 1"];
}
COMS2003[label="COMS2003\nAAA"];
COMS2XXX[label="COMS2XXX\nMC"];
COMS2002[label="COMS2002\nDBF"];
COMS2001[label="COMS2001\nOS"];
COMS3000[label="COMS3000\nAAI"];
COMS3003[label="COMS3003\nFLA"];
COMS3004[label="COMS3004\nAN"];
COMS3002[label="COMS3002\nSE"];
// This line will hide the formatting nodes.
//node[shape=none,width=0,height=0, label=""];
// THIS NEXT LINE CAUSES THE PROBLEM
// If I remove MATH1034 from this line, things go normal.
{rank=same;MATH1034->n1[ltail=cluster0,dir=none ]; n1->n2->n3->n4->n5[dir=none];}
n1->COMS1015[style=dotted];
n2->COMS1016[style=dotted];
n4->COMS1017[style=dotted];
n5->COMS1018[style=dotted];
MATH1034 -> MATH2007[lhead=cluster1, ltail=cluster0];
MATH2018 -> STAT2XXX[style=invis];
MATH2007 -> MATH2019[style=invis];
//edge[dir=none];
n3->n6->n7[arrowhead=none];
{rank=same; COMS1016->n6->COMS1017[style=invis];}
{rank=same; COMS2001->n7[style=invis]; n7->COMS2003;}
COMS1015 -> COMS2001;
//{rank=same; COMS1017 -> p1 -> COMS1018;}
//p1 -> COMS2003;
//p1 -> COMS2XXX;
COMS1017 -> COMS2XXX;
COMS1017 -> COMS2001;
COMS1017 -> COMS2003;
COMS1018 -> COMS2003;
COMS1018 -> COMS2XXX;
COMS1018 -> COMS2002;
COMS1016 -> COMS2003;
COMS1016 -> COMS2001[weight=100,style=invis];
MATH2007 -> COMS2001[ltail=cluster1,style=dotted]
MATH2007 -> COMS2003[ltail=cluster1,style=dotted]
{rank=same;COMS2XXX -> COMS2002[dir=back, style=dotted]}
{rank=same;COMS2003 -> COMS2XXX[dir=back]}
subgraph cluster5{
label="";
{rank=same;COMS3004 -> COMS3003 -> COMS3000 -> COMS3002[style=invis];}
}
COMS2003 -> COMS3000[weight=1000];
COMS1016 -> COMS3003;
COMS2001 -> COMS3004[weight=1000];
COMS2002 -> COMS3002[weight=1000];
MATH2007 -> COMS3004[ltail=cluster1,lhead=cluster5];
}
The MATH modules should be next to each other and in a box.
Here is the very broken one:
Here is the correct layout, but without the edge between MATH1034 and n1:
Any help would really be appreciated I've looked everywhere and nothing seems to work.
The node Math1034 is in two different subgraphs which isn't allowed. dot actually emits the following warning:
Warning: MATH1034 was already in a rankset, deleted from cluster G
Warning: MATH1034 -> MATH2007: tail not inside tail cluster cluster0
Warning: MATH1034 -> n1: tail not inside tail cluster cluster0
The solution is to remove MATH1034 from the second cluster, and add the edge without constraining ranks:
{rank=same; n1[ltail=cluster0,dir=none ]; n1->n2->n3->n4->n5[dir=none];}
MATH1034 -> n1[constraint=false];
I am trying to visualize a tree structure using graphviz, problem is as the graph gets bigger graphviz starts to rearrange the order of the nodes. Say I have the following,
A
/ | \
B C D
it becomes,
A
/ | \
B D C
it probably does this to save space but in my context order of the nodes matter I have tried adding,
graph [ordering="out"];
but it did not change the output.
EDIT:
digraph bt {
graph [ordering="out"];
node [style="rounded", shape=box]
N_2386 -> N_2387
N_2387 -> N_2388
N_2388 -> N_2389
N_2388 -> N_2390
N_2387 -> N_2391
N_2386 -> N_2392
subgraph cluster_2393 {
labeljust = "l";
style=dashed;color="#B0B0B0"
N_2392 -> N_2394
N_2394 -> N_2395
N_2395 -> N_2396
N_2396 -> N_2397
N_2397 -> N_2398
N_2397 -> N_2399
N_2396 -> N_2400
N_2400 -> N_2401
N_2400 -> N_2402
N_2395 -> N_2403
N_2403 -> N_2404
N_2404 -> N_2405
N_2405 -> N_2406
N_2403 -> N_2407
N_2407 -> N_2408
N_2408 -> N_2409
N_2409 -> N_2410
N_2410 -> N_2411
N_2411 -> N_2412
N_2412 -> N_2413
N_2412 -> N_2414
N_2412 -> N_2415
N_2411 -> N_2416
N_2416 -> N_2417
N_2416 -> N_2418
N_2416 -> N_2419
N_2408 -> N_2420
N_2408 -> N_2421
N_2403 -> N_2422
N_2395 -> N_2423
N_2392 -> N_2424
}
}
graph in question What I need is, N_2387 should be on the right N_2392 should be on the left. Which is the order I insert them.
I tried the following
digraph g {
ordering=out ;
node [shape=box] ;
a -> b ; a -> c ; a -> d ; a -> e ; a -> f ;
a -> g ; a -> h ; a -> i ; a -> j ; a -> k ;
a -> l ; a -> m ; a -> n ; a -> o ; a -> p ;
a -> q ; a -> r ; a -> s ; a -> t ; a -> u ;
a -> v ; a -> w ; a -> x ; a -> y ; a -> z ;
}
and all nodes b-z are on the same level in the correct order.
What version are you using?
If you want to control ordering of specific items use an invisible edge between them. Combining this with the rank directive gives you a lot of control.
eg: here's a sample tagcloud layout from Graphviz:
/*
Using a graph and relationships just to push things onto different lines.
Two layout rules:
1) all items on a given line go into a "rank=same" phrase
2) a relationship is needed between the first word on each line and the next line down to
force the vertical alignment.
*/
digraph {
edge[style=invisible]
node[shape=none]
fred [fontsize=18]
harry [fontsize=8]
jack [fontsize=12]
sally [fontsize=12]
mika
amy
jan
jack -> fred
fred -> mika
{rank=same;fred;harry}
{rank=same;mika amy; jan}
}
If you change the first branch to a subgraph the two subgraphs will be ordered as written in the file.
It seems that the subgraph as a higher precedence as a normal node and therefor the ordering=out seems not to be honored.
This works:
digraph bt {
graph [ordering="out"];
node [style="rounded", shape=box]
N_2386 -> N_2387
subgraph cluster_first {
N_2387 -> N_2388
N_2388 -> N_2389
N_2388 -> N_2390
N_2387 -> N_2391
}
N_2386 -> N_2392
subgraph cluster_2393 {
labeljust = "l";
style=dashed;color="#B0B0B0"
N_2392 -> N_2394
N_2394 -> N_2395
N_2395 -> N_2396
N_2396 -> N_2397
N_2397 -> N_2398
N_2397 -> N_2399
N_2396 -> N_2400
N_2400 -> N_2401
N_2400 -> N_2402
N_2395 -> N_2403
N_2403 -> N_2404
N_2404 -> N_2405
N_2405 -> N_2406
N_2403 -> N_2407
N_2407 -> N_2408
N_2408 -> N_2409
N_2409 -> N_2410
N_2410 -> N_2411
N_2411 -> N_2412
N_2412 -> N_2413
N_2412 -> N_2414
N_2412 -> N_2415
N_2411 -> N_2416
N_2416 -> N_2417
N_2416 -> N_2418
N_2416 -> N_2419
N_2408 -> N_2420
N_2408 -> N_2421
N_2403 -> N_2422
N_2395 -> N_2423
N_2392 -> N_2424
}
}
I sometimes have an issue like this with manually created files where there are links between the B, C and D type features and they get rearranged.
A solution to this in my case, which may be useful to you is to do
B -> C [weight=10;style=invis]
C -> D [weight=10;style=invis]
You may not need to use weights indicating importance of the connection.
Generally, this should prefer the order B C D (or D C B) over others, and should prevent muddling. I don't remember ever having the sequence reversed.
Recently I had a problem where version 4.7.5 was showing before version 4.7.4 in an image I drew (showing the versions and changes in some software).
I solved this by adding the style=invis line below.
"4.7.3" -> fix121_on_4_7
fix121_on_4_7 -> "4.7.4"
"4.7.4" -> fix132 [style=invis]
"4.7.3" -> fix132
fix132 -> "4.7.5"
Graphviz is designed to generate graphs with pleasing appearance. Trying to force layout defeats much of the value of the tool.
As noted, the invisible edges can be used to enforce some layout, and lexicographic ordering (earlier nodes tend to be placed more left) can also indicate a preference.
In general, adding more constraints to a layout produces perverse layouts that are incredibly difficult to troubleshoot.
Some deviation from an expected layout should not automatically be cause to try forcing the result. Fewer constraints makes generated graphs remain good looking as they change over time, even if they can radically change in appearance.