1

Here's the dot file I have:

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;
}

How do I get a visual that would look like this:

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

So we can clearly see that ModuleA and ModuleB act as middlewares? I tried groupping them in clusters but I still get cluster to overlap on vertical axis instead of them being clearly on different levels. I don't mind if lines cross boxes as it's not possible otherwise.

Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99

1 Answers1

1

Once you are not satisfied with how graphviz positioned nodes on the graph, you are entering an ugly world of invisible edges, constraint-falses and weights.

I've added constraint=false attribute for your main -> init_c edge and added few invisible edges (I temporary marked them red for clarity). If you want to further adjust the position of nodes and clusters, you can play with weight attribute of different edges.

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

Result:

Dany
  • 4,521
  • 1
  • 15
  • 32
  • Thank you, thought is there a particular logic behind selecting which invisible edges to select? From the look of it it seems like the logic is to form a common path in a symmetric way and edges point from to node without changing weight of internal nodes. so init is always first. – Loïc Faure-Lacroix Feb 05 '20 at 03:50
  • @LoïcFaure-Lacroix well there's no particular logic, what I usually do is I plot a graph without invisible edges and then start adding them to the parts which need to be adgusted. E.g. in a vertical graph I would add edge from A to B if B should appear approximately below A on the graph – Dany Feb 05 '20 at 10:46
  • Makes, sense. quite ugly thought. – Loïc Faure-Lacroix Feb 06 '20 at 16:18