score:3

Accepted answer

The problem is that the graph you are trying to emulate doesn't have a linear x-axis based on time (it's missing days). You'll need to use a linear scale based on the number of data points and then custom set the label values.

I didn't really test this code so there may be bugs. However, this is how I would approach the problem.

// Create a formatter that given an index, will print the day number for the
// data at that index in data
var dayFormatter = d3.time.format('%d');
var dayAxisFormatter = function(d) {
    return dayFormatter(new Date(data[d].timestamp));
}

// Create a formatter that given an index, will print the short month name
// along with the day number for the data at that index in data
var dayWithMonthFormatter = d3.time.format('%b %d');
var dayWithMonthAxisFormatter = function(d) {
   return dayWithMonthFormatter(new Date(data[d].timestamp));
}

// Custom formatter to handle printing just the day number except for the first
// instance of the month, there we will print the short month and the day

// helper to create the formatter function that d3 accepts
function timeFormat(formats) {
  return function(date) {
    var i = formats.length - 1, f = formats[i];
    while (!f[1](date)) f = formats[--i];
    return f[0](date);
  };
}
var firstDone = {}; // track the months so first instance gets month label
var tickFormatter = timeFormat([
    [dayAxisFormatter, function(d) { return true; }],
    [dayWithMonthFormatter, function(d) {
        var month = (new Date(data[d].timestamp)).getMonth();
        var result = !firstDone['m' + month];
        firstDone['m' + month] = true;
        return result;
     }],
]);

// Set up a regular linear scale. This would normally just count up from
// 0 to d.length, but we'll use a custom formatter to print out our day
// numbers instead.
var x = d3.scale.linear()
    .domain([0, d.length]) // set the domain to be from 0 to # of points
    .range([margin,width-margin]);

// Set up the axis to use our customer formatter
var xAxis = d3.svg.axis()
    .scale(x)
    .tickSize(height)
    .tickFormat(tickFormatter);

// Now when you go to draw your data, you need to remember that the
// underlying scale is based on the data index, not the data timestamp.
chart.selectAll("rect")
    .data(data)
    .enter().append("svg:rect")
    .attr("x", function(d, i) { return x(i); })
    ...

Related Query

More Query from same tag