Graphviz如何在只绘制一层时消除层与层之间的边缘以及如何缩小结果的输出维度?

Graphviz how to eliminate edges between layers when only one layer should be drawn and how to shrink the output dimension of the result?

我在 graphviz 中使用多层并为它们定义节点(UML 样式)(原始代码有 ~1700 行和 5 层):


    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"]
     }

当我通过点

知道运行这个
dot.exe -Glayerselect=classes -Tsvg beans.dot -o beans.svg

那么到不可见的 springBean1 的边也将被绘制,从我的角度来看这没有意义,因为只有当两个节点都存在(可见)时才应该绘制边。 有没有办法改变这一点,除了为连接不同层上的节点的边缘添加额外的层?

而且看起来整个图(包括不可见层)都将被绘制,这使得我的原始图像在只选择它的一小层时变得非常大 - 有没有办法只绘制可见部分并且有输出尺寸小?

似乎这只能用 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;
 ]

这为我解决了过滤不需要的边缘和最终图像大小的问题。