Layout without a document?

I’m trying to upgrade to version 4.0, but I’ve come across a problem. I’m creating an instance of a network object and manually adding nodes and links to it (rather than just creating it from a document). Whenever I call PerformLayout(), the Nodes and Links collections are cleared.

More precisely, I’ve derived a class off of GoLayoutForceDirectedNetwork and am adding nodes by calling GoLayoutGenericNetwork.AddNode(N). I’m creating links by calling GayLayoutGenericNetwork.LinkNodes (N, N, null). In all cases, the type of N is GoLayoutForceDirectedNode. I’ve also derived a class off of GoLayoutForceDirected where I assign my derived network class to the Network property just after construction. Just before calling PerformLayout, I create a new GoDocument and assign it to GoLayout.Document.

Interesting, the Document assignment clears the Nodes and Links collections, so what I’m really doing is more like this:

var network = Network;
var doc = new GoDocument();
Document = doc;
Network = network;

I tried moving this back to the constructor of the derived layout class (so the document would be present when I called AddNode and LinkNodes), but the collections still get cleared. Plus having this code in the constructor is a bad idea since calling GoLayout.Document is a virtual member call in a constructor.

Any ideas as to why my collections are cleared when I call PeformLayout?

So I made a few changes to eliminate the class derived from GoLayoutForceDirectedNetwork. All my custom code is now in the class derived from GoLayoutForceDirected. I’m now creating a derived layout instance, creating a GoDocument, adding the document to the layout, and finally calling GoLayoutForceDirected.CreateNetwork() and assigning that to the layout’s Network property. (I finally saw the help documentation that setting the Document property of the layout object sets the Network property to null.)

I also refactored my code to use just the types available in v3.0.3 (GoLayoutForceDirectedNode, etc). To simplify things I also skipped adding links, so the only objects in the network are GoLayoutForceDirectedNode objects. I tried running this much simpler code against both 3.0.3 and 4.0 with the same result: the Network.Nodes collection is cleared. (I verified under the debugger that the expected versions of the Northwoods assemblies are being loaded, so it’s not definitely not just a 4.0 issue.)I’m guessing I’m doing something wrong. Any ideas what that might be?

If you have a custom GoLayoutForceDirectedNetwork, you will want to
override GoLayoutForceDirected.CreateNetwork to return a new instance
of your network class.

Any GoLayout may modify its Network’s collection of Nodes and of Links. In the case of GoLayoutForceDirected, it is splitting up the Network to find separate subnetworks so they can be laid out separately. It does this by calling GoLayoutGenericNetwork.SplitIntoSubNetworks.

If there aren’t any links in the network, it means that each node should be left in the original network, because they are all unconnected.

After re-reading your messages, I still don’t understand what it is that you are trying to do. What is your goal here?

The goal is to take a small set of points (>25) and run them through a force directed layout so they are dispersed. The points correspond to visual objects, but the visual layer of this application is not built using GoDiagram.

So now what I have is a class that derives from GoLayoutForceDirected. There is no longer a derived network class. I’m adding GoLayoutForceDirectedNode objects to the GoLayoutForceDirected.Network property (using the network’s AddNode() method). Here’s how I instantiate the derived layout class:

var doc = new GoDocument();
_layout = new MyLayout();
_layout.Document = doc;
_layout.Network = _layout.CreateNetwork();

I never add any data to the document, just the network. When I call PerformLayout, the Nodes collection is cleared and the NodeCount is set to zero.

Is there any reason you can’t use trivial GoNodes in a GoDocument?

It just seemed strange having to construct view level objects when really I just want to perform layouts.