Home > Mobile >  Connect a line between 2 divs
Connect a line between 2 divs

Time:10-30

I am trying to make a network-like design with divs and connecting lines between every two divs but when I used svg and line tags with the JS function below, the console showed an error saying that

position is not a function.

What is wrong with my code? How do I fix it or are there other ways to draw lines between two divs? ** The problem is solved but now I tried to use loops and arrays because if I connected all the divs manually it will take forever. so I wrote the code below but know it shows the same error again. I tried to put each element of the array in a variable but it also didn't work. **

Here is the code:

```
  $(function() {
var orgs = document.getElementsByClassName('org'),
    lines = document.getElementsByClassName('con-line'),
    org1,
    org2,
    line,
    pos1,
    pos2,
    count = 0;

for (let i = 0; i < orgs.length; i  ) {
    
    org1 = orgs[i];

    for (let j = 0; j < orgs.length; j  ) {

        org2 = orgs[j];
        line = lines[count];


        if (j != i)
        {
            pos1 = org1.position();
            pos2 = org2.position();

            line
                .attr('x1', pos1.left)
                .attr('y1', pos1.top)
                .attr('x2', pos2.left)
                .attr('y2', pos2.top)
                .attr('stroke', 'red')
                .attr('stroke-width', 2);

                count  ;
        }
      }

  }    
  });
```
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

jQuery

  1. Try to wrap your code into "document ready" construction. This will ensure that the code is executed after the jQuery is loaded.

  2. Define the stroke and stroke-width attributes to make the line visible.

Show code snippet

$(function() {
  var line1= $('#line1');
  var div1 = $('#org1');
  var div2 = $('#org2');

  var l1pos1 = div1.position();
  var l1pos2 = div2.position();

  line1
    .attr('x1', l1pos1.left)
    .attr('y1', l1pos1.top)
    .attr('x2', l1pos2.left)
    .attr('y2', l1pos2.top)
    .attr('stroke', 'red')
    .attr('stroke-width', 10);
});
.con{
    margin-top: 50px;
}

.con-title{
    width: 100%;
    text-align: center;
    color: #4E4E50;
    font-size: 40px;
    font-weight: bold;
}

.org-map{
    position: relative;
    width: 300px;
    height: 300px;
    margin: 40px auto 0 auto;
}

.org{
    position: absolute;
}

.org .org-box{
    position: relative;
    bottom: 0px;
    width: 15px;
    height: 15px;
    border-radius: 20px;
    background: #4E4E50;
    transition: 0.6s;
}

#org1{
    transform: translate(-50%, 0%);
    bottom: 80%;
    left: 50%;
}

#org2{
    transform: translate(-50%, 0%);
    bottom: 65%;
    left: 20%;
}

#org3{
    transform: translate(-50%, 0%);
    bottom: 35%;
    left: 20%;
}

#org4{
    transform: translate(-50%, 0%);
    bottom: 50%;
    left: 50%;
}

#org5{
    transform: translate(-50%, 0%);
    bottom: 65%;
    left: 80%;
}

#org6{
    transform: translate(-50%, 0%);
    bottom: 35%;
    left: 80%;
}

#org7{
    transform: translate(-50%, 0%);
    bottom: 20%;
    left: 50%;
}

.org:hover .org-box{
    background: #C3073F;
    animation: org 1s;
    animation-fill-mode: forwards;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="con">
  <div class="con-title">Contributions</div>
  <div class="org-map">
    <div class="org" id="org1">
        <div class="org-box">
            <img src="" alt="">
        </div>
    </div>
    <div class="org" id="org2">
        <div class="org-box">
            <img src="" alt="">
        </div>
    </div>
    <div class="org" id="org3">
        <div class="org-box">
            <img src="" alt="">
        </div>
    </div>
    <div class="org" id="org4">
        <div class="org-box">
            <img src="" alt="">
        </div>
    </div>
    <div class="org" id="org5">
        <div class="org-box">
            <img src="" alt="">
        </div>
    </div>
    <div class="org" id="org6">
        <div class="org-box">
            <img src="" alt="">
        </div>
    </div>
    <div class="org" id="org7">
        <div class="org-box">
            <img src="" alt="">
        </div>
    </div>
    <svg width="500" height="500">
        <line id="line1"/>
        <line id="line2"/>
    </svg>
  </div>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Pure JavaScript

  1. You can use the Element.getBoundingClientRect() method to get more information about div blocks.

  2. In this case, in the calculations, it is necessary to take into account the position of the SVG element itself. To do this, we subtract from the absolute coordinates of the points the corresponding coordinates of the upper left corner of the SVG.

This is an example of the JavaScript code without jQuery:

let line1 = document.getElementById('line1');

let svgRect = document.getElementById('lines').getBoundingClientRect();

let rect1 = document.getElementById('org1').getBoundingClientRect();
let rect2 = document.getElementById('org2').getBoundingClientRect();

let dot1x = (rect1.left   rect1.right) / 2;
let dot1y = (rect1.top   rect1.bottom) / 2;

let dot2x = (rect2.left   rect2.right) / 2;
let dot2y = (rect2.top   rect2.bottom) / 2;

setAttributes(line1, {
  'x1': dot1x - svgRect.left,
  'y1': dot1y - svgRect.top,
  'x2': dot2x - svgRect.left,
  'y2': dot2y - svgRect.top,
  'stroke': 'red',
  'stroke-width': 4,
});

// helper function from https://stackoverflow.com/a/12274782/6263942
function setAttributes(el, attrs) {
  for(var key in attrs) {
    el.setAttribute(key, attrs[key]);
  }
}
.con {
  margin-top: 50px;
}

.con-title {
  width: 100%;
  text-align: center;
  color: #4E4E50;
  font-size: 40px;
  font-weight: bold;
}

.org-map {
  position: relative;
  width: 300px;
  height: 300px;
  margin: 40px auto 0 auto;
}

.org {
  position: absolute;
}

.org .org-box {
  position: relative;
  bottom: 0px;
  width: 15px;
  height: 15px;
  border-radius: 20px;
  background: #4E4E50;
  transition: 0.6s;
}

#org1 {
  transform: translate(-50%, 0%);
  bottom: 80%;
  left: 50%;
}

#org2 {
  transform: translate(-50%, 0%);
  bottom: 65%;
  left: 20%;
}

#org3 {
  transform: translate(-50%, 0%);
  bottom: 35%;
  left: 20%;
}

#org4 {
  transform: translate(-50%, 0%);
  bottom: 50%;
  left: 50%;
}

#org5 {
  transform: translate(-50%, 0%);
  bottom: 65%;
  left: 80%;
}

#org6 {
  transform: translate(-50%, 0%);
  bottom: 35%;
  left: 80%;
}

#org7 {
  transform: translate(-50%, 0%);
  bottom: 20%;
  left: 50%;
}

.org:hover .org-box {
  background: #C3073F;
  animation: org 1s;
  animation-fill-mode: forwards;
}
<div class="con">
  <div class="con-title">Contributions</div>
  <div class="org-map">
    <div class="org" id="org1">
      <div class="org-box">
        <img src="" alt="">
      </div>
    </div>
    <div class="org" id="org2">
      <div class="org-box">
        <img src="" alt="">
      </div>
    </div>
    <div class="org" id="org3">
      <div class="org-box">
        <img src="" alt="">
      </div>
    </div>
    <div class="org" id="org4">
      <div class="org-box">
        <img src="" alt="">
      </div>
    </div>
    <div class="org" id="org5">
      <div class="org-box">
        <img src="" alt="">
      </div>
    </div>
    <div class="org" id="org6">
      <div class="org-box">
        <img src="" alt="">
      </div>
    </div>
    <div class="org" id="org7">
      <div class="org-box">
        <img src="" alt="">
      </div>
    </div>
    <svg width="500" height="500" id="lines">
        <line id="line1"/>
        <line id="line2"/>
    </svg>
  </div>
</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related