Group layout not working as expected

Hi everyone,

I am trying to use groups in a GraphsLinksModel with a TreeLayout. Everything works fine when I expand/collapse nodes without any groups present in the diagram:

However, as soon as I associate the same nodes with a group that has layout = null, as instructed in the SubGraphs page, the layout is broken when toggling the nodes:

What am I doing wrong?

This is the group template I am using:

    return new go.Group("Vertical")
      .add(new go.Panel("Auto")
        .add(new go.Shape("Rectangle", {
          fill: "rgba(128,128,128,0.33)"
        }))
        .add(new go.Placeholder({
          padding: 10
        }))
        .add(new go.TextBlock({
          alignment: go.Spot.TopLeft,
          font: "14px Roboto"
        })
          .bind("text", "label"))
      );

You need to set the Group.layout property in the group template to either null or (more commonly) an instance of a layout – in your case a TreeLayout. The choice depends on the kind of results you want.

Dear Walter,

as I already mentioned, I tried setting the layout to null and to the layout used by the diagram. None of these changed anything about the behaviour which seems to be a tree layout with an angle of 270:

 return new go.Group("Vertical", {
      layout: this.diagram.layout
    })
      .add(new go.Panel("Auto", {
        stretch: go.GraphObject.Horizontal,
      })
        .bind("background", "color", v => v ?? 'black')
        .add(new go.TextBlock({
          font: "500 14px Roboto",
          stroke: 'black',
          verticalAlignment: go.Spot.Center,
          margin: new go.Margin(5)
        })
          .bind("text", "label"))
      )
      .add(new go.Panel("Auto")
        .add(new go.Shape("Rectangle", {
          fill: "black",
          stroke: "transparent",
          strokeWidth: 0,
          opacity: .5
        })
          .bind("fill", "color", v => v ?? 'black'))
        .add(new go.Placeholder({
          padding: 20,
          minSize: new go.Size(200, 40)
        }))
      );

Ah, OK, your template that you showed above did not set the Group.layout to anything.

How is your Diagram.layout defined? Is it a TreeLayout with angle == 270?

The TreeLayout instance is initially created with the diagram and I set this layout instance to the group template when the template is created. Here’s the initial tree layout options:

  angle: number = 90;
  layerSpacing: number = 100;
  nodeSpacing: number = 50;
  alternateAngle: number = 90;
  alternateLayerSpacing: number = 100;
  alternateNodeSpacing: number = 150;

These do not at all match the result. It seems that the layout property in the group template is either ignored or replaced by some default value.

I’d like to be able to bind the layout in the template as a user can change the layout type at runtime. But I’d be happy if it worked as expected for now…

I’m not sure what’s going on, but I think the basic problem is that you cannot share the layout used by Diagram.layout to also be any Group.layout.

Make a separate instance of TreeLayout to assign to Group.layout.

When implementing the layout copy function I figured out that by the time the group template was created, the diagram layout was not yet initialized.

Changed the initialization order, provided a method for cloning the current layout and now it works.

Thanks! :-)

In v2.2.12, just released, we have added a check in the Group.layout property setter to notice if the new value is the same as Diagram.layout. If it is, it now throws an exception.

You can copy a layout by calling Layout.copy.

Perfect. Thank you! :-)