Is it possible to define subgraphs (clusters) in Graphviz with a specified, fixed layout - graphviz

How can I create subgraphs/clusters in Graphviz, with nodes at specific positions, and then have Graphviz rotate and arrange these subgraphs according to a set of interconnecting edges (i.e. edges not within the subgraphs)?
Here's my current attempt. Problem is that I want to be able to define the internal ordering of the nodes, such that, as an example, the nodes in subgraph "3" are aligned in a row (and always ordered A-B-C):
graph {
forcelabels=true
color=lightgrey
subgraph cluster_1 {
node[shape=point]
{rank=same r1A r1B}
label="1"
r1A [xlabel="A", fontsize=7]
r1B [xlabel="B", fontsize=7]
}
subgraph cluster_2 {
node[shape=point]
{rank=same r2A r2B}
label="2"
r2A [xlabel="A", fontsize=7]
r2B [xlabel="B", fontsize=7]
}
subgraph cluster_3 {
node[shape=point]
{rank=same volA volB volC}
label="3"
volA [xlabel="A", fontsize=7]
volB [xlabel="B", fontsize=7]
volC [xlabel="C", fontsize=7]
}
}
If I add edges, I want Graphviz to be able to rotate the subgraphs, but while preserving that internal layout and ordering. Here, using engine fdp, subgraph "3" gets all rearranged (for obvious reasons, since I haven't got any way of fixing the layout):
And what about more advanced "layouts"? Is it possible/feasible to make a subgraph resembling a microcontroller, something like this:

Unfortunately, none of the Graphviz engines do node rotation. You would have to create a complete engine for node rotation (the architecture supports this) or a pre/post processor just for node rotation (more later)
Also Graphviz only seems to support text rotation at a Root graph level. This might be a killer, depending on your requirements.
If you want to use clusters (suggestion: nope), you probably need to use the dot engine to line up your nodes.
Html-records (possibly with included images) would probably be a "better" choice for the ICs. Again, none of the engines will rotate them, but ...
Cycles are cheap, so if there are not "too many" ICs, generate all possibilities (each IC rotated & not) and then eyeball evaluate or write a post-processing program to determine the "best" result.
Also note that Graphviz edge routing might not produce what you want.

Related

How to center a cluster in graphviz

Having a example graph like this:
digraph g{
subgraph cluster_test{
john;
mike;
}
amy->john;
jack->mike;
jack->john;
james->john;
}
How could the cluster_test subgraph be positioned so each other nodes are getting places around it.
The fdp layout uses a "spring" model and may suit your needs better than the hierarchical graphs dot produces. It's the only other layout besides dot which supports clusters.

How to draw overlapping clusters in Graphviz?

I'm trying to use GraphViz to draw graphical models. However, I didn't find a way to make draw overlapping clusters. For example, how can I make "nodeA->nodeB" to lie inside both clusterA and clusterB?
AFAIK you can't.
Clusters as described in the documentation:
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.
The whole idea of clusters is not to overlap, but to group nodes (and graphviz raises an error when a node is part of two subgraphs).

Drawing a border around a set of vertices in Graphviz

I am trying to draw a graph with Graphviz.
I wish to draw a dotted line around a set of vertices, symbolizing that they are a part of a bigger entity.
Say for example, if I have three vertices as eggs, chicken and ham, I should be able to draw a dotted line around all three of them, and label that border as food.
It is possible to group nodes in graphviz by putting them into a cluster. A cluster is a special kind of subgraph which certain layout engines (dot, fdp, ...) support, and if supported, the nodes in a cluster will be drawn together.
From the documentation:
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.
Important: The ID of the subgraph has to start with cluster.
Example:
graph g{
subgraph cluster_food {
eggs; chicken; ham;
label="Food";
graph[style=dotted];
}
}

Graphviz: Stacking fields vertically within a subraph

I am trying to stack a group of fields vertically (there are 8 specific fields, so I would preferably have 4x4) within Graphviz. I have a subgraph cluster containing 8 fields, which by default are lined up side by side horizontally, making connections extremely messy. I feel it would be much more clear if the subfields were stacked vertically.
A common technique to layout nodes is to use invisible edges.
In the following example, the nodes n1-n8 are layed out vertically within a cluster, but no edges are displayed.
digraph g{
subgraph cluster0 {
edge[style=invis];
n1->n2->n3->n4->n5->n6->n7->n8;
}
// some visible edges from nodes outside of the cluster to nodes within the cluster
a -> b;
a -> {n2;n7;n8};
b -> {n4;n6;n7;};
}

Grouping output edges from graphviz

I'm trying to draw a graph with two kinds of edges, and I want the two kinds of edges to link to each node from opposite sides, as much as possible. I.e. if an edge of type A enters from the left, I want all edges of type B to exit to the right. I know I could specify compass directions, but I'd like graphviz to be able to switch this around to minimize graph clutter.
Is it this, or something similar, possible?
If you don't want to specify compass points, you'll probably not want to use HTML like labels and ports either.
If you're using dot, you still can achieve something similar by using the samehead and the sametail attributes. From the reference:
Edges with the same head and the same
samehead value are aimed at the same
point on the head
This lets you group outgoing and incoming edges. Here's a simple example:
digraph g{
rankdir=LR;
edge[samehead=h1, sametail=t1];
a1->b->c1;
a2->b->c2;
edge[samehead=h2, sametail=t2];
a3->b->c3;
a4->b->c4;
}
This of course is only about grouping heads and tails of edges, and does not guarantee opposite sides for edges of different types.
My current solution is to replace my old nodes with edges, thus creating two nodes - one for each "port" in the graph. I can then my edges between these "port nodes". Eg. instead of
node1 -> node2 [ sametail="b", samehead = "a" ]
I write
node1_a -> node1_b [ dir=none, style=bold ]
node2_a -> node2_b [ dir=none, style=bold ]
node1_a -> node2_b // if I got head and tail right :-)
Although I don't get boxes for my "nodes", this works okay for my purposes.

Resources