I am using multiple layers in graphviz and define nodes (UML-Style) for them like (original has ~1700 lines of code and 5 layers):
strict digraph G
{
compound=true;
rankdir = TD
clusterrank = local
layers="beans:classes";
node [shape = record]
subgraph clusterApplicationContext
{
label = "applicationContext";
"springBean1" [layer="beans"]
}
subgraph clusterPackageTest
{
label = "Package test";
"Bean1" [layer="classes", label = "{Bean1|\l|\l}"]
}
edge [arrowhead = vee, style = dashed]
"springBean1" -> {"Bean1"} [layer="beans:classes"]
}
When I know run this through dot with
dot.exe -Glayerselect=classes -Tsvg beans.dot -o beans.svg
then the edge to the not visible springBean1 will also be drawn, which makes no sense from my point of view, because edges should only be drawn when both nodes are present (visible). Is there a way to change this, except with having additional layers for edges that connect nodes on different layers?
Also it looks like the whole graph (including the invisible layers) will be drawn, which makes my original image very large when only selecting a small layer of it - is there a way to only draw the visible part and have a small output size?
Seems to be that this could only be done with gvpr:
beans.bat:
set layers=beans:classes
rem beans:jsps:classes:http:externals
gvpr.exe -o beansFiltered.dot -a %layers% -f beansFilter.gvpr beans.dot
dot.exe -Glayerselect=%layers% -Tsvg beansFiltered.dot -o beans.svg
beansFilter.gvpr:
BEGIN
{
int i;
int j;
int k;
string wantedLayers[int];
string layersArr[int];
int found;
j = 0;
for (i = 0; i < ARGC; ++i)
{
unset(layersArr);
split(ARGV[i], layersArr, ':');
for (k = 0; k < #layersArr; ++k)
{
wantedLayers[j++] = layersArr[k];
}
}
}
BEG_G
{
$tgtname = $.name;
for (i = 0; i < #wantedLayers; ++i)
{
$tgtname = sprintf("%s%s%s", $tgtname, "_", wantedLayers[i]);
}
graph_t subgraphs[int];
graph_t subgraph;
subgraph = fstsubg($);
i = 0;
while (subgraph != NULL)
{
if (substr(subgraph.name, 0, 1) != "%")
{
subgraphs[i++] = subgraph;
}
subgraph = nxtsubg(subgraph);
}
}
N
[
unset(layersArr);
split(layer, layersArr, ':');
for (i = 0; i < #layersArr; ++i)
{
found = 0;
for (j = 0; j < #wantedLayers; ++j)
{
if (layersArr[i] == wantedLayers[j])
{
found = 1;
}
}
if (found == 0)
{
return 0;
}
}
return 1;
]
{
found = 0;
for (i = 0; i < #subgraphs; ++i)
{
if (isSubnode(subgraphs[i], $))
{
graph_t sg = subg($T, subgraphs[i].name);
copyA(subgraphs[i], sg);
subnode(sg, $);
++found;
break;
}
}
if (found == 0)
{
node_t newnode = node($T, $.name);
copyA($, newnode);
}
}
E
[
unset(layersArr);
split(layer, layersArr, ':');
for (i = 0; i < #layersArr; ++i)
{
found = 0;
for (j = 0; j < #wantedLayers; ++j)
{
if (layersArr[i] == wantedLayers[j])
{
found = 1;
}
}
if (found == 0)
{
return 0;
}
}
return 1;
]
This solves both problems for me the filtering of unwanted edges and the final image size.