Search code examples
javascriptsvgtreedrag-and-dropmxgraph

How to update the graph model efficiently after certain operation in mxgraph?


After consecutive drag and drop in mxgraph, the parentInfo is lost for cell.

Children and Parents for cell are not getting updated after consecutive drag and drop.

Drag and Drop is handled using connect, the logic behind is simple. Removing the existing parent connection and establishing new edge connection with target node.

mxConnectionHandler.prototype.connect = function(
      source,
      target,
      evt,
      dropTarget
    ) {
      var sourceParentCell = getParentCell(source);
      if (sourceParentCell !== target) {
        graph.getModel().beginUpdate();
        try {
          var edges = graph.getEdgesBetween(sourceParentCell, source);
          _.each(edges, edge => {
            graph.getModel().remove(edge);
          });
          graph.insertEdge(parent, null, '', target, source);
        } finally {
          graph.getModel().endUpdate();
        }
      }
    };
  }

Here goes the click event handler for the cell which provides information about the cell when clicked along with its immediate parent cell info.

graph.addListener(mxEvent.CLICK, function(sender, evt) {
      var cell = evt.getProperty('cell');
      if (cell && cell.id) {
        const nodeData = hierarchialData(graph, cell);
        console.log('cellInfo => ', JSON.stringify(nodeData));
        console.log(
          'parentInfo => ',
          JSON.stringify(getParentCell(cell).value)
        );
      }
    });

The above code is working fine for two drags, later the parentInfo is lost and shows the cell itself as its parent.

Deployed in Heroku here: https://express-mxgraph.herokuapp.com/

Demo:

enter image description here

When it reaches to the node: 20-Double click to set name, you will notice its parentInfo is same: 20-Double click to set name and not 22-Double click to set name and hence the edge construction fails miserably.

What's going wrong here, am I updating the vertex and edge properly or not?

Also onload of the url, you may observe the whole graph is dragged towards the mouse move. This also should be avoided.

Steps to reproduce:

  • Move 14-Double click to set name under 20-Double click to set name

    Click on 14-Double click to set name, you will see cellInfo as 14-Double click to set name and parentInfo as 20-Double click to set name which is correct

  • Now drag 20-Double click to set name under 22-Double click to set name

    Click on 20-Double click to set name, CellInfo and ParentInfo both contains 20-Double click to set name. ParentInfo actually should contain 22-Double click to set name.

  • So the cell 20-Double click to set name, it is already in a bad shape and when you now try to connect with 18-Double click to set name. The graph breaks


Solution

  • As i could not find any references for clone and deep cloning has a bug in jGraph itself and its open issue as well, i managed to solve this having the reference copy of cell and re-constructing the cells under target.

    mxConnectionHandler.prototype.connect = function(source, target) {
      const nodeData = [{"id":"12","value":"12-Double click to set name","children":[{"id":"14","value":"14-Double click to set name"}]}]
      drawNodes(graph, nodeData, target, source); // recursively
    };