Restoring group location when collapsed

My friend, i’m already using GOJS for two years and i was complaining about this strange behavior several times : A group that this is collapsed does not restore its original position before it was expended.
For the best of my understanding, this feature should have been GOJS built in native behavior.
Instead, you’re asking me to implement my own code and try and understand the difference between location and position (why in first place, do you maintain two variables ? this is quite miss leading)
I’m implementing an network editor (like visio) and this strange behavior is quite frustrating my customers almost making my solution’s unusable.
Anyway, now i use Group.position. Still, the same behavior.
I can send u the entire code if you wish. Typescript.

Hmmm, well, in that case I may have been misunderstanding what the problem has been. Try this with no event handlers or DiagramEvent listeners, just the two overrides of CommandHandler commands.

        $(go.Diagram, "myDiagramDiv",
          {
            scrollMode: go.Diagram.InfiniteScroll,
            "commandHandler.collapseSubGraph": function(grp) {
              var gview = null;
              var group = findGroup(grp);
              if (group) gview = this.diagram.transformDocToView(group.location);
              go.CommandHandler.prototype.collapseSubGraph.call(this, grp);
              if (gview) {
                this.diagram.position = group.location.copy().subtract(gview);
                gview = null;
              }
            },
            "commandHandler.expandSubGraph": function(grp) {
              var gview = null;
              var group = findGroup(grp);
              if (group) gview = this.diagram.transformDocToView(group.location);
              go.CommandHandler.prototype.expandSubGraph.call(this, grp);
              if (gview) {
                this.diagram.position = group.location.copy().subtract(gview);
                gview = null;
              }
            },
            . . .

and

    function findGroup(grp) {
      if (grp instanceof go.Group) return grp;
      var it = this.diagram.selection.iterator;
      while (it.next()) {
        if (it.value instanceof go.Group) return it.value;
      }
      return null;
    }

Thanks Walter,
Currently, i’m out of the office,
Will try tomorrow.

Hi Walter,
I tried the code but it didn’t help much.
I noticed that the code does not restore the group.position nor saves the original position before expanding.
Do i miss something ?

After your further description, it occurred to me that maybe you just wanted the group to stay at the same point in view coordinates when you expand and when you collapse any group. The group position in document coordinates does not really matter to you. I think my code satisfies that requirement, although to maximize the opportunity to meet that requirement even when the group is near the edge of the document, I specified InfiniteScroll so that there are no scrolling limits.

I see,
What i noticed is that when a group is expanded, its adjacent groups are “moved” aside.
Is it possible to avoid the movement of the adjacent groups so that the expanded group will “hide” them and not move them ?
i suspect that some “auto” layout is turned on…
Let me try to describe the user experisne :
The use drag nodes onto a diagram and place. At some point, the user presses a button and the nodes are grouped by some attributes (siteId). For example, some group are added to siteId=100 and some to siteId=200.
After the groups are created, the user sees only two nodes = group(100) and group(200).
Then, when he press on of the groups, for example group(100), it is expanded but group(200) is also moved.
After dragging then two groups elsewhere in the diagram, and expanding one of the group, the second group stoppes moving.
So, i guess that only after the groups are created, the diagram is invalidated causing the adjecnt groups to move. I tried to set the layout.isOngoing to false.
Didn’t help.

Yes, the document-coordinates positioning of nodes is the responsibility of the Diagram.layout.

I have sample code that can simulate the behavior.
How can i upload the file ?

Send email to GoJS at our domain (nwoods.com). Thanks.

I cannot find any place to upload a file ?

email attachment

This is exactly what i couldn’t find.
Could you send me a link ?

??? send email; attach the text file with “.html” extension or “.txt”, not “.js” because the mail server will reject it if it thinks it might be executable.

OK,
Sent email to gojs.
Please rename to html extension

  1. Run the HTML
  2. Group Nodes (button on the right side).
  3. Expand the “Alpha” group, by double click. The “Beta” group will also move.
  4. Collapse “Alpha” group and expand again. At this time the “Beta” group will NOT move.

Got it. Thanks.

We need to be clear about some terminology.

An instance of a Part (which would include a Node or a Group) moves when its Part.location or GraphObject.position or GraphObject.actualBounds changes its x or y value. All of those properties are in document coordinates for Parts.

If you look at the position of group “Beta” before and after expanding or collapsing “Alpha”, it does not change value. So “Beta” does not move.

But the diagram does scroll. Just look at the value of Diagram.position before and after.

    $(go.Diagram, . . .,
        {
                            "ModelChanged": function(e) {
                              if (e.isTransactionFinished && myDiagram) {
                                console.log("Diagram.position: " + myDiagram.position.toString());
                                myDiagram.nodes.each(function(n) {
                                  if (n.isTopLevel) console.log(n.position.toString());
                                });
                              }
                            }
        });

So what can be done to avoid this “one time” virtual movement of “Beta” group ?

Well, since my understanding of your requirements keeps changing, so does the code:

    scrollMode: go.Diagram.InfiniteScroll,
    "commandHandler.collapseSubGraph": function(grp) {
        var dpos = this.diagram.position.copy();
        go.CommandHandler.prototype.collapseSubGraph.call(this, grp);
        this.diagram.position = dpos;
      },
    "commandHandler.expandSubGraph": function(grp) {
        var dpos = this.diagram.position.copy();
        go.CommandHandler.prototype.expandSubGraph.call(this, grp);
        this.diagram.position = dpos;
      }

First of all i apologize for miss leading you.
I know that this thread started with “restoring” the group location.
Then, it changed to “avoid movement of adjacent nodes”.
It was changed since i noticed that after the “first” expansion, the group does restore its location on the seconds, third… expansion time, so i could live with that.
Yet, i noticed that the adjacent nodes “moves” aside during the first expansion, so i asked you about “beta” group movement.
Sorry for the mess.
Still, i added your code to my html code, (the one that i sent you), AS IS and “beta” group still moves.

Did you include something like what I wrote before?

Much better.
Thanks