javascriptjquerymxgraph

How to avoid duplicate drag in mxgraph


I want to avoid duplicate drop on mxgraph canvas.

let say I have dragged Pipe on canvas 2nd time it should not allow it be dragged on canvas.

Question: how to avoid duplicate drop on canvas

Here is my working code drag with duplicate allowed

Drag and Drop

var graph = {};

function initCanvas() {

  //This function is called onload of body itself and it will make the mxgraph canvas
  graph = new mxGraph(document.getElementById('graph-wrapper'));
  graph.htmlLabels = true;
  graph.cellsEditable = false;

  // render as HTML node always. You probably won't want that in real world though
  graph.convertValueToString = function(cell) {
    return cell.value;
  }

  const createDropHandler = function (cells, allowSplit) {
    return function (graph, evt, target, x, y) {
      const select = graph.importCells(cells, x, y, target);
      graph.setSelectionCells(select);
    };
  };

  const createDragPreview = function (width, height) {
    var elt = document.createElement('div');
    elt.style.border = '1px dashed black';
    elt.style.width = width + 'px';
    elt.style.height = height + 'px';
    return elt;
  };

  const createDragSource = function (elt, dropHandler, preview) {
    return mxUtils.makeDraggable(elt, graph, dropHandler, preview, 0, 0, graph.autoscroll, true, true);
  };

  const createItem = (id) => {

    const elt = document.getElementById(id);
    const width = elt.clientWidth;
    const height = elt.clientHeight;

    const cell = new mxCell('', new mxGeometry(0, 0, width, height), 'fillColor=none;strokeColor=none');
    cell.vertex = true;
    graph.model.setValue(cell, elt);

    const cells = [cell];

    const bounds = new mxRectangle(0, 0, width, height);
    createDragSource(elt, createDropHandler(cells, true, false, bounds), createDragPreview(width, height), cells, bounds);
  };


  createItem("shape_1");
  createItem("shape_2");
  createItem("shape_3");
}
#graph-wrapper {
  background: #333;
  width: 100%;
  height: 528px;
 }
<html>

<head>
    <title>Toolbar example for mxGraph</title>

    <script type="text/javascript">
        mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
    </script>
    <script src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>
    <script src="./app.js"></script>
</head>

<body onload="initCanvas()">
    <h4>Drag same box 2 times on the canvas. see duplicate is allowed</h4>

    <div>
        <div id="shape_1"
            style="width: 100px; height: 100px; border-radius: 50%; background: red; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center;">
            Pipe
        </div>

        <div draggable="true" id="shape_2"
            style="width: 100px; height: 100px; border-radius: 5%; background: orange; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center;">
            Team
        </div>
        
        <div draggable="true" id="shape_3"
            style="width: 100px; height: 64px; background: #009688; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center; border-radius: 207px; flex-direction: column;">
            <div> <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
                    <path d="M0 0h24v24H0V0z" fill="none" />
                    <path
                        d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" />
                </svg></div>
            <div>Info</div>
        </div>
    </div>

    <div id="graph-wrapper">

    </div>
</body>

</html>


Solution

  • You just need check all current cells value of maxgarph in createDropHandler. So get all cells by graph.getModel().cells and then check to see if the cells you want to add exists or not:

    let allcells = graph.getModel().cells;
    for (var i in allcells)
        if (allcells[i].value && (allcells[i].value.id == cells[0].value.id))
            return;
    

    var graph = {};
    
    function initCanvas() {
        //This function is called onload of body itself and it will make the mxgraph canvas
        graph = new mxGraph(document.getElementById('graph-wrapper'));
        graph.htmlLabels = true;
        graph.cellsEditable = false;
    
        // render as HTML node always. You probably won't want that in real world though
        graph.convertValueToString = function (cell) {
            return cell.value;
        }
    
        const createDropHandler = function (cells, allowSplit) {
            return function (graph, evt, target, x, y) {
                debugger
                let allcells = graph.getModel().cells;
                for (var i in allcells)
                    if (allcells[i].value && (allcells[i].value.id == cells[0].value.id))
                        return;
                const select = graph.importCells(cells, x, y, target);
                graph.setSelectionCells(select);
            };
        };
    
        const createDragPreview = function (width, height) {
            var elt = document.createElement('div');
            elt.style.border = '1px dashed black';
            elt.style.width = width + 'px';
            elt.style.height = height + 'px';
            return elt;
        };
    
        const createDragSource = function (elt, dropHandler, preview) {
            return mxUtils.makeDraggable(elt, graph, dropHandler, preview, 0, 0, graph.autoscroll, true, true);
        };
    
        const createItem = (id) => {
            const elt = document.getElementById(id);
            const width = elt.clientWidth;
            const height = elt.clientHeight;
    
            const cell = new mxCell('', new mxGeometry(0, 0, width, height), 'fillColor=none;strokeColor=none');
            cell.vertex = true;
            graph.model.setValue(cell, elt);
    
            const cells = [cell];
    
            const bounds = new mxRectangle(0, 0, width, height);
            createDragSource(elt, createDropHandler(cells, true, false, bounds), createDragPreview(width, height), cells, bounds);
        };
    
    
        createItem("shape_1");
        createItem("shape_2");
        createItem("shape_3");
    }
    <html>
    
    <head>
        <title>Toolbar example for mxGraph</title>
    
        <script type="text/javascript">
            mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
        </script>
        <script src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>
        <script src="./app.js"></script>
        <style>
            #graph-wrapper {
                background: #333;
                width: 100%;
                height: 528px;
            }
        </style>
    </head>
    
    <body onload="initCanvas()">
        <h4>Drag same box 2 times on the canvas. see duplicate is allowed</h4>
    
        <div>
            <div id="shape_1"
                 style="width: 100px; height: 100px; border-radius: 50%; background: red; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center;">
                Pipe
            </div>
    
            <div draggable="true" id="shape_2"
                 style="width: 100px; height: 100px; border-radius: 5%; background: orange; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center;">
                Team
            </div>
    
            <div draggable="true" id="shape_3"
                 style="width: 100px; height: 64px; background: #009688; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center; border-radius: 207px; flex-direction: column;">
                <div>
                    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
                        <path d="M0 0h24v24H0V0z" fill="none" />
                        <path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" />
                    </svg>
                </div>
                <div>Info</div>
            </div>
        </div>
    
        <div id="graph-wrapper">
    
        </div>