skip to Main Content

I’ve created some HTML, CSS and JQuery to display a graph based on values in the div with the classname of "out".
I have a need for multiple graphs to be placed on the page. The problem I have is that when I try and place multiple graphs on the page, only the first one shows.
Is there a way I can call the same JQuery function multiple times on the same page and get it to operate correctly?

My code is below:

$(document).ready(function() {
  $(".out div").each(function() {
    var num = $(this).html()
    var iNum = parseInt(num);
    var eq = $(this).index();
    var finalSum = (iNum / 20);
    $(".graph-div").eq(eq).find("div.graph-bar").css("height", finalSum + "px");
  });
});
.graph-box {border:1px solid #ccc; width:fit-content;}
.graph-bar {width:120px; align-items: center; box-sizing: border-box;}
.graph {display:flex; text-align: center; width:90px; align-items: center; box-sizing: border-box;}
.graph-div {width:120px; align-self: flex-end;}
.out {display:flex; text-align: center;}
.parties {display:flex; border:1px solid #ccc; text-align: center; width: fit-content;}
.out div, .parties div {width:120px;}
.out div:nth-child(odd), .parties div:nth-child(odd)  {background-color:#F0F0F0;}
.out div:nth-child(even), .parties div:nth-child(even) {background-color:#F9f9f9;}
.con {background-color: blue;}
.lab {background-color: red;}
.gre {background-color: green;}
.lib {background-color: orange;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

<div class="graph-box">
  <div class="graph">
    <div class="graph-div">
      <div class="graph-bar con"></div>
    </div>
    <div class="graph-div">
      <div class="graph-bar lab"></div>
    </div>
    <div class="graph-div">
      <div class="graph-bar gre"></div>
    </div>
    <div class="graph-div">
      <div class="graph-bar lib"></div>
    </div>
  </div>
  <div class="out">
    <div>1200</div>
    <div>7000</div>
    <div>160</div>
    <div>6899</div>
  </div>
</div>
<div class="parties">
  <div>Conservative</div>
  <div>labour</div>
  <div>Green</div>
  <div>Liberal <br> Democrats</div>
</div>

<div class="graph-box">
  <div class="graph">
    <div class="graph-div">
      <div class="graph-bar con"></div>
    </div>
    <div class="graph-div">
      <div class="graph-bar lab"></div>
    </div>
    <div class="graph-div">
      <div class="graph-bar gre"></div>
    </div>
    <div class="graph-div">
      <div class="graph-bar lib"></div>
    </div>
  </div>
  <div class="out">
    <div>1200</div>
    <div>7000</div>
    <div>160</div>
    <div>6899</div>
  </div>
</div>
<div class="parties">
  <div>Conservative</div>
  <div>labour</div>
  <div>Green</div>
  <div>Liberal <br> Democrats</div>
</div>

2

Answers


  1. It’s because every single instance is only targeting the first set of graph bar outputs. You need to adjust your code to target the graph bars within the same parent – you can see here I’ve modified this line to scope the query properly and it shows two graphs now

    $(this).closest(".graph-box").find(".graph-div")
    
    $(document).ready(function() {
      $(".out div").each(function() {
        var num = $(this).html()
        var iNum = parseInt(num);
        var eq = $(this).index();
        var finalSum = (iNum / 20);
        $(this).closest(".graph-box").find(".graph-div").eq(eq).find("div.graph-bar").css("height", finalSum + "px");
      });
    });
    .graph-box {border:1px solid #ccc; width:fit-content;}
    .graph-bar {width:120px; align-items: center; box-sizing: border-box;}
    .graph {display:flex; text-align: center; width:90px; align-items: center; box-sizing: border-box;}
    .graph-div {width:120px; align-self: flex-end;}
    .out {display:flex; text-align: center;}
    .parties {display:flex; border:1px solid #ccc; text-align: center; width: fit-content;}
    .out div, .parties div {width:120px;}
    .out div:nth-child(odd), .parties div:nth-child(odd)  {background-color:#F0F0F0;}
    .out div:nth-child(even), .parties div:nth-child(even) {background-color:#F9f9f9;}
    .con {background-color: blue;}
    .lab {background-color: red;}
    .gre {background-color: green;}
    .lib {background-color: orange;}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    
    <div class="graph-box">
      <div class="graph">
        <div class="graph-div">
          <div class="graph-bar con"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar lab"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar gre"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar lib"></div>
        </div>
      </div>
      <div class="out">
        <div>1200</div>
        <div>7000</div>
        <div>160</div>
        <div>6899</div>
      </div>
    </div>
    <div class="parties">
      <div>Conservative</div>
      <div>labour</div>
      <div>Green</div>
      <div>Liberal <br> Democrats</div>
    </div>
    
    <div class="graph-box">
      <div class="graph">
        <div class="graph-div">
          <div class="graph-bar con"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar lab"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar gre"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar lib"></div>
        </div>
      </div>
      <div class="out">
        <div>1200</div>
        <div>7000</div>
        <div>160</div>
        <div>6899</div>
      </div>
    </div>
    <div class="parties">
      <div>Conservative</div>
      <div>labour</div>
      <div>Green</div>
      <div>Liberal <br> Democrats</div>
    </div>
    Login or Signup to reply.
  2. Your issue is this line:

    var eq = $(this).index();
    

    which will give you the index only within this‘s parent – so the fifth div across all out is actually index==0 because it’s the first div in the second out.

    So when you do $(".graph-div").eq(eq), eq==0 so will find the first .graph-div across all graph-divs.

    You have some options, including:

    1. link the data with the graph, eg using data- attributes

    this would be the most flexible as the order and position/structure of the HTML would not matter, but may be overkill in this scenario

    1. limit $(".graph-div") selection to match the out

    details in other answer – requires restructuring the HTML, which may not be appropriate in all cases

    1. change .index() to apply across all out divs:

    requires that out/graphs are all in the same order (which makes sense otherwise they won’t line up…)

    To apply .index() across all out divs:

    var eq = $(".out div").index(this);
    

    or

    var eq = $(this).index(".out div");
    

    the first would allow you to cache $(".out div") – not below shown for clarity of the change.

    Which option you choose depends on how you layout the HTML

    Updated snippet:

    $(document).ready(function() {
      $(".out div").each(function() {
        var num = $(this).html()
        var iNum = parseInt(num);
        //var eq = $(this).index();
        var eq = $(".out div").index(this);
        //var eq = $(this).index(".out div");
        var finalSum = (iNum / 20);
        $(".graph-div").eq(eq).find("div.graph-bar").css("height", finalSum + "px");
      });
    });
    .graph-box {border:1px solid #ccc; width:fit-content;}
    .graph-bar {width:120px; align-items: center; box-sizing: border-box;}
    .graph {display:flex; text-align: center; width:90px; align-items: center; box-sizing: border-box;}
    .graph-div {width:120px; align-self: flex-end;}
    .out {display:flex; text-align: center;}
    .parties {display:flex; border:1px solid #ccc; text-align: center; width: fit-content;}
    .out div, .parties div {width:120px;}
    .out div:nth-child(odd), .parties div:nth-child(odd)  {background-color:#F0F0F0;}
    .out div:nth-child(even), .parties div:nth-child(even) {background-color:#F9f9f9;}
    .con {background-color: blue;}
    .lab {background-color: red;}
    .gre {background-color: green;}
    .lib {background-color: orange;}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    
    <div class="graph-box">
      <div class="graph">
        <div class="graph-div">
          <div class="graph-bar con"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar lab"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar gre"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar lib"></div>
        </div>
      </div>
      <div class="out">
        <div>1200</div>
        <div>7000</div>
        <div>160</div>
        <div>6899</div>
      </div>
    </div>
    <div class="parties">
      <div>Conservative</div>
      <div>labour</div>
      <div>Green</div>
      <div>Liberal <br> Democrats</div>
    </div>
    
    <div class="graph-box">
      <div class="graph">
        <div class="graph-div">
          <div class="graph-bar con"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar lab"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar gre"></div>
        </div>
        <div class="graph-div">
          <div class="graph-bar lib"></div>
        </div>
      </div>
      <div class="out">
        <div>3500</div>
        <div>7000</div>
        <div>6000</div>
        <div>6899</div>
      </div>
    </div>
    <div class="parties">
      <div>Conservative</div>
      <div>labour</div>
      <div>Green</div>
      <div>Liberal <br> Democrats</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search