Question

I'm attempting to make a histogram using primarily time and date data, provided in a json file (along with other info) in this format: 2014-03-01 00:18:00. I've looked at http://bl.ocks.org/mbostock/3048450 as an example, but I haven't managed to crack it. The key part seems to be this:

    var data = d3.layout.histogram()
        .bins(x.ticks(20))
        (dataset.timestamp);

When I view my code in the browser it gives "TypeError: data is undefined", and refers to d3.v3.js line 5878.

Assuming I fix that error, the next place it may stumble is the axis formatting:

    var formatDate = d3.time.format("%y-%m-%d %h:%m:%s");

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom")
        .tickFormat(formatDate);

Will the format syntax correspond correctly to my time and date format?

Was it helpful?

Solution 2

So I figured it out, thanks to the helpful answers here. First off, the json data is acquired:

d3.json("inkmarch.json", function(error, json) {
        if (error) return console.warn(error);
        dataset = json; 

Then I specify a formatting variable specific to my date formatting:

var formatDate = d3.time.format("%Y-%m-%d %H:%M:%S");

I map the re-formatted dates to another var:

mappedSet = (dataset.map(function(d) {return formatDate.parse(d.timestamp).getTime()}))

And finally I can make a proper histogram dataset.

var data = d3.layout.histogram()
            .bins(x.ticks(31))
            .value(function(d) {return formatDate.parse(d.timestamp).getTime()})
            (dataset);

(31 ticks since this is monthly data from March). I did away with the d3.time.scale since they were integers anyway, so my scales look like such:

var x = d3.scale.linear()
        .domain([d3.min(mappedSet), d3.max(mappedSet)])
        .range([0, width]);
var y = d3.scale.linear()
        .domain([0, d3.max(data, function(d) { return d.y; })])
        .range([height, 0]);

(Still not sure what the function in the y domain does). The svg and bar vars look exactly like the example I linked in my question post, as do the 'rect' and 'text' bars (except I changed width of rect and x position of the text to fixed values since the example formulas were giving hideous negative values). Thanks again for the help, I'm sure I'll have more d3 questions in the near future.

OTHER TIPS

I don't think that the histogram layout accepts non-numeric input (I could be wrong). One option would be to convert the dates into the number of milliseconds since 1970 by parsing and using getTime():

var formatDate = d3.time.format("%Y-%m-%d %H:%M:%S");

var data = d3.layout.histogram()
    .bins(x.ticks(20))
    .value(function(d) {return formatDate.parse(d.timestamp).getTime()})
    (dataset);

You'll need to make sure that the x scale (as in x.ticks(20)) has a domain based on the millisecond data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top