Binding margin property

How do I bind the margin property? I can see the margin changing if I hard code it but the binding doesn’t set the margin. This is what I have :

new go.Binding("margin", "entries", function(v) {
              if(v.length > MAX){ return new go.Margin(0, 20, 0, 0); }
              else { return new go.Margin(0, 8, 0, 0); }
            })

thank you!!

That looks fine. What happens when you set a breakpoint in the conversion function in order to debug it?

Oh I see I have access to the items inside entries but not entries itself. My nodeDataArray looks like:

nodeDataArray: [
        {
          key: "Alpha",
          entries: [
            { name: "1", type: "int" },
            { name: "2", type: "int" }
          ]
        }

I can bind to name and type but looks like I don’t have access to entries. To explain a little what I’m doing, I have a table and its itemArray is bound to entries. I set the itemTemplate in the table to a tableRow that contains a textBlock, and I am trying to add the binding above to that textBlock. Is it possible for me to bind to entries in this situation?

I’m confused what you want to do. Could you please provide more details?

sorry that was confusing. I have a table like this below, and I want to bind a property of the TextBlock in the TableRow to the length of elements in the entries in the nodeDataArray. I can successfully bind in the TableRow to name and type but not entries.

		$(go.Panel, "Table",
        {
          name: "TABLE",
          stretch: go.GraphObject.Fill,
          itemTemplate: $(go.Panel, "TableRow",  
              $(go.TextBlock,
              new go.Binding("height", "entries", function(v) {
                if(v.length > MAX_ENTRIES_SHOWN){ return 20; }
                else { return 30; }
              }),
              new go.Binding("text", "type")),
            )
        },
        new go.Binding("itemArray", "entries")
		)

my nodeDataArray looks like this:

nodeDataArray: [
        {
          key: "Alpha",
          entries: [
            { name: "1", type: "int" },
            { name: "2", type: "int" }
          ]
        }

So when there are a lot of entries, the TextBlocks would be short, and when there are few of them, they would be a bit taller. But you aren’t changing the font size, so you are just changing the apparent spacing between the rows.

I don’t understand what you are trying to do. The default behavior, since you set stretch: go.GraphObject.Fill on the Table Panel, would be to allocate extra vertical space to each row if there is enough space for all of the rows. If there isn’t enough for all of the rows, each row would be sized normally and the bottom rows would be clipped. You can see that behavior when you resize the node in this code:

myDiagram.nodeTemplate =
  $(go.Node, "Auto",
    { resizable: true },
    $(go.Shape, { fill: "white" }),
    $(go.Panel, "Table",
      new go.Binding("itemArray", "entries"),
      {
        stretch: go.GraphObject.Fill,
        itemTemplate:
          $(go.Panel, "TableRow",
            $(go.TextBlock,
              new go.Binding("text"))
          )
      }
    )
  );

myDiagram.model = new go.GraphLinksModel(
[
  { 
    entries: [
      { text: "first" },
      { text: "second" },
      { text: "third" },
      { text: "fourth" },
      { text: "fifth" }
    ]
  }
]);

I’m more asking how it is possible to bind to the entries in the code I have, because I don’t know how to access it from inside the itemTemplate. I have more things in my actual itemTemplate that I removed because it isn’t relevant to the question. The binding I sent for the height doesn’t work because I can’t access entries. Does that make sense? I just want to know what I could pass in as the second argument in the binding for me to get the length of the entries array. Sorry I am not explaining this very well

Binding sources for item panels (i.e. the panels created for each item of a Panel.itemArray) are limited to properties on the particular Array item.

However, you can access the node data object via a conversion function. For example:

itemTemplate:
  $(go.Panel, "TableRow",
    $(go.TextBlock, { column: 0 },
      new go.Binding("text")),
    $(go.TextBlock, { column: 1 },
      new go.Binding("text", "", (item, tb) => tb.part.data.entries.length.toString()))
  )

Note that if the length of the entries Array changes, even by calling methods such as Model.addArrayItem, the Bindings will not be re-evaluated, because the binding system cannot know about the implicit dependencies present in your conversion functions.

Well, if you replace the whole data.entries Array by calling Model.set on the node data object with the “entries” property, that could work.

that is perfect, thank you so much!