Cryptic dot error message for graph with big (sub)clusters - graphviz

I've written a little tool dumping (in dot format) the dependency graph of a project where all the files living in the same directory are gathered in a cluster. When I try to generate a pdf containing the corresponding graph, dot starts to cry:
The command dot -Tpdf trimmedgraph.dot -o graph.pdf produces the cryptic error message Error: install_in_rank clusterReals virtual rank 21 i = 0 an = 0 which does not yield any result on google.
I've tried to edit trimmedgraph.dot manually: turning the subgraph clusterReals into Reals yields a file that can be compiled but all the content of my Reals/ directory is obviously not gathered anymore.
Is there a way to generate only dot-valid files (I was planning to send my patch upstream eventually but if I cannot guarantee that everything will be okay...)?
I've put the two versions of trimmedgraph.dot online but they are rather big and given that I have no idea where the problem is, I cannot really come up with a minimal file recreating the problem.

I think (but couldn't find any documentation about this) cluster names have to be unique within the entire dot file. In your file however, there are two subgraphs called clusterReals.
The solution is to make sure all cluster names are unique - since the name doesn't appear anywhere in the output, you may just use numbers when generating dot files.
A quick test shows that strange things happen when reusing the same cluster name:
digraph dependencies {
subgraph cluster0 {
label="First cluster 0";
Node1;
subgraph cluster0 {
label="Second cluster 0";
Node2;
}
}
subgraph cluster0 {
label="Third cluster 0";
Node3;
}
subgraph cluster1 {
label="Cluster 1";
Node4;
subgraph cluster0 {
label="Fourth cluster 0";
Node5;
}
}
}
All the cluster0 seem to be merged together (nodes, label), unless it is not possible because they're included by other clusters. At least that's what it looks like... Since the consequences are unpredictable (error in your case), I'd try to always use unique cluster names.

Related

Can I refer to a node using a short name in DOT

I'm trying to respresent a binary tree with GraphViz using DOT, can I have a longer text string as a node's text but them just refer to it using a shortname when linking it?
I'm working with GraphViz through Pandoc and Pandoc-plot.
I've tried setting and node's ID, name, label and refering to it but it just doesn't work. In my document it just got the codeblock instead a rendered graph, I've tested it with a simple graph and it renders fine.
I've tried a graph like this in the GraphViz online editor and the node's with the long names don't get connected in the right way.
graph {
"Adam \n 01/01"[id="adam"]
"Bella \n01/02"[id="bella"]
"Eloise \n01/05"
adam -- bella
bella -- eloise
}
Looks like you mix up node names and node labels (by default the node name is equal to the node label, so in your case the node name is "Adam \n 01/01" and also the label is "Adam \n 01/01" so you have to refer to it like:
"Adam \n 01/01" -- "Bella \n01/02"
but this is quite cumbersome and error prone so looks like you are looking for (as indicated bu "short names" request):
graph {
adam [label="Adam \n 01/01"]
bella [label="Bella \n01/02"]
eloise [label ="Eloise \n01/05"]
adam -- bella
bella -- eloise
}

Cytoscape don't load the node and edge attribute from my dot file

I am using cytoscape to display a graph i made with graphviz. I installed the add-on dot-app from the cytoscape app store to be able to load my graph.
My graph is loading perfectly, all the edges are connected to the nodes wanted. But the attributes of my nodes and edges aren't showing up.
Here is a simplified example (less attributes, nodes and edges) that is not working :
graph map {
node1 [color="#888888"]
node2 [color="#888888"]
node1 -- node2 [color="#1f78b4"]
}
It generates the following graph :
I managed to find code example of dot file loaded in cytoscape, the following one load the attributes well :
graph toy_example {
graph [bb="-85.648,-58.068,63.891,73.497",outputorder=edgesfirst, overlap=false];
node [fillcolor="#888888",label="\N",style=filled];
1 [height=0.5,pos="-58.648,-8.4777",width=0.75];
2 [height=0.5,pos="36.891,3.383",width=0.75];
2 -- 1 [pos="10.278,0.079128 -2.8626,-1.5522 -18.68,-3.5159 -31.846,-5.1504"];
3 [height=0.5,pos="12.665,-40.068",width=0.75];
3 -- 1 [pos="-9.8989,-30.072 -18.223,-26.385 -27.653,-22.208 -35.986,-18.516"];
3 -- 2 [pos="22.24,-22.895 23.933,-19.858 25.695,-16.698 27.386,-13.665"];
4 [height=0.5,pos="8.8474,55.497",width=0.75];
4 -- 2 [pos="18.03,38.433 21.097,32.734 24.516,26.38 27.592,20.664"];
4 -- 3 [pos="9.5835,37.071 10.264,20.041 11.269,-5.1139 11.944,-22.022"];
}
Generating the following graph :
Do you know why my attributes can't load ?
I tried destroying and creating the view on my graph but it don't do anything. The node table of both graphs only have "shared name" and "name".
If you look at the example that worked, the node color is defined as "fillcolor", not "color". This is because Cytoscape nodes can have two different colors, fillcolor and bordercolor, so the app authors chose to differentiate that by the attribute name. You would have to play around to see what they called the edge color. In Cytoscape it's called "Stroke Color (Unselected)", so you might try "edgecolor" or "strokecolor".
-- scooter

Multiple graphs inside Graphviz DOT file

I have this Graphviz DOT graph:
digraph unit_test {
label="Unit test"
edge [fillcolor="#a6cee3" color="#1f78b4"]
node[shape="ellipse" style="filled" fillcolor="#1f77b4"]
start
end
node[shape="box" style="filled" fillcolor="#ff7f0e"]
process
subgraph cluster_process {
label = "Major logic"
process
}
start -> process
process -> end
}
The above renders as:
I have this second graph:
digraph details {
label = "Process details"
edge [fillcolor="#a6cee3" color="#1f78b4"]
node[shape="ellipse" style="filled" fillcolor="#1f77b4"]
start
end
node[shape="box" style="filled" fillcolor="#ff7f0e"]
details
subgraph cluster_details {
label = "Details"
details
}
start -> details
details -> end
}
Which renders to:
Problem
When I put the above two graphs inside the same DOT file named supporting.dot and I run dot -Tpng -o supporting.png supporting.dot command, terminal prints out some jiberish and the output image file won't contain both graphs, it just contains the first one. Is it possible to use multiple graphs inside a single DOT file? If so, what am I missing?
Question is unclear about what is to be accomplished, but maybe the following is a starting point
digraph G{
subgraph unit_test {
label="Unit test"
edge [fillcolor="#a6cee3" color="#1f78b4"]
node[shape="ellipse" style="filled" fillcolor="#1f77b4"]
start
end
node[shape="box" style="filled" fillcolor="#ff7f0e"]
process
subgraph cluster_process {
label = "Major logic"
process
}
start -> process
process -> end
}
subgraph details {
label = "Process details"
edge [fillcolor="#a6cee3" color="#1f78b4"]
node[shape="ellipse" style="filled" fillcolor="#1f77b4"]
start1 [label="start"]
end1 [label="end"]
node[shape="box" style="filled" fillcolor="#ff7f0e"]
details
subgraph cluster_details {
label = "Details"
details
}
start1 -> details
details -> end1
}
}
Note the naming / labels in the second subgraph.
Dot can't render 2 graphs into a single file, the output you see is probably the content of one of the graphs as a png.
In order to prevent that, you may run your graphs first through gvpack - something similar to:
gvpack -u supporting.dot | dot -Tpng -o supporting.png
This combines all graphs in supporting.dot into a single graph, which then is rendered with dot.
The layout of the graphs can be influenced by some more options of gvpack.
It is legal to have multiple graphs defined in one input file. You can then produce multiple output files using the -O option, like this:
dot -Tpng -O multi.gv
This will produce multi.gv.png and multi.gv.2.png
I got a better answer
http://www.bound-t.com/manuals/ref-manual.pdf
The -dot_dir option and the names of drawing files
The -dot option creates a single file that contains all drawings from one Bound-T run. If you
then use the dot tool to create a PostScript file, each drawing will go on its own page in the
PostScript file. However, dot can also generate graphical formats that do not have a concept of
"page" and then it may happen that only the first drawing is visible. If you want to use such
non-paged graphical formats it is better to create a directory (folder) to hold the drawing files
and use the Bound-T option -dot_dir instead of the option -dot. The -dot_dir option creates a
separate file for each drawing, named as follows:
• The call-graph of a root subprogram is put in a file called cg_R_nnn.dot, where R is the
link-name of the root subprogram, edited to replace most non-alphanumeric characters
with underscores '_', and nnn is a sequential number to distinguish root subprograms that
have the same name after this editing.
• If the call-graph of some root subrogram is recursive, Bound-T draws the joint call-graph of
all roots and puts it in a file called jcg_all_roots_001.dot.
• The flow-graph of a subprogram is put in a file called fg_S_nnn.dot, where S is the linkname of the subprogram, edited as above, and nnn is a sequential number to distinguish
subprograms that have the same name after this editing and also to distinguish drawings
that show different flow-graphs (execution bounds) for the same subprogram.
The sequential numbers nnn start from 1 and increment by 1 for each drawing file; the same
number sequence is shared by all types of drawings and all subprograms. For example, if we
analyse the root subprogram main?func that calls the two subprograms start$sense and
start$actuate, with the -dot_dir option and -draw options that ask for one flow-graph drawing
of each subprogram, the following drawing files are created:
• cg_main_func_001.dot for the call-graph of main?func
• fg_main_func_002.dot for the flow-graph of main?func
• fg_start_sense_003.dot for the flow-graph of start$sense
• fg_start_actuate_004.dot for the flow-graph of start$actuate.

Aligning Clusters within Graphviz

I am using Graphviz to automatically create an architecture diagram. I am having the following two problems and was hoping to get assistance.
I am using UUID to uniquely identify a component (example: "a5320de8-a320-11ea-bb37-0242ac130002" [label="Component A"]). When mapping A -> B, I'll get "Component A" -> b0c5e47c. Which is strange. The only way that I've been able to map UUID to UUID is to put quotes around them. Any suggestions?
I want to align clusters in a specific manner and specific direction. I've tried {rank=same; cluster_B, cluster_C, cluster_D}; and "9653369c-a322-11ea-bb37-0242ac130002" -> "aa31adb9-9621-40c2-855c-621832dd8c61" [style=invis] But neither work.
I have three sections within my dot file, they are:
Components (within this section, I list out all 100+ components and color code them based on a specific rule.
Clusters (within this section, I cluster the components into specific 'groupings')
Diagram or mapping (within this section, I then map the different components and clusters).
Here is a sample of my DOT file.
digraph architecture {
#graph [rankdir=LR]
compound=true;
#Compliant
node[fillcolor="#013220" style="filled" shape=square fontcolor="white"];
"a5320de8-a320-11ea-bb37-0242ac130002" [label="Component A"]
"b0c5e47c-a320-11ea-bb37-0242ac130002" [label="Component B"]
#Clusters
#Customer-facing client application cluster
subgraph cluster_A{
label="Client Apps";
"f7b3915d-6b3d-4d4c-bef0-bdabda915c03";
"9912de2b-739a-4c5c-834e-e0c3d09d70d1";
"16bb2066-9293-470e-99ec-c59d8426c0ab";
"641a6601-f4f6-4c06-baa6-e5e232f8abed";
"c5e92b09-a470-4fb6-af5c-e5f7dbeff919";
}
#Diagrams
"f7b3915d-6b3d-4d4c-bef0-bdabda915c03" -> {"35305026-d285-458c-85ad-7eae4e785e84", "76e0e679-42a6-47f0-9164-abc223da07fe"};
76e0e679-42a6-47f0-9164-abc223da07fe" -> "35305026-d285-458c-85ad-7eae4e785108";
}
I get something like:
However, I want to arrange the cluster is a specific way, like:
As you found out, hyphens are not legal characters in a node ID unless the string is quoted. If you want more info: https://www.graphviz.org/doc/info/lang.html
There is no straight-forward to align clusters. Sometime you can force desired alignment by embedding multiple clusters within another cluster to "shrink-wrap" them. For example embed B3 and B4 within cluster B34. But no guarantees.
You can use gvpr to reposition clusters (and their contents) but that can get pretty complex.

Force Graphviz to complain for duplicate nodes

I just noticed that duplicate node names (even if labeled uniquely) get processed without complaint by Graphviz. For example, consider the following simple graph as rendered (with circo) in the image below:
graph {
a [label="a1"]
a [label="a2"]
b
c
d
e
a -- b;
b -- c;
a -- c;
d -- c;
e -- c;
e -- a;
}
I want the above graph to have two nodes: a1 and a2. So I know I should instantiate them with unique names (different than what I did above). But in a large graph, I may not notice that I mistakenly instantiated two different nodes with identical names. So if I do something like this, I'd like to force Graphviz to complain about it or bring it to my attention somehow, maybe with a warning or an error message.
How do I accomplish that?
All the graphviz programs silently merge nodes with duplicate names and I cannot find any way to have them produce a warning when they do that. Since we only have to find the cases where nodes are declared by themselves, however, rather than nodes that are implicitly declared when an edge is declared (in which case duplication is normal and expected), we just have to find all the node names and identify the duplicates.
If no more than one node is ever declared on a line, this could be done with the following script:
#!/bin/sh
sed -n 's/^[\t ][\t ]*\([_a-zA-Z][_a-zA-Z0-9]*\) *\(\[.*\)*;*$/\1/ p' | \
sort | uniq -c | awk '$$1>1'
If we call this script findDupNodes, we can run it as follows:
$ findDupNodes <duplicates.gv
2 a
The script finds node names that are either declared by themselves or with a list of attributes that starts with [, sorts them, counts how many times each is declared (with uniq -c) and filters out the ones that are declared only once.
Multiple nodes can be declared on a single line (e.g. a; b; c; d;) but this script does not handle that case, or (probably) some other cases -- most of which would probably require a full-blown xdot language parser.
Nevertheless, this script should find many of the duplicate node names that might find their way into hand-written graphviz scripts.

Resources