How to update node dimensions programtically

Hi @walter,

I hope you are doing fine :)

I want to know how to update a Group’s (Node) Dimension programmatically. basically, i need to grab hold of the documentBounds of the node and update its width and height, but i couldn’t find a api to update the same.

could you help me in the right direction .

thanks in advance,
Manoj

That depends on the Group template and what you really want to change.

actually, i have the group template below ,

 return $(
    Group,
    'Auto',
    settings(),
    { zOrder: groupZOrder },
    { minSize: new Size(0, 0) },
    { layout: diagramGridLayout() },
    roundedPanel(color),
    { padding: 30 },
  );

so by default, the dimension of the group is 0, 0, however when I add the nodes inside it(grouping nodes ), then it will dynamically take the new dimensions to accommodate all child nodes inside it.

we have an HTML layer on top of this and there we have an expand/collapse button, on clicking the expand button, I want to programmatically reduce the group height and width to the desired size and vice versa when I try to expand it.

so to do this, I need to know which API I should call to reduce the dimension of the group node.

I was expecting setDocumentBounds() would do the job, but there isnt any api by that name, there is only getDocumentBounds().

So does the Group only consist of a “RoundedRectangle” Shape? There’s no Placeholder?

yes there is no placeholder, just the group.

because like i said, we are showing corresponding html layer on top of go js node at exact position for bettee ui and easy accessibility.

also we felt building ui on html layer is easy compared to gojs layer, which requires extensive knowledge of the api.

btw, is placeholder necessary?

A Placeholder is used to make sure the Group naturally has at least the same bounds (position and size) as its collection of member Parts. I still cannot tell how you are using Groups, so I cannot say whether you should be using a Placeholder or not.

Does this code do something like what you want?

If so, you could programmatically change the size of a “group” by setting its data.size property. (Within a transaction of course.)

<!DOCTYPE html>
<html>

<head>
  <title>Simple Group Resizing</title>
  <!-- Copyright 1998-2024 by Northwoods Software Corporation. -->
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  This sample uses a Group template that does not use a Placeholder, but allows the user
  to resize the group. Resizing of a group will not allow the group to resize smaller than its members.
  Moving member nodes is limited to stay within the group.

  <script src="../latest/release/go.js"></script>
  <script id="code">
    const $ = go.GraphObject.make;

    const GroupMargin = new go.Margin(5);

    myDiagram =
      new go.Diagram("myDiagramDiv",
        {
          "resizingTool.computeMinSize": function () {  // method override
            const group = this.adornedObject.part;
            const membnds = group.diagram.computePartsBounds(group.memberParts);
            membnds.addMargin(GroupMargin);
            membnds.unionPoint(group.location);
            return membnds.size;
          },
          "undoManager.isEnabled": true
        });

    // this is a Part.dragComputation function for limiting where a Node may be dragged
    function stayInGroup(part, pt, gridpt) {
      // don't constrain top-level nodes
      const grp = part.containingGroup;
      if (grp === null) return pt;
      // try to stay within the background Shape of the Group
      const back = grp.resizeObject;
      if (back === null) return pt;
      // allow dragging a Node out of a Group if the Shift key is down
      //if (part.diagram.lastInput.shift) return pt;
      const p1 = back.getDocumentPoint(go.Spot.TopLeft);
      const p2 = back.getDocumentPoint(go.Spot.BottomRight);
      const b = part.actualBounds;
      const loc = part.location;
      // no placeholder -- just assume some Margin
      const m = GroupMargin;
      // now limit the location appropriately
      const x = Math.max(p1.x + m.left, Math.min(pt.x, p2.x - m.right - b.width - 1)) + (loc.x - b.x);
      const y = Math.max(p1.y + m.top, Math.min(pt.y, p2.y - m.bottom - b.height - 1)) + (loc.y - b.y);
      return new go.Point(x, y);
    }

    myDiagram.nodeTemplate =
      $(go.Node,
        { dragComputation: stayInGroup, locationSpot: go.Spot.Center },
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        $(go.TextBlock, new go.Binding("text", "key"))
      );

    myDiagram.groupTemplate =
      $(go.Group, "Vertical",
        {
          locationObjectName: "SHAPE",
          locationSpot: go.Spot.Center,
          selectionObjectName: "SHAPE",
          resizable: true, resizeObjectName: "SHAPE",
          computesBoundsAfterDrag: true
        },
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        $(go.TextBlock, { font: "bold 11pt sans-serif" },
          new go.Binding("text", "key")),
        $(go.Shape, { name: "SHAPE", fill: "whitesmoke" },
          new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify))
      );

    myDiagram.model = new go.GraphLinksModel(
      [
        { key: "Alpha", loc: "65 -35" },
        { key: "Beta", group: "Epsilon", loc: "90 40" },
        { key: "Gamma", group: "Epsilon", loc: "125 85" },
        { key: "Delta", loc: "113 153" },
        { key: "Epsilon", isGroup: true, loc: "115 60" }
      ], [
      { from: "Alpha", to: "Beta" },
      { from: "Beta", to: "Gamma" },
      { from: "Gamma", to: "Delta" }
    ]);

    myDiagram.select(myDiagram.findTopLevelGroups().first());
  </script>
</body>

</html>

thanks for sharing the complete example, ill check this and see how i can achieve the same in my program.

thanks @walter

ill accept it as solution for now, if something doesnt work, then ill reply on the same