findItemPanelForData

I must be doing something odd, because I cannot seem to get the findItemPanelForData to work.

outputPanel.itemArray
(2) [{…}, {…}]
   0: {id: "4221ac33-271b-4109-85c6-790a87546c48", name: "discount_cashflow_envvars.log", substitution: ""}
   1: {id: "76b4ecdc-fb35-4e3d-a026-3731997a619a", name: "mk_conf.cashflows.csv", substitution: "out_inst_discount"}length: 2__proto__: Array(0)

outputPanel.findItemPanelForData(outputPanel.itemArray[0])
null

outputPanel.elements.first()
X {__gohashid: 1444, F: 4194307, rb: 1, kg: X, Qa: "", …}

outputPanel.elements.first().data
{id: "4221ac33-271b-4109-85c6-790a87546c48", name: "discount_cashflow_envvars.log", substitution: ""}

outputPanel.elements.first().data === outputPanel.itemArray[0]
true

It has to be the full object right, there’s nothing like the findByExample functions where you can pass partial data?

I have an object data json, and I’m trying to iterate over all the nodes in my diagram and find matching names. I have the vast majority of it working, but I was hoping to avoid basically writing my own “findItemPanelByExample” function.

Yes, there’s no pattern-matching method for items. The argument to Panel.findItemPanelForData has to be a reference to the actual data object.

Your debug session does seem wrong, but I cannot reproduce any problem. Here’s my code:

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2020 by Northwoods Software Corporation. -->
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
        { "undoManager.isEnabled": true });

    // This binding conversion function assigns data.row and data.column values
    // so that each object in the Array fills up to five items in a column before
    // continuing to the next column.
    // The Panel.itemTemplate simply binds the GraphObject.row and GraphObject.column
    // values so that the "Table" Panel puts each element (basically a TextBlock in its own Panel)
    // into the corresponding cell of the table.
    function assignCells(arr) {
      var x = 0;
      var y = 0;
      for (var i = 0; i < arr.length; i++) {
        arr[i].column = x;
        arr[i].row = y++;
        if (y > 4) {  // limit to 5 per column
          x++;  // start next column
          y = 0;
        }
      }
      return arr;
    }

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        $(go.Shape, { fill: "white" }),
        $(go.Panel, "Table",
          {
            name: "TABLE",
            margin: 4,
            // a minimal template that puts elements into particular rows and columns
            itemTemplate:
              $(go.Panel,
                $(go.TextBlock,
                  { margin: 2 },
                  new go.Binding("text", "name")),
                new go.Binding("row"),
                new go.Binding("column")
              )
          },
          new go.Binding("itemArray", "items", assignCells)
        )
      );

    myDiagram.model = new go.GraphLinksModel([
      { key: "Alpha", items: [
        { name: "one" },
        { name: "two" },
        { name: "three" },
        { name: "four" },
        { name: "five" },
        { name: "six" },
        { name: "seven" },
        { name: "eight" },
        { name: "nine" },
        { name: "ten" },
        { name: "eleven" },
        { name: "twelve" },
        { name: "thirteen" },
        { name: "fourteen" },
        { name: "fifteen" },
        { name: "sixteen" },
        { name: "seventeen" }
      ]},
      { key: "Beta", items: [
        { name: "one" },
        { name: "two" },
        { name: "three" }
      ]}
    ],[
      { from: "Alpha", to: "Beta" }
    ]);
  }

  function highlightItem() {
    var node = myDiagram.findNodeForKey("Alpha");
    if (!node) return;
    var tablepanel = node.findObject("TABLE");
    if (!tablepanel) return;
    myDiagram.commit(function(diag) {
      // choose one data item to highlight
      var arr = node.data.items;
      var item = arr[Math.floor(Math.random()*arr.length)];
      // update Panel directly, rather than via a Binding
      var pan = tablepanel.findItemPanelForData(item);
      if (pan) {
        pan.background = "lime";
        document.getElementById("myMessages").textContent += item.name + "\n";
      }
    });
  }

  function clearHighlights() {
    var node = myDiagram.findNodeForKey("Alpha");
    if (!node) return;
    var tablepanel = node.findObject("TABLE");
    if (!tablepanel) return;
    myDiagram.commit(function(diag) {
      tablepanel.elements.each(function(pan) { pan.background = null; });
      document.getElementById("myMessages").textContent = "";
    });
  }
  </script>
</head>
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
  <button onclick="highlightItem()">Highlight item at random from node Alpha</button>
  <button onclick="clearHighlights()">Clear all highlights</button>
  <div>
    <textarea id="myMessages" style="height: 300px"></textarea>
  </div>
</body>
</html>