Graphviz: how to reduce the top and bottom margins of a node? - graphviz

How can I reduce the top and bottom margins of these Graphviz nodes? I am specifying "0.05, 0.0 as the margins to each node, with fontsize = 8.

digraph { rankdir = LR
node [shape=box margin=0 width=0 height=0]
asdf [label="asdf\nasdf"]
qwer [label="qwerqwer"]
asdf -> qwer
}

Nodes have a default minimum size (width and height), so if you reduce margins beyond a certain point, it has no effect. At least, this is how it works with box (rectangular) nodes and some of the other simple shapes.
width and height actually specify the minimum width and height, not the actual width and height (unless you also specify that sizes are fixed). So to get smaller margins, you can just use very small width and height values, and the shapes will still be stretched to fit the labels.
With defaults:
digraph {
node [shape=box]
a -> "longer name"
"longer name" -> "taller\nname"
}
Smaller:
digraph {
node [shape=box,width=0.1,height=0.1]
a -> "longer name"
"longer name" -> "taller\nname"
}
You can also set the margin itself if you want it smaller:
digraph {
node [shape=box,width=0.1,height=0.1,margin=0.01]
a -> "longer name"
"longer name" -> "taller\nname"
}

Related

Graphviz drawing - make a box that starts at one node and goes to the end of another one

I have a timeline and would like a box to be drawn next to a particular number of years
digraph timeline {
node [fontsize=24, shape = plaintext];
1940 -> 1950;
1950 -> 1955;
1955 -> 1960;
node [fontsize=20, shape = box];
{ rank=same; 1940 test; }
}
This places a timeline on the left hand side going from 1940 to 1950 and so forth. I would like draw a box next to the numbers that starts at 1940 - which is what I do now with { rank=same; 1940 test; } and that ends with 1955.
Here is an example of the box drawn at 1940
Here is an example of the box drawn at 1955 with code { rank=same; 1955 test; }
I would like to have the box drawn from the start of 1940 position to the end of 1955 position, so encompassing these two boxes right now.
Tricky solution is to draw a cluster and place invisible nodes inside it using style=invis. Then align the cluster with the timeline using newrank.
Script:
digraph timeline {
newrank=true;
node [fontsize=24, shape = plaintext];
1940 -> 1950 -> 1955 -> 1960;
subgraph cluster_1 {
test [fontsize=20]
cl_start [shape=none style=invis]
cl_end [shape=none style=invis]
cl_start -> test -> cl_end [style=invis]
}
{rank=same;1940;cl_start}
{rank=same;1955;cl_end}
}
Result:
No easy way to do this with Graphviz.
dot does not allow nodes to span ranks. It centers all nodes in the same rank on the same line (horizontal, with rankdir=TB).
if you set rankdir=LR, you can get nodes to span years, but positioning & node sizing become difficult
you could put a node on every year you want the final node to span and the post-process the result to overwrite the several nodes with a single large node.
you can us the neato -n (https://graphviz.org/faq/#FaqDotWithNodeCoords) capability and position & size all the nodes yourself
or you could try another language entirely (maybe pikchr https://pikchr.org/home/doc/trunk/homepage.md)

How can I align two (disconnected) nodes in GraphViz?

Suppose I have the GraphViz graph:
digraph G {
a->b->d;
c->d;
}
How can I make a and c be aligned vertically, i.e. appear at the same height?
You can align them using grouping and a group-scope attribute:
digraph G {
{rank = same; a; c;}
a->b->d;
c->d;
}
Note that if your rankdir value is different, this alignment will not be vertical: e.g. if rankdir=LR then a and c will be horizontally aligned to the same position - with the arrows pointing rightwards.

Arranging graphviz clusters

I'm trying to generate the following construct:
I have four graphs. Three of them are supposed to be in the first "row", all vertically aligned by their vertical center. The fourth graph is supposed to be below the other three, in the second "row". It should be horizontally aligned with either the horizontal center of the upper row's middle graph or the horizontal center of the entire upper row. Additionally there will be edges between some members of separate clusters/graphs.
Here there are only edges between members of cluster_a and cluster_d, but there may be edges between members of any combination of clusters.
Ususal you can do this by adding some additional invisible scarfolding nodes and edges e.g.:
digraph G {
rankdir=LR
edge[minlen=2]//enable finer control over node location when scarfolding
subgraph cluster_d { label=cluster_d
d_0->d_2
d_1->d_0
//d_1->d_3
//extra node to simulate edge between edges
d_13[shape=point]
d_1->d_13[dir=none minlen=1]
d_13->d_3[minlen=1]
d_3->d_2
d_3->d_3
}
subgraph cluster_abc { // better align cluster
subgraph cluster_a { label=cluster_a
a_0->a_2
a_0->a_3
a_1->a_0
a_1->a_1
a_1->a_2
a_1->a_3
//a_2->a_3
//extra node to simulate edge between edges
a_23[shape=point]
a_2->a_23[dir=none minlen=1]
a_23->a_3[minlen=1]
a_3->a_2
a_3->a_3
}
subgraph cluster_c { label=cluster_c
c_0->c_0
c_0->c_1
c_0->c_2
c_0->c_3
c_1->c_3
c_3->c_3
c_2->c_0
c_2->c_1
c_2->c_2
c_2->c_3
}
subgraph cluster_b { label=cluster_b
b_0->b_0
b_0->b_2
b_0->b_3
b_1->b_1
b_1->b_2
b_1->b_3
b_2->b_0
b_3->b_2
}
color=invis
}
{//scarfolding
edge[style=invis]node[style=invis] //hide scarfolding
{
rank=same
node[shape=point] //minimize impact on edge routing around the scarfolding nodes
x_0
x_1
}
a_3->c_0
c_3->b_0
// we can not use same rank across cluster boundary so instead of a_3->d_1 we do a_2->x_0 + x_1->d_1
a_2->x_0
x_1->d_1[minlen=3]
}
{
edge[headclip=false tailclip=false]
a_2->d_1[dir=none constraint=false]
a_3->d_3[dir=none]
}
a_23->d_13[dir=none constraint=false]
}

Graphviz: reducing margin on skewed polygon node

I want to use a skewed polygon (aka parallelogram) on Graphviz, the problem is there is too much space between parallelogram border and it's text.
digraph G {
poly1[margin=0, width=0, height=0, shape=polygon, label="This is a polygon\nwithout skew"]
poly2[margin=0, width=0, height=0, shape=polygon, label="This is a polygon\nwith skew", skew=0.3]
}
This is the result of previous code:
As you can see, as soon I set a skew value (ìn this case skew=0.3) the polygon's interior margin increases a lot. Setting margin=0, width=0 and height=0 does not solve the issue.
Is there a way to remove the polygon's interior margin?
There's a way, but it ain't pretty:
digraph G {
poly1[margin=0, width=0, height=0, shape=polygon, label="This is a polygon\nwithout skew"]
poly2[margin=0, width=1.8, height=0.46, shape=polygon, fixedsize=true, label="This is a polygon\nwith skew", skew=0.3]
}
Adding fixedsize=true and specifying the node's width and height (by trial and error) yields this:

equal widths for boxes in graphviz

Is it possible to get two boxes to be as wide as the widest one.
digraph G {
node[shape=box];
"A long description of a node" -> "short description";
}
Will produce:
But I want the two boxes' size to be aligned.
You can control the (minimum) size of the box with the width and height parameters:
digraph G {
node[shape=box, width = 2.5, height = .75 ];
"A long description of a node" -> "short description";
}
yields

Resources