如何将 html 个形状拖入 mxgraph canvas
How to drag html shapes into mxgraph canvas
我想将这 3 个形状拖放到 mxgraph
canvas(黑色区域)。
注意:我想完整保留canvas上的拖动元素,包括形状、大小、颜色、文字等
不知道insertVertex
有没有用。目前无法将橙色、红色或其他方框拖入暗区。
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>
这个有效:
function onDragOver(event) {
event.preventDefault();
}
function onDragStart(event) {
event
.dataTransfer
.setData('text/plain', event.target.id);
event
.currentTarget
.style
.backgroundColor = 'yellow';
}
function onDrop(event) {
const id = event
.dataTransfer
.getData('text');
const draggableElement = document.getElementById(id);
const dropzone = event.target;
dropzone.appendChild(draggableElement);
event
.dataTransfer
.clearData();
}
var canvas = document.getElementById("myCanvas-1");
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Team", 60, 60);
var canvas = document.getElementById("myCanvas-2");
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Pipe", 70, 60);
.example-parent {
border: 2px solid #DFA612;
color: black;
display: flex;
font-family: sans-serif;
font-weight: bold;
}
.example-origin {
flex-basis: 100%;
flex-grow: 1;
padding: 10px;
}
.example-draggable {
background-color: white;
font-weight: normal;
margin-bottom: 10px;
margin-top: 10px;
padding: 10px;
}
.example-dropzone {
background-color: darkgrey;
flex-basis: 100%;
flex-grow: 1;
padding: 10px;
}
<div class="example-parent">
<div class="example-origin">
<div id="draggable-1" class="example-draggable" draggable="true" ondragstart="onDragStart(event);">
<canvas id="myCanvas-1" width="200" height="100" style="width: 100px; height: 100px; border-radius: 5%; background: orange; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center;">
</canvas>
</div>
<div id="draggable-2" class="example-draggable" draggable="true" ondragstart="onDragStart(event);">
<canvas id="myCanvas-2" width="200" height="100" style="width: 100px; height: 100px; border-radius: 50%; background: red; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center;">
</canvas>
</div>
<div class="example-dropzone" ondragover="onDragOver(event);" ondrop="onDrop(event);">Drop
</div>
</div>
</div>
查看本教程:https://www.digitalocean.com/community/tutorials/js-drag-and-drop-vanilla-js-de
在 mxgraph 中,通常使用所谓的“模板”来完成。您可以使用 XML 定义自己的自定义形状,然后使用 mxgraph 来处理其余部分。 RTFM :)
如果你不想遵循这条基线路径,那么事情会变得越来越难。无论如何,回到正题——你可以使用这个例子(它是你可以在 mxgraph 中找到的“侧边栏”代码的采用版本)——有关函数的详细信息,请参阅 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>
请注意,您的代码和另一个答案侧重于通用拖放,这不适用于 mxgraph。您需要使用特定于库的代码。
我想将这 3 个形状拖放到 mxgraph
canvas(黑色区域)。
注意:我想完整保留canvas上的拖动元素,包括形状、大小、颜色、文字等
不知道insertVertex
有没有用。目前无法将橙色、红色或其他方框拖入暗区。
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>
这个有效:
function onDragOver(event) {
event.preventDefault();
}
function onDragStart(event) {
event
.dataTransfer
.setData('text/plain', event.target.id);
event
.currentTarget
.style
.backgroundColor = 'yellow';
}
function onDrop(event) {
const id = event
.dataTransfer
.getData('text');
const draggableElement = document.getElementById(id);
const dropzone = event.target;
dropzone.appendChild(draggableElement);
event
.dataTransfer
.clearData();
}
var canvas = document.getElementById("myCanvas-1");
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Team", 60, 60);
var canvas = document.getElementById("myCanvas-2");
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Pipe", 70, 60);
.example-parent {
border: 2px solid #DFA612;
color: black;
display: flex;
font-family: sans-serif;
font-weight: bold;
}
.example-origin {
flex-basis: 100%;
flex-grow: 1;
padding: 10px;
}
.example-draggable {
background-color: white;
font-weight: normal;
margin-bottom: 10px;
margin-top: 10px;
padding: 10px;
}
.example-dropzone {
background-color: darkgrey;
flex-basis: 100%;
flex-grow: 1;
padding: 10px;
}
<div class="example-parent">
<div class="example-origin">
<div id="draggable-1" class="example-draggable" draggable="true" ondragstart="onDragStart(event);">
<canvas id="myCanvas-1" width="200" height="100" style="width: 100px; height: 100px; border-radius: 5%; background: orange; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center;">
</canvas>
</div>
<div id="draggable-2" class="example-draggable" draggable="true" ondragstart="onDragStart(event);">
<canvas id="myCanvas-2" width="200" height="100" style="width: 100px; height: 100px; border-radius: 50%; background: red; display: inline-flex; text-align: center; color: #fff; align-items: center; justify-content: center;">
</canvas>
</div>
<div class="example-dropzone" ondragover="onDragOver(event);" ondrop="onDrop(event);">Drop
</div>
</div>
</div>
查看本教程:https://www.digitalocean.com/community/tutorials/js-drag-and-drop-vanilla-js-de
在 mxgraph 中,通常使用所谓的“模板”来完成。您可以使用 XML 定义自己的自定义形状,然后使用 mxgraph 来处理其余部分。 RTFM :)
如果你不想遵循这条基线路径,那么事情会变得越来越难。无论如何,回到正题——你可以使用这个例子(它是你可以在 mxgraph 中找到的“侧边栏”代码的采用版本)——有关函数的详细信息,请参阅 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>
请注意,您的代码和另一个答案侧重于通用拖放,这不适用于 mxgraph。您需要使用特定于库的代码。