In graphviz/dot, I can place nodes on the same rank with {rank=same; ND1 ND2 ND3}.
Looking at the dot language, I conclude that {...} is part of the subgraph statement.
If this is the case, I don't understand why I need a subgraph to rank nodes. I assume this is because I don't have a correct mental image of what constitutes a subgraph in graphviz.
So, my question is: what is a subgraph in graphviz exactly and why do I have to start a subgraph to rank nodes that don't have anything to do with this subgraph.
From the documentation you cite:
In the second role, a subgraph can provide a context for setting attributes. For example, a subgraph could specify that blue is the default color for all nodes defined in it. In the context of graph drawing, a more interesting example is:
subgraph {
rank = same; A; B; C;
}
This (anonymous) subgraph specifies that the nodes A, B and C should all be placed on the same rank if drawn using dot.
This use of subgraphs to set rank of nodes is exactly the sort of context to which the documentation is referring (explicitly in this case). The syntax supports a special contextual meaning in this case.
Related
I want to draw a graph with "dot" format. The graph I want is a (sub)graph in a graph style. The subgraph (a child) has internal graph, and the (parent) graphs are connected among the parents, and does not connect to children that are connected only in the subgraph.
Could you please guide how writing such style with the dot-format, with an example?
Good news:
creating your "parent nodes" is pretty easy. Graphviz, (dot) calls them "cluster subgraphs" (or clusters). (well documented on p. 19 of https://www.graphviz.org/pdf/dotguide.pdf) see below for an example.
Bad news:
explicitly sizing clusters is very difficult. Dot sizes a cluster to be just big enough to contain its nodes.
explicitly positioning clusters is also quite difficult. Dot positions clusters based on the "best" positioning of the component nodes, specifically the edges that connect nodes within the various clusters.
drawing edges from one cluster to another is a kludge. You define an edge from a node contained within one cluster to another node contained within a different cluster and instruct dot to clip that edge so it appears to be from cluster to cluster. This uses the attribute compound=true. (again, read the documentation listed above)
Finally: the fdp engine allows cluster-to-cluster edges, but you lose the directionality of the edges
Drawn with dot:
digraph C {
graph [compound=true] // allows edges to/from clusters
// create an extra cluster to try to keep clusterA above clusterB
subgraph clusterWrapper {
graph [peripheries=0] // no box around
subgraph clusterA {
graph [peripheries=1] // box around
a -> c
b->c
c->d
}
subgraph clusterB {
graph [peripheries=1] // box around
f->g
e->g
}
} // end of wrapper
subgraph clusterC {
edge [dir=none ] // no arrowheads
h->k
i->k
i->l
j->l
{rank=same h->i->j [style=invis]}
}
b->f [ltail=clusterA, lhead=clusterB];
l:s->b:n [ltail=clusterC, lhead=clusterA];
l->f [style=invis weight=50]
}
Giving:
In this graph the bottom edge is not drawn symmetrical to the top edge:
digraph G {
A:ne -> A:nw;
A:sw -> A:se;
}
I want it to look more like a "fat snowman" with the edge A:sw -> A:se; looping below the node. Is there a way?
Short answer no - or not easily.
Loops seem to be placed from the rankdir direction. If rankdir is TB (down), loops seem to be placed "up".
It you're willing to work at it, you can run your graph twice, once with rankdir=TB, once with rankdir=BT - both times with -Tdot. Then you'd have to replace the offending edge with the equivalent edge from the other graph. [I hope this makes some sense]
Here is a tweaked version of your graph run with different values of rankdir:
digraph G {
A:ne -> A:nw;
A:sw -> A:se;
dummy [style=invis]
dummy -> A [style=invis]
}
In the attached figure, the nodes are arranged in a circle around the node. Is there a (possibly generic) way to arrange the nodes only in the lower semi-circle, without having to provide fixed coordinates for the nodes?
Edit: Would like to achieve something like shown in the image attached below. As one can see - all the nodes are arranged in the lower semi-circular region (this figure was made using CMap Tools).
The code is trivial, but pasting it anyway.
digraph semicircle {
rankdir="TD"
graph [nodesep="0.1", ranksep="0.3", center=true]
mindist="0.4"
S [label="Root", style="filled", fillcolor="greenyellow", shape="box"]
subgraph cluster1 {
rank="same"
A; B; C; D;
S -> {A, B, C, D};
} }
using dot/circo : graphviz version 2.40.1
I noted that circo placed nodes counter-clockwise, starting at 3 o'clock.
I added enough invisible nodes to fill the 2 through 10 o'clock positions.
To make the inter-nodal distances even more uniform I added:
node [shape=square style=rounded]
The result I got is this:
Try this:
digraph semicircle {
rankdir="TD"
graph [nodesep="0.1", ranksep="0.3", center=true, root=S]
mindist="0.4"
S [label="Root", style="filled", fillcolor="greenyellow", shape="box"]
subgraph cluster1 {
rank="same"
A
z1[style=invis label=""]
z2[style=invis label=""]
B; C; D;
S -> A
S -> z1,z2 [style=invis]
S -> { B, C, D};
}
}
I have a .dot digraph which shows a graph as I want (depicting relationship between some tables). I want to add redundant edges to the graph (to represent redundant relationships in the database which exist only to write queries less effortly). These redundat edges, which will be written in a "dotted" style, must not change the deployment of nodes in the graph.
In other words, there's edges which must affect the node positions to print the graph pretty, and other edges which must to be added after the node positions are already computed (which will be styled differently --light gray, dotted, etc; to show that they're not main edges).
Is there options in Graphviz to specify "extra" edges?
Use constraint=false and color=gray on those additional edges.
digraph G {
a -> b -> c -> d;
d -> a [constraint=false,color=gray]
a -> z -> x -> d;
}
Play with that on http://graphviz.it/#/rhlWBZsz
I'm trying to create a graph with two subgraphs in dot. The code is as follows:
digraph G {
subgraph step1 {
style=filled;
node [label="Compiler"] step1_Compiler;
node [label="Maschine"] step1_Maschine;
color=lightgrey;
}
subgraph step2 {
style=filled;
color=lightgrey;
node [label="Interpretierer"] step2_Interpretierer;
node [label="Maschine"] step2_Maschine;
label="Virtuelle Maschine";
}
"Programm (Java)" -> step1_Compiler;
step1_Compiler -> step1_Maschine;
step1_Maschine -> "Bytecode";
"Bytecode" -> step2_Interpretierer;
step2_Interpretierer -> step2_Maschine;
step2_Maschine -> "Ergebnis";
}
The result I am getting looks like the following:
I expected to see a box around both subgraphs. What am I missing here?
You'll have to prefix the name of your subgraphs with cluster:
subgraph clusterstep1 {
and
subgraph clusterstep2 {
in order to get the style and label.
From the graphiz documentation, section "Subgraphs and Clusters":
The third role for subgraphs directly involves how the graph will be
laid out by certain layout engines. If the name of the subgraph begins
with cluster, Graphviz notes the subgraph as a special cluster
subgraph. If supported, the layout engine will do the layout so that
the nodes belonging to the cluster are drawn together, with the entire
drawing of the cluster contained within a bounding rectangle. Note
that, for good and bad, cluster subgraphs are not part of the DOT
language, but solely a syntactic convention adhered to by certain of
the layout engines.