Add space between 2 connected nodes - graphviz

I would like to add a little more horizontal space between the 2 nodes so the edge labels appear associated to their node (instead of in the middle of the edge):
The graphviz source:
digraph {
rankdir="LR";
node [shape=cylinder]
clone
initial
clone -> initial [headlabel="origin",taillabel="clone"]
}
Expected:
I tried using nodesep but it seems to only work when there are no edges.

nodesep was a good try, but your ranking is LR, so ranksep is the way to go
digraph {
rankdir="LR";
ranksep=1.2 // rank-to-rank in inches
node [shape=cylinder]
clone
initial
clone -> initial [headlabel="origin",taillabel="clone"]
}
Giving:

Related

How do I force nodes to be drawn next to each other with Graphviz dot?

I'm looking to have a series of nodes in a row, joined by an edge. This works fine when the graph's rankdir is set to TB or BT, but it rearranges the nodes when I set it to LR or RL so they're no longer next to each other. Example images are included.
I've taken my code and stripped it down to it's minimum point for demonstration. The code is the same for both of the following graphs, aside from line 2 (which specifies rankdir):
digraph{
rankdir=LR;
node[shape=box,fontcolor=white,color=black,fillcolor=black,style=filled];
edge[dir=none,color=black];
Josh -> JoshParent;
JoshParent -> Hero;
JoshParent[shape=circle,label="",height=0.0001,width=0.0001];
{
rank=same;
Kae[label="Kae"];
Hero[label="Hero"];
Kae -> Hero;
}
Kae -> KaeParent;
Hero -> HeroParent;
KaeParent -> Liz;
KaeParent[shape=circle,label="",height=0.0001,width=0.0001];
HeroParent -> George;
HeroParent[shape=circle,label="",height=0.0001,width=0.0001];
{
rank=same;
George[label="George"];
Liz[label="Liz"];
Ocean[label="Ocean"];
Egg[label="Egg"];
Liz -> Ocean -> Egg;
}
}
This is what's shown with rankdir=TB:
This is what's shown with rankdir=LR:
As you can see, from the LR image, the nodes have been drawn in the order "Ocean, George, Egg", rather than "Ocean, Egg, George" as it is with the TB image.
You can force the order by adding an explicit but invisible edge from Egg to George:
Liz -> Ocean -> Egg; // last line of your code
Egg -> George[ style = invis ]; // additional edge
This produces
I don't have an explanation for the different behaviour between TB and LR, though.

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]
}

graphviz/dot: can the distance between two nodes be set individually?

I'm trying to use dot (version 2.28.0) in order to make a flow chart of my source code. For that, I would like the graph to consist of subgraphs where each of these subgraphs represents a source file in the code base. At the top of each subgraph, there should be the file name as a node in a visually easily distinguishable fashion (i.e. bold, white text on dark blue background). Below the file name node should be the nodes representing the flow of routines in that file in the order they are being called.
My problem now is that I would like the distance between "filename nodes" and "routine nodes" to be smaller than the distance between individual "routine nodes", plus, there should be no arrow between.
I tried to use the minlen attribute for the edge connecting the "filename node" to the first "routine node", but when I set that to a value below 1.0, the two nodes come out next to each other rather than stacked.
Is there any way to make the first two nodes be closer to each other than the other two, yet top/bottom oriented?
digraph "prog.c"
{
edge [fontname="FreeSans",fontsize="12",labelfontname="FreeSans",labelfontsize="10"];
node [fontname="FreeSans",fontsize="14",shape=record,height=0.2];
compound=true;
subgraph cluster_main {
Node1_0 [label="main.c", shape=folder, fontcolor="white", style=filled, fillcolor="#00008b"];
Node1_1 [label="routine1()"];
Node1_2 [label="routine2()"];
edge [color="transparent", minlen="0.5"]; // stacking not ok
// edge [color="transparent", minlen="1.0"]; // stacking ok
Node1_0 -> Node1_1 ;
edge [color="black", minlen="1.0"];
Node1_1 -> Node1_2 ;
}
}
Edit: I should have commented out the line which lead to the undesired result rather than the one leading to the desired result (I had planned to attach two pngs for clarification, but I'm not allowed to do so as a newbie); so here is the code I would actually want to modify in a way that the first two nodes have a different (smaller) distance to each than the last two.
digraph "prog.c"
{
edge [fontname="FreeSans",fontsize="12",labelfontname="FreeSans",labelfontsize="10"];
node [fontname="FreeSans",fontsize="14",shape=record,height=0.2];
compound=true;
subgraph cluster_main {
Node1_0 [label="main.c", shape=folder, fontcolor="white", style=filled, fillcolor="#00008b"];
Node1_1 [label="routine1()"];
Node1_2 [label="routine2()"];
//edge [color="transparent", minlen="0.5"]; // stacking not ok
edge [color="transparent", minlen="1.0"]; // stacking ok
Node1_0 -> Node1_1 ;
edge [color="black", minlen="1.0"];
Node1_1 -> Node1_2 ;
}
}
There are a couple of "graph" properties that can control what you need.
pad, ranksep, nodesep
Also, I increased your node size, but only for my own ease of use...
digraph "prog.c"
{
graph [pad=".75", ranksep="0.25", nodesep="0.25"];
node [fontname="FreeSans",fontsize="14",shape=record,width=2, height=.5];
edge [fontname="FreeSans",fontsize="12",labelfontname="FreeSans",labelfontsize="10"];
compound=true;
subgraph cluster_main {
Node1_0 [label="main.c", shape=folder, fontcolor="white", style=filled, fillcolor="#00008b"];
Node1_1 [label="routine1()"];
Node1_2 [label="routine2()"];
edge [color="transparent", minlen="0.5"]; // stacking not ok
// edge [color="transparent", minlen="1.0"]; // stacking ok
Node1_0 -> Node1_1 ;
edge [color="black", minlen="1.0"];
Node1_1 -> Node1_2 ;
}
}

edge-layout in graphviz for fixed node positions

I was trying to write my own little algorithm for graph layout that only creates a node layout but does not define edge routes. When I use Graphviz to turn the resulting dot file into a graph, the edges are straight lines that cross the nodes and even overlap each other. Is there a way to use Graphviz to layout the edges as nicely as the dot algorithm does, but have the nodes in predetermined fixed positions?
You can see the effect for instance on the following graph:
digraph test {
"a" [pos="0.0,0.0"];
"b" [pos="50.0,50.0"];
"c" [pos="100.0,100.0"];
"a" -> "b";
"a" -> "c";
"b" -> "c";
}
When drawn with dot -Knop -Tpng -otest.png test.dotty the line between a and c crosses b. What I want is that all nodes keep their positions, but the line between a and c goes around b.
Just add:
splines=true;
to your graph - result is:

How to specify the length of an edge in graphviz?

In a directed graph, if there is a cycle, the graphviz makes that edge really short.
Is there a parameter that would let me change the length of the cyclic edge, so that
the graph looks a bit uniform.
digraph ER {
rankdir="LR";
//orientation=landscape;
node [shape=ellipse, fontsize=30];
{node [label="Original"] old;}
{node [label="Final"] new;}
{node [label="Intermediate"] ir;}
old -> ir [label="suggest", fontsize=30];
ir -> ir [label="validate", fontsize=30, len=f];
ir -> new [label = "finalize", fontsize=30];
}
Edit: Sorry, my answer will make edges longer, but not the self referencing edges you need.
len doesn't work in dot, but minlen does.
https://www.graphviz.org/doc/info/attrs.html#d:minlen
x->y
[minlen=5]
len doesn't works in dot, but you can try this trick:
digraph G {
rankdir=LR
a->b[dir=both]
b->c[dir=both,label=" "]// Just use the space to increase the edge length
}
If rankdir=TB, use label="\n" (repeat the \n as necessary) to increase the length.
I found that the following attribute nodesep worked to solve this problem with sfdp.
From nodesep | Graphviz:
For layouts other than dot
nodesep affects the spacing between loops on a single node, or multiedges between a pair of nodes.
Note that this is a graph attribute, so the value is the same for all edges in the graph.
From dot(1):
len=f sets the optimal length of an edge. The default is 1.0.
You can make the cyclic edge longer by adding a bunch of invisible cyclic edges before your visible one, like this:
digraph ER {
rankdir="LR";
//orientation=landscape;
node [shape=ellipse, fontsize=30];
{node [label="Original"] old;}
{node [label="Final"] new;}
{node [label="Intermediate"] ir;}
old -> ir [label="suggest", fontsize=30];
ir -> ir [style="invis"]
ir -> ir [style="invis"]
ir -> ir [style="invis"]
ir -> ir [style="invis"]
ir -> ir [label="validate", fontsize=30, len=f];
ir -> new [label = "finalize", fontsize=30];
}
In .dot language, the edge connects two notes with different ranks.
The length of edge is equal to (difference in ranks)*ranksep
default ranksep (in graph attribute) is 0.75 inch, so edge of adjacent nodes will be 0.75 inch.
To reduce the edge length, you set ranksep into a smaller value in graph atrribute
There's another approach that I now use for this:
I use graphviz to output the file in dot format
dot -T dot -Kneato -o ./positioned.dot ./input.dot
This file will contain the Bezier curve definitions for every edge.
I manually change the points to curve the way I want it to draw.
This may look a little daunting at first but once you figure out, how they work this isn't hard, I'm inching towards a script that will do this for me automatically
then re-run dot with your edited positioned file as the input
dot -T png -Kneato -O ./positioned.dot
With this approach I've pretty much turned dot into my text based visio replacement

Resources