My initDiagram function is not able to update the visual of user category

Hi,

Am able to see the one set of nodes in both View and log and the other set for bottom half is not viewable and only in log as a combined array of objects.

In console.log(state.diagramNodeData) am able to see All the data fetched from Devices and Users with category property… but my intiFunction in similar sample with static data is working fine, but in the project it is giving me No Node template found for category “” and Using default node template.

Could you please help me where am I going wrong

public initDiagram(): go.Diagram {
    const $ = go.GraphObject.make;

    const dia = $(go.Diagram, {
      'undoManager.isEnabled': true,
      // layout: $(go.GridLayout, {
      //   wrappingColumn: -1,
      //   // alignment: go.GridLayout.Forward,
      //   // sorting: go.GridLayout.Ascending,
      //   spacing: new go.Size(20, 10),
      //   // background: "lightyellow"      
      // }),

      model: $(go.GraphLinksModel, {
        linkKeyProperty: 'key', // IMPORTANT! must be defined for merges and data
        // positive keys for nodes
        makeUniqueKeyFunction: (m: go.Model, data: any) => {
          let k = data.key || 1;
          while (m.findNodeDataForKey(k)) k++;
          data.key = k;
          return k;
        },
        nodeKeyProperty: "key"
      }),
    });

    const deviceTemplate = $(go.Node, "Auto", {
      locationSpot: go.Spot.TopCenter,
      // isShadowed: true,
      shadowOffset: new go.Point(1, 1),
      // shadowColor: "#cccccc",
    },
      // {
      //   click: (e, node) => {
      //     node.diagram.clearHighlighteds();
      //     const n = node.part.data;
      //     this.selectedDeviceId = n.id;
      //     console.log("selected Device ID is " + n.id);

      //     GridviewComponent.isSelIdPresent = GridviewComponent.staticSelDvUs1.filter(user => user.deviceId === n.id);
      //     console.log(GridviewComponent.isSelIdPresent);

      //     for (const user of GridviewComponent.staticSelDvUs1) {
      //       if (user.deviceId === n.id) {
      //         const name = user.name;
      //         console.log("selected Device is " + n.name)
      //         console.log(name + " To be Higlighted NAME")
      //         node.diagram.findNodesByExample({ name }).each(element => {
      //           element.isHighlighted = true;
      //           console.log(element.data.name + " is Matched")
      //           console.log(" HIGHLIGHT is set to true")
      //           //   element.updateTargetBindings();
      //         });
      //       } else {
      //         n.isHighlighted = false;
      //         console.log(n.name)
      //         console.log(user.name)
      //         console.log(" HIGHLIGHT is set to false")
      //       }
      //     }
      //   }
      // },




      // ----------------------Binding for category based on ID Property
      //     new go.Binding("category", "id", (id) => {
      //       if (id) {
      //         return "device"; // set category to "device" if id exists
      //       } else {
      //         return "user"; // set category to "user" if id doesn't exist
      //       }
      //     }),
      // // ----------------------Binding for category based on ID Property
      $(go.Shape, "RoundedRectangle",
        {
          width: 100,
          height: 50,
          fill: "lightblue",
          stroke: "#6c767e",
          strokeWidth: 1,
        }
      ),
      $(go.TextBlock,
        {
          alignment: go.Spot.Center,
          margin: 5,
          stroke: "black",
          textAlign: "center",
          font: "14pt Sego UI,sans-serif",
          maxSize: new go.Size(150, NaN),
        },
        new go.Binding("text", "name").makeTwoWay()
      ),
    );
    const userTemplate = $(go.Node, "Auto", {
      locationSpot: go.Spot.BottomCenter,
      // isShadowed: true,
      shadowOffset: new go.Point(1, 1),
      // shadowColor: "#cccccc",
    },
      $(go.Shape, "RoundedRectangle",
        {
          width: 100,
          height: 50,
          fill: "#adbce6",
          stroke: "#6c767e",
          strokeWidth: 1
        },
        // the Shape.stroke color depends on whether Node.isHighlighted is true
        new go.Binding("stroke", "isHighlighted", h => h ? "red" : "black").ofObject(),
        new go.Binding("strokeWidth", "isHighlighted", h => h ? 3 : 1).ofObject(),
      ),
      $(go.TextBlock,
        {
          alignment: go.Spot.Center,
          margin: 5,
          stroke: "black",
          textAlign: "center",
          font: "14pt Sego UI,sans-serif",
          maxSize: new go.Size(150, NaN),
        },
        new go.Binding("text", "name").makeTwoWay()
      ),
    );

    const templmap = new go.Map<string, go.Node>();
    templmap.add("Device", deviceTemplate);
    templmap.add("User", userTemplate);
    dia.nodeTemplateMap = templmap;

    return dia;
  };

Thanks,
Ganesh

The immediate issue seems to be that your model node data objects don’t specify a category property and your Diagram.nodeTemplateMap doesn’t have an entry for the default name, which is the empty string. I suggest that you rename one of your two templates to be “”. Whether you choose “Device” or “User” probably depends on which one is most common and least likely to be set properly in the data.

applied by “” empty template for user, but couldn’t pass through. Now managed to put as TWO Diagrams and able to get almost… One last step is need to highlight the users based on a device diagram selection to highlight the users in the user diagram… and am able to get upon click event the list of users related to device… and trying to bind it with user diagram name with a function highlightUsersByDeviceId() as below… Request your help… went through TWO Diagrams sample and there is by click and drag events, which are not related to my requirement. And trying to get the function details from there as well…

    this.fc_diagram = $(go.Diagram, 'ResourcePlanningDiagramDiv',
      {
        layout:
          $(go.GridLayout, { sorting: go.GridLayout.Forward }), // use a GridLayout
        padding: new go.Margin(5, 5, 25, 5) // to see the names of shapes on the bottom row
      })

    this.fc_diagram.nodeTemplate =
      $(go.Node, "Auto",
        {
          locationSpot: go.Spot.TopCenter,          
          isShadowed: true, shadowBlur: 5,
          shadowOffset: new go.Point(1, 5),
          shadowColor: "rgba(0, 0, 0, 1)",
        },
        {
          click: (e, obj) => {
            if (obj.part.isSelected) {
              this.selConfID = obj.part.data.id;
              console.log(`Selected Conf ID is : ${this.selConfID}`);
              this.getConfUsers(this.selConfID);
            };
          },
        },
        $(go.Shape, "RoundedRectangle", roundedRectangleParams,
          {
            name: "SHAPE",
            fill: "#ffffff",
            stroke: "#6c767e",
            strokeWidth: 0,
            width: 180,
            height: 50,
            margin: 5
          },        
        ),
        $(go.Panel, "Table",
          $(go.TextBlock,
            {
              row: 0, alignment: go.Spot.Center,
              font: "16pt Sego UI,sans-serif",
              textAlign: "center",
              stroke: "rgba(0, 0, 0, .87)",
              maxSize: new go.Size(150, NaN),
              margin: 5
            },
            new go.Binding("text", "name").makeTwoWay()
          ),
        )
      )

    function highlightUsersByDeviceId() {
      console.log("Highlight to be triggered upon Conf Selection")
      console.log(this.presentConfUsers)

      for (const user of this.presentConfUsers) {
        this.fc_diagram.nodes.each(conf => {
          if (user.conferenceNetID === conf.id) {
            console.log("USER IS AVAILABLE" + user.name)
          }
        })
      }
    };
    this.user_diagram = $(go.Diagram, 'SmartTerminalDiagramDiv',
      {
        layout:
          $(go.GridLayout, { sorting: go.GridLayout.Forward }), // use a GridLayout
        padding: new go.Margin(5, 5, 25, 5) // to see the names of shapes on the bottom row
      })

    this.user_diagram.nodeTemplate =
      $(go.Node, "Auto",
        {
          locationSpot: go.Spot.BottomCenter,
          // locationSpot: new go.Spot(0, 0, 0, 0),
          isShadowed: true, shadowBlur: 5,
          shadowOffset: new go.Point(1, 5),
          shadowColor: "rgba(0, 0, 0, 1)",
        },
        {
          selectionChanged: n => {
            let count = n.diagram.selection.count
            if (count++) {
              console.log(count)
              const selectedUser = n.data.name
              if (!this.usersSelForConf.includes(selectedUser)) {
                this.usersSelForConf.push(selectedUser)
                console.log(this.usersSelForConf)
              }
              else if (count--) {
                console.log(count)
                if (count === 1){
                  this.usersSelForConf = [];
                  console.log("RESET EMPTY THE SELECTED USERS")
                }
                alert("Selected again, hence will be removed : " + selectedUser)
                const index = this.usersSelForConf.indexOf(selectedUser);
                n.part.isSelected = false;
                this.usersSelForConf.splice(index, 1);
                console.log(`User ${selectedUser} deSelected now.`)
                console.log(this.usersSelForConf)
              }
            }
          }
        },
        $(go.Shape, "RoundedRectangle", roundedRectangleParams,
          {
            name: "SHAPE",
            fill: "#ffffff",
            stroke: "#6c767e",
            strokeWidth: 0,
            width: 180,
            height: 50,
          },
          // gold if highlighted, white otherwise
          new go.Binding("fill", "isHighlighted", highlightUsersByDeviceId).ofObject()
          // new go.Binding("fill", "isHighlighted", h => h ? "gold" : "#ffffff").ofObject()

        ), 

Thanks,
Ganesh

I tried using your code, but there’s way too much that is undefined for me to do that.

Just looking at your highlightUsersByDeviceId function, be aware that the “conf” parameter of the function passed to Diagram.nodes Iterable.each will be of type Node. That means there won’t be any “id” property. Node | GoJS API
Perhaps you meant to get the Part.data for the Node:

diagram.nodes.each(conf => {
  if (user.conferenceNetID === conf.data.id) { ... }
})

Note: I have no idea what type the user variable is.

Noted for the highlight on confId, by mistake used the diagram nodes to iterate… Actually is a counter check for Selected Device ID with its user list of property of same selected device id… And updated to the comparison as above… And not with diagram nodes id… in future will go through part.data.id. User info is gathered from the click event of a Device Diagram as in the above codes this.getConfUsers(this.selConfID)

And by the way managed to highlight across two diagrams… Thank you so much for all the help given so far.