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; }
}
Related
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:
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:
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.
I have a directed graph specified in Graphviz's dot language, e.g.
digraph G { A -> B [label="foo"]; A -> B [label="bar"]; B -> A; C; }
I want to automatically process this into a graph with its edges reversed, i.e.
digraph G { B -> A [label="foo"]; B -> A [label="bar"]; A -> B; C; }
I would like to use a robust solution (i.e. one that understands the graph and therefore probably doesn't use sed) that preserves any existing edge labels and other attributes. Note that I am not merely talking about getting dot to render my graph with the arrows pointing backward; I really need a graph whose edges are reversed. (In this case, I intend to reverse the edges, apply prune, then reverse the edges again.)
How can I reverse the direction of every edge in a Graphviz (dot-language) graph?
Easiest way is to include a graph-level dir statement where you reverse the direction of the arrows. By default, the direction is forward. If you reverse it at the top of your graph, then without changing a single other line, the graph will show up the way you want.
What you have now is this:
digraph G
{
edge [dir="forward"]; /* implied */
A -> B [label="foo"];
A -> B [label="bar"];
B -> A;
C;
}
What you want is this:
digraph G
{
edge [dir="back"]; /* note the change to this line */
A -> B [label="foo"];
A -> B [label="bar"];
B -> A;
C;
}
The best I've come up with so far is
BEG_G {
graph_t g = graph($.name + " reversed", "D");
int edge_id = 0;
}
N {
clone(g, $);
}
E {
node_t newHead = clone(g, $.head);
node_t newTail = clone(g, $.tail);
edge_t newEdge = edge_sg(g, newHead, newTail, edge_id);
copyA($, newEdge);
edge_id++;
}
END_G {
$O = g;
}
which I then invoke with gvpr.
This does add a "key" attribute to all resultant edges, but I'm not sure how to avoid that and still preserve multiple edges between the same pair of nodes.
When I do echo 'digraph G { A -> B [label="foo"]; A -> B [label="bar"]; B -> A; C; }' | gvpr -f reverseAllEdges.gvpr, I get:
digraph "G reversed" {
A -> B [key=2];
B -> A [key=0, label=foo];
B -> A [key=1, label=bar];
C;
}
I don't know how robust this will prove to be, but it looks promising.
The Python library NetworkX has a directed multigraph type, MultiDiGraph, which has a reverse() method. It also uses pydot for loading and writing DOT files.
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"];