Using go.Spot.Center alignment on the vertical swim lanes sample


I am trying to implement a diagram similar to the vertical swim lanes sample as seen here:

Everything seems to be working fine, until I change the placeholder alignment for the Diagram’s groupTemplate from go.Spot.TopLeft to go.Spot.Center. The effect I am trying to achieve is to have the swim lanes align the contained nodes in the center of the swim lane, when the diagram is drawn. The side-effect of changing the placeholder’s alignment is that when a node in any of the swim lanes is dragged, the other nodes in the same lane move as well. If the alignment is set to TopLeft, then this does not happen.

To illustrate the side-effect better, I have created this jsfiddle, so that you can replicate easilly:

Try for example moving around any node inside Lane 1 and you will notice that when the node is dropped in a new position within the lane, the other nodes slightly move as well.
The example in the jsfiddle is an exact copy of the sample code in github:

The line of code I changed to achieve the Centered effect is 326 on github and 304 in the jsfiddle posted above.

Is there a way to still set the alignment to Centered for the diagram’s groupTemplate placeholder and not have the side-effect of the other nodes in the swim lane being re-positioned when moving a node?

I haven’t tried your code yet, but it seems to me that if something is centered, when you change its size by moving one of its nodes, then it makes sense that it (the Placeholder) has to move in order to keep it centered.

Hi @walter,

Yes, agreed, this would be an expected behavior. What I am trying to achieve is to have the placeholder center the items on the first draw, but then switch it to use go.Spot.TopLeft so that then the items are moved around it does not try to recenter them.

Do you have any suggestion on how I could make something like that?

Leave the Placeholder as:

              { padding: 12, alignment: go.Spot.TopLeft }),

and add this to the initialization of the Diagram:

  "InitialLayoutCompleted": function(e) {
    var diagram = e.diagram;
    diagram.nodes.each(function(n) {
      var grp = n;
      if (grp instanceof go.Group && grp.category === "") {
        var memberctr = diagram.computePartsBounds(grp.memberParts).center;
        var lanectr = grp.findObject("SHAPE").getDocumentBounds().center;
        diagram.moveParts(grp.memberParts, lanectr.subtract(memberctr));

Basically, after everything has been loaded and laid out, it moves all of the lane/group contents to be in the middle of the lane.

Pure magic, thank you Walter!
That did the trick.

It occurs to me now that you might want to do the same movement of the lane/group’s members after the user has resized a lane. But maybe you don’t. Your choice.

Yes, that is exactly how I used the code snippet you posted. I used the same approach in the LaneResizingTool.prototype.resize method and that creates a nice visual effect of the swim lanes being resized equally on both the right and the left side. Pretty cool! Thank you @walter.