Make Shapes in Horizontal Panel wrap to next line in case max width is exceeded

Hi, how can we make Shapes inside Horizontal Panel wrap to next line in case max width is exceeded:

Initial Node:

When Show More (3 dotted button) is clicked:

What I want:

Please help. Thanks.

Code for Horizontal Panel with dots/badges/stars:

Off hand I can’t think of an easy way to do that. It might be possible to automatically divide up the items array into equal sections, each going to a separate Panel. Imagine a Vertical Panel of Horizontal Panels.

By the way, you’re not supposed to modify anything in a binding conversion function.

Hi, Thanks, and your pointed mistake is noted, hopefully will fix that soon :). I just wanted to check whether there’s a built-in option/parameter for such a behavior but I guess we’ll have to go the ugly route.

Here you go:

    function segmentArrayBy(n) {
      return function(a) {
        var r = [];
        for (i = 0; i < a.length; i += n) {
          r.push(a.slice(i, i+n));
        }
        return r;
      }
    }

    myDiagram.nodeTemplate =
      $(go.Node, "Spot",
        $(go.Panel, "Auto",
          $(go.Shape, { fill: "white" },
            new go.Binding("fill", "color")),
          $(go.TextBlock, { margin: 8 },
            new go.Binding("text"))
        ),
        $(go.Panel, "Vertical",
          { alignment: new go.Spot(0.5, 1, 0, -4), alignmentFocus: go.Spot.Top },
          new go.Binding("itemArray", "items", segmentArrayBy(5)),
          {
            itemTemplate:
              $(go.Panel, "Horizontal",
                new go.Binding("itemArray", ""),
                {
                  itemTemplate:
                    $(go.Panel,
                      $(go.Shape, { width: 8, height: 8, strokeWidth: 0 },
                        new go.Binding("fill", ""))
                    )
                })
          })
      );

    myDiagram.model = $(go.GraphLinksModel,
      {
        nodeDataArray:
        [
          { key: 1, text: "Alpha", color: "lightblue",
            items: [ "black", "silver", "gray", "white",
            "maroon", "red", "purple", "fuchsia", "green", "lime",
            "olive", "yellow", "navy", "blue", "teal", "aqua", "orange" ]
          }
        ]
      });

thanks but our items have variable width, but I did get the idea. And also your binding function observation helped us solve the variable link height problem :). Thanks for that too.

The Vertical Panel of Horizontal Panels will work with variably sized items. The only drawback is that you need to decide beforehand how many items you can have in a row (i.e. in each Horizontal Panel).

Thanks @walter , I am trying to do something similar. I am currently using your sample code but can’t quite get it working.

This thread is 4 years old so there may be a better way of doing it.

What I don’t understand about the sample above is, what exactly makes GoJS care to evaulate more than the first 5 elements new go.Binding("itemArray", "items", segmentArrayBy(5)) ? (5 at a time etc)

Actually, that’s true – there is now the PanelLayoutFlow extension: Flow PanelLayout
PanelLayoutFlow | GoJS API

That should be simpler to use than this topic’s approach of Arrays of Arrays of data presented in a “Vertical” Panel of “Horizontal” Panels.