Issue with Group Object Placement and GridLayout in GoJS

Hi,
I’m currently working on a project where I’m utilizing GoJS version 2.2.13 to implement a diagram with draggable and droppable groups.
I’ve encountered a specific issue related to the placement of group objects and the use of go.GridLayout.

I have successfully implemented a grid layout for the groups, ensuring that the objects within the group are arranged in a grid.

However, when I drag and drop objects into a group, the placement of the group seems to shift to the top-left corner of the diagram unexpectedly.

Here’s a snippet of the code I’m using for the grid layout like Regrouping Demo (gojs.net):

const finishDrop = (e: go.InputEvent, group: go.Group | null): void => {
    // Check if the drop target is a group
    const isDroppedToGroup = group instanceof go.Group;

    // Get the success status of the operation
    const isSuccess = isDroppedToGroup
        ? // If dropped onto a group, add the selected objects as members
          group.addMembers(e.diagram.selection, true)
        : // If dropped onto a diagram (not a group), add the selected objects to the diagram
          e.diagram.commandHandler.addTopLevelParts(e.diagram.selection, true);

    // If the operation was successful and the drop target is a group, perform layout
    if (isSuccess && isDroppedToGroup) {
        const layout = $(go.GridLayout, {
            wrappingWidth: NaN,
            alignment: go.GridLayout.Position,
            cellSize: new go.Size(1, 1),
            spacing: new go.Size(4, 4),
        });
        layout.doLayout(group);
    }

    // If the operation failed, cancel the current tool to undo the operation
    if (!isSuccess) {
        e.diagram.currentTool.doCancel();
    }
};

I suspect that the problem lies in how I handle the layout after adding members to the group, but I’m uncertain about the correct approach.

Your assistance would be greatly appreciated.

What is your Group template?

It is unusual to replace its layout during a drop.

First, I appreciate your assistance with my inquiries regarding the use of GoJS.

I acknowledge your observation that it is unusual for the layout to be replaced during a drop in GoJS. As per the sample code, it appears that the “layout” property is configured in the Group’s template, which seems to be a common configuration approach.

However, the core issue I would like to address pertains to the behavior during diagram initialization. Setting the “layout” property in the Group’s template triggers the execution of the layout during diagram redraw, and this is not the behavior I anticipated. Allow me to rephrase my question.

I am using GoJS to create a diagram, and my goal is to save drawing data (node positions and link states) for later reproduction of the diagram by reloading the saved data. Unfortunately, when the “layout” property is set in the Group’s template, the layout is executed during the initial display, preventing the restoration of the saved state during redraw.

Is there a way to prevent the execution of the layout in the Group’s template during redraw (initial display)?

For your information, I am using ReactDiagram for rendering.

Thank you in advance.

If everything in your model always has information in it that all of the node templates use (probably via a data Binding on the Part.location property), then you don’t need to set any layout – neither Diagram.layout nor Group.layout.

If sometimes your model data doesn’t have that location information and you want to perform a layout automatically, then maybe the Diagram and your Group template(s) should indeed have a layout set on them, but by default have their Layout.isInitial and Layout.isOngoing properties set to false.

Then when you want a layout to occur, you have two choices:

  1. Explicitly call Layout.invalidateLayout or Diagram.layoutDiagrams.
  2. Set up a “LayoutCompleted” DiagramEvent listener that resets those Layout isinitial and isOngoing properties back to false. Then:
    a) when loading a new model, set isInitial to true on the Diagram.layout before replacing the Diagram.model, or
    b) when modifying an existing model, set isOngoing to true on the Diagram.layout or Group.layout before doing the modification.

Thank you for your response.
I see, the isInitial and isOngoing settings also contribute to the behavior.
After much consideration, I was able to achieve the expected behavior by setting the groupTemplate as follows.

layout: new go.GridLayout({
            wrappingWidth: NaN,
            alignment: go.GridLayout.Position,
            cellSize: new go.Size(1, 1),
            spacing: new go.Size(4, 4),
            isInitial: false,
            isOngoing: true,
        }),