Reusable Bar Charts
Here's a sweet ass example of bar charts in a really reusable form.
HTML
<div id="svg_canvas"></div>
CSS
/* Styles go here */
.bar
{
fill : steelblue;
}
.bar-text
{
text-anchor: middle;
}
JavaScript
function BarChart(config)
{
var margins = {top : 20, right : 10, bottom : 10, left : 25};
var xScale, yScale;
function chart(selection)
{
createSVGCanvas(selection)// <---- Works
//selection.call(createSVGCanvas) // <---- Doesn't Work
.call(calculateScales)
.call(dataLayer)
return this;
}
function createSVGCanvas(selection)
{
//This properly returns an svg element, but in the broken version
// the next .call'd function, has a selection of the
// div#svg_canvas.
return selection.append("svg")
.attr("width", config.width)
.attr("height", config.height);
}
function calculateScales(selection)
{
// in the broken version, the selection
// is of the div#svg_canvas NOT the svg.
var data = selection[0][0].__data__;
var xDomain = d3.range(0, data.length);
var yDomain = [d3.max(data) + 1, d3.min(data) - 1];
var xRange = [margins.left, config.width - margins.right];
var yRange = [margins.top, config.height - margins.bottom];
xScale = d3.scale.ordinal().domain(xDomain).rangeRoundBands(xRange, .3, .3);
yScale = d3.scale.linear().domain(yDomain).range(yRange);
return selection;
}
function dataLayer(selection)
{
var barGrouping = selection.append("g").attr("id", "data_layer");
var bars = barGrouping.selectAll("rect")
.data(function(datum){return datum})
.enter()
.append("rect")
.attr("class", "bar")
.attr("id", function(datum, index) { return "bar-" + index;})
.attr("width", xScale.rangeBand())
.attr("height", function(datum){return yScale.range()[1] - yScale(datum);})
.attr("x", function(datum, index){return xScale(index);})
.attr("y", function(datum){return yScale(datum) ;});
return selection;
}
return chart;...