Dynamic Group sizing based on group's member parts

I have a problem in sizing groups.
My requirement is to dynamically size (or) resize groups based on its memberParts.

Approaches Tried:

  1. Using Placeholder
    This was working fine based the groups position was moving due to size change.
    Tried with computeIncludingLocation, as we are using locationSpot:go.Spot.Center this didn’t work correctly.
  1. Using Layout
    In this approach we override the doLayout() in go.Layout, This approach renders the that custom resizing a bit later, so it doesn’t suits well for our use-ases
  1. Using Shape
    This approach was working better for our use-case. we were computing the size based on its member parts.
const computeRect = (parent: go.Group) => {
      let holder = parent.findObject("StructShape")
      let point = holder.getDocumentPoint(go.Spot.TopLeft)
      let children = parent.memberParts
      if (children.count < 1) {
        return
      }
      let maxX = -Infinity, maxY = -Infinity
      while (children.next()) {
        let child = children.value
        if (child instanceof go.Link) continue
        let childBound = child.getDocumentPoint(go.Spot.BottomRight)
        if (childBound.x < point.x || childBound.y < point.y) {
          let bound = child.actualBounds
          childBound = child.location
          childBound.x += bound.width / 2
          childBound.y += bound.height / 2
        }
        maxX = Math.max(maxX, childBound.x)
        maxY = Math.max(maxY, childBound.y)
      }
      holder.height = maxY - point.y
      holder.width = maxX - point.x
    }

and our current structure for group

$(go.Group, "Spot", getNodeProperties(),
      {
        memberAdded: (thisGroup: go.Group, part) => {
          if (thisGroup.isSubGraphExpanded) {
            if (thisGroup.memberParts.count > 0) {
              computeRect(thisGroup)
            }
          }
        },
      },
      new go.Binding("isSubGraphExpanded", "isExpanded", (val: boolean) => {
        return val
      }).makeTwoWay((val, srcData: VolanteRow<FlowElementField>) => {
        if (val !== srcData.isExpanded) {
          messageFlowTable.toggleRowExpanded([srcData.id], val)
        }
      }),
      $(go.Panel, "Auto", { name: "subFlowPanel" },
        getShapeForNode("RoundedRectangle"),
        $(go.Panel, "Vertical",
          $(go.Panel, go.Panel.Horizontal,
            new go.Binding("background", "original", (val) => { return val.visual.fillColor }),
            getIconForNode(),
            getTextForNode(5),
            $("SubGraphExpanderButton", { alignment: go.Spot.Right })),
          $(go.Shape, "RoundedRectangle",
            { name: "StructShape", stroke: null, alignment: go.Spot.TopLeft, minSize: new go.Size(200, 100) },
            new go.Binding("fill", "original", (val) => {
              return val.visual.subGraphColor || "white"
            }),
            new go.Binding("visible", "isExpanded")
          )
        )
      ),
      makePort("DefaultFlowPort", "1", go.Spot.Bottom),
      makePort("ExceptionFlowPort", "2", go.Spot.Right)
    );

Major Issue:

  • we need to call that computeRect() after the response data being injected to that group data. diagram.requestUpdate() also used but it executes before response being loaded

[EDIT: fixed class]

You could try to override the undocumented protected method of the Placeholder class. You’ll need to define a subclass of Placeholder and use it in your Group template(s).

  protected computeMemberBounds(result: Rect): Rect;

In your override, compute the rectangle that you want, modify the given result Rect, and return it.

we tried…that also not suit for our use-case

Oops, sorry about that. I just checked – it’s a method of Placeholder, not Group.

thats why we are not using placeholder, we use our own custom shape, we are resizing shape in selection moved diagram event

Your Shape can surround the Placeholder, as is typical for most Group templates.