Skip to content

Instantly share code, notes, and snippets.

@productivity-for-programmers
Last active September 1, 2023 10:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save productivity-for-programmers/6ef09ef5ccd5ab62a2d259d4c7260376 to your computer and use it in GitHub Desktop.
Save productivity-for-programmers/6ef09ef5ccd5ab62a2d259d4c7260376 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsPlumb Video</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<script
src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"
integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsPlumb/2.13.1/js/jsplumb.min.js" integrity="sha512-uRRmBpTXPtyfLZow7fU6oPbRK8UbmhBZeayUcQpRDmjkXhxfm1eK9AgA/N321nBw1n3qVFQk2srxyeTqXAqWEA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
#diagram, #toolbox {
margin: 20px 0;
border-width: 2px;
border-style: solid;
border-color: lightgrey;
height: 90vh;
}
#toolbox {
display: flex;
padding: 10px;
flex-flow: row wrap;
align-content: flex-start;
}
.control {
border-color: green;
border-radius: 10px;
border-width: 2px;
border-style: solid;
width: 120px;
text-align: center;
cursor: move;
height: fit-content;
height: -moz-max-content;
background-color: white;
}
#diagram .control {
position: absolute;
}
.window {
z-index: 20;
}
.jtk-connector {
z-index: 4;
}
.jtk-endpoint {
z-index: 5;
}
.jtk-overlay {
z-index: 6;
}
.custom-menu {
z-index: 1000;
position: absolute;
background-color: #C0C0C0;
border: 1px solid black;
padding: 2px;
}
#toolbox .control {
margin: 10px 5px;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div id="toolbox" class="justify-content-center">
<div class="control search"><i class="fa fa-search"></i> Search</div>
<div class="control filter"><i class="fa fa-filter"></i> Filter</div>
<div class="control sort"><i class="fa fa-sort"></i> Sort</div>
<div class="control email"><i class="fa fa-envelope-o"></i> Email</div>
</div>
</div>
<div class="col-md-9">
<div id="diagram" style="height: 90vh; position: relative">
<div id="control1" class="control" style="left: 50px; top: 50px">Control 1</div>
<div id="control2" class="control" style="left: 300px; top: 200px">Control 2</div>
</div>
</div>
</div>
</div>
<script>
// https://stackoverflow.com/a/2117523
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
instance = jsPlumb.getInstance({});
instance.setContainer("diagram");
instance.bind("ready", function () {
instance.registerConnectionTypes({
"red-connection": {
paintStyle: {stroke: "red", strokeWidth: 5},
hoverPaintStyle: {stroke: "red", strokeWidth: 10},
connector: "Flowchart"
}
});
instance.draggable("control1", {"containment": true});
instance.draggable("control2", {"containment": true})
instance.addEndpoint("control1", {
endpoint: "Dot", // rectangle, blank, image
anchor: ["RightMiddle"],
isSource: true,
connectionType: "red-connection"
});
instance.addEndpoint("control2", {
endpoint: "Dot",
anchor: ["LeftMiddle"],
isTarget: true,
connectionType: "red-connection"
});
// https://stackoverflow.com/a/4502207
instance.bind("contextmenu", function (component, event) {
if (component.hasClass("jtk-connector")) {
event.preventDefault();
window.selectedConnection = component;
$("<div class='custom-menu'><button class='delete-connection'>Delete connection</button></div>")
.appendTo("body")
.css({top: event.pageY + "px", left: event.pageX + "px"});
}
});
$("body").on("click", ".delete-connection", function (event) {
instance.deleteConnection(window.selectedConnection);
});
$(document).bind("click", function (event) {
$("div.custom-menu").remove();
});
$("body").on("contextmenu", "#diagram .control", function (event) {
event.preventDefault();
window.selectedControl = $(this).attr("id");
$("<div class='custom-menu'><button class='delete-control'>Delete control</button></div>")
.appendTo("body")
.css({top: event.pageY + "px", left: event.pageX + "px"});
});
$("body").on("click", ".delete-control", function (event) {
instance.remove(window.selectedControl);
});
$("#toolbox .control").draggable({
helper: "clone",
containment: "body",
appendTo: "#diagram"
});
$("#diagram").droppable({
drop: function(event, ui) {
var id = uuidv4();
var clone = $(ui.helper).clone(true);
clone.attr("id", id);
clone.appendTo(this);
instance.draggable(id, {containment: true});
instance.addEndpoint(id, {
endpoint: "Dot",
anchor: ["RightMiddle"],
isSource: true,
connectionType: "red-connection"
});
instance.addEndpoint(id, {
endpoint: "Dot",
anchor: ["LeftMiddle"],
isTarget: true,
connectionType: "red-connection"
});
}
})
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment