Group expander Right alignment

Hi, I need to put the group expander button to the right and the text in the middle.

This is my gruop template:

  var tpl = $(go.Group, "Spot",
      new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
      {
        selectionAdornmentTemplate: $(go.Adornment, 'Auto', {margin: 8}, $(go.Placeholder)),
        resizable: true,
        computesBoundsAfterDrag: true,
        ungroupable: false,
        selectionObjectName: 'BODY',
        resizeObjectName: 'BODY',
     //   locationObjectName: 'BODY',
        mouseDrop: me.controller.finishDrop,
        subGraphExpandedChanged: function(grp) {
          var shp = grp.resizeObject;
          if (grp.diagram.undoManager.isUndoingRedoing) return;
          if (grp.isSubGraphExpanded) {
            shp.height = grp._savedBreadth;
          } else {
            grp._savedBreadth = shp.height;
            shp.height = NaN;
          }
        },
        handlesDragDropForMembers: true  // don't need to define handlers on member Nodes and Links
      },
      new go.Binding("isSubGraphExpanded", "expanded").makeTwoWay(),
      $(go.Panel, "Auto",
        {name: 'BODY'},
        new go.Binding("height").makeTwoWay(),
        new go.Binding("width").makeTwoWay(),
        $(go.Shape, viewConfig.shape || 'RoundedRectangle',
          new go.Binding("fill").makeTwoWay(),
          // new go.Binding("visible", "isSubGraphExpanded").ofObject(),
          Ext.apply({name: 'BODY', minSize: new go.Size(130, 30)}, viewConfig.config),
          {
            spot1: go.Spot.TopLeft, spot2: go.Spot.BottomRight
          }),
        $(go.Panel, go.Panel.Vertical,  // title above Placeholder
          $(go.Panel, go.Panel.Horizontal,  // button next to TextBlock
            {
              name: "HEADER",
              //stretch: go.GraphObject.Horizontal,
              stretch: go.GraphObject.Fill,
              background: "transparent",
              margin: 1,
              defaultAlignment: go.Spot.TopRight
            },
            $(go.TextBlock,
              {
                alignment: go.Spot.TopLeft,
                //stretch: go.GraphObject.Fill,
                editable: true,
                margin: 5,
                isMultiline: false,
                textAlign: 'center',
                font: 'bold 10pt Segoe UI,Segoe UI Web Regular,Segoe UI Symbol,Segoe,Tahoma,Trebuchet,Arial,Verdana'
              },
              new go.Binding("text", "text").makeTwoWay()
            ),
            $("SubGraphExpanderButton", {
              alignment: go.Spot.TopRight,
              margin: 5
            })
          ),  // end Horizontal Panel
          $(go.Placeholder, {padding: 5, alignment: go.Spot.TopLeft})
        )// end Vertical Panel
      ),
      $(go.Panel, "Horizontal",
        {
          alignment: go.Spot.Top,
          alignmentFocus: new go.Spot(0.5, 0, 0, -8)
        },
        [makePort("IN", true)]),
      $(go.Panel, "Horizontal",
        {
          alignment: go.Spot.Bottom,
          alignmentFocus: new go.Spot(0.5, 1, 0, 8)
        },
        [makePort("OUT", false)])
    );

Any idea? thanks!

What happens when you change the Panel type from “Horizontal” to “Table” and remove the alignment on the TextBlock?

Without row and column definitions?

Yes, there would be only one cell in that Table Panel.

Have that Table Panel also stretch: go.GraphObject.Horizontal.

No, the same as before.

 var tpl = $(go.Group, "Spot",
      new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
      {
        selectionAdornmentTemplate: $(go.Adornment, 'Auto', {margin: 8}, $(go.Placeholder)),
        resizable: true,
        computesBoundsAfterDrag: true,
        ungroupable: false,
        selectionObjectName: 'BODY',
        resizeObjectName: 'BODY',
     //   locationObjectName: 'BODY',
        mouseDrop: me.controller.finishDrop,
        subGraphExpandedChanged: function(grp) {
          var shp = grp.resizeObject;
          if (grp.diagram.undoManager.isUndoingRedoing) return;
          if (grp.isSubGraphExpanded) {
            shp.height = grp._savedBreadth;
          } else {
            grp._savedBreadth = shp.height;
            shp.height = NaN;
          }
        },
        handlesDragDropForMembers: true  // don't need to define handlers on member Nodes and Links
      },
      new go.Binding("isSubGraphExpanded", "expanded").makeTwoWay(),
      $(go.Panel, "Auto",
        {name: 'BODY'},
        new go.Binding("height").makeTwoWay(),
        new go.Binding("width").makeTwoWay(),
        $(go.Shape, viewConfig.shape || 'RoundedRectangle',
          new go.Binding("fill").makeTwoWay(),
          // new go.Binding("visible", "isSubGraphExpanded").ofObject(),
          Ext.apply({ minSize: new go.Size(130, 30)}, viewConfig.config),
          {
            spot1: go.Spot.TopLeft, spot2: go.Spot.BottomRight
          }),
        $(go.Panel, go.Panel.Vertical,  // title above Placeholder
          $(go.Panel,
            go.Panel.Table,
            //go.Panel.Horizontal,  // button next to TextBlock
            {
              name: "HEADER",
              stretch: go.GraphObject.Horizontal,
              background: "transparent",
              margin: 1//,              defaultAlignment: go.Spot.TopRight
            },
            $(go.TextBlock,
              {
               // alignment: go.Spot.Left,
                //stretch: go.GraphObject.Fill,
                editable: true,
                margin: 5,
                isMultiline: false,
                textAlign: 'center',
                font: 'bold 10pt Segoe UI,Segoe UI Web Regular,Segoe UI Symbol,Segoe,Tahoma,Trebuchet,Arial,Verdana'
              },
              new go.Binding("text", "text").makeTwoWay()
            ),
            $("SubGraphExpanderButton", {
              alignment: go.Spot.TopRight,
              margin: 5
            })
          ),  // end Horizontal Panel
          $(go.Placeholder, {padding: 5, alignment: go.Spot.TopLeft})
        )// end Vertical Panel
      ),
      $(go.Panel, "Horizontal",
        {
          alignment: go.Spot.Top,
          alignmentFocus: new go.Spot(0.5, 0, 0, -8)
        },
        [makePort("IN", true)]),
      $(go.Panel, "Horizontal",
        {
          alignment: go.Spot.Bottom,
          alignmentFocus: new go.Spot(0.5, 1, 0, 8)
        },
        [makePort("OUT", false)])
    );

Why is so difficult? It would be better if there were any kind of “filler” or width percentage. So, only using Horizontal panel we could have something like this:
$(go.Panel, ‘Horizontal’,{text; ‘ObjectA’, width: ‘70%’ }, {text; ‘ObjectB’, width: ‘30%’ }

I just tried your code, excising the code that you didn’t provide and that I couldn’t define on my own. I got this:

Which I think is what you wanted. So I don’t know what else that you are doing to affect the panel layout.

However when I collapse the group the TextBlock and “SubGraphExpanderButton” get collapsed too, in a way that I assume you do not want. So here’s a better way of doing it:

      $(go.Group, "Table",
        {
          resizable: true,
          computesBoundsAfterDrag: true,
          selectionObjectName: 'BODY',
          resizeObjectName: 'BODY',
          subGraphExpandedChanged: function(grp) {
            var shp = grp.resizeObject;
            if (grp.diagram.undoManager.isUndoingRedoing) return;
            if (grp.isSubGraphExpanded) {
              shp.height = grp._savedBreadth;
            } else {
              grp._savedBreadth = shp.height;
              shp.height = NaN;
            }
          }
        },
        $(go.Panel, "Horizontal", { row: 0 },
          [makePort("IN", true)]),
        $(go.Panel, "Auto", { row: 1, name: 'BODY' },
          new go.Binding("height").makeTwoWay(),
          new go.Binding("width").makeTwoWay(),
          $(go.Shape, 'RoundedRectangle',
            { fill: "lightyellow", minSize: new go.Size(130, 30) }),
          $(go.Panel, go.Panel.Table,
            { stretch: go.GraphObject.Horizontal },
            $(go.TextBlock,
              {
                editable: true, isMultiline: false, textAlign: 'center',
                font: 'bold 10pt Segoe UI,Segoe UI Web Regular,Segoe UI Symbol,Segoe,Tahoma,Trebuchet,Arial,Verdana'
              },
              new go.Binding("text", "text").makeTwoWay()
            ),
            $(go.Placeholder, { row: 1, padding: 5, alignment: go.Spot.TopLeft })
          )
        ),
        $("SubGraphExpanderButton", { row: 1, alignment: go.Spot.TopRight, margin: 5 }),
        $(go.Panel, "Horizontal", { row: 2 },
          [makePort("OUT", false)])
      );

Fine, thank you!
If I resize vertically, the text of the group goes down.

You’re right – I should have cleaned up the rest of the code:

      $(go.Group, "Table",
        {
          resizable: true,
          computesBoundsAfterDrag: true,
          selectionObjectName: 'BODY',
          resizeObjectName: 'BODY',
          subGraphExpandedChanged: function(grp) {
            var shp = grp.resizeObject;
            if (grp.diagram.undoManager.isUndoingRedoing) return;
            if (grp.isSubGraphExpanded) {
              shp.height = grp._savedBreadth;
            } else {
              grp._savedBreadth = shp.height;
              shp.height = NaN;
            }
          }
        },
        $(go.Panel, "Horizontal", { row: 0 },
          makePort("IN", true)),
        $(go.Panel, "Auto", { row: 1, name: 'BODY' },
          new go.Binding("height").makeTwoWay(),
          new go.Binding("width").makeTwoWay(),
          $(go.Shape, 'RoundedRectangle',
            { fill: "lightyellow", minSize: new go.Size(130, 30) }),
          $(go.Placeholder, { padding: new go.Margin(20, 5, 5, 5), alignment: go.Spot.TopLeft })
        ),
        $(go.TextBlock,
          { row: 1, alignment: go.Spot.Top, margin: 5,
            editable: true, isMultiline: false, textAlign: 'center',
            font: 'bold 10pt Segoe UI,Segoe UI Web Regular,Segoe UI Symbol,Segoe,Tahoma,Trebuchet,Arial,Verdana'
          },
          new go.Binding("text").makeTwoWay()
        ),
        $("SubGraphExpanderButton", { row: 1, alignment: go.Spot.TopRight, margin: 5 }),
        $(go.Panel, "Horizontal", { row: 2 },
          makePort("OUT", false))
      );

Thanks!, we go well!
Now, for the group content. I don’t set any layout, because I need absolute free layout for the parts inside it.
In this case, when I draw a part of the group, the group relayout its content. How to prevent that?

Various choices: GoJS Layouts -- Northwoods Software

I need absolute layout in the group. When I drop a part form the pallette into diagram, I replace it with a new Group with two children .
I need to center this two parts into the group:

var ob = node.data,
        x = node.getDocumentPoint(go.Spot.Center).x;

      ob.loc = go.Point.stringify(node.location),
      ob.isGroup = true;
      ob.text = textForNode;

      if (node.data.group) {//if has parent group change the fill
        ob.fill = '#FABB57';
      }

      diagram.model.removeNodeData(node.data);
      diagram.model.addNodeData(ob);

      diagram.model.addNodeData({
        "category":  ActionManager.FLOWinitial,
        "group": node.data.id,
        "loc": go.Point.stringify(new go.Point(x, node.location.y + 20)),
        "text": ""
      });
      diagram.model.addNodeData({
        "category":  ActionManager.FLOWfinal,
        "group": node.data.id,
        "loc": go.Point.stringify(new go.Point(x, node.location.y + 450)),
        "text": ""
      });

How can center these parts?, with my code the parts show Left aligned

You had explicitly specified the GraphObject.alignment of the Placeholder in your Group template to be go.Spot.TopLeft.

So you could set it to be go.Spot.Center instead.

Thank you!