jsPlumb
jQuery
.appendTo
Insert every element in the set of matched elements to the end of the target.
<div id="app">
<h1>jQuery</h1>
</div>
<script>
$('<p>I love you.</p>').appendTo($('#app'))
</script>
Snipaste_2019-03-16_20-23-04.png
可以省略闭合标签
<div id="app">
<h1>jQuery</h1>
</div>
<script>
$('<p>I love you.</p>').appendTo($('#app'))
$('<span style="display: inline-block; width: 30px; height: 10px; background: purple;">').appendTo($('#app')) // span 未写 “闭合” 标签
</script>
Snipaste_2019-03-16_20-44-17.png
Codepen: https://codepen.io/MonguDykrai/pen/RdyGjL
http://api.jquery.com/appendto/
.html()
.html(htmlString)
A string of HTML to set as the content of each matched element.
<div id="app">
<h1>jQuery</h1>
</div>
<script>
$('<p>').appendTo($('#app')).html('<span>I love you.')
</script>
Snipaste_2019-03-16_20-57-16.png
Codepen: https://codepen.io/MonguDykrai/pen/MxGbwK
save and load
Save
$.each(jsPlumb.getConnections(), function (idx, connection) {
connections.push({
connectionId: connection.id,
pageSourceId: connection.sourceId,
pageTargetId: connection.targetId,
anchors: $.map(connection.endpoints, function(endpoint) {
return [[endpoint.anchor.x,
endpoint.anchor.y,
endpoint.anchor.orientation[0],
endpoint.anchor.orientation[1],
endpoint.anchor.offsets[0],
endpoint.anchor.offsets[1]]];
})
});
});
Load
$.each(connections, function( index, elem ) {
var connection1 = jsPlumb.connect({
source: elem.pageSourceId,
target: elem.pageTargetId,
anchors: elem.anchors
});
});
Connectors
gap
Snipaste_2019-03-17_06-15-24.pngoptional, defaults to 0 pixels. Lets you specify a gap between the end of the Connector and the elements to which it is attached.
cornerRadius
Snipaste_2019-03-17_06-17-56.pnghttp://jsplumb.github.io/jsplumb/connectors.html
getUuid | getUuids
jsPlumb.bind("connection", function (conn, originalEvent) {
console.log(conn.targetEndpoint.getUuid());
});
const endpoint = jsPlumb.addEndpoint(
$("#" + id),
{
uuid: id + "lt-in",
isTarget: true,
anchor: [0, 0.2]
}
);
console.log(endpoint.getUuid());
$.each(jsPlumb.getConnections(), function (idx, connection) {
// console.log(connection.getUuids()); // ["decisioncontainer1rm-out", "decisioncontainer2lm-in"]
connections.push({
// connectionId: connection.id,
sourceId: connection.sourceId,
targetId: connection.targetId,
uuids: connection.getUuids(), // getUuids
anchors: $.map(connection.endpoints, function(endpoint) {
console.error(endpoint.getUuid());
// console.log(endpoint)
return [
[
endpoint.anchor.x,
endpoint.anchor.y,
// endpoint.anchor.orientation[0],
// endpoint.anchor.orientation[1],
// endpoint.anchor.offsets[0],
// endpoint.anchor.offsets[1]
]
];
})
});
});
使用 uuid 回显
$.each(connections, function (index, elem) {
console.log(elem)
// jsPlumb.connect({
// source: elem.sourceId,
// target: elem.targetId,
// anchors: elem.anchors
// });
jsPlumb.connect({
uuids: elem.uuids
});
});
https://community.jsplumbtoolkit.com/apidocs/classes/Endpoint.html#method_getUuid
完整代码
回显.gif<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- <link rel="stylesheet" href="./index.css"> -->
<style>
.window {}
.window:hover {
cursor: pointer;
}
.menu {
background-color: #EFEFEF;
border: 1px solid #346789;
box-shadow: 2px 2px 5px #AAAAAA;
color: black;
min-height: 3em;
position: absolute;
min-width: 5em;
}
.task {
background-color: #EEEEEF;
border: 1px solid #346789;
border-radius: 0.5em;
box-shadow: 2px 2px 5px #AAAAAA;
color: black;
min-height: 3em;
position: absolute;
min-width: 5em;
}
/* Start End */
.point {
background-color: #333333;
border: 1px solid #AAAAAA;
border-radius: 50%;
box-shadow: 2px 2px 5px #AAAAAA;
color: white;
min-width: 50px;
min-height: 30px;
font-size: 11pt;
padding: 10px;
position: absolute;
text-align: center;
}
.point:hover {
box-shadow: 2px 2px 19px #AAAAAA;
}
.decision {
/* transform: rotate(-45deg); */
overflow: hidden;
border: 1px solid #346789;
border-radius: 0.3em;
color: black;
backface-visibility: hidden;
background: none repeat scroll 0 0 #F4F4F4;
box-shadow: 0 0 0 1px #CCCCCC;
color: #000000;
display: block;
height: 80px;
overflow: hidden;
/* position: relative; */
position: absolute;
text-decoration: none;
width: 80px;
}
.decision .ctrl_container {
display: table-cell;
height: 80px;
padding: 0 10px;
text-align: center;
/* transform: rotate(45deg); */
vertical-align: middle;
width: 80px;
}
.button {
text-align: center;
border: 1px solid;
margin: 5px;
}
.button:hover {
cursor: pointer;
}
.menu_button {
padding: 5px;
}
.menu_button:hover {
background-color: #AAAAAA;
color: black;
}
.button_add {
background-color: #00CC00;
float: left;
border-radius: 50%;
box-shadow: 0px 3px 8px #aaa, inset 0px 2px 3px #fff;
padding: 2px;
height: 25px;
width: 25px;
color: grey;
}
.button_add:hover {
background-color: #00AA00;
color: black;
}
.button_remove {
font-size: 9pt;
color: darkgrey;
border-radius: 30%;
box-shadow: 0px 3px 8px #aaa, inset 0px 2px 3px #fff;
padding: 5px;
min-width: 10px;
max-width: 15px;
text-align: center;
}
.task .button_remove {
float: right;
}
.decision .button_remove {
margin: auto auto;
}
.button_remove:hover {
background-color: darkred;
color: white;
}
.menu_button_container {
margin: 5px;
}
.ctrl_container {
margin: 5px;
height: 40px;
}
.details_container {
margin: 5px;
min-height: 40px;
}
.detail_label {
font-size: 9pt;
color: grey;
}
.detail_text {
width: 80px;
font-size: 10pt;
}
._jsPlumb_connector,
._jsPlumb_startpoint {
cursor: pointer;
}
</style>
</head>
<body>
<!-- Menu -->
<div
id="menuContainer"
class="menu"
style="left: 20px;"
>
<p style="text-align: center;">Menu</p>
<div class="menu_button_container">
<div class="button_add_task button menu_button ele-draggable" id="button_add_task" draggable="true">Add Task</div>
<div class="button_add_decision button menu_button ele-draggable" id="button_add_decision" draggable="true">Add Decision</div>
<div>
<button id="saveButton" class="button menu_button">Save</button>
<button id="loadButton" class="button menu_button" style="float: right;">Load</button>
</div>
<div>
<button
id="resetButton"
class="button menu_button"
style="background: rgba(0, 169, 200, 1); float: right; margin-bottom: 10px;"
>
Reset
</button>
</div>
</div>
</div>
<div
id="drawingArea"
style="width:100%; min-height:700px; background: #d6d6d6; margin-bottom: 6px;"
>
</div>
<textarea
id="jsonOutput"
style="width:100%; height:140px;"
>
{"nodes":[{"blockId":"decisioncontainer7","nodetype":"decision","positionX":339,"positionY":158},{"blockId":"taskcontainer8","nodetype":"task","positionX":436,"positionY":313},{"blockId":"decisioncontainer9","nodetype":"decision","positionX":679,"positionY":369},{"blockId":"taskcontainer10","nodetype":"task","positionX":926,"positionY":374},{"blockId":"decisioncontainer7","nodetype":"decision","positionX":339,"positionY":158},{"blockId":"decisioncontainer7","nodetype":"decision","positionX":339,"positionY":158},{"blockId":"taskcontainer11","nodetype":"task","positionX":621,"positionY":132},{"blockId":"decisioncontainer12","nodetype":"decision","positionX":1280,"positionY":376}],"connections":[{"sourceId":"decisioncontainer7","targetId":"taskcontainer8","uuids":["decisioncontainer7rm-out","taskcontainer8tm-in"],"anchors":[[1,0.5],[0.5,0]]},{"sourceId":"taskcontainer8","targetId":"decisioncontainer9","uuids":["taskcontainer8rm-out","decisioncontainer9lm-in"],"anchors":[[1,0.5],[0,0.5]]},{"sourceId":"decisioncontainer9","targetId":"taskcontainer10","uuids":["decisioncontainer9rm-out","taskcontainer10lb-in"],"anchors":[[1,0.5],[0,0.8]]},{"sourceId":"taskcontainer11","targetId":"taskcontainer10","uuids":["taskcontainer11rm-out","taskcontainer10lt-in"],"anchors":[[1,0.5],[0,0.2]]},{"sourceId":"taskcontainer10","targetId":"decisioncontainer12","uuids":["taskcontainer10rm-out","decisioncontainer12lm-in"],"anchors":[[1,0.5],[0,0.5]]}],"numberOfElements":12}
</textarea>
<script src="https://cdn.bootcss.com/jquery/2.2.1/jquery.js"></script>
<script src="https://cdn.bootcss.com/jsPlumb/2.9.0/js/jsplumb.js"></script>
<script>
var offsetX = 0;
var offsetY = 0; // 开始拖拽时鼠标指针位于元素的坐标值
var numberOfElements = 0;
var htmlBase = "drawingArea";
jsPlumb.ready(function () {
jsPlumb.draggable(".window");
// console.log(jsPlumb.Defaults)
jsPlumb.importDefaults({
MaxConnections: 1,
Endpoint: ["Dot", { radius: 6 }],
EndpointStyle: { fill: "#8aa2d8" },
EndpointHoverStyle: { fill: "#224492" },
PaintStyle: { stroke: '#e85050', strokeWidth: 2 },
HoverPaintStyle: { stroke: "#9e1b1b", strokeWidth: 2 },
Connector: [
"Flowchart",
{
gap: 10,
midpoint: 0,
// alwaysRespectStubs: true,
stub: 2,
cornerRadius: 2
}
],
ConnectionOverlays: [
["Arrow", {
location: 1,
id: "arrow",
length: 10,
width: 14,
foldback: 0.6
}]
]
});
// jsPlumb.bind("connection", function (conn, originalEvent) {
// console.log(conn.targetEndpoint.getUuid());
// });
// 不能自己连自己
jsPlumb.bind("beforeDrop", function ({ sourceId, targetId }, originalEvent) {
if (sourceId == targetId) {
return false;
}
return true;
});
$("#resetButton").on("click", function () {
jsPlumb.empty("drawingArea");
});
$("#" + htmlBase).on("click", ".button_remove", function () {
var parentnode = $(this)[0].parentNode.parentNode;
jsPlumb.deleteConnectionsForElement(parentnode);
jsPlumb.removeAllEndpoints(parentnode);
$(parentnode).remove();
});
$(".ele-draggable").on("dragstart", (ev, ff) => {
const { originalEvent, target } = ev;
offsetX = ev.offsetX;
offsetY = ev.offsetY;
originalEvent.dataTransfer.setData("text", target.id); // e.g. button_add_task
});
$("#drawingArea").on("dragover", ev => {
ev.preventDefault();
});
$("#drawingArea").on("drop", ev => {
const { originalEvent } = ev;
var posX = ev.pageX - offsetX; // 需要减去鼠标的偏移值
var posY = ev.pageY - offsetY;
if (!originalEvent.dataTransfer) return; // 连线时会触发 drop 事件,值为 undfined
var data = originalEvent.dataTransfer.getData("text");
if (data == "button_add_task") {
addTask({ posX, posY });
}
if (data == "button_add_decision") {
addDecision({ posX, posY });
}
});
$("#saveButton").click(function () {
saveFlowchart();
});
$("#loadButton").click(function () {
loadFlowchart();
});
});
function addTask({id, posX, posY}) {
const scenario = "task";
// console.warn(id);
if (typeof id === "undefined") {
numberOfElements++;
id = "taskcontainer" + numberOfElements;
// console.log(id);
}
$(`
<div class="window task node" id="${id}" data-nodetype="task" style="left: ${posX}px; top: ${posY}px;">
<div class="ctrl_container">
<div class="button_remove">x</div>
</div>
<div class="details_container">
<label class="detail_label">Name</label>
<input class="detail_text" value="" />
</div>
</div>
`)
.appendTo("#" + htmlBase);
// console.log(id)
addEndpoint({ id, scenario })
jsPlumb.draggable(id);
}
function addDecision({id, posX, posY}) {
const scenario = "decision";
// console.warn(id);
if (typeof id === "undefined") {
numberOfElements++;
id = "decisioncontainer" + numberOfElements;
// console.log(id);
}
$(`
<div class="window decision node" id="${id}" data-nodetype="decision" style="left: ${posX}px; top: ${posY}px;">
<div class="ctrl_container" style="margin-top: -10px;">
<div class="button_remove">x</div>
</div>
<div
class="details_container"
style="margin: -20px 0 0 6px; min-height: 20px; font-size: 12px; text-align: center;"
>
<span>Decision</span>
</div>
</div>
`)
.appendTo("#" + htmlBase);
// console.log(id)
addEndpoint({ id, scenario })
jsPlumb.draggable(id);
}
function addEndpoint({ id, scenario }) {
if (scenario == "task") {
const endpoint = jsPlumb.addEndpoint(
id,
{
uuid: id + "lt-in",
isTarget: true,
anchor: [0, 0.2]
}
);
console.log(endpoint.getUuid());
jsPlumb.addEndpoint(
id,
{
uuid: id + "lm-in",
isTarget: true,
anchor: [0, 0.5]
}
);
jsPlumb.addEndpoint(
id,
{
uuid: id + "lb-in",
isTarget: true,
anchor: [0, 0.8]
}
);
jsPlumb.addEndpoint(
id,
{
uuid: id + "tm-in",
isTarget: true,
// anchor: [0.5, 0, 0, -1, 100, 0],
anchor: [0.5, 0, 0, -1, 0, 0],
}
);
jsPlumb.addEndpoint(
id,
{
uuid: id + "rm-out",
isSource: true,
anchor: "Right"
}
);
return;
}
jsPlumb.addEndpoint(
id,
{
uuid: id + "lm-in",
isTarget: true,
anchor: [0, 0.5]
}
);
jsPlumb.addEndpoint(
id,
{
uuid: id + "rm-out",
isSource: true,
anchor: "Right"
}
);
}
function saveFlowchart() {
var nodes = []
$(".node").each(function (idx, elem) {
var $elem = $(elem);
nodes.push({
blockId: $elem.attr("id"),
nodetype: $elem.attr("data-nodetype"),
positionX: parseInt($elem.css("left"), 10),
positionY: parseInt($elem.css("top"), 10)
});
});
var connections = [];
$.each(jsPlumb.getConnections(), function (idx, connection) {
// console.log(connection.getUuids()); // ["decisioncontainer1rm-out", "decisioncontainer2lm-in"]
connections.push({
// connectionId: connection.id,
sourceId: connection.sourceId,
targetId: connection.targetId,
uuids: connection.getUuids(),
anchors: $.map(connection.endpoints, function(endpoint) {
console.error(endpoint.getUuid());
// console.log(endpoint)
return [
[
endpoint.anchor.x,
endpoint.anchor.y,
// endpoint.anchor.orientation[0],
// endpoint.anchor.orientation[1],
// endpoint.anchor.offsets[0],
// endpoint.anchor.offsets[1]
]
];
})
});
});
var flowChart = {};
flowChart.nodes = nodes;
flowChart.connections = connections;
flowChart.numberOfElements = numberOfElements;
// console.log(flowChart);
var flowChartJson = JSON.stringify(flowChart);
// console.log(flowChartJson);
$("#jsonOutput").val(flowChartJson);
}
function loadFlowchart() {
var flowChartJson = $("#jsonOutput").val();
var flowChart = JSON.parse(flowChartJson);
var nodes = flowChart.nodes;
$.each(nodes, function (index, elem) {
const id = elem.blockId;
const posX = elem.positionX;
const posY = elem.positionY;
if (elem.nodetype == "task") {
addTask({ id, posX, posY });
repositionElement(id, posX, posY);
// console.error(id);
}
if (elem.nodetype == "decision") {
addDecision({ id, posX, posY });
repositionElement(id, posX, posY);
// console.error(id);
}
});
var connections = flowChart.connections;
$.each(connections, function (index, elem) {
console.log(elem)
// jsPlumb.connect({
// source: elem.sourceId,
// target: elem.targetId,
// anchors: elem.anchors
// });
jsPlumb.connect({
uuids: elem.uuids
})
});
numberOfElements = flowChart.numberOfElements;
}
function repositionElement({ id, posX, posY }) {
console.log(id);
$("#" + id).css("left", posX);
$("#" + id).css("top", posY);
jsPlumb.repaint(id);
}
</script>
</body>
</html>
github: https://github.com/MonguDykrai/jsPlumb-Learning-Notes
网友评论