microsoft / automatic-graph-layout

A set of tools for graph layout and viewing
Other
1.36k stars 308 forks source link

[Question] Vertical node order with subgraphs #193

Open mikeclayton opened 5 years ago

mikeclayton commented 5 years ago

Hi,

I've just started using this library today, so apologies in advance if this is an RTFM-type question, but when using nested subgraphs, I can't seem to get the nodes to appear in a "topological" (I think it's called) order from top to bottom.

For example, this code:

        static void Main(string[] args)
        {

            var graph = Program.MakeNestedGraph();

            var image = new Bitmap(1500, 1000);
            var renderer = new GraphRenderer(graph);
            renderer.CalculateLayout();
            renderer.Render(image);
            image.Save("c:\\temp\\example.png", ImageFormat.Png);

        }

        private static Graph MakeNestedGraph()
        {

            var graph = new Graph();

            var rg = new Subgraph("rg");
            var vnet = graph.AddNode("vnet");
            var nic = new Subgraph("nic");
            var subnet = graph.AddNode("subnet");
            var ipcfg = graph.AddNode("ipcfg");
            var nsg = graph.AddNode("nsg");
            var ipaddr = graph.AddNode("ipaddr");
            var vm = graph.AddNode("vm");

            graph.RootSubgraph.AddSubgraph(rg);
            rg.AddNode(vnet);
            rg.AddNode(subnet);
            rg.AddSubgraph(nic);
            nic.AddNode(ipcfg);
            rg.AddNode(nsg);
            rg.AddNode(vm);
            rg.AddNode(ipaddr);

            graph.AddEdge(vnet.Id, subnet.Id);
            graph.AddEdge(subnet.Id, ipcfg.Id);
            graph.AddEdge(nic.Id, nsg.Id);
            graph.AddEdge(nic.Id, vm.Id);
            graph.AddEdge(ipcfg.Id, ipaddr.Id);

            return graph;

        }

generates this image:

example

but, I'd like the "vnet" and "subnet" nodes to be above the "nic" subgraph (not necessarily aligned directly above, just higher up vertically in the chart).

I thought maybe doing something like this would help:

            graph.LayerConstraints.AddUpDownConstraint(vnet, subnet);
            graph.LayerConstraints.AddUpDownConstraint(subnet, nic);
            graph.LayerConstraints.AddUpDownConstraint(subnet, ipcfg);

but that doesn't seem to make any difference.

Am I missing something obvious? Or could you give some pointers on how to force the "top-to-bottom layout so that all "source" nodes are higher than their "target" nodes (assuming there's no cycles in the graph)?

Thanks,

Mike

levnach commented 5 years ago

I do not think the behavior is documented somewhere. As I am seeing from the code at some stage of the layout method "Rectangle PackGraphs(IEnumerable components, LayoutAlgorithmSettings settings)" invoked and it ignores the settings, and packs the nodes to keep some aspect ratio. It might need a fix, but it will require some time from me that I do not have now.

mikeclayton commented 5 years ago

Hi,

Thanks for the quick response, and no worries about getting a fix out - I might try replacing the nested [nic [ipcfg] ] subgraph with just two flattened nodes (e.g. [nic] -> [ipcfg]) as a workaround to see if that lays out a bit better without breaking the feel of the diagram.

In any case, at least I know it's not just because I'm doing something wrong, so I can stop looking now :-).

Cheers,

Mike