|  | <!DOCTYPE html> | 
        
          |  | <style> | 
        
          |  |  | 
        
          |  | </style> | 
        
          |  | <svg width="960" height="500"></svg> | 
        
          |  | <script src="https://d3js.org/d3.v3.min.js"></script> | 
        
          |  | <script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script> | 
        
          |  | <script> | 
        
          |  |  | 
        
          |  | var svg = d3.select("svg"), | 
        
          |  | margin = {top: 20, right: 20, bottom: 30, left: 40}, | 
        
          |  | width = +svg.attr("width") - margin.left - margin.right, | 
        
          |  | height = +svg.attr("height") - margin.top - margin.bottom, | 
        
          |  | g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | 
        
          |  | var x0 = d3.scale.ordinal() | 
        
          |  | .rangeRoundBands([0, width], .1); | 
        
          |  | var x1 = d3.scale.ordinal(); | 
        
          |  | var y = d3.scale.linear() | 
        
          |  | .range([height, 0]); | 
        
          |  | var z = d3.scale.ordinal() | 
        
          |  | .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); | 
        
          |  | var xAxis = d3.svg.axis() | 
        
          |  | .scale(x0) | 
        
          |  | .orient("bottom"); | 
        
          |  | var yAxis = d3.svg.axis() | 
        
          |  | .scale(y) | 
        
          |  | .orient("left") | 
        
          |  | .ticks(null, "s") | 
        
          |  | .tickFormat(d3.format(".2s")); | 
        
          |  | d3.csv("data.csv", function(d, i, columns) { | 
        
          |  | d['Population'] = +d['Population']; | 
        
          |  | return d; | 
        
          |  | }, function(error, data) { | 
        
          |  | if (error) throw error; | 
        
          |  | var cf = crossfilter(data); | 
        
          |  | var dimension = cf.dimension(function (d) { return d['State']; }); | 
        
          |  | var group = dimension.group().reduce( | 
        
          |  | function (p, v) { | 
        
          |  | p[v['Category']] = (p[v['Category']] || 0) + v['Population']; | 
        
          |  | return p; | 
        
          |  | }, | 
        
          |  | function (p, v) { | 
        
          |  | p[v['Category']] = (p[v['Category']] || 0) - v['Population']; | 
        
          |  | return p; | 
        
          |  | }, | 
        
          |  | function () { | 
        
          |  | return {}; | 
        
          |  | } | 
        
          |  | ); | 
        
          |  | var groupedData = group.all(); | 
        
          |  | //get all stacks | 
        
          |  | /* | 
        
          |  | var stackSet = new Set(); | 
        
          |  | data.forEach(function (d) { stackSet.add(d['Category']); }); | 
        
          |  | var stacks = []; | 
        
          |  | stackSet.forEach(function (s) { stacks.push(s); }); | 
        
          |  | stacks.sort(); | 
        
          |  | */ | 
        
          |  | var stacks = [ 'Under 5 Years', | 
        
          |  | '5 to 13 Years', | 
        
          |  | '14 to 17 Years', | 
        
          |  | '18 to 24 Years', | 
        
          |  | '25 to 44 Years', | 
        
          |  | '45 to 64 Years', | 
        
          |  | '65 Years and Over' ]; | 
        
          |  |  | 
        
          |  | x0.domain(data.map(function(d) { return d['State']; })); | 
        
          |  | x1.domain(stacks).rangeRoundBands([0, x0.rangeBand()]); | 
        
          |  | y.domain([0, d3.max(data, function(d) { return d['Population']; })]).nice(); | 
        
          |  | g.append("g") | 
        
          |  | .selectAll("g") | 
        
          |  | .data(groupedData) | 
        
          |  | .enter().append("g") | 
        
          |  | .attr("transform", function(d) { return "translate(" + x0(d.key) + ",0)"; }) | 
        
          |  | .selectAll("rect") | 
        
          |  | .data(function(d) { return stacks.map(function(key) { return {key: key, value: d.value[key]}; }); }) | 
        
          |  | .enter().append("rect") | 
        
          |  | .attr("x", function(d) { return x1(d.key); }) | 
        
          |  | .attr("y", function(d) { return y(d.value); }) | 
        
          |  | .attr("width", x1.rangeBand()) | 
        
          |  | .attr("height", function(d) { return height - y(d.value); }) | 
        
          |  | .attr("fill", function(d) { return z(d.key); }); | 
        
          |  | var xAxisGraph = g.append("g") | 
        
          |  | .attr("class", "x axis") | 
        
          |  | .attr("transform", "translate(0," + height + ")") | 
        
          |  | .style({'stroke': '#000', 'fill': 'none','stroke-width': '1px'}) | 
        
          |  | .call(xAxis); | 
        
          |  | xAxisGraph | 
        
          |  | .selectAll("text") | 
        
          |  | .attr("font-size", 10); | 
        
          |  | var yAxisGraph = g.append("g") | 
        
          |  | .attr("class", "y axis") | 
        
          |  | .style({'stroke': '#000', 'fill': 'none','stroke-width': '1px'}) | 
        
          |  | .call(yAxis); | 
        
          |  | yAxisGraph | 
        
          |  | .selectAll("text") | 
        
          |  | .attr("font-size", 10); | 
        
          |  | yAxisGraph | 
        
          |  | .append("text") | 
        
          |  | .attr("x", 2) | 
        
          |  | .attr("y", y(y.ticks().pop()) + 0.5) | 
        
          |  | .attr("dy", "0.32em") | 
        
          |  | .attr("fill", "#000") | 
        
          |  | .attr("font-size", 10) | 
        
          |  | .attr("text-anchor", "start") | 
        
          |  | .text("Population"); | 
        
          |  | var legend = g.append("g") | 
        
          |  | .attr("font-family", "sans-serif") | 
        
          |  | .attr("font-size", 10) | 
        
          |  | .attr("font-weight", "bold") | 
        
          |  | .attr("text-anchor", "end") | 
        
          |  | .selectAll("g") | 
        
          |  | .data(stacks.slice().reverse()) | 
        
          |  | .enter().append("g") | 
        
          |  | .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); | 
        
          |  | legend.append("rect") | 
        
          |  | .attr("x", width - 19) | 
        
          |  | .attr("width", 19) | 
        
          |  | .attr("height", 19) | 
        
          |  | .attr("fill", z); | 
        
          |  | legend.append("text") | 
        
          |  | .attr("x", width - 24) | 
        
          |  | .attr("y", 9.5) | 
        
          |  | .attr("dy", "0.32em") | 
        
          |  | .text(function(d) { return d; }); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | </script> |