Arranging nodes in swimlane

Dear support,
I am using swimming pool node from node-link demo. In my diagram, I create several lanes and each lane contains other types of nodes in it. I want to arrange these nodes in the lane. I have tried to use ‘layout’. There are links among the nodes from different lanes as well as nodes from same lane. As the layout works on entire goview document, i could not perform layout on the nodes inside the lane. However, i could arrange the entire swimming pool not the nodes in the lanes. How to arrange these nodes(in the lane) through code.

Thanks

You have to do the layout for each lane. SubGraphApp has a recursive sample of stepping into each group… same idea.

Note you aren’t going to get smart layout of connections between lanes this way, but we don’t have any samples of how to get around that.

Dear Jake,
Thank you very much for the reply.
In my application, I have only one swimming pool node containing 5 swim lanes in it. And each of the lane contains GoBasic nodes and there are connections among the nodes. Connections exists between any two nodes which may be form same lane or different lane.
I have already tried using the layout method from SubGraphApp4. I copied the method from the sample and called the method with input as goView.document. I checked the method. When I give the goViewDocument as input which is taken as IGoCollection. This collection only contains swimmingPool node and links in the diagram. I try to give input as swimming pool lanes but it did not work.
I am giving here the swimming pool node code which i used in my application. Here, I am using the dictionary to find added nodes in the lane. In SwimmingPool example links between the nodes are added in the lane node. But in my case links exists between nodes from different nodes. So I have added these links in goView.document. I am creating the links in other part of the application.
As there are different layers in Swimming pool example, it is difficult to find nodes in goView documents. I am not sure how to do it. I am still working on it. Could you please suggest on how to layout the nodes in the lanes in my application. At the moment, when I add nodes in a lane through code, the nodes get placed at same location in the lane and overlap/cover previous nodes which were added earlier in the same lane. I also want suggestion on where the links should be, I mean in lane or directly part of document(which the case in my application). I just want to layout the nodes in the lane to avoid overlapping of the nodes.

Thanks

[Serializable]
public class SwimmingPool : GoSubGraphBase
{
public SwimmingPool()
{
myLanes = new SwimmingPoolLanes();
Add(myLanes);
GoText lab = new GoText();
lab.Selectable = false;
lab.Bold = true;
lab.Text = “SEQUENCE - Levels”;
Add(lab);
}
public static Dictionary<int, GoBasicNode> nodesInDoc = new Dictionary<int, GoBasicNode>();
public void Initialize(GoView goView, List<double[]> PropSeq, object[] SCCs)
{

        goView.Document.AllowLink = false;
        

        for (int i = 0; i < PropSeq.Count(); i++)
        {
            SwimLane lane = AddLane(Color.FromArgb(50, Color.Blue), 100);
            lane.Text = "Level - " + (i + 1).ToString();

            for (int k = 0; k < PropSeq[i].Count(); k++)
            {

                GoBasicNode node = new GoBasicNode();
                node.LabelSpot = GoObject.Middle;
                node.Shape = new GoRectangle();
                node.Shape.BrushColor = Color.White;
                node.Text = (PropSeq[i][k] +1).ToString();
                node.Position = new PointF(lane.Left + 150, lane.Top + 10);
                nodesInDoc.Add((int)(PropSeq[i][k] + 1), node);>  /////////I am using this dicitonary as i was not able to find the node from the document with the string. this dictionary is used while creating links among the nodes
                lane.Add(node);

                if((int)PropSeq[i][k] < SCCs.Count() && ((SCCs[(int)PropSeq[i][k]]) as List<int>).Count() > 1)
                {
                    for (int l = 1; l < ((SCCs[(int)PropSeq[i][k]]) as List<int>).Count(); l++)
                    {
                        node = new GoBasicNode();
                        
                        node.LabelSpot = GoObject.Middle;
                        node.Shape = new GoRectangle();
                        node.Shape.BrushColor = Color.White;
                        node.Text = (  (SCCs[(int)PropSeq[i][k]] as List<int>)[l] + 1).ToString();
                        node.Position = new PointF(lane.Left + 150, lane.Top + 10);
                        nodesInDoc.Add((int)(((SCCs[(int)PropSeq[i][k]] as List<int>)[l] + 1)), node); /////////////////////////////
                        lane.Add(node);
                    }

                }

}}

Here’s is some layout code I once did when I was doing a sample I never finished that used Swimlanes. This was a method I added to the SwimmingPool class.

This code is something like 5 years old. I’ve given it a quick test, and it at least seems to work, within lanes… but connections between lanes is (like I said earlier) an issue. But it will give you a starting point.

    public void LayoutNodes() {
      foreach (SwimLane lane in this.Lanes) {

        GoLayoutTree layout = new GoLayoutTree();
        layout.Document = this.Document;
        layout.Network = layout.CreateNetwork();
        layout.Network.AddNodesAndLinksFromCollection(lane, true);
        layout.ArrangementOrigin = lane.Position + new SizeF(10, 10); // 10,10 offset
        layout.PerformLayout();

        // have to remove HollowRectangle & label from collection, or ExpandPaintBounds makes lane grow a little each time.
        GoCollection coll = new GoCollection();
        foreach (GoObject o2 in lane) {
          if (o2 is IGoNode || o2 is IGoLink) coll.Add(o2);
        }
        SizeF size = lane.Size;
        RectangleF b = GoDocument.ComputeBounds(coll, null);
        if (b.Width > size.Width) size.Width = b.Width;
        if (b.Height > size.Height) size.Height = b.Height;
        if (size != lane.Size) {
          size.Height += 10;  // a little pad on the bottom.
          lane.Size = size;
        }
      }
    }

and you could call it like this… if you have a Layout button.

    private void buttonLayout_Click(object sender, EventArgs e)
    {
      foreach (GoObject o in goView1.Document)
      {
        if (o is SwimmingPool)
        {
          SwimmingPool pool = o as SwimmingPool;
          pool.LayoutNodes();
        }
      }
    }

Dear Jake,
Thank you very much for the quick reply.