How to create group and add node dynamically in it


#1

I’m trying to group nodes who are connected and having same color property.
This i’m trying to do dynamically in code

         export const graphData = {
          nodeKeyProperty: "id",
           nodeDataArray: [
          { id: -1, category: "Start", loc: "175 0", text: "Start" },
        { id: -2, category: "End", loc: "175 660", text: "End" },
        {
           id: 0,
           color: "RED",
          Frequency: "3",
       },
       {
         id: 1,
         color: "GREEN",
         Frequency: "2",
        },
       {
        id: 2,
        color: "BLUE",
        Frequency: "3",
   
      },
{
  id: 3,
  color: "BLUE",
  Frequency: "4",
},
{
  id: 4,
  color: "PINK",
  Frequency: "1",

},
{
  id: 5,
  App: "BLUE",
  Frequency: "1",
},
{
  id: 6,
  color: "PINK",
  Frequency: "1",

},
{
  id: 7,
  color: "BLUE",
}
],
  linkDataArray: [
    { from: -1, to: 1, text: "" },
    { from: 0, to: -2, text: "" },
    { from: 1, to: 2, text: 1 },
    { from: 1, to: 4, text: 1 },
    **{ from: 2, to: 3, text: 3 },**
    { from: 2, to: 7, text: 1 },
    { from: 3, to: 0, text: 2 },
    **{ from: 3, to: 2, text: 1 },**
    **{ from: 3, to: 5, text: 1 },**
    { from: 4, to: 2, text: 1 },
    { from: 5, to: 6, text: 1 },
    { from: 6, to: 0, text: 1 },
    **{ from: 7, to: 3, text: 1 },**
    { from: 4, to: 6, text: 1 }
  ],
};

Here, the bold item should be in group, where group title should be color.

I’m not able to group items together.

diagram.links.each(val => {
  if (val.data.from !== -1 && val.data.to !== -2) {
    const fromNode = this.diagram.findNodeForKey(val.data.from);
    const toNode = this.diagram.findNodeForKey(val.data.to);
    __colorname = fromNode.data.color;
    if (__colorname.includes(toNode.data.color) {
        fromNode.isSelected = true;
        toNode.isSelected = true;
        this.processDiagram.commandHandler.archetypeGroupData = {
          title: __appname,
          isGroup: true
        };
        this.processDiagram.commandHandler.groupSelection();
       .
       .
       .

above implementation yields the result, but it do it in nested way and what I want is all the nodes with color: “BLUE” should get grouped together.

Pleas suggest what approach should I take

Examples visited -


#2

I suggest that you preprocess the model data, figuring out what groups you want, adding node data objects for those groups, and then assigning individual nodes to the appropriate groups.

Basically, just look at the model data and modify the model data.


#3

If understood it correctly, I should create node and make it’s isGroup:true take it’s Id and assign it to other node’s “group” property.

If I modify my data at run time, how to reload them to take updated data with grouping ?


#4

Empty group shells are created, now how to add nodes in them :(

   createGroupNode(name) {
        const newnode = {
        id: name,
        title: name,
        isGroup: true
        };

        myDiagram.startTransaction("add group node");
        myDiagram.model.addNodeData(newnode);
        myDiagram.commitTransaction("add group node");
    }
    public groupNodes() {
        let __appname: string;

        myDiagram.links.each(val => {
        if (val.data.from !== -1 && val.data.to !== -2) {
            const fromNode = myDiagram.findNodeForKey(val.data.from);
            const toNode = myDiagram.findNodeForKey(val.data.to);
            __colorname = fromNode.data.color.split(":")[0];
            let groupNode = myDiagram.findNodeForKey(__colorname );
            if (!groupNode) {
            this.createGroupNode(__colorname );
            groupNode = myDiagram.findNodeForKey(__colorname );
            }
            fromNode.data["group"] = __colorname ;
            toNode.data["group"] = __colorname ;
        }
        });

        myDiagram.nodes.each(val => {
        console.log(val.data);
        });

    }

#5

If you don’t want to preprocess the data as Walter suggested, you can try calling GraphLinksModel.setGroupKeyForNodeData.

myDiagram.model.setGroupKeyForNodeData(fromNode.data, __colorname);

You probably want to wrap the whole loop in a transaction rather than just the group creation portion of it.


#6

Yes, my suggestion was to augment the model before assigning Diagram.model. So there’s no use of transactions or tools or commands.


#7

So below is the initial sol’n which worked for me (working on improvements), I’m updating the graph data before creating diagram

private getColorObject(parentdData, key) {
    return parentdData.nodeDataArray.find(elm => {
      return elm.id === key;
    });
  }

  private setGroupName(parentdData, key, groupName) {
    parentdData.nodeDataArray.map(elm => {
      if (elm.id === key && elm.id !== groupName) {
        elm["group"] = groupName;
      }
    });

    return parentdData;
  }
  public groupNodes(graphData: any) {
    graphData.linkDataArray.forEach(element => {
      if (element.text) {
        const fromNode = this.getColorObject(graphData, element.from);
        const toNode = this.getColorObject(graphData, element.to);
        const fromColor = fromNode.color;
        const toColor = toNode.color;
        const newnode = {
          id: fromColor,
          title: fromColor,
          isGroup: true
        };
        if (fromColor === toColor && !fromColor.toLowerCase().includes("start")) {
          if (!this.getColorObject(graphData, fromColor)) {
            graphData.nodeDataArray.push(newnode);
          }

          this.setGroupName(graphData, element.from, fromColor);
          this.setGroupName(graphData, element.to, toColor);
        }
      }
    });
  }
}