I'm making a bar chart using the Dimensional Charting javascript library dc.js, which is based on d3 and crossfilter.
All I want to do is display a histogram with a specified number of bins, this should be easy using the barChart
function.
I have an array called data
which contains floating-point values between 0 and 90000, and I just want to display the distribution using a histogram with 10 bins.
I use the following code to produce the histogram below:
var cf = crossfilter(data);
var dim = cf.dimension(function(d){ return d[attribute.name]; });
var n_bins = 10;
var xExtent = d3.extent(data, function(d) { return d[attribute.name]; });
var binWidth = (xExtent[1] - xExtent[0]) / n_bins;
grp = dim.group(function(d){return Math.floor(d / binWidth) * binWidth;});
chart = dc.barChart("#" + id_name);
chart.width(200)
.height(180)
.margins({top: 15, right: 10, bottom: 20, left: 40})
.dimension(dim)
.group(grp)
.round(Math.floor)
.centerBar(false)
.x(d3.scale.linear().domain(xExtent).range([0,n_bins]))
.elasticY(true)
.xAxis()
.ticks(4);
That doesn't really look right: each bar is really skinny! I want a normal looking histogram, where the bars are thick and nearly touch each other, with maybe a couple of pixels of padding between each bar. Any idea what I'm doing wrong?
Bar charts in dc.js use the xUnits function to automatically calculate the width of the bars in a histogram based on the range of your x-axis. If you want to set the width to a static value you can use a custom xUnits function for example:
This should give you a more fitting width.
The suggestion given by user2129903 to use the
chart.xUnits()
to specify a customxUnits
function is indeed the way to go. I'd like to add to that an example and a bit of an explanation as to choose the return value of that custom function.The doc says:
That is, assuming you want to make a histogram, you can either directly specify the number of bins or calculate it from your desired bin size and return that from that function. You need to specify this when the numeric keys of your grouping are not successive, equidistant integers.
Here is an example:
Note that in this example it can also work to retrieve the number of bins or the bins' key values from the group object itself, e.g., like this
This will however fail (i.e., produce the wrong bar width), when there are empty bins.
For reference: