Issue with Group Auto Resizing during a Move

Hello, I’m having a problem with groups in my diagram. I am using the CommandHandler Ctrl-G to create new groups based on my selection. My diagram is using a LayeredDigraphLayout and my group template also sets another instance of LayeredDigraphLayout on the group. The group template also uses a placeholder for the member parts.

Everything is working great with one exception. When I move the group it quickly flashes (auto resizes) during the move. When the move is completed it returns to the size I would expect based on the nodes within the placeHolder (the original size before the move).

For example if I have this layout…

N1
|
||||G|||||
|   N2   |
|   |    |
|   N3   |
||||||||||

Imagine the links are such N1 -> N2, N2 -> N3 (no links to the group itself). When I move Group G to the right, during the move the node N3 seems to move to the top of the diagram while N2 remains stationary. This causes the link from N2 to N3 to curl back around up to the top and causes the vertical size of G to increase.

If I don’t have that link from N2 -> N3 then the move happens smoothly without causing the group to auto resize.

My setting on the group is to not allow the user to resize it.

I’m using version 1.6.9, the latest download at this time.

I just tried this simplified version of samples/basic.html, and moving the Group works well:

  function init() {
    if (window.goSamples) goSamples();
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
        {
          initialContentAlignment: go.Spot.Center,
          layout: $(go.LayeredDigraphLayout, { direction: 90, isRealtime: false }),
          "undoManager.isEnabled": true
        });

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        { locationSpot: go.Spot.Center },
        $(go.Shape, "RoundedRectangle",
          { fill: "white", portId: "" },
          new go.Binding("fill", "color")),
        $(go.TextBlock,
          { font: "bold 14px sans-serif", margin: 6 },
          new go.Binding("text", "text"))
      );

    myDiagram.linkTemplate =
      $(go.Link,
        { toShortLength: 3 },
        $(go.Shape,
          { strokeWidth: 2 },
          new go.Binding("stroke", "color")),
        $(go.Shape,
          { toArrow: "Standard", stroke: null },
          new go.Binding("fill", "color"))
      );

    myDiagram.groupTemplate =
      $(go.Group, "Vertical",
        {
          selectionObjectName: "PANEL",
          layout: $(go.LayeredDigraphLayout, { direction: 90, isRealtime: false })
        },
        $(go.TextBlock,
          { font: "bold 19px sans-serif" },
          new go.Binding("text", "text"),
          new go.Binding("stroke", "color")),
        $(go.Panel, "Auto",
          { name: "PANEL" },
          $(go.Shape, "Rectangle",
            { fill: "rgba(128,128,128,0.2)", stroke: "gray", strokeWidth: 3 }),
          $(go.Placeholder, { padding: 10 })
        )
      );

    // Create the Diagram's Model:
    var nodeDataArray = [
      { key: 1, text: "Alpha", color: "lightblue" },
      { key: 2, text: "Beta", color: "orange" },
      { key: 3, text: "Gamma", color: "lightgreen", group: 5 },
      { key: 4, text: "Delta", color: "pink", group: 5 },
      { key: 5, text: "Epsilon", color: "green", isGroup: true }
    ];
    var linkDataArray = [
      { from: 1, to: 2, color: "blue" },
      { from: 3, to: 4, color: "green" },
      { from: 1, to: 3, color: "purple" }
    ];
    myDiagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
  }

So I cannot reproduce the problem.

Hi Walter,

Your example works fine for me, too. I have more going in my case so I will try to isolate why it doesn’t work for my diagram. I’ve been looking at your docs and examples for a couple days now.

My links go to custom ports on the nodes, not the node itself, so I will try to see if I can build on your simple example and add my stuff in till I can replicate. Of course I have event handlers, too, which could complicate things.

It seems like only during the move, some of the group members are losing their location and being moved off the diagram as if they don’t have a location set. Then when the move ends the location is getting set back.

Here are some screenshots captured during the move.

I think I’ve isolated it now to one or more of the bindings on my nodes. I have plenty of bindings to functions on the node properties and when I strip down the node to be very simple this problem does not occur.

I’ll report back when I find which binding(s) are the culprit.

After many experiments the problem was a binding to geometryString. The binding for that icon in the examples given above was to a function like this…

stepIconGeo: function(part) {
  return go.Geometry.fillPath(part.data.iconGeoString);
},

This caused the weird behavior when moving the group.

To solve this I calculated the fillPath up front and put this into the node data as property geoString.

Then changed to a simple binding like this:

new go.Binding("geometryString", "geoString"))

What was your Binding before? I’m suspicious that it was doing something unnecessary.

The binding before (weird behavior) was to a function that called go.Geometry.fillPath and returned the result. The binding after (fixed) was to a simple node data property whose value was the result of calling go.Geometry.fillPath.

Is it possible there are any side effects in the fillPath function?

No, the static function Geometry.fillPath has no side effects.

Was your original Binding .ofObject()? I’m guessing that it had been something like:

    $(go.Shape, new go.Binding("geometryString", "", stepIconGeo).ofObject(), . . .)

That could have been better expressed as the simpler and faster:

    $(go.Shape, new go.Binding("geometryString", "iconGeoString", function(str) { return go.Geometry.fillPath(str); }), . . .)

But what you’ve done is even better, at the expense of changing your data.