Different Spacing around Group members/nodes in Grid Layout

I have a req where i have 2 different types of nodes (Created by node templates) inside a Group.

I want Less spacing around around one type of node and more on a different type. Such that one type of node appears more Nearer.

With below code, all nodes are equally spaced.

diagram.groupTemplate =  // for cells
            $(go.Group, "Auto",
                {
                    layerName: "Background", avoidable: false,
                    stretch: go.GraphObject.Fill,
                    selectable: false,
                    computesBoundsAfterDrag: true,
                    computesBoundsIncludingLocation: true,
                    layout: $(go.GridLayout,  // automatically lay out the lane's subgraph
                        {
                            wrappingColumn: 1,
                            cellSize: new go.Size(50, 50),
                             spacing: new go.Size(50, 50),
                            comparer: reorderBasedOnLoc
                        }),

I am using Table Layout sample code and modified according to our need.

Need something like below, Where N2 needs to be nearer to N1

I think i should approach this with sub groups. Let me try that and update here

I was going to suggest that you define the node template so that there is margin built into the node that is not visible. Example:

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2024 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
  <textarea id="mySavedModel" style="width:100%;height:300px"></textarea>

  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
const myDiagram =
  new go.Diagram("myDiagramDiv", {
      layout: new go.GridLayout({ wrappingColumn: 4, spacing: new go.Size(0, 0), cellSize: new go.Size(1, 1) }),
      "undoManager.isEnabled": true,
      "ModelChanged": e => {     // just for demonstration purposes,
        if (e.isTransactionFinished) {  // show the model data in the page's TextArea
          document.getElementById("mySavedModel").textContent = e.model.toJson();
        }
      }
    });

myDiagram.nodeTemplate =
  new go.Node("Auto", { selectionObjectName: "BODY" })
    .add(
      new go.Panel("Auto", { name: "BODY", width: 100, height: 50 })
        .bind("margin")
        .add(
          new go.Shape({ fill: "white" })
            .bind("fill", "color"),
          new go.TextBlock()
            .bind("text")
        )
    );

myDiagram.model = new go.Model(
[
  { key: 1, text: "Alpha", color: "lightblue" },
  { key: 2, text: "Beta", color: "orange" },
  { key: 3, text: "Gamma", color: "lightgreen" },
  { key: 4, text: "Delta", color: "pink" },
  { key: 11, text: "Alpha", color: "lightblue" },
  { key: 12, text: "Beta", color: "orange" },
  { key: 13, text: "Gamma", color: "lightgreen", margin: 10 },
  { key: 14, text: "Delta", color: "pink" },
  { key: 21, text: "Alpha", color: "lightblue" },
  { key: 22, text: "Beta", color: "orange" },
  { key: 23, text: "Gamma", color: "lightgreen", margin: 20 },
  { key: 24, text: "Delta", color: "pink" },
  { key: 31, text: "Alpha", color: "lightblue" },
  { key: 32, text: "Beta", color: "orange" },
  { key: 33, text: "Gamma", color: "lightgreen" },
  { key: 34, text: "Delta", color: "pink" },
]);

Hey walter, Thanks for the replay. I guess using subgroup will be scalable for future features. I was able to achieve it with sub group, below is snap of actual (Please ignore yellow marking)

Though i am facing aligning the sub group to normal nodes, can you help me in this regard. (Undesired space is marked with blue color and red background is subgroup)

i am using table layout, and below is complete code for group template

$(go.Diagram, {
                contentAlignment: go.Spot.TopLeft,
                layout: $(TableLayout, $(go.RowColumnDefinition, { row: 1, height: 50 }),  // fixed size column headers
                    $(go.RowColumnDefinition, { column: 1, width: 50 })),
                // disallow nodes to be dragged to the diagram's background
                mouseDrop: e => {
                    e.diagram.currentTool.doCancel();
                },
                // a clipboard copied node is pasted into the original node's group (i.e. lane).
                // automatically re-layout the swim lanes after dragging the selection
                "SelectionMoved": relayoutDiagram,  // this DiagramEvent listener is
                "SelectionCopied": relayoutDiagram, // defined above
                "toolManager.hoverDelay": 300,
                "commandHandler.doKeyDown": () => { },
                isReadOnly: this.props.isReadOnly,
                model: $(go.GraphLinksModel,
                    {
                        linkKeyProperty: 'key',  // IMPORTANT! must be defined for merges and data sync when using GraphLinksModel
                        // positive keys for nodes
                        makeUniqueKeyFunction: (m, data) => {
                            let k = data.key || 1;
                            while (m.findNodeDataForKey(k)) k++;
                            data.key = k;
                            return k;
                        },
                        // negative keys for links
                        makeUniqueLinkKeyFunction: (m, data) => {
                            let k = data.key || -1;
                            while (m.findLinkDataForKey(k)) k--;
                            data.key = k;
                            return k;
                        }
                    })
            });

const makeGroupLayout = (isSubGraph) => {
            return $(go.GridLayout,  // automatically lay out the lane's subgraph
                {
                    wrappingColumn: 1,
                    cellSize: isSubGraph ? new go.Size(0, 0) : new go.Size(50, 50),
                    spacing: isSubGraph ? new go.Size(0, 10) : new go.Size(50, 50),
                    comparer: reorderBasedOnLoc,
                    alignment: go.Spot.Left
                });
        }

        diagram.groupTemplate =  // for cells
            $(go.Group, "Auto",
                {
                    layerName: "Background", avoidable: false,
                    stretch: go.GraphObject.Fill,
                    selectable: false,
                    computesBoundsAfterDrag: true,
                    computesBoundsIncludingLocation: true,
                    layout: makeGroupLayout(false),
                    handlesDragDropForMembers: true,  // don't need to define handlers on member Nodes and Links
                    mouseDragEnter: (e, group, prev) => { group.isHighlighted = true; },
                    mouseDragLeave: (e, group, next) => { group.isHighlighted = false; },
                    mouseDrop: (e, group) => {
                          // drop logic
                },
                new go.Binding('layout', '', ({ isSubGraph }) => makeGroupLayout(isSubGraph)),
                new go.Binding("row"),
                new go.Binding("column", "col"),
                new go.Binding('background', '', ({ isSubGraph }) => isSubGraph ? 'red' : 'transparent'),
                // the group is normally unseen -- it is completely transparent except when given a color or when highlighted
                $(go.Shape,
                    {
                        fill: "transparent", stroke: "transparent",
                        strokeWidth: 25,
                        stretch: go.GraphObject.Fill
                    },
                    new go.Binding("fill", "color")),
                $(go.Panel, 'Vertical', {},
                    new go.Binding('alignment', '', ({ isSubGraph }) => isSubGraph ?
                        go.Spot.Left : new go.Spot(0, 0, 25, 25)),
                    new go.Binding('padding', ({ isSubGraph }) => isSubGraph ?
                        new go.Margin(0, 0) : new go.Margin(0, 25, 25, 0)),
                    $(go.Placeholder))
            );

Update, alignment issue is happening only when a cell contains two different kinds of members i.e Normal node and sub group.

If its only Nodes or only sub groups in a cell then above aligning issue is not happening. (not able to figure out where i am making the mistake)

Hmmm, I don’t know what might be causing that. The padding on the Placeholder is suspicious, but it isn’t big enough to account for the extra space.

Padding inside the placeholder should add space within subgroup (i.e red box) right. Tried varying the values but its not affecting the outer space.

One workaround i am thinking to wrap all the nodes inside subgroup even there are no related nodes that way we will have only one type of nodes. But i.e not ideal right

Do you set or bind the Part.alignment on your Nodes or your Groups?
Maybe you want to set TableLayout.defaultAlignment to go.Spot.Left or go.Spot.TopLeft.

Thank you… Yes parts were having alignment. After removing its better than earlier though there is some extra space on the left side even after removing. Will try to investigate more.