Change edge placement from beneath to above nodes in Graphviz - graphviz

It took me some time to make the graph below look like it does right now, and I'm almost satisfied. The one thing that still bothers me is that the connection between D and B should be above all nodes for the sake of aesthetics.
The funny thing is, that supplying the ports for the edge doesn't impress dot which just makes the edge cross the connected nodes.
Do you have an idea on how to avoid this?
digraph {
graph [splines=ortho, nodesep=0.2, fontname="DejaVu Sans", rankdir=LR]
node [shape=box, fontsize=8]
edge [arrowsize=0.5]
subgraph cluster {
style=invis;
A -> B -> C;
A -> B -> C;
A -> B -> C -> D;
D -> E;
D:nw -> B:ne;
}
{
D -> F -> { C; E };
}
}
PS: You need the latest Graphviz version in order to get orthogonal edges.

It may be a function of the version of the engine you use. I'm not sure what version of dot the GraphViz Workspace http://graphviz-dev.appspot.com/ uses but it does run your problem connector across the top.

Related

In graphviz, can you bring two vertices closer together?

When describing a graph with graphviz, I sometimes find I want two vertices to appear closer together than the layout engine I chose places them. Is there a way to hint that I want them closer?
I'm mostly interested in the case of two connected vertices, so an answer specific to that case is fine.
Concrete example:
digraph G {
node [shape="circle"];
Start [shape="none" label=""];
C [shape="doublecircle"];
Start -> A;
A -> B [label="0,1"];
B -> C [label="0,1"];
C -> D [label="0,1"];
D -> D [label="0,1"];
}
I want the vertices Start and A to be closer.
You can't do that, but you can make nearly everything else twice as big, here is a start.
(But you can't increase the size of an edge to self)
digraph G {
rankdir=LR
edge[minlen=2 fontsize=28 arrowsize=2 penwidth=2]
node[fontsize=28 height=1 penwidth=2]
graph[fontsize=28 penwidth=2]
node [shape="circle"];
Start [shape="none" label=""];
C [shape="doublecircle"];
Start -> A[minlen=1]; // not twice the size to get the requested effect
A -> B [label="0,1"];
B -> C [label="0,1"];
C -> D [label="0,1"];
D -> D [label="0,1"];
}
[this answer applies specifically to dot]
there is no edge-level attribute that explicitly sets or changes edge length
the graph-level nodesep attribute sets minimum distance between two nodes of same rank
so:
digraph G {
nodesep=.17
{
rank=same
node [shape="circle"];
Start [shape="none" label=""];
C [shape="doublecircle"];
Start -> A;
A -> B [label="0,1"];
B -> C [label="0,1"];
C -> D [label="0,1"];
D -> D [label="0,1"];
}
}
produces:
To increase the distance between the other nodes, you can add spaces to the labels.
I'm not wild about it either, but this change:
B -> C [label=" 0,1 "]; // pad to make label (and edge) longer
produced this:

GraphViz: how to connect a node to the containing subgraph

I just learned how to connect nodes and subgraphs here on Stackoverflow. However, I want to connect a node to the containing subgraph:
digraph G {
compound=true;
subgraph cluster0 {
a -> b;
a -> c;
c -> {a b c} [lhead=cluster0];
}
c -> d;
d -> {a b c} [lhead=cluster0];
}
A quick sketch what I mean:
I want to connect d -> {a b c}, but for clarity reasons, I don't want to draw three different arrows, but just one arrow to the grouping of nodes. One way to do that is only list one arrow, like d -> a. That works, but is there a way to "collapse" three arrows into one when the head points to a cluster?
However, c -> {a b c} is not possible to point to a cluster, because c is part of that cluster. Is there a way to go around this?
you will need some scaffolding i.e. invisible node (and maybe edges) e.g.:
digraph top {
compound=true
node[shape=rectangle]
subgraph cluster1 {
a->{b c}
}
c->d
d->b[lhead=cluster1]
ca[shape=point height=0] // make ca invisible
a->ca:n[dir=back ltail=cluster1] // by drawing the arrow backward we get more control of the layout, n and s compass make the edge go smooth when enter and exiting ca
ca:s->c[dir=none] // no arrow on the tail part
}
rendered on viz-js.com:

How to put all unlinked nodes to the right?

digraph
{
rankdir=LR
a -> b
c -> b
b -> d
e // unlinked node
}
There are some nodes which are not linked to any of the other nodes in my dot file. Without explicitly using rank to define those nodes, is there any graceful way to put them to the right most position since it is a hard work to reparse the whole relations for finding them out and it is almost impossible to figure it out the maximum depth of the generated graph due to the opaqueness of node rearrangement policy?
You could put the unlinked nodes in a subgraph and use rank="max" to achieve this:
digraph
{
rankdir=LR;
a -> b;
c -> b;
b -> d;
{ rank="max"; e; }
}

simple "T shaped" graph in graphviz

Need draw a graph with dot/graphviz like this image:
The texts can be above arrows, like graphviz does it. But how to achieve the T-layout? Need make a cluster for the top row?
This is one possibility using rank=same for a subgraph:
digraph g {
node[shape=point, width=0.2];
{
rank=same;
p1 -> n [label="text1"];
n -> p2 [label="text2"];
}
n -> p3 [label="text3", dir=back];
n[label="node", shape=rect, style=rounded];
}
You could also use a left-right layout instead of top-down.
An other possibility is to disable the effect of some edges using constraint=false:
digraph g {
node[shape=point, width=0.2];
p1 -> n [label="text1", constraint=false];
n -> p2 [label="text2", constraint=false];
n -> p3 [label="text3", dir=back];
n[label="node", shape=rect, style=rounded];
}
The result is the same.
dot usually layouts trees in layers. To force an edge to not be a layer separation you can add the constraint=false option. So something like:
digraph {
A [shape=point]
B [shape=point]
C [shape=point]
N [label="node"]
A -> N [label="text1", constraint=false]
N -> B [label="text2", constraint=false]
N -> C [label="text3", dir=back]
}
should work.
Note that the edge from the lower node to "node" has to be backwards, since dot layouts trees from top to bottom. Therefore the logical edge direction has to be from top to bottom, even though the display direction might be the other way round (which is the case here).

Right to left edges in dot (Graphviz)

I'm trying to display edges going from right to left (i.e. backwards) using dot:
C <- A -> B
The best I could do was:
digraph {
a -> b;
c -> a [dir="back"];
{rank=same;c a b}
}
..which is fine, except I don't like using c -> a when the edge is directed the other way.
So I wanted to share this solution (which didn't seem to be mentioned on SO) and check if I'm missing something obvious.
See: http://www.graphviz.org/doc/info/attrs.html#k:dirType
I have no alternative to your usage of dir, but i can make it slightly shorter, if you want horizontal alignment, use the rankdir property of graph, to force direction from left to right.
digraph {
rankdir=LR;
a->b;
c->a [dir="back"];
}
To make edges point backwards by default:
digraph {
edge [dir="back"];
a -> b;
c -> a;
}
Then, override the default to point forwards:
c -> d [dir="forward"];

Resources