Here’s code that does a GoLayeredDigraph layout on every SwimmingPool it finds in a GoDocument.
Note it doesn’t do anything to fix up links across lanes. You might be able to handle this (a little) by setting layout.ArrangementOrigin to align with the “from” node in a lane that starts with a “linked to” node.
Note the code works for either GoLayoutDirection.Down or GoLayoutDirection.Right.
private void menuItemLayoutSwimlanes_Click(object sender, EventArgs e) {
GoView view = goView1;
view.Document.StartTransaction();
foreach (GoObject o in view.Document) {
if (o is SwimmingPool) {
SwimmingPool pool = o as SwimmingPool;
SwimmingPoolLanes lanes = pool.Lanes as SwimmingPoolLanes;
float max = -1.0f;
foreach (GoObject s in lanes) {
SwimLane lane = s as SwimLane;
if (lane != null) {
GoLayoutLayeredDigraph layout = new GoLayoutLayeredDigraph();
layout.Document = view.Document;
GoLayoutLayeredDigraphNetwork network = layout.CreateNetwork();
network.AddNodesAndLinksFromCollection(lane, true);
layout.Network = network;
float margin = lanes.SwimLaneMargin;
PointF ao = lane.Position + new SizeF(margin, margin);
layout.ArrangementOrigin = ao;
layout.DirectionOption = GoLayoutDirection.Down;
layout.PerformLayout();
// the lane is done, now check to see if the layout area is bigger than the
// size of lane. remember the max across all lanes.
// Note that LayoutChildren will fix the area in one direction, we're just doing the other here.
RectangleF content = lane.ContentBounds;
RectangleF r = lane.Background.Bounds;
if (lanes.Orientation == Orientation.Vertical) {
if (content.Right > r.Right - lane.Margin) {
float w = content.Right + lane.Margin - r.X;
if (w > max) max = w;
}
}
else {
if (content.Bottom > r.Bottom - lane.Margin) {
float h = content.Bottom + lane.Margin - r.Y;
if (h > max) max = h;
}
}
}
}
// now, bump size of swimlanes if needed.
if (max > -1.0) {
foreach (GoObject s in lanes) {
SwimLane lane = s as SwimLane;
if (lane != null) {
if (lanes.Orientation == Orientation.Vertical) {
lane.Background.Width = max;
}
else {
lane.Background.Height = max;
}
}
}
}
}
}
view.Document.FinishTransaction("layout swimlanes");
}