digraph messages { //concentrate=true; subgraph clusterclients { client1 [shape = box]; client2 [shape = box]; client3 [shape = box]; style = dashed; label = "Clients"; } subgraph clusternode1 { subgraph clusterc2s1 { c2s11; c2s12; style = invis; } subgraph clusterservices1 { service11; service12; service13; style = invis; } //subgraph clusters2s1 { //s2s11; //s2s12; //style = invis; //} c2s11 -> auth1; c2s12 -> auth1; auth1 -> c2s11; auth1 -> c2s12; c2s11 -> sm1; c2s11 -> router1; c2s12 -> sm1; c2s12 -> router1; router1 -> local1; router1 -> service11; router1 -> service12; router1 -> service13; router1 -> s2s11; router1 -> s2s12; service11 -> router1; service12 -> router1; service13 -> router1; s2s11 -> router1; s2s12 -> router1; local1 -> sm1; sm1 -> c2s11; sm1 -> c2s12; style = dashed; label = "Node1"; } subgraph clusternode2 { c2s2 -> auth2; auth2 -> c2s2; c2s2 -> sm2; c2s2 -> router2; router2 -> local2; router2 -> service21; router2 -> s2s21; service21 -> router2; s2s21 -> router2; local2 -> sm2; sm2 -> c2s2; style = dashed; label = "Node2"; } subgraph clusterservers { server1 [shape = box]; server2 [shape = box]; server3 [shape = box]; style = dashed; label = "Servers"; } client1 -> c2s11; client2 -> c2s12; client3 -> c2s2; c2s11 -> client1 [constraint=false]; c2s12 -> client2 [constraint=false]; c2s2 -> client3 [constraint=false]; s2s11 -> server1 [minlen = 2]; s2s12 -> server2 [minlen = 2]; s2s21 -> server3 [minlen = 2]; server1 -> s2s11 [constraint=false]; server2 -> s2s12 [constraint=false]; server3 -> s2s21 [constraint=false]; router1 -> router2; router2 -> router1; sm1 -> sm2; sm2 -> sm1; label = "Data Flows"; }