Graphviz: Align tree roots in a forest - graphviz

I defined a forest (a set of trees) in DOT.
I am using dot for layouting.
Now the problem: The trees have different depths. I would like to align the root nodes on the same level, however on default the nodes are aligned by the leaves.

I think you mixed up actual with expected in your question
digraph {
// create a forest hanging from the ceiling
node[shape=box]
edge[dir=back]
a->b->c
d->e->f->g
h->i
// ground the forest
ground_node[style=invis]
subgraph {
c;g;i
} -> ground_node [style=invis]
}

Related

Graph in Graph Extraction

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:

Graphviz (dot) control edge routing

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 GraphViz, make node positions within a subgraph independent from nodes in other subgraphs?

Using dot, the basic layout puts nodes into layers. If you create subgraphs, it groups related nodes inside of rectangles, but the nodes are still in layers, and those layers are influenced by the nodes outside of the subgraph.
Sometimes, this is great. But sometimes, when a subgraph is an independent visual entity, it might be nice to be able to lay out its content without respect to the layers of the other parts of the graph. Take for example the following:
digraph x {
subgraph one {
a [ label="a\nvery\nlong\nlabel" ]
b [ label="another\nvery\nlong\nlabel" ]
c [ label="still\nmore\nlong\nlabels" ]
a -> b - > c
}
subgraph two {
w -> x -> y -> z
}
}
Because of the long labels, the nodes in subgraph one will take up a lot of space. But because of the layer-based layout, the nodes in subgraph two will be vertically aligned with the corresponding nodes from subgraph one.
Is there a way to make it layout subgraph two as if subgraph one did not exist?
Not directly with dot. Dot does rank alignment across the entire graph. However here are two ways to get close to what you want:
use neato -Goverlap=false -Gmode=hier to approximate a dot layout:
or split the various parts into separate graphs, use dot -Tdot to layout each, then use gvpack (https://graphviz.org/pdf/gvpack.1.pdf) to combine the parts into a single output. Like so:
dot -Tdot ComboGraph1a.gv >ComboGraph1a.dot
dot -Tdot ComboGraph1b.gv >ComboGraph1b.dot
gvpack -array_ib2 ComboGraph1?.dot |neato -Tpng -n2 >oooo.png
Giving:

Add extra edges to a digraph in Graphviz

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

Graphviz subgraph doesn't get visualized

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.

Resources