如何获得 3 个不同级别的单个集群?

How do I get individual clusters on 3 different levels?

这是我的点文件:

digraph G {
   rankdir=TB;
   ranksep=1;

   subgraph cluster_application {

       subgraph cluster_module_core {
         init_a -> service_a;
         init_a -> service_b;
         init_a -> service_c;
         init_a -> service_d;
       }

       subgraph cluster_module_a {
         init_d -> service_c_1;
         init_d -> service_d_1;
       }

       subgraph cluster_module_b {
         init_b -> service_a_1;
         init_b -> service_b_1;
       }

       subgraph cluster_module_db {
         init_c -> db_service;
         db_service -> db;
       }
   }

   main -> init_a;
   main -> init_b;
   main -> init_c;
   main -> init_d;

   service_a -> service_a_1;
   service_b -> service_b_1;
   service_c -> service_c_1;
   service_d -> service_d_1;

   service_a_1 -> db_service;
   service_b_1 -> db_service;
   service_c_1 -> db_service;
   service_d_1 -> db_service;
}

如何获得如下所示的视觉效果:

                        Main
                         |
                         |
                   +------------+
                   |    core    |
                   +------------+
                    /  /     \  \
                   /  /       \  \
          +-----------+     +-----------+
          | Module A  |     |  Module B |
          +-----------+     +-----------+
                   \  \       /  /
                    \  \     /  /
                   +-------------+
                   | Module DB   |
                   +-------------+

所以我们可以清楚地看到ModuleA和ModuleB充当了中间件?我尝试将它们分组到集群中,但我仍然让集群在垂直轴上重叠,而不是它们明显处于不同的级别。我不介意线条是否穿过盒子,否则就不可能。

一旦您对 graphviz 在图上定位节点的方式不满意,您将进入一个充满不可见边、约束错误和权重的丑陋世界。

我已经为您的 main -> init_c 边缘添加了 constraint=false 属性,并添加了一些不可见的边缘(为了清楚起见,我暂时将它们标记为红色)。如果你想进一步调整节点和簇的位置,你可以玩不同边缘的 weight 属性。

digraph G {
   rankdir=TB;
   ranksep=1;

   subgraph cluster_application {

       subgraph cluster_module_core {
         init_a -> service_a;
         init_a -> service_b;
         init_a -> service_c;
         init_a -> service_d;
       }

       subgraph cluster_module_a {
         init_d -> service_c_1;
         init_d -> service_d_1;
       }

       subgraph cluster_module_b {
         init_b -> service_a_1;
         init_b -> service_b_1;
       }

       subgraph cluster_module_db {
         init_c -> db_service;
         db_service -> db;
       }
   }

   main -> init_a;
   main -> init_b;
   main -> init_c [constraint=false]
   main -> init_d;

   service_a -> service_a_1;
   service_b -> service_b_1;
   service_c -> service_c_1;
   service_d -> service_d_1;

   service_a_1 -> db_service;
   service_b_1 -> db_service;
   service_c_1 -> db_service;
   service_d_1 -> db_service;

   service_d -> init_d [color="red"] #[style=invis]
   service_d -> init_b [color="red"] #[style=invis]
   service_d_1 -> init_c [color="red"] #[style=invis]
   service_b_1 -> init_c [color="red"] #[style=invis]
}

结果: