2

I am having trouble with a graph I'm creating in JavaScript. My graph takes data from the sales object and displays it in a graph. I am trying to add a button so that if it is clicked, all the sales.Sales values are set to 0, therefore resetting the graph to blank. I have tried using a loop to iterate through it, however, it only removes the December div and not the other 11 months. I included the HTML and JavaScript below.

HTML:

<!DOCTYPE html>
<html>
    <head>
        <link rel = "stylesheet" href = "css/styles.css">
    </head>
    <body>
        <script src = "js/sales-graph.js"></script>
        <h1 id = "main_title">Titan Sports and Apparel LLC</h1>
        <div id = "labels"></div><br />

        <footer>© Titan Sports and Apparel LLC | Email: TitanSportsApparel@gmail.com</footer>
        <br />
        <br />
        <br />
        <br />
        <button id = "resetgraph">Reset Graph</button>
    </body>
</html>



function barGraph (sales) {

    //Create graph
    var graph = document.createElement("div");
    graph.style.position = "relative";
    graph.style.marginTop = "20%";
    
    //Set height
    var Maxheight = 0;
    for (var i = 0; i < sales.length; i += 1) {
        Maxheight = Math.max(Maxheight, sales[i].value);
    }
    graph.style.height = (Maxheight + 10) + "px";
    
    //Give graph border
    graph.style.borderBottomStyle = "solid";
    graph.style.borderBottomWidth = "1px";

    //Iterate through data
    var position = 0;

    var width = 80;

    for (i = 0; i < sales.length; i += 1) {
        var salesItem = sales[i];
        var bar = document.createElement("div");

        //Bar styling
        bar.style.position = "absolute";
        bar.style.left = position + "px";
        bar.style.width = width + "px";
        bar.style.backgroundColor = salesItem.Color;
        bar.style.height = salesItem.Sales + "px";
        bar.style.bottom = "0px";
        bar.innerHTML = salesItem.Sales;
        bar.style.fontSize = "20px";
        bar.style.textAlign = "center";

        //Only removes december?
        document.getElementById("resetgraph").addEventListener("click", function() {
            for (j = 0; j < sales.length; j++) {
                bar.style.height = "0px";
                bar.innerText = "";
            }
        });

        //Append
        graph.appendChild(bar);
        //Set bar width
        position += (width * 2);
    }
    
    return graph;
};

function addlabel (sales) {
    var labels = document.getElementById("labels")
    labels.style.marginTop = "1px";
    var width = 158.5;

    for (var i = 0; i < sales.length; i+= 1) {
        var labelcontent = sales[i];
        var label = document.createElement("span");

        label.innerHTML = labelcontent.Month;
        label.style.display = "inline-block";
        label.style.width = width + "px";
        label.style.paddingLeft = "0px"
        labels.appendChild(label);

    }
    return labels;
}

window.onload = function () {
    var sales = [
        {Month: "January", Sales: 40, Color: "Red"},
        {Month: "February", Sales: 10, Color: "Green"},
        {Month: "March", Sales: 100, Color: "Blue"},
        {Month: "April", Sales: 65, Color: "Yellow"},
        {Month: "May", Sales: 75, Color: "Brown"},
        {Month: "June", Sales: 120, Color: "Grey"},
        {Month: "July", Sales: 121, Color: "Turquoise"},
        {Month: "August", Sales: 175, Color: "Cyan"},
        {Month: "September", Sales: 220, Color: "Gold"},
        {Month: "October", Sales: 275, Color: "Grey"},
        {Month: "November", Sales: 300, Color: "Purple"},
        {Month: "December", Sales: 15, Color: "Pink"},
    ]
    
    var annotation = document.createElement("div")
    width = 1750;
    annotation.style.width = width + "px";
    annotation.style.textAlign = "center";
    annotation.innerHTML = "Sales are in thousands";

    var graph = barGraph(sales);
    var labels = addlabel(sales)
    document.body.appendChild(graph);
    document.body.appendChild(labels);
    document.body.appendChild(annotation);
};
TBA
  • 1,921
  • 4
  • 13
  • 26
Alex
  • 57
  • 8

1 Answers1

0

In your code, you were looping through all the sales items but you were applying the style only on the current bar, which was for your case the last item, December.

So, what I did is, set a unique ID, gave them the name of the month for each of your bars, and then on button click, I looped through all the sales items, tried to find if they exist or not. If they do then just applied your style on that bar.

var sales = [];

     document.getElementById("resetgraph").addEventListener("click", function() {
          for (j = 0; j < sales.length; j++) {
               //check if all the element exist according to their id
               var bar = document.getElementById(sales[j].Month);
               if(bar){
                    //if exist then remove
                    bar.style.height = "0px";
                    bar.innerText = "";
               }else{
                    console.log("element not exist");
               }
          }
     });

     function barGraph (sales) {

          //Create graph
          var graph = document.createElement("div");
          graph.id = "mainGraph";
          graph.style.position = "relative";
          graph.style.marginTop = "20%";

          //Set height
          var Maxheight = 0;
          for (var i = 0; i < sales.length; i += 1) {
          Maxheight = Math.max(Maxheight, sales[i].value);
          }
          graph.style.height = (Maxheight + 10) + "px";

          //Give graph border
          graph.style.borderBottomStyle = "solid";
          graph.style.borderBottomWidth = "1px";

          //Iterate through data
          var position = 0;

          var width = 80;

          for (i = 0; i < sales.length; i += 1) {
          var salesItem = sales[i];
          var bar = document.createElement("div");
          //set an unique id for each of the bar graph
          bar.id = sales[i].Month;

          //Bar styling
          bar.style.position = "absolute";
          bar.style.left = position + "px";
          bar.style.width = width + "px";
          bar.style.backgroundColor = salesItem.Color;
          bar.style.height = salesItem.Sales + "px";
          bar.style.bottom = "0px";
          bar.innerHTML = salesItem.Sales;
          bar.style.fontSize = "20px";
          bar.style.textAlign = "center";

          //Append
          graph.appendChild(bar);
          //Set bar width
          position += (width * 2);
          }

          return graph;
     };

     function addlabel (sales) {
          var labels = document.getElementById("labels")
          labels.style.marginTop = "1px";
          var width = 158.5;

          for (var i = 0; i < sales.length; i+= 1) {
          var labelcontent = sales[i];
          var label = document.createElement("span");

          label.innerHTML = labelcontent.Month;
          label.style.display = "inline-block";
          label.style.width = width + "px";
          label.style.paddingLeft = "0px"
          labels.appendChild(label);

          }
          return labels;
     }

     window.onload = function () {
      sales = [
          {Month: "January", Sales: 40, Color: "Red"},
          {Month: "February", Sales: 10, Color: "Green"},
          {Month: "March", Sales: 100, Color: "Blue"},
          {Month: "April", Sales: 65, Color: "Yellow"},
          {Month: "May", Sales: 75, Color: "Brown"},
          {Month: "June", Sales: 120, Color: "Grey"},
          {Month: "July", Sales: 121, Color: "Turquoise"},
          {Month: "August", Sales: 175, Color: "Cyan"},
          {Month: "September", Sales: 220, Color: "Gold"},
          {Month: "October", Sales: 275, Color: "Grey"},
          {Month: "November", Sales: 300, Color: "Purple"},
          {Month: "December", Sales: 15, Color: "Pink"},
          ];

          var annotation = document.createElement("div")
          width = 1750;
          annotation.style.width = width + "px";
          annotation.style.textAlign = "center";
          annotation.innerHTML = "Sales are in thousands";

          var graph = barGraph(sales);
          var labels = addlabel(sales)
          document.body.appendChild(graph);
          document.body.appendChild(labels);
          document.body.appendChild(annotation);
     };
 <h1 id = "main_title">Titan Sports and Apparel LLC</h1>
        <div id = "labels"></div><br />

        <footer>© Titan Sports and Apparel LLC | Email: TitanSportsApparel@gmail.com</footer>
        <br />
        <br />
        <br />
        <br />
        <button id = "resetgraph">Reset Graph</button>
TBA
  • 1,921
  • 4
  • 13
  • 26
  • The answer gives me an error in chrome when I try it. I even copied and pasted the exact code but it gives me this error @TBA . Uncaught TypeError: Cannot read properties of null (reading 'addEventListener') at sales-graph.js:3 – Alex Nov 13 '21 at 14:54
  • @Alex Can you please provide the ID of the button? and also can you please check if you imported your sales-graph.js file in your HTML page or not – TBA Nov 13 '21 at 14:58
  • `

    Titan Sports and Apparel LLC


    © Titan Sports and Apparel LLC | Email: TitanSportsApparel@gmail.com




    ` also the id is graphreset. and I did change it in the js file too. @TBA
    – Alex Nov 13 '21 at 15:02
  • see the button you used here is different than the button I used in the code, you used ` – TBA Nov 13 '21 at 15:04
  • My apologies for not clarifying, I tried running it on both id's and neither worked. I still get the error when line 3 is document.getElementById("graphreset") and the button id = graphreset, and the same when it was graphreset id. I just tried experimenting while I was waiting on the reply. I'm unsure why the code runs fine in your code snippet but not on my end. @TBA – Alex Nov 13 '21 at 15:08
  • @Alex Can I get the full code? I just wanna see how you are trying – TBA Nov 13 '21 at 15:09
  • This is terribly confusing. I tried putting it in a code pen and it works there, and it works in the code snippet you added as well. However, when I run it locally on chrome it doesn't work. I tried running it directly from the HTML file and from the live server plugin I use in visual studio code. And yes my js file is referenced correctly in my HTML. I've never seen something like this before. Here's a link to the codepen where it works: https://codepen.io/Alexxxz/pen/rNzqxvZ @TBA – Alex Nov 13 '21 at 15:19
  • 1
    @Alex instead of importing the script inside the head tag, import it in the bottom, before the body tag ends – TBA Nov 13 '21 at 15:27
  • 1
    `When you put the script in an external file and then load that external script from the , it loads BEFORE the DOM is ready. That means that if your script tries to reference elements in the page like you are with document.getElementById(), those elements will not exist yet.` – TBA Nov 13 '21 at 15:29
  • @Alex [check this](https://stackoverflow.com/a/8716680/10117433). canon explained it very nicely here. `The position of your DOM-reliant script can have a profound effect upon its behavior. Browsers parse HTML documents from top to bottom. Elements are added to the DOM and scripts are (generally) executed as they're encountered. This means that order matters. Typically, scripts can't find elements that appear later in the markup because those elements have yet to be added to the DOM.` – TBA Nov 13 '21 at 15:37