How to make Group not moving while dragging nodes

I’m trying to create a diagram looks like the screenshot below.

Basically it’s a TableLayout with 5 columns and 5 rows:

  • cell [0,1] with colSpan = 2: Group 1
  • cell [0,3] with colSpan = 2: Group 2
  • cell [1,1] to cell [1,4]: Column 1, 2, 3, 4
  • cell [2,0]: Row 1
  • cell [2,1] with colSpan = 4: this area contains rectangle boxes called “containers” whose left positions are different from each other
  • each “container” is a GridLayout group which contains multiple nodes
  • nodes in this diagram can be moved between containers, they cannot live outside containers

Issues:

  1. When I drag a node, its container also moves which is not expected. If I don’t use go.Placeholder in container’s template then the container does not move but the nodes are not placed properly inside container. I tried to set {movable: false, selectable: false} to container but it does not help either. What is the correct way to achieve this?

  2. How can I make the row height expand automatically when a container receives new nodes? The row height should be equal to max height of its containers. An example would be appreciated.

You can access this demo here: JS Bin - Collaborative JavaScript Debugging

Thanks
Hieu Do

Have you tried setting Group | GoJS API to true?

For your second question, that is the default behavior. Perhaps there are limits on the height of the node’s that are being laid out by the TableLayout?

I tried setting computesBoundsAfterDrag to true, it makes the container not moving while dragging, but after I release the mouse, the container moves.

Did you want to constrain where users could move nodes? Perhaps by limiting them to the area of the cell? Or can nodes be dragged out of cells/groups into other cells/groups?

Yes, I want nodes to be dragged out of groups and put into other groups

There are several samples that demonstrate that behavior – for example: Regrouping Demo.

Basically, consider implementing Group.mouseDrop, mouseDragEnter, and mouseDragLeave. Also consider setting Group.handlesDragDropForMembers to true.

I’ve checked the Regrouping Demo example, the groups also move/resize when you drag the nodes.

group%20moves

My requirement does not allow groups (aka Container) to move, they must be stationary (size and position are fixed) and are only area where nodes reside in.

The Group.mouseDrop in the example above just adds the node to the new group using var ok = grp.addMembers(grp.diagram.selection, true);, it does not affect group position so the group still moves.

Is there any other way to make group not moving?

That sample has each Group.layout as an instance of GridLayout, in order to avoid overlapping nodes within each group. Clearly you don’t have to do that if you don’t want to. But you do want the groups to get larger as the user moves the member nodes apart, don’t you? That will cause neighboring groups to overlap, unless some outer layout moves them to avoid the overlap.

The groups are positioned to avoid overlap so we don’t need to worry about that. The nodes are stretched horizontally and aligned vertically inside groups. And yes, groups height need to grow/shrink when nodes are added/removed from them.

OK, but exactly what dragging behavior do you want to disallow? And what do you want to allow?

I just want the groups not to automatically resize or move themselves after I drop a node to them. Please look at this example Table Layout and imagine all cells in the table are fixed width, nodes are stretched horizontally to take up the cell width (like a stack or a GridLayout with only 1 column). Each cell has a minHeight which equals to, for example, 3 nodes, and if you drop 4th node to it, its height will extend programmatically. Basically, I just want to control the position and size of the groups using code.

OK, to be clear, you are depending on the diagram’s layout to move groups so that they do not overlap each other, just as the Regrouping sample does. But you do not want a group to change size when its membership has not changed.

Well, the easiest implementation would be to control the size of each Group via code and not use any Placeholder at all.

I am surprised that you are not saying that you want to prevent the user from dropping a node so that it crosses over the boundary of a group. If you haven’t considered that but do want that restriction, I suppose your Group.layout, which sounds like it could just be a GridLayout with GridLayout.wrappingColumn set to 1, will automatically do that for you.

Hmmm, it might be best if you customized the Group.layout by overriding Layout.commitLayout to call the super method and then set the height of the Group the way that you want. The details depend on how you define the template.

So you still need to implement Group.mouseDrop to add the dropped nodes as members of the group. Optionally you should implement mouseDragEnter and mouseDragLeave and set handlesDragDropForMembers. You don’t need computesBoundsAfterDrag.

Your mouseDrop handler might want to call Layout.invalidateLayout on the group’s layout, so that any moves within a group (i.e. not changing any memberships) will still result in a layout that ensures all nodes are nicely lined up.