dot tool doubles arrows - cluster-computing

I've recently been using dot to create flow- and callgraphs of a rather complex assembly program. All in all this works perfectly fine, with just a little hickup. Sometimes, when drawing a line from one node inside a cluster to another node in a different cluster, the line somehow doubles.
I've added a stripped down version of my problem as code and a dot output image.
Thanks
digraph G {
ratio=auto; node[fontsize=12]; label="boot"; newrank=true;
{
node[shape=plaintext];
1->2[arrowsize=0.7,penwidth=0.1];
}
Reset->uart_init[arrowsize=0.7, penwidth=0.1];
{ rank=same; "Reset"; "1"; }
{ rank=same; "uart_init"; "2"; }
/* terminalhooks cluster */
subgraph cluster42 {
fontsize=12;
label="terminalhooks.asm";
labelloc=b;
type->emit[arrowsize=0.7,penwidth=0.1];
emit[label=<emit<BR/><FONT POINT-SIZE="8">Terminal redirection hooks<BR/>für eventuelle Umleitungen</FONT>>];
}
/* stm-terminal cluster */
subgraph cluster43 {
fontsize=12;
label="stm-terminal.asm";
labelloc=b;
emit->serial_emit->serial_qemit[arrowsize=0.7,penwidth=0.1];
serial_emit[label=<serial_emit<BR/><FONT POINT-SIZE="8">Ausgabe Char via UART</FONT>>];
serial_qemit[label=<serial_qemit<BR/><FONT POINT-SIZE="8">Prüft TXE (Transmit Buffer Empty)</FONT>>];
}
{ rank=same; "type"; "emit"; "serial_emit"; "serial_qemit"; }
}
dot graph

I have no idea why this happening, but adding tailport=e seems to fix it:
emit->serial_emit->serial_qemit[tailport=e,arrowsize=0.7,penwidth=0.1];
# -----^-----
Edit:
It appears the newrank atr causing the problem.
digraph G {
newrank=true;
subgraph cluster42 {
0;
1;
0->1;
}
subgraph cluster43 {
2;
3;
1->2->3;
}
{ rank=same; 0; 1; 2; 3; }
}
produce:
but if you remove:
newrank=true;
it produce:
Edit 2:
For this example you can use rankdir=LR and remove the rank=same:
digraph G {
rankdir=LR;
subgraph cluster42 {
0;
1;
0->1;
}
subgraph cluster43 {
2;
3;
1->2->3;
}
}
maybe you can do same with your complex graph too.

Related

Forcing subgraphs to align with newrank=true

Here is my graph:
Is it possible to shift the "User-facing options" subgraph downward, so that "User-facing content" is above both that subgraph and the "Internal tags" subgraph? I tried using the technique described in https://stackoverflow.com/a/18410951/2954547 to force either topic or role to align with tag, but for some reason it really really wants to put the other node in that subgraph above the tag node, and not below it.
I see that you can also mess with the weight parameter to adjust the output, as in https://stackoverflow.com/a/14348263/2954547, but this just made the lines shorter and longer.
My desired output is to shift the left subgraph like so:
Current source code:
digraph G {
compound=true;
newrank=true;
subgraph cluster_userFacing {
label="User-facing options";
labelloc="bottom";
role [label="User Role\n(User Classification)"];
topic [label="Topic\n(External Tag)"];
}
subgraph cluster_content {
label="User-facing Content";
article [label="Article"];
podcastEpisode [label="Podcast Episode"];
}
subgraph cluster_internal {
label="Internal tags";
labelloc="bottom";
tag [label="Tag\n(Internal Tag)"];
tagCategory [label="Tag Category"];
tag -> tagCategory;
}
role -> tag [dir="none"];
topic -> tag [dir="none"];
article -> tag;
podcastEpisode -> tag;
{ rank="min"; podcastEpisode; article; }
{ rank="same"; topic; tag; }
}
Enclosed the two clusters inside a new invisible (peripheries=0) cluster.
Set constraint=false to override ranking. And added an invisible edge.
digraph G {
node [height=.78] // make all nodes same height
subgraph clusterGroup{
peripheries=0
subgraph cluster_userFacing {
peripheries=1
label="User-facing options";
labelloc="bottom";
role [label="User Role\n(User Classification)" ]
topic [label="Topic\n(External Tag)"];
}
subgraph cluster_internal {
peripheries=1
label="Internal tags";
labelloc="bottom";
tag [label="Tag\n(Internal Tag)" group=G];
tagCategory [label="Tag Category"];
tag -> tagCategory;
}
}
subgraph cluster_content {
label="User-facing Content";
article [label="Article" ]
podcastEpisode [label="Podcast Episode" group=G];
}
role -> tag [dir="none" constraint=false];
topic -> tag [dir="none" constraint=false];
article -> tag
podcastEpisode -> tag;
role -> topic [style=invis]
}
Giving:

graphviz cluster top down

digraph {
rankdir=LR
compound=true
node [shape="plaintext"];
transfer->transferRead; transfer->transferWrite;
transferRead->transferReadSendData[lhead=cluster_transferRead]
subgraph cluster_transferRead{
{
rank=same;
transferGetFile->transferSendType->transferReadSendData->transferRecvID;
}
}
}
I want the cluster in the right,top to down。but get down to top。how to fix it?
You could reverse the edge direction in the graph and reverse the way they are displayed in the cluster:
edge[dir=back];
transferRecvID->transferReadSendData->transferSendType->transferGetFile

Graphviz : Ordering node in a cluster

I'm working on an auto-generated Graphviz (so it need to be a general solution, not for this particular example). It draws the topology of a network. but the results inside the cluster don't look organised.
Here is the topology:
Here is the associed code :
digraph G {
splines=polyline;
subgraph cluster_sh5sl8 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh5sl8_L1 [label = "L1"];
label = "5/8";
}
subgraph cluster_sh5sl10 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh5sl10_L1 [label = "L1"];
label = "5/10";
}
subgraph cluster_sh5sl12 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh5sl12_L1 [label = "L1"];
label = "5/12";
}
subgraph cluster_sh5sl14 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh5sl14_L1 [label = "L1"];
label = "5/14";
}
subgraph cluster_sh5sl16 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh5sl16_L1 [label = "L1"];
label = "5/16";
}
subgraph cluster_sh6sl3 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh6sl3_L1 [label = "L1"];
label = "6/3";
}
subgraph cluster_sh6sl8 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh6sl8_L1 [label = "L1"];
label = "6/8";
}
subgraph cluster_sh6sl10 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh6sl10_L1 [label = "L1"];
label = "6/10";
}
subgraph cluster_sh6sl12 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh6sl12_L1 [label = "L1"];
label = "6/12";
}
subgraph cluster_sh6sl14 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh6sl14_L1 [label = "L1"];
label = "6/14";
}
subgraph cluster_sh6sl16 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh6sl16_L1 [label = "L1"];
label = "6/16";
}
subgraph cluster_sh30sl1 {
rank=same;
style=filled;
color=lightgrey;
node [style=filled,color=white];
sh30sl1_9600 [label = "9600"]; sh30sl1_9590 [label = "9590"]; sh30sl1_9580 [label = "9580"]; sh30sl1_9570 [label = "9570"]; sh30sl1_9560 [label = "9560"]; sh30sl1_9280 [label = "9280"]; sh30sl1_9270 [label = "9270"]; sh30sl1_9260 [label = "9260"]; sh30sl1_9250 [label = "9250"]; sh30sl1_9220 [label = "9220"]; sh30sl1_9190 [label = "9190"]; sh30sl1_OMD [label = "OMD"];
label = "30/1";
}
sh30sl1_9570 -> sh5sl8_L1;
sh30sl1_9560 -> sh5sl10_L1;
sh30sl1_9280 -> sh5sl12_L1;
sh30sl1_9270 -> sh5sl14_L1;
sh30sl1_9260 -> sh5sl16_L1;
sh30sl1_9220 -> sh6sl3_L1;
sh30sl1_9250 -> sh6sl8_L1;
sh30sl1_9190 -> sh6sl10_L1;
sh30sl1_9600 -> sh6sl12_L1;
sh30sl1_9590 -> sh6sl14_L1;
sh30sl1_9580 -> sh6sl16_L1;
sh6sl12_L1 -> sh30sl1_9600;
sh6sl14_L1 -> sh30sl1_9590;
sh6sl16_L1 -> sh30sl1_9580;
sh5sl8_L1 -> sh30sl1_9570;
sh5sl10_L1 -> sh30sl1_9560;
sh5sl12_L1 -> sh30sl1_9280;
sh5sl14_L1 -> sh30sl1_9270;
sh5sl16_L1 -> sh30sl1_9260;
sh6sl8_L1 -> sh30sl1_9250;
sh6sl3_L1 -> sh30sl1_9220;
}
Note that I'm using FDP, but I can use anything else if it works. Currently, FDP gives me the best results.
How can I order this?
I already tried with clusterrank, ranksep, nodesep, constraint=false, or call them in another order, etc. I tried create un inivible node and link every other node inside a cluster to make them equidistant, but it didn't work.
I do not have an answer yet that would work with generated results- I have a similar issue where I can modify the graphviz file myself:
with
<graphviz>
digraph hierachy {
rankdir="LR"
graph [ordering="out"];
subgraph cluster_Hierachie {
label="Hierachie"
n0
n10000
n20000
n30000
n40000
n50000
n0->n10000
n0->n20000
n0->n30000
n0->n40000
n0->n50000
}
}
</graphviz>
which is rendered as:
and so far found the following links:
Preventing graphviz from rearranging nodes
please note the different suggestions on how to specify "ordering=out"
digraph g {
ordering=out ;
or
digraph bt {
graph [ordering="out"];
none of these work for me although https://stackoverflow.com/a/9169194/1497139 got 1 upvote and https://stackoverflow.com/a/9168680/1497139 has 2 upvotes
http://www.graphviz.org/content/ordering-edges
suggests to use
rank=same
so I tried:
<graphviz>
digraph hierachy {
rankdir="LR"
graph [ordering="out"];
subgraph cluster_Hierachie {
label="Hierachie"
n0
n10000
n20000
n30000
n40000
n50000
n0->n10000
n0->n20000
n0->n30000
n0->n40000
n0->n50000
{
rank=same;n0;n10000;n20000;n30000;n40000;n50000
}
}
}
</graphviz>
which renders as:
http://www.graphviz.org/content/cluster-changes-nodes-order
suggests to add
style=invis
{ rank=same 0 -- 1 [style=invis]
}
nodes. I tried that to no avail and ended up doing
<graphviz>
digraph hierachy {
rankdir="LR"
graph [ordering="out"];
subgraph cluster_Hierachie {
label="Hierachie"
n0
n10000
n20000
n30000
n40000
n50000
n0->n50000
n0->n40000
n0->n30000
n0->n20000
n0->n10000
}
}
</graphviz>
which renders as:
which I consider to be a valid work-around given the strange behavior of reverse ordering in clusters.

Force "heading" nodes to top of graph in rankdir=LR

I want to have the 'start middle end' label appear at the top of my graph
But it seems to default to the bottom no matter where I put the code. Is it possible?
digraph G {
rankdir=LR;
{node [shape=plaintext, fontsize=16];
"Start"->"Middle"->"End"[style=invis];
}
node [shape=box];
{ rank=same
"Start";a;
}
{ rank=same
"Middle";b;d;
}
{ rank=same
"End";c;e;
}
"a"->"b"->"c";
"d"->"e";
}
This works for me.
digraph G {
rankdir=LR;
{
node [shape=box];
blank [style=invisible]
blank -> d [style=invisible dir=none]
"a"->"b"->"c";
"d"->"e";
}
{
node [shape=plaintext, fontsize=16];
"Start"->"Middle"->"End"[style=invisible dir=none];
}
}

Graphviz: Place edge label on the other side

This may be related to How to place edge labels ON edge in graphviz: I have the following graph, which I visualize using the command dot -Teps g.dot > g.eps:
graph triple {
node [shape=box]; User; Object; Tag;
node [shape=diamond,style=filled]; Triple;
{
User -- Triple [label = "1"];
Object -- Triple [label = "1"];
}
{
rank=same;
User;
Object;
}
Triple -- Tag [label="n"];
}
I would like the result to be more symmetric by putting the label between User and Triple on the left side of the graph.
Manual placement of edge labels cannot be done with graphviz.
However, you could use the headlabel, labeldistance and labelangle attributes:
graph triple {
node [shape=box]; User; Object; Tag;
node [shape=diamond,style=filled]; Triple;
{
User -- Triple [headlabel = "1", labeldistance=2.5, labelangle=20];
Object -- Triple [headlabel = "1", labeldistance=2.5, labelangle=-20];
}
{
rank=same;
User;
Object;
}
Triple -- Tag [label="n"];
}
Output:
And here's the second workaround using splines=false and double edges:
graph {
splines=false;
node [shape=box]; User; Object; Tag;
node [shape=diamond,style=filled]; Triple;
{
User -- Triple [label = "1"];
User -- Triple [label = ""];
Object -- Triple [label = ""];
Object -- Triple [label = "1"];
}
{
rank=same;
User;
Object;
}
Triple -- Tag [label="n"];
}
Output:
I gave up trying to get it to work in Graphviz. Instead, I rendered as a pdf, marked up the pdf to add labels myself, and then flattened the pdf into a new pdf so the markups would be part of the pdf.

Resources