代码之家  ›  专栏  ›  技术社区  ›  PowerStat

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

  •  0
  • PowerStat  · 技术社区  · 7 年前

    我在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的边,这在我看来毫无意义,因为只有当两个节点都存在(可见)时才应绘制边。 除了为连接不同层上节点的边设置附加层之外,是否有其他方法可以更改此设置?

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

    1 回复  |  直到 7 年前
        1
  •  0
  •   PowerStat    7 年前

    似乎这只能通过gvpr来实现:

    豆子.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;
     ]
    

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

    推荐文章