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