Search code examples
graphviz

Nested directed subgraphs


I'm trying to obtain nested subgraphs in graphviz.

Graphviz version is 2.38.0 (20140413.2041)

Here is the code:

digraph G {
        subgraph cluster_win {
                style=filled;
                color=lightgrey;
                label = "Windows"

                subgraph extra_enabled {
                    fillcolor = "#EDF1F2"; 
                    color = "#028d35";
                    label="Subdirectory extra included";

                    node [style=filled,color=white];
                    config_debug1 [label = "Configure Debug"];
                    config_release1 [label = "Configure Release"];
                    build_debug1 [label = "Build"];
                    build_release1 [label = "Build"];

                    config_debug1 -> build_debug1;
                    config_release1 -> build_release1;

                    shape=rect;
                    style=rounded; 
                }

                subgraph extra_disabled {
                    label = "Subdirectory extra excluded";

                    config_debug2 [label = "Configure Debug"];
                    config_release2 [label = "Configure Release"];
                    build_debug2 [label = "Build"];
                    build_release2 [label = "Build"];
                    config_debug2 -> build_debug2;
                    config_release2 -> build_release2;
                }

                checkout [style=filled, color=white];
                checkout -> extra_enabled;
                checkout -> extra_disabled;
        }

        start -> checkout;

        start [label="git push"; shape=Mdiamond];
}

And this is the result. no nested subgraphs

Graphviz draws two ordinary nodes "extra_enabled" and "extra_disabled". However, I want them to be subgraphs, containing nodes "Configure Release", "Configure Debug", "Build" and another "Build".

How can I fix it?


Solution

  • You need to do two things:

    • Connect nodes only, you cannot connect to a cluster
    • Cluster names need to be prefixed by cluster_

    Applying this to your code

    digraph G {
            subgraph cluster_win {
                    style=filled;
                    color=lightgrey;
                    label = "Windows                  "
    
                    subgraph cluster_extra_enabled {
                        fillcolor = "#EDF1F2"; 
                        color = "#028d35";
                        label="Subdirectory extra included";
    
                        node [style=filled,color=white];
                        config_debug1 [label = "Configure Debug"];
                        config_release1 [label = "Configure Release"];
                        build_debug1 [label = "Build"];
                        build_release1 [label = "Build"];
    
                        config_debug1 -> build_debug1;
                        config_release1 -> build_release1;
    
                        shape=rect;
                        style=rounded; 
                    }
    
                    subgraph cluster_extra_disabled {
                        label = "Subdirectory extra excluded";
    
                        config_debug2 [label = "Configure Debug"];
                        config_release2 [label = "Configure Release"];
                        build_debug2 [label = "Build"];
                        build_release2 [label = "Build"];
                        config_debug2 -> build_debug2;
                        config_release2 -> build_release2;
                    }
    
                    checkout [style=filled, color=white];
                    checkout -> config_debug1;
                    checkout -> config_release2;
            }
    
            start -> checkout;
    
            start [label="git push"; shape=Mdiamond];
    }
    

    I get

    enter image description here

    which is probably close to what you want. Note that I have added a few spaces to the label "Windows " to get it out of the way of the arrow. You could also use labeljust. There are also ways to make the edge end at the boundary of the cluster, but that would have needed a lot more editing on my part which I was not sure you want it.