Add new node without changing/reloading diagram

Hi Team,

Following is our requirement:

  1. We don’t want to reload/redraw/rearrange our current go graph
  2. We want to add a new node in our current go graph dynamically
  3. The newly added node should be added on the left-hand side
  4. The new node should not overlap the existing node

We have set isOngoing to false to prevent automatic layout every time node data array/link data array is being changed.

When new nodes are currently added, they are overlapping on existing nodes.

Layout being used is TreeLayout.

const processDiagram = ( go.Diagram, id, // create a Diagram for the DIV HTML element { initialContentAlignment: go.Spot.Center, 'undoManager.isEnabled': this.isEditing, 'draggingTool.isEnabled': this.isEditing, // Disables node drag 'panningTool.isEnabled': true, // Disables tree drag allowHorizontalScroll: true, // Disables horizontal scroll allowVerticalScroll: true, // Disables vertical scroll layout: (go.TreeLayout, {
isRealtime: false,
angle: 90,
layerSpacing: this.layerSpacing,
isOngoing: false
}),
initialDocumentSpot: go.Spot.Bottom,
initialViewportSpot: go.Spot.Bottom,
initialAutoScale: go.Diagram.Uniform})

Please let us know what additional information you need.

R,
Akash

If you don’t want the regular TreeLayout to happen once you have added a new node, where do you want the new node to be located? It would help if we saw a sketch or screenshot illustrating what is happening now and where you wanted the new node to go. Or do you not care as long as your requirements #3 and #4 are met?

.
As per the attached image, in expected graph(right), new nodes should be on left side and also they should not overlap on existing nodes as depicted in currrent graph(left)

Ah, there might be links connecting with the new node? Hmm, it seems to me that you really want to do another layout – it would be the only way to get everything right. But if you are using TreeLayout, with graphs that are not tree-structured, maybe that wouldn’t be really helpful anyway.

But if you don’t want to do another layout, you will need to compute the area where the node might go, based on the nodes connected with the new node. Then you can find an empty area by calling Diagram.findPartsIn. I don’t know if you want to align the new node vertically with existing “layers” of nodes.

Can you share any code example

This is a very specific custom situation, so I don’t think we have any code for this.

Here is my code where I’m trying to add the new node on left or right side of the process map.
diagramBackBoneNodes is an array of nodes which are initially loaded and rendered.

Next, I’m merging the new model and updating the layout, also, making sure when new model is updated new nodes should have their x and y coordinates on a blank available space near to its parent node. However, the node is still overlapping each other

    InitialLayoutCompleted: (e) => {
        e.diagram.nodes.each((_node) => {
        this.diagramBackBoneNodes.push(_node.data['id']);
        });
        },

    const model = this.processDiagram.model as go.GraphLinksModel;
      model.mergeNodeDataArray(changes.graphData.currentValue.nodeDataArray);
      model.mergeLinkDataArray(changes.graphData.currentValue.linkDataArray);
      this.processDiagram.layoutDiagram(true);
      this.processDiagram.nodes.each((_node) => {
        if (!this.diagramBackBoneNodes.includes(_node.data['id'])) {
          const connectedNodes = _node.findLinksConnected();
          const nearestCoordinate = { x: 10, y: 10 };
          connectedNodes.each(val => {
            nearestCoordinate.x = val.position.x;
            nearestCoordinate.y = val.position.y;
          });
          const { x, y } = this.coordinateConflict(nearestCoordinate.x, nearestCoordinate.y);
          _node.position = new go.Point(x, y);

        }
      });

 coordinateConflict(x: number, y: number) {
     const p = this.processDiagram.findPartsIn(new go.Rect(x, y, 300, 200));
     console.log('conflict', p.count);
     if (p.count !== 0) {
       x = x + 300;
       y = y + 200;
       this.coordinateConflict(x, y);
     } else {
       x = x + 300;
       y = y + 200;
     }
     return { x, y };
   }

To format your code, surround your code with lines consisting of three backquotes. I’ve done that for you.

You at least want to call Diagram.findPartsIn with the partialInclusion argument true. Diagram | GoJS API