title: d3.js: Confusion about the order in which the code is executed
body: <p>I am trying to make an interactive bar chart in D3.js
  I <a href="https://github.com/Federicopvs/stateBankExposition.git" rel="nofollow">uploaded everything to github</a> for easy reference. I also included index.html at the end of my question.</p>
  
  <p>My starting point is data.json containing an array of 7 items (i.e. countries). Each country has an attribute 'name' and four other attributes. These represent the exposition of private banks and the state to Greek debt for the years 2009 and 2014.</p>
  
  <p>My goal is to create a bar chart that starts by showing the exposition of each country's banks and public sector in 2009 (so two bars for each country) and that changes to the year 2014 once the user clicks on the appropriate button.</p>
  
  <p>I had managed to make it all work nicely! However, I had to create manually separate lists for each (sub-)dataset I needed to use. For example I created one called y2009 which included the exposition of bank and state for country 1, then the same for country 2, an so on..
  (I left one of the list and commented it out on line 43)</p>
  
  <p>I wanted to make my code more flexible so I created a for loop that extracts the data and creates the lists for me. (see lines 46-60). This did not work because the for loops would start before the data was actually loaded. Hence I would end up with empty lists.
  So I grouped the for loops into a function (prepare()) and executed that function within the function that loads the data (lines 18-30). This fixed that issue...</p>
  
  <p>..and created a new one! The two functions that should set the scales (see lines 67-73) do not work because their calculations require on one of the lists created by the for loops (namely 'total').
  (I assume this is due to the list being created after the scale methods are called.)</p>
  
  <p>The curious thing is that if I run the script, then copy in the console the xScale and yScale functions, and then copy the draw function (lines 101-212) everything works.
  Hence I tried to group everything into functions (e.g. setScales, draw) so that I would call them in the order I want at the end of the script (lines 214-215) but this creates problem because certain variables (e.g. xScale and yScale) need to be global.
  I also tried to first create them in the global space and then modify them through setScales. This did not work either.</p>
  
  <p>Summing up, wait I don't understand is:</p>
  
  <ul>
  <li><p>In which order should I write the code to make things work(again)? Is it a good idea to wrap operations within functions (e.g. setting the scales, drawing bars and labels) and then calling the function in the right order?</p></li>
  <li><p>Which type of object is created with the scale method? I am confused on whether they are actual functions.</p></li>
  </ul>
  
  <p>I hope this was not too much of a pain to read and thank everyone who made it through!</p>
  
  <p>Fede</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
  
  &lt;head&gt;
  &lt;script type="text/javascript" src="d3.min.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
  &lt;p&gt;Introductory text here!&lt;/p&gt;
  
  &lt;p&gt;
  &lt;button id="change2009"&gt; 2009 &lt;/button&gt;
  &lt;button id="change2014"&gt; 2014 &lt;/button&gt;
  &lt;/p&gt;
  
  &lt;div id="country"&gt;&lt;/div&gt;
  
  &lt;script type="text/javascript"&gt;
  
  d3.json("data.json", function(error, json) {
      if (error) {
          console.log(error);
      } else{
      console.log(json);
      dataset=json;
      }
  
  prepare (dataset);
  
  });
  
  //load data
  var dataset;
  var bank09=[];
  var state09=[];
  var bank14=[];
  var state14=[];
  var y2009=[];
  var y2014=[];
  var total=[];
  var xScale;
  var yScale;
  //var total = [4.76, 0, 0.12, 6.36, 4.21, 0, 0.04, 7.96, 78.82, 0, 1.81, 46.56, 45, 0, 13.51, 61.74, 6.86, 0, 1.06, 40.87, 12.21, 0, 1.22, 13.06, 1.21, 0, 0.39, 27.35];
  
  
  function prepare (dataset){
      for (i in dataset) {bank09.push(dataset[i].bank09);
      state09.push(dataset[i].state09);
      bank14.push(dataset[i].bank14);
      state14.push(dataset[i].state14);
      y2009.push(dataset[i].bank09);
      y2009.push(dataset[i].state09);
      y2014.push(dataset[i].bank14);
      y2014.push(dataset[i].state14); 
      total.push(dataset[i].bank09);
      total.push(dataset[i].state09);
      total.push(dataset[i].bank14);
      total.push(dataset[i].state14);
      }
  }
  
  //overwrite dataset
  dataset2=y2009;
  
  //scales
  function setScales () {
      var xScale = d3.scale.ordinal()
                .domain(d3.range(total.length/2))
                .rangeRoundBands([0, w], 0.1);
      var yScale = d3.scale.linear()
                .domain([0, d3.max(total)])
                .range([0, h]);
      console.log(yScale(89));
  }
  
  //layout
  var w = 600;
  var h = 600;
  var barPadding = 1;
  
  //coountry names
  var country = ["Austria", "Belgium", "France", "Germany", "Italy", "Holland", "Spain"];
  
  d3.select("#country")
      .data(country)
      .enter()
      .append("rect")
      .attr("class", "country")
      //.append("text")
      //.text(function(d){
      //    return d;
      //  })
  
  
  //draw svg
  var svg = d3.select("body")
              .append("svg")
              .attr("width", w)
              .attr("height", h);
  
  function draw () {
  //draw bars
  svg.selectAll("rect")
    .data(dataset2)
      .enter()
      .append("rect")
      .attr("x", function(d, i) {
          return xScale(i);
      })
      .attr("y", function(d){
          return h - yScale(d);
      })
      .attr("width", xScale.rangeBand)
      .attr("height", function(d) {
      return yScale(d);
      })
      .attr("fill", "black");
  
  
  //add labels
  svg.selectAll("text")
      .data(dataset2)
      .enter()
        .append("text")
        .text(function(d){
                  return d;
              })
        .attr("text-anchor", "middle")
        .attr("font-family", "sans-serif")
        .attr("font-size", "12px")
        .attr("fill", "red")
        .attr("x", function(d, i){
           return xScale(i) + xScale.rangeBand() / 2;
           })
        .attr("y", function(d) {
       if (d&lt;3) {
         return h - 15;
         } else {
           return h - yScale(d) + 15;}
           })
  
  
    //interactivity
    d3.select("#change2014")
      .on("click", function() {
      //update data
      dataset2=y2014;
      //update bars
      svg.selectAll("rect")
         .data(dataset2)
         .transition()
         .duration(3000)
         .attr("y", function(d){
         return h - yScale(d);
         })
         .attr("height", function(d) {
         return yScale(d);
         })        
      //update labels
      svg.selectAll("text")
        .data(dataset2)
        .transition()
        .duration(3000)          
        .text(function(d){
          return d;
        })
        .attr("x", function(d, i){
          return xScale(i) + xScale.rangeBand() / 2;
        })
        .attr("y", function(d) {
          if (d&lt;3) {
            return h - 15;
          } else {
            return h - yScale(d) + 15;}
        })
      })
  
  
    d3.select("#change2009")
      .on("click", function() {
      //update data
      dataset2=y2009;
      //update bars
      svg.selectAll("rect")
         .data(dataset2)
         .transition()
         .duration(3000)           
         .attr("y", function(d){
         return h - yScale(d);
         })
         .attr("height", function(d) {
         return yScale(d);
         })
      //update labels
      svg.selectAll("text")
        .data(dataset2)
        .transition()
        .duration(3000)          
        .text(function(d){
          return d;
        })
        .attr("x", function(d, i){
          return xScale(i) + xScale.rangeBand() / 2;
        })
        .attr("y", function(d) {
          if (d&lt;3) {
            return h - 15;
          } else {
            return h - yScale(d) + 15;}
        })
      })
  }
  
  setScales ();
  draw();
  &lt;/script&gt;
  </code></pre>
  
  <p></p>
  
  <p></p>