score:2

Accepted answer

There are some issues with your dates, which need to be in working order to use a time scale.

Firstly, Your date format is 4/1/2015 but you are parsing it with d3.timeParse("%Y-%m-%d");

You will only get null values parsing with this, to see this try:

data.forEach(function(d) {
    d.date = parseDate(d.date);
    console.log(d.date); // null
});

As you use slashes rather than dashes, and you use month, day, year, try:

d3.timeParse("%m/%d/%Y");

Secondly, and related to dates is that you set an initial domain based on hard coded minimum and maximum dates, that works, but you overwrite it with this:

 x.domain(data.map(function(d){ return d.date }));

A timescale domain takes in a minimum and a maximum for the domain. You are providing an array of every value, instead, use:

x.domain(d3.extent( data, function(d){ return d.date }) );

On to the graph and bar width, .bandwidth() isn't a method of a continuous scale (hence your error: "Uncaught TypeError: x.bandwidth is not a function"). In a continuous scale the bars are placed based on their value, there is no natural bar width (bars are not placed with regular spacing unless the increment between each data value is the same).

As you have a data point for each month (there are no holes in the data), and each data point represents an equal length in time, we can set bar width to be a fraction of the plot area width, where the width of the plot area is split equally between each data point:

(width-margin.right-margin.left)/data.length

Here's your graph with these changes:

enter image description here

And here's a working example.


Lastly, note that you need to return a value here:

.attr("x", function(d) { return console.log(x(d.data.date)); })

Log before the return statement if you want to debug:

.attr("x", function(d) { console.log(x(d.date.date)); return x(d.data.date); })

Related Query