当前位置:网站首页>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
 Insert picture description here
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