当前位置:网站首页>Based on jsplumb JS to achieve multi list one to many connection effect
Based on jsplumb JS to achieve multi list one to many connection effect
2022-04-23 21:23:00 【Sister Chunfeng】
js How to write it Reference resources https://juejin.cn/post/6915642997195407368
design sketch 
js Realization
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> attachment demo</title>
<script type="text/javascript" src="./jsplumb.js"></script>
<style>
.ul-list {
display: inline-block;
}
.ul-list li {
list-style-type: none;
border: 1px solid red;
height: 30px;
line-height: 30px;
text-align: center;
width: 100px;
}
</style>
</head>
<body>
<div>
<div><button id="btn"> Get connection </button></div>
<textarea rows="5" cols="50" class="textarea"> </textarea>
<div id="container"></div>
</div>
<script>
// Define list data
let data;
// Define the default connection relationship data
let relationship;
// Definition jsplumb Instance variables
let instance;
data = [
[
{
title: " I am a a1 La! ",
id: "a1",
},
{
title: " I am a a2 La! ",
id: "a2",
},
{
title: " I am a a3 La! ",
id: "a3",
},
],
[
{
title: " I am a b1 La! ",
id: "b1",
},
{
title: " I am a b2 La! ",
id: "b2",
},
{
title: " I am a b3 La! ",
id: "b3",
},
],
[
{
title: " I am a c1 La! ",
id: "c1",
},
{
title: " I am a c2 La! ",
id: "c2",
},
{
title: " I am a c3 La! ",
id: "c3",
},
],
];
relationship = [
{
source: "a1", target: "b1" },
{
source: "a1", target: "b2" },
{
source: "b1", target: "c3" },
];
// Loop list data Render list ul
data.forEach((v1, i1) => {
let ul = document.createElement("ul");
// Add a class name Convenient for later access
ul.classList.add("ul-list");
let lis = "";
v1.forEach((v2) => {
// id Must be set to... Of data id Then add custom attributes index The value is the index of the current list Later need to use
lis += `<li id=${
v2.id} index=${
i1}>${
v2.title}</li>`;
});
ul.innerHTML = lis;
document.getElementById("container").appendChild(ul);
});
jsPlumb.ready(function () {
// initialization jsPlumb establish jsPlumb example
init();
// Set the elements that can be the starting point and the ending point of the line
setContainer();
// Set the default connection
setConnect();
// In connection Events Only adjacent lists are allowed to be connected Cannot connect across lists
setRule();
jsPlumb.fire("jsPlumbDemoLoaded", instance);
});
// initialization jsPlumb establish jsPlumb example
function init() {
instance = jsPlumb.getInstance({
Connector: "Straight", // Connector shape Bezier: Bessel curve Flowchart: have 90 The flow line of the turning point StateMachine: State machine Straight: A straight line
// PaintStyle: { strokeWidth: 3, stroke: "#ffa500", "dashstyle": "2 4" }, // Connector style
Endpoint: ["Dot", {
radius: 5 }], // Endpoint
EndpointStyle: {
fill: "#ffa500" }, // Endpoint style
Container: "container", // Target container id
ListStyle: {
endpoint: ["Rectangle", {
width: 30, height: 30 }],
},
});
}
// Connection elements can be set
function setContainer() {
// amount to css Selectors You can also use id Selection, etc
let uls = jsPlumb.getSelector(".ul-list");
// take dom Element is set as the starting or ending point of the line The element with the starting point set can start the connection Only the element set as the end point can be the end point of the connection
instance.batch(function () {
uls.forEach((ul) => {
let lis = ul.querySelectorAll("li");
lis.forEach((li) => {
// take li Set as start point
instance.makeSource(li, {
allowLoopback: false,
anchor: ["Left", "Right"], // Set the endpoint location
});
// take li Set as end point
instance.makeTarget(li, {
anchor: ["Left", "Right"],
});
});
});
});
}
// Set the default connection
function setConnect() {
relationship.forEach(function (el) {
// source Is the starting element of the connection id target Is the end element of the connection id
instance.connect({
source: el.source, target: el.target });
});
}
// Only adjacent lists are allowed to be connected
function setRule() {
// // Connection event Connection to the current location is not allowed list
instance.bind("connection", function (connInfo, originalEvent) {
// connInfo yes jsPlumb object Can print out what Kangkang has
// according to sourceId Get the start connection element li According to li Of index Custom properties Judge that only adjacent... Are allowed to be connected ul list
let index = Number(
document
.getElementById(connInfo.connection.sourceId)
.getAttribute("index")
);
let allow = [];
if (data[index + 1]) {
allow = [...allow, ...data[index + 1].map((_) => _.id)];
}
if (data[index - 1]) {
allow = [...allow, ...data[index - 1].map((_) => _.id)];
}
// If the line end element (targetId) Elements not at the starting point (sourceId) Before and after ul List range Just delete the connection
if (allow.indexOf(connInfo.connection.targetId) == -1) {
// Delete connection
instance.deleteConnection(connInfo.connection);
}
});
}
// to button Register the click event to get the connection relationship
document.getElementById("btn").addEventListener("click", function () {
let newRelationship = '';
instance.getAllConnections().forEach((el) => {
newRelationship+=` ${
el.sourceId} Connected to ${
el.targetId}`;
});
document.querySelector('.textarea').value = newRelationship
console.log(document.querySelector('.textarea'));
// jsplumb Common methods
// jsplumb.getConnections({souce: 'sourceID', target: 'targetID'}); // Get the specified connection
// 1. jsPlumb.getAllConnections() Get all connectors
// 2. jsPlumb.deleteEveryConnection(); Empty all connection lines
// 3. jsPlumb.deleteConnection(connInfo.connection); // Delete connector
// 4. jsPlumb.setContainer(document.getElementById("main"));// Initialize instantiated components
});
</script>
</body>
</html>
vue changes ( Change the line here into a single )
<template>
<div>
<div><button id="btn" @click="getLianXian()"> Get connection </button></div>
<textarea rows="5" cols="50" class="textarea" v-model="textareaVal">
</textarea>
<div id="container">
<ul class="ul-list" v-for="(item, index) in data" :key="index">
<li
v-for="(i, indexes) in item"
:id="i.id"
:index="index"
:key="indexes"
>
{
{
i.title }}
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: "App",
components: {
},
data() {
return {
data: [
[
{
title: " I am a a1",
id: "a1",
},
{
title: " I am a a2",
id: "a2",
},
{
title: " I am a a3",
id: "a3",
},
],
[
{
title: " I am a b1",
id: "b1",
},
{
title: " I am a b2",
id: "b2",
},
{
title: " I am a b3",
id: "b3",
},
],
],
relationship: [
{
source: "a1", target: "b2" },
{
source: "a2", target: "b1" },
],
instance: "",
addponit: "",
textareaVal: "",
};
},
computed: {
},
mounted() {
this.$nextTick(() => {
jsPlumb.ready(() => {
// initialization jsPlumb establish jsPlumb example
this.init();
// Set the elements that can be the starting point and the ending point of the line
this.setContainer();
// Set the default connection
this.setConnect();
// In connection Events Only adjacent lists are allowed to be connected Cannot connect across lists
this.setRule();
// Click Delete connection
this.delete();
// Determine if a connection is established
this.beforeDrop();
jsPlumb.fire("jsPlumbDemoLoaded", this.instance);
});
// jsplumb Common methods
// jsplumb.getConnections({souce: 'sourceID', target: 'targetID'}); // Get the specified connection
// 1. jsPlumb.getAllConnections() Get all connectors
// 2. jsPlumb.deleteEveryConnection(); Empty all connection lines
// 3. jsPlumb.deleteConnection(connInfo.connection); // Delete connector
// 4. jsPlumb.setContainer(document.getElementById("main"));// Initialize instantiated components
});
},
methods: {
// initialization jsPlumb establish jsPlumb example
init() {
this.instance = jsPlumb.getInstance({
Connector: "Straight", // Connector shape Bezier: Bessel curve Flowchart: have 90 The flow line of the turning point StateMachine: State machine Straight: A straight line
// PaintStyle: { strokeWidth: 3, stroke: "#ffa500", "dashstyle": "2 4" }, // Connector style
Endpoint: ["Dot", {
radius: 5 }], // Endpoint
EndpointStyle: {
fill: "#000" }, // Endpoint style
Container: "container", // Target container id
ListStyle: {
endpoint: ["Rectangle", {
width: 30, height: 30 }],
},
});
},
// Connection elements can be set
setContainer() {
// amount to css Selectors You can also use id Selection, etc
let uls = jsPlumb.getSelector(".ul-list");
// take dom Element is set as the starting or ending point of the line The element with the starting point set can start the connection Only the element set as the end point can be the end point of the connection
this.instance.batch(() => {
uls.forEach((ul) => {
let lis = ul.querySelectorAll("li");
lis.forEach((li) => {
// take li Set as start point
this.instance.makeSource(li, {
allowLoopback: false,
anchor: ["Left", "Right"], // Set the endpoint location
});
// take li Set as end point
this.instance.makeTarget(li, {
anchor: ["Left", "Right"],
});
});
});
});
},
// Set the default connection
setConnect() {
this.relationship.forEach((el) => {
// source Is the starting element of the connection id target Is the end element of the connection id
this.instance.connect({
source: el.source, target: el.target });
});
},
// Only adjacent lists are allowed to be connected
setRule() {
// // Connection event Connection to the current location is not allowed list
this.instance.bind("connection", (connInfo, originalEvent) => {
// connInfo yes jsPlumb object Can print out what Kangkang has
// according to sourceId Get the start connection element li According to li Of index Custom properties Judge that only adjacent... Are allowed to be connected ul list
let index = Number(
document
.getElementById(connInfo.connection.sourceId)
.getAttribute("index")
);
let allow = [];
if (this.data[index + 1]) {
allow = [...allow, ...this.data[index + 1].map((_) => _.id)];
}
if (this.data[index - 1]) {
allow = [...allow, ...this.data[index - 1].map((_) => _.id)];
}
// If the line end element (targetId) Elements not at the starting point (sourceId) Before and after ul List range Just delete the connection
if (allow.indexOf(connInfo.connection.targetId) == -1) {
// Delete connection
this.instance.deleteConnection(connInfo.connection);
}
});
},
delete() {
this.instance.bind("click", (conn, originalEvent) => {
if (window.prompt(" Are you sure to delete the clicked link ? Input 1 determine ") === "1") {
this.instance.deleteConnection(conn);
}
});
},
beforeDrop() {
// When the link is established
this.instance.bind("beforeDrop", (info) => {
let checkArrsourceId = [];
let checkArrtargetId = [];
this.instance.getAllConnections().forEach((el) => {
checkArrsourceId.push(el.sourceId);
checkArrtargetId.push(el.targetId);
});
let fenId = checkArrsourceId.concat(checkArrtargetId);
console.log(fenId, "fenId-----");
console.log(fenId.indexOf(info.sourceId), "allId.indexOf(fenId)====");
if (
fenId.indexOf(info.sourceId) == -1 ||
fenId.indexOf(info.targetId) == -1
) {
return true; // The link will be established automatically
} else {
return false; // Links will not be established , Be careful , Must be false
}
});
},
getLianXian() {
let newRelationship = "";
this.instance.getAllConnections().forEach((el) => {
newRelationship += ` ${
el.sourceId} Connected to ${
el.targetId}`;
});
this.textareaVal = newRelationship;
},
},
};
</script>
<style>
* {
padding: 1;
margin: 1;
}
#container {
width: 500px;
}
.ul-list {
display: inline-block;
}
.ul-list li {
list-style-type: none;
border: 1px solid red;
height: 30px;
line-height: 30px;
text-align: center;
width: 100px;
}
</style>
版权声明
本文为[Sister Chunfeng]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/110/202204200620164113.html
边栏推荐
- Arm architecture assembly instructions, registers and some problems
- Pyuninstaller package exe cannot find the source code when running, function error oserror: could not get source code
- 又一款数据分析神器:Polars 真的很强大
- Detectron2 using custom datasets
- Express③(使用Express编写接口、跨域有关问题)
- Pikachuxss how to get cookie shooting range, always fail to return to the home page
- 阿里云回应用户注册信息泄露事件
- 引入结构化并发,Swift 5.5 发布!
- Opencv reports an error. Expected PTR < CV:: UMAT > for argument '% s'‘
- Google tries to use rust in Chrome
猜你喜欢

Use 3080ti to run tensorflow GPU = 1 X version of the source code
![[leetcode refers to the two numbers of offer 57. And S (simple)]](/img/c2/7c1434e3c0bbcc6d6364361c3a3ab4.png)
[leetcode refers to the two numbers of offer 57. And S (simple)]

Google 尝试在 Chrome 中使用 Rust

Zhongchuang storage | how to choose a useful distributed storage cloud disk

一文解决浏览器跨域问题

Common problems in deploying projects with laravel and composer for PHP

Keywords static, extern + global and local variables

Opencv application -- jigsaw puzzle

Question brushing plan -- backtracking method (I)

Introduction to tensorrt
随机推荐
Opencv application -- jigsaw puzzle
[leetcode refers to offer 42. Maximum sum of continuous subarrays (simple)]
flomo软件推荐
Sharpness difference (SD) calculation method of image reconstruction and generation domain index
使用mbean 自动执行heap dump
Presto on spark supports 3.1.3 records
Pyuninstaller package exe cannot find the source code when running, function error oserror: could not get source code
setInterval、setTimeout、requestAnimationFrame
Lunch on the 23rd day at home
Detectron2 using custom datasets
Use 3080ti to run tensorflow GPU = 1 X version of the source code
Amazon and epic will be settled, and the Microsoft application mall will be opened to third parties
[leetcode refers to the substructure of offer 26. Tree (medium)]
Arm architecture assembly instructions, registers and some problems
[leetcode refers to offer 10 - I. Fibonacci sequence (simple)]
Plato Farm元宇宙IEO上线四大,链上交易颇高
Pytorch selects the first k maximum (minimum) values and their indexes in the data
Recommended usage scenarios and production tools for common 60 types of charts
【SDU Chart Team - Core】SVG属性类设计之枚举
setInterval、setTimeout、requestAnimationFrame