randomleather
randomleather

Reputation: 33

How to structure multiple subgraphs in Graphviz?

My ultimate aim is to write a python script that will automatically generate graphviz graphs based on some input data. However, I'm first focusing just on the graphviz.

This is currently what I have:

digraph G {
compound=true;
node [shape=box];
edge [dir=none];

subgraph cluster_overall{
        subgraph cluster_top{
        apple;
        banana;
        }
        subgraph clustermsc{
        basket1;
        basket2;
        label="Baskets";
        }
        subgraph cluster_bottom{
        orange;
        kiwi;
        }
label="Test";
}       
apple -> basket1;
banana -> basket2;
orange -> basket1;
kiwi -> basket2;
}

Current: https://i.sstatic.net/oLKn8.png

This is what I want my final graph to look like. With the number of fruits evenly distributed between the top and bottom section (based on the input date):

Final: https://i.sstatic.net/jb56Y.png

How do I structure the page to have 3 static, separate sections. Currently the fruit's placement constantly changes based on node they point to.

Please let me know if I wasn't clear in my explanation, I'll try better explaining it. Thanks. Don't have enough repuation to directly post images.

Upvotes: 1

Views: 3306

Answers (2)

vaettchen
vaettchen

Reputation: 7659

In graphviz, it is important to produce the hierarchy as the tool sees it, not reproducing the logic that is on your mind. simply reversing the edges from your baskets to the "lower" fruits does the job:

digraph G {
compound=true;
node [shape=box];
edge [dir=none];

subgraph cluster_overall{
        subgraph cluster_top{
        apple;
        banana;
        }
        subgraph clustermsc{
        basket1;
        basket2;
        label="Baskets";
        }
        subgraph cluster_bottom{
        orange;
        kiwi;
        }
label="Test";
}       
apple -> basket1;
banana -> basket2;
basket1 -> orange;  // !!!
basket2-> kiwi;     // !!!
}

gives you

enter image description here

If you want to force a certain order of items (such as apple being to the left of banana), you can do so by replacing your definition with

subgraph cluster_top{
    { rank = same; apple -> banana[ style = invis ] }
    }

Upvotes: 2

Dany
Dany

Reputation: 4750

If I correctly understood you, you need to connect clusters with invisible edges to force their position.

Here I've added a dummy node into each cluster (because to connect clusters you have to connect nodes in these clusters and then add lhead and ltail attributes).

Then I've connected these clusters in the correct order with invisible edges. Also I've added an extremely big weight to these edges to give them priority over other edges.

Is that what you need?

digraph G {
    compound=true;
    node [shape=box];
    edge [dir=none];

    subgraph cluster_overall{
            subgraph cluster_top{
            dummy_top [shape=point width=0 style=invis]
            apple;
            banana;
            }
            subgraph clustermsc{
            dummy_msc [shape=point width=0 style=invis]
            basket1;
            basket2;
            label="Baskets";
            }
            subgraph cluster_bottom{
            dummy_bottom [shape=point width=0 style=invis]
            orange;
            kiwi;
            }
    label="Test";
    }
    dummy_top -> dummy_msc [
        style=invis
        weight=100
        lhead="clustermsc"
        ltail="cluster_top"
    ]
    dummy_msc -> dummy_bottom [
        style=invis
        weight=100
        lhead="cluster_bottom"
        ltail="clustermsc"
    ]
    apple -> basket1;
    banana -> basket2;
    orange -> basket1;
    kiwi -> basket2;

}

Upvotes: 0

Related Questions