Skip to content

Instantly share code, notes, and snippets.

@danroberts
Forked from mbostock/.block
Last active October 23, 2015 22:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danroberts/cc6f3159f49fed6f6a8d to your computer and use it in GitHub Desktop.
Save danroberts/cc6f3159f49fed6f6a8d to your computer and use it in GitHub Desktop.
Grouped Bar Chart with Crossfilter

This is a fork of mbostock's grouped bar chart example, to demonstrate how to use crossfilter to produce the same result.

This grouped bar chart is constructed from a CSV file storing the populations of different states by age group. The chart employs conventional margins and a number of D3 features:

State Age Range Population
CA Under 5 Years 2704659
CA 5 to 13 Years 4499890
CA 14 to 17 Years 2159981
CA 18 to 24 Years 3853788
CA 25 to 44 Years 10604510
CA 45 to 64 Years 8819342
CA 65 Years and Over 4114496
TX Under 5 Years 2027307
TX 5 to 13 Years 3277946
TX 14 to 17 Years 1420518
TX 18 to 24 Years 2454721
TX 25 to 44 Years 7017731
TX 45 to 64 Years 5656528
TX 65 Years and Over 2472223
NY Under 5 Years 1208495
NY 5 to 13 Years 2141490
NY 14 to 17 Years 1058031
NY 18 to 24 Years 1999120
NY 25 to 44 Years 5355235
NY 45 to 64 Years 5120254
NY 65 Years and Over 2607672
FL Under 5 Years 1140516
FL 5 to 13 Years 1938695
FL 14 to 17 Years 925060
FL 18 to 24 Years 1607297
FL 25 to 44 Years 4782119
FL 45 to 64 Years 4746856
FL 65 Years and Over 3187797
IL Under 5 Years 894368
IL 5 to 13 Years 1558919
IL 14 to 17 Years 725973
IL 18 to 24 Years 1311479
IL 25 to 44 Years 3596343
IL 45 to 64 Years 3239173
IL 65 Years and Over 1575308
PA Under 5 Years 737462
PA 5 to 13 Years 1345341
PA 14 to 17 Years 679201
PA 18 to 24 Years 1203944
PA 25 to 44 Years 3157759
PA 45 to 64 Years 3414001
PA 65 Years and Over 1910571
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = 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")
.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 + ")");
d3.csv("data.csv", function(error, data) {
if (error) throw error;
var ndx = crossfilter(data);
var stateAgeNames = ndx.dimension(function(d) {
return [d["State"], d["Age Range"]];
})
var stateAgeGroup = stateAgeNames.group().reduceSum(function(d) {
return d.Population;
});
var stateAccessor = function(d) {
return d.key[0];
}
var ageNameAccessor = function(d) {
return d.key[1];
}
var populationAccessor = function(d) {
return d.value;
}
var filteredData = stateAgeGroup.all();
console.log('filteredData', filteredData);
var ageNames = d3.set(filteredData.map(ageNameAccessor)).values()
var states = d3.set(filteredData.map(stateAccessor)).values()
var maxPopulation = d3.max(filteredData.map(populationAccessor));
console.log(maxPopulation)
x0.domain(states);
x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, maxPopulation]);
var nestedData = d3.nest()
.key(stateAccessor)
.key(ageNameAccessor)
.rollup(function(d) {
return {"value": populationAccessor(d[0])};
})
.entries(filteredData)
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");
var state = svg.selectAll(".state")
.data(nestedData)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x0(d.key) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.values } )
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { console.log((d.values.value)); return x1( d.key ); })
.attr("y", function(d) { return y(d.values.value); })
.attr("height", function(d) { return height - y(d.values.value); })
.style("fill", function(d) { return color(d.key); });
var legend = svg.selectAll(".legend")
.data(ageNames.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment