title: d3.js - How to do data mapping and filter for Stacked Bar graph
body: <p>I am implementing a Stacked Bar graph in d3.js. It is for populations of various categories (category of people) in city over the years . Although I have achieved a bit of outcome with the help of some references but I haven't got the exact result I wanted.</p>
  
  <p>I guess I am facing some problems in data mapping and filter functions, and assigning them in color domain.</p>
  
  <p>Any help would be much appreciated.</p>
  
  <p>Here is my code :-</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  
  &lt;meta charset="utf-8"&gt;
  &lt;style&gt;
  
  body {
  font: 10px sans-serif;
  }
  
  .axis path,
  .axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
  }
  
  .bar {
  fill: steelblue;
  }
  
  .x.axis path {
  display: none;
  }
  
  &lt;/style&gt;
  &lt;body&gt;
  &lt;script src="http://d3js.org/d3.v3.min.js"&gt;
  &lt;/script&gt;
  &lt;script&gt;
  
  
  var margin = {
    top: 20, right: 20, bottom: 30, left: 40}
      ,
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom,
      yAxMin_PA = 0,
  yAxMax_PA = 1500;
  
  var x = d3.scale.ordinal()
      .rangeRoundBands([0, width], .1);
  
  var  y = d3.scale.linear()
     .domain([yAxMin_PA, yAxMax_PA])
     .range([height, 0]);
  
  var color = d3.scale.category20();
  
  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom");
  
  var yAxis = d3.svg.axis()
      .scale(y)
      .orient("left")
      .tickFormat(d3.format(".2s"));
  
  var svg = d3.select("body").append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
  var data = {
    "bars": [
      {
        "year": 2004,
        "population": [
          {
            "category": 1,
            "strength": 31
          }
          ,
          {
            "category": 2,
            "strength": 21
          }
          ,
          {
            "category": 3,
            "strength": 41
          }
        ]
      }
      ,
      {
        "year": 2005,
        "population": [
          {
            "category": 1,
            "strength": 23
          }
          ,
          {
            "category": 2,
            "strength": 43
          }
          ,
          {
            "category": 3,
            "strength": 33
          }
        ]
      }
      ,
      {
        "year": 2006,
        "population": [
          {
            "category": 1,
            "strength": 29
          }
          ,
          {
            "category": 2,
            "strength": 41
          }
          ,
          {
            "category": 3,
            "strength": 55
          }
          ,
          {
            "category": 4,
            "strength": 69
          }
          ,
          {
            "category": 5,
            "strength": 89
          }
          ,
          {
            "category": 6,
            "strength": 75
          }
        ]
      }
      ,
      {
        "year": 2007,
        "population": [
          {
            "category": 1,
            "strength": 49
          }
          ,
          {
            "category": 2,
            "strength": 43
          }
          ,
          {
            "category": 3,
            "strength": 25
          }
        ]
      }
      ,
      {
        "year": 2008,
        "population": [
          {
            "category": 1,
            "strength": 20 
          }
          ,
          {
            "category": 2,
            "strength": 43
          }
          ,
          {
            "category": 3,
            "strength": 55
          }
        ]
      }
    ]
  }
      ;
  
  
  
  x.domain(data.bars.map(function(d) {
    return d.year;
  }
                        ));
  
  svg.append("g")
    .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);
  
  svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
  .append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 6)
  .attr("dy", ".71em")
  .style("text-anchor", "end")
  .text("Population");
  
  for (k = 0; k &lt; data.bars.length; k++) {
  var state = svg.append("g")
      .attr("class", "g")
      .attr("transform", function (d) {
          return "translate(" + x(data.bars[k].year) + ",0)";
      });
  
  state.selectAll("rect")
      .data(data.bars[k].population)
      .enter().append("rect")
  //.attr("width", x.rangeBand())
  .attr("class", "rect_grp" + k)
      .attr("id", function (d, i) {
          return "rect" + i;
      })
      .attr("width", function () {
          return x.rangeBand();
      })
      .attr("y", function (d, i) { /*console.log("hiii");*/
          if (i != 0) {
  
              var prevHgt = d3.select(".rect_grp" + k + "#rect" + (i - 1)).attr("height"); // Select height of previous rectangle
              var ylimit = d3.select(".rect_grp" + k + "#rect" + (i - 1)).attr("y"); // Select y of previous rectangle
              console.log("prevHgt=&gt;" + prevHgt);
  
              return ((parseFloat(ylimit)) - (parseFloat(prevHgt)));
          } else {
              return y(d.strength);
          }
      })
      .attr("height", function (d, i) {
  
          return (Math.round(y(yAxMin_PA)) - Math.round(y(d.strength)));
  
      })
      .style("fill", function (d, i) {
          console.log(i);
          return color(i);
      });
  </code></pre>
  
  <p>}</p>
  
  <pre><code>&lt;/script&gt;
  </code></pre>