Collapsing SubGraphs in bulk doesn't update document bounds correctly

So I’m assuming this is an issue with the way I’m collapsing subgraphs, but I can’t see to track down a different way to do this.

I have a diagram with several expandable/collapsible subgraphs. The diagram has a listener to manipulate the viewport to keep the changed objects in a reasonable view:

      SubGraphCollapsed: (e: go.DiagramEvent) => {
        const nodes = e.subject as go.List<go.Group>;
        setTimeout(() => {
          const diagram = e.diagram;
          if (
            diagram.viewportBounds.width > diagram.documentBounds.width &&
            diagram.viewportBounds.height > diagram.documentBounds.height
          ) {
            diagram.zoomToRect(diagram.documentBounds);
          }
        });
      },

Then I have buttons that expand/collapse all subGraphs:

const collapseGroup = (group: go.GraphObject) => {
  if (!(group instanceof go.Group)) return;
  let diagram = group.diagram;
  if (diagram === null) return;
  let cmd = diagram.commandHandler;
  cmd.collapseSubGraph(group);
};

and

  const collapseAll = (e: go.InputEvent): void => {
    if (!e.diagram) return;
    const diagram = e.diagram;
    if (diagram instanceof go.Diagram) {
      diagram.startTransaction('collapse');
      const nodes = new go.List<go.Group>();
      diagram.nodes.each((g: go.Node) => {
        if (g instanceof go.Group) {
          g.collapseSubGraph();
          nodes.add(g);
        }
      });
      diagram.redraw();
      diagram.raiseDiagramEvent('SubGraphCollapsed', nodes);
      diagram.commitTransaction('collapse');
    }
  };

If I put a breakpoint in the event handler and use the individual collapse, the document bounds are updated fine. If I use the same breakpoint and use the collapseAll, the document bounds aren’t updated, and my ‘zoomToFit’ fails. I have an exact copy of this code, but inverted for expand, and it all works fine (because it’s check doesn’t require document bounds.) I could do something like calculating a bounding rect around all nodes and comparing to the viewport, but I figured I’d check and see if there was something obvious I was missing before that.

Also, as an aside, a commandhandler.collapseSubGraph that accepts a collection would be swell, rather than just single nodes or the current selection.

It’s pretty clear the bounds are still messed up afterwards because of the scrollbar also:

I just tried your code, but I was unable to reproduce any problem. Maybe I tried the wrong configuration of templates or of data. Is there any chance you could help us reproduce the problem?

Your call to redraw is superfluous.

Which things would be useful? I can email them to you.

Thanks – yes, send it to GoJS at our domain, nwoods.com.
A minimal stand-alone page is usually easiest to reproduce and test.

I can see if I can make something, but it’s a pretty big project haha. Lemme see how minimal I can make it.

So I spent some time digging into it, and I figured the problem out.

The issue is the context menu. When the click handler runs, and the transaction commits, the context menu is still “part” of the diagram, and so the document bounds are including it.

I need a way to clear the context menu before the document bounds are calculated, or make them not count as part of it.

(I spent a while trying to make a working simplified example and failed miserably, so I just ended up debugging haha)

I would prefer to not use an html context menu, so I think some way to destruct the context menu inside the transaction before I commit might be the play? Or maybe I need to bite the bullet and start in on html context menus.

Set Part.isInDocumentBounds to false on the context menu.
Part | GoJS API