Table Panel with dynamic column widths

Hi

We’re busy investigating converting some of our GoXam diagrams to GoJS diagrams.
In some of our GoXam diagrams we have swimlane containers that have a header and a body section.

See:

As you can see, the header section has an initial minimum width but it can grow if the header text starts to get very long.

We’re trying to replicate the same behaviour in GoJS using Table Panels. Unfortunately, we’re having some difficulty getting the header column to dynamically grow in width, if needed.

See:

As you can see we’ve kind of replicated the behaviour but the location of the group part seems to shift to the left when the header section resizes to accommodate long text.

This is our current group template that we’re using for the swimlane:

var swimlaneHorizontal = $m(go.Group, "Table",                    
    { locationSpot: go.Spot.Center, height: 150, width: 400 },
     new go.Binding("location", "location", go.Point.parse), //the initial location of the group
     new go.Binding("width", "width"),
     new go.Binding("height", "height"),        
     $m(go.Panel, "Auto",           
        { column: 0, minSize: new go.Size(30, 0) },
        new go.Binding("height", "height"),
        $m(go.Shape, "Rectangle", {fill: "white"}),
        $m(go.TextBlock, new go.Binding("text", "text"), {angle: 270, margin: 4})
     ),
     $m(go.Panel, "Auto",
        { column: 1, stretch: go.GraphObject.Fill },
        new go.Binding("height", "height"),
        $m(go.Shape, "Rectangle", {fill: "white"}),
        $m(go.Placeholder)
     )       

);

Thanks
Justin

I’m trying to think of the cleanest way to do this. Something like this: http://codepen.io/simonsarris/pen/ZGerMG

  var swimlaneHorizontal = $m(go.Group, "Auto",
      {
        locationSpot: go.Spot.Center,
      },
      new go.Binding("location", "location", go.Point.parse), //the initial location of the group
      $m(go.Shape, "Rectangle", {fill: null }),
      $m(go.Panel, "Table",
        { height: 100, width: 200, background: 'rgba(255,0,0,.2)' },
        new go.Binding("width", "width"),
        new go.Binding("height", "height"),
        $m(go.RowColumnDefinition, { column: 0, minimum: 30 } ),
        $m(go.RowColumnDefinition, { column: 1, separatorStroke: 'black' } ),
          $m(go.TextBlock, new go.Binding("text", "text"), {
            column: 0, angle: 270, background: 'rgba(0,255,0,.3)', wrap: go.TextBlock.WrapFit
            },
            new go.Binding("width", "height")
          ),
        $m(go.Panel,
          { column: 1, stretch: go.GraphObject.Fill, background: 'rgba(0, 0, 255, .3)' },
          $m(go.Placeholder)
        )
      )
  );

There may be an even cleaner way, though. Background colors are added for debugging/visualizing the space that things take up.

Note how I’m using a table panel with two RowColumnDefinitions, and Column 1 has a separatorStroke of black, which gives a 1-pixel line between the two columns. This allows for a nicer template since it means only one auto panel is required, one that goes around the entire table.

Hi Simon

Thanks for taking the time of coming up with an alternative solution but unfortunately I still have the problem of the part’s location shifting to the left when the header section starts to grow.

Here’s what it looks like when the header is at it’s default width:

Here’s what it looks like when the header starts to grow:

As you can see, the part’s location shifts to the left.

Here’s the updated model definition in your CodePen sample:

myDiagram.model = new go.GraphLinksModel(
[
  { key: "Alpha", text: "short text", isGroup: true, height: 100, location: "0 0" },
  { key: "Alpha", text: "long long long long long long long long text",  location: "0 120", isGroup: true, height: 100  }
],
[
]);

Thanks
Justin

Because you are using a Placeholder, the location of the Group is dependent on the area occupied by the member Nodes and Links.

If you want the Group.location to be at the top-left corner of the whole Group, I think you need to remove the Placeholder, and remove setting Part.locationSpot to Spot.Center (or just set it to the default value, Spot.TopLeft).

Hi Walter

We’re trying to convert existing GoXam diagrams into GoJS diagrams. Those existing GoXam diagrams specify location coordinate information that were created with node templates that have Node.LocationSpot=“Center”. If we don’t use Spot.Center for the locationSpot on our GoJS templates then won’t the nodes be incorrectly positioned?

Removing the Placeholder solves the issue and I understand what you mean by mentioning that the Groups location is dependent on the bounds of the Placeholder… However, without a Placeholder, I’m assuming the Group cannot contain any child parts?

Thanks
Justin

Without a Placeholder the Group can still have member Parts – they just won’t be naturally limited to be “within” the area of the Group’s visual tree.

The Planogram sample demonstrates Groups without Placeholders. http://gojs.net/latest/samples/planogram.html Note that one can drop an item (a simple Node) into a rack (a Group), and then moving the Group also moves the Node. But one can resize the Group or the Node so that the Node is no longer physically within the Group. I suppose one could customize the ResizingTool to avoid even that, if one wanted to.

Thanks Walter, will take a look at the samples

Also, see what happens if you use position instead of location to place the groups:

The location object in a group is always the Placeholder, if there is one, so the location was making the placeholders line up. Position is always the top-left corner of the entire Node/Group, so using position will make them line up nicely as you’d expect.

(… until you put nodes inside the group, which might shift the placeholder.)