I want to drag and drop those 3 shapes into mxgraph
canvas (which is the black area).
Note: I want to fully preserve the drag element on the canvas, including shape, size, color, text, etc.
I don’t know whether insertVertex
does it work. Dragging the orange,red or other box in to the dark area currently does not work.
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')); } function handleDrag(event) { event.dataTransfer.setData("draggedId", event.target.id); } function allowDrop(event) { event.preventDefault(); } function handleDrop(event) { console.log('dropped'); event.preventDefault(); var parent = graph.getDefaultParent(); graph.getModel().beginUpdate(); var element = document.getElementById(event.dataTransfer.getData('draggedId')) var gridRect = document.getElementById('graph-wrapper').getBoundingClientRect(); var targetX = event.x - gridRect.x; var targetY = event.y - gridRect.y; try { graph.insertVertex(parent, null, element, targetX, targetY); } finally { // Updates the display graph.getModel().endUpdate(); } }
#graph-wrapper { background: #333; width: 100%; height: 528px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!-- Copyright (c) 2006-2013, JGraph Ltd Dynamic toolbar example for mxGraph. This example demonstrates changing the state of the toolbar at runtime. --> <html> <head> <title>Toolbar example for mxGraph</title> <script type="text/javascript"> mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src'; </script> <script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script> </head> <body onload="initCanvas()"> <h4>Drag Boxes onto the black canvas and see what happens</h4> <div> <div draggable="true" id="shape_1" ondragstart="handleDrag(event)" 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" ondragstart="handleDrag(event)" 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" ondragstart="handleDrag(event)" 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" ondrop='handleDrop(event)' ondragover="allowDrop(event)"> </div> </body> </html>
Advertisement
Answer
In mxgraph, normally you do that using so-called “stencil”. You can define your own custom shapes using XML, and then use mxgraph to take care of the rest. RTFM 🙂
If you don’t want to follow this baseline path, then things will become increasingly harder. Anyway, back to the point – you can use this example (it’s an adopted version of the “sidebar” code you can find in the mxgraph) – for the details on functions see the Sidebar.js:
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"); }
<html> <head> <title>Toolbar example for mxGraph</title> <style> #graph-wrapper { background: #333; width: 100%; height: 528px; } </style> <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 Boxes onto the black canvas and see what happens</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>
Note that your code, and the other answer focuses on generic drag-n-drop, which is not applicable to mxgraph. You need to use library-specific code.