Spacemonkey
Spacemonkey

Reputation: 1763

D3.js: Define ordinal axis from JSON data

Working with d3.js I want to represent area charts. I get data from JSON array of objects like this:

[{"time":"00:00 - 00:15","energy":10},
 {"time":"00:15 - 00:30","energy":20},
 {"time":"00:30 - 00:45","energy":30},
 {"time":"00:45 - 01:00","energy":50},
 {"time":"01:00 - 01:15","energy":60},
 {"time":"01:15 - 01:30","energy":70}...]

In order to represent the domain in x Axis (time) I have hardcoded all 96 elements of the domain like this:

x.domain(["00:00 - 00:15","00:15 - 00:30","00:30 - 00:45","00:45 - 01:00",
        "01:00 - 01:15","01:15 - 01:30","01:30 - 01:45","01:45 - 02:00",
        "02:00 - 02:15","02:15 - 02:30","02:30 - 02:45","02:45 - 03:00",
        "03:00 - 03:15","03:15 - 03:30","03:30 - 03:45","03:45 - 04:00",
        "04:00 - 04:15","04:15 - 04:30","04:30 - 04:45","04:45 - 05:00",
        "05:00 - 05:15","05:15 - 05:30","05:30 - 05:45","05:45 - 06:00",
        "06:00 - 06:15","06:15 - 06:30","06:30 - 06:45","06:45 - 07:00",
        "07:00 - 07:15","07:15 - 07:30","07:30 - 07:45","07:45 - 08:00",
        "08:00 - 08:15","08:15 - 08:30","08:30 - 08:45","08:45 - 09:00",
        "09:00 - 09:15","09:15 - 09:30","09:30 - 09:45","09:45 - 10:00",
        "10:00 - 10:15","10:15 - 10:30","10:30 - 10:45","10:45 - 11:00",
        "11:00 - 11:15","11:15 - 11:30","11:30 - 11:45","11:45 - 12:00",
        "12:00 - 12:15","12:15 - 12:30","12:30 - 12:45","12:45 - 13:00",
        "13:00 - 13:15","13:15 - 13:30","13:30 - 13:45","13:45 - 14:00",
        "14:00 - 14:15","14:15 - 14:30","14:30 - 14:45","14:45 - 15:00",
        "15:00 - 15:15","15:15 - 15:30","15:30 - 15:45","15:45 - 16:00",
        "16:00 - 16:15","16:15 - 16:30","16:30 - 16:45","16:45 - 17:00",
        "17:00 - 17:15","17:15 - 17:30","17:30 - 17:45","17:45 - 18:00",
        "18:00 - 18:15","18:15 - 18:30","18:30 - 18:45","18:45 - 19:00",
        "19:00 - 19:15","19:15 - 19:30","19:30 - 19:45","19:45 - 20:00",
        "20:00 - 20:15","20:15 - 20:30","20:30 - 20:45","20:45 - 21:00",
        "21:00 - 21:15","21:15 - 21:30","21:30 - 21:45","21:45 - 22:00",
        "22:00 - 22:15","22:15 - 22:30","22:30 - 22:45","22:45 - 23:00",
        "23:00 - 23:15","23:15 - 23:30","23:30 - 23:45","23:45 - 00:00"]);

This is working, enter image description here

but I wanted to move to something more elegant like using d3.min() and d3.max(). But this is not working. Here is my code.

x.domain([d3.min(json, function(d){return d["time"]}),d3.max(json, function(d){return d["time"]})]);

and the graphic result. enter image description here

I have two questions:

1- It is any way of define my domain in one line? I have checked the time scales but I don't know how to integrate it in my code and if can use it in quarter intervals. If I use scale.ticks(d3.time.minutes, 15) I don't know how to match domain and my JSON data definition.

2- If you see bottom of my first chart, ticks text is overwrited. I would like to represent only hours (1 tick for each 4 quarters). How can I do that?

Thanks in advance.

Upvotes: 2

Views: 2009

Answers (2)

PA.
PA.

Reputation: 29369

If you want to reproduce what you already have hardcoded, you need a discrete domain formed by categories represented by strings, not a continuous domain.

So, you need to generate the array of strings for your domain,

sprintf = require("sprintf").sprintf;

var categories = new Array;
for (var i=0, t1=0, t2=15; i<24*4; i++, t1+=15, t2+=15) {
  categories[i]=sprintf(
    "%02d:%02d - %02d:%02d",
    Math.floor(t1/60),t1%60,Math.floor(t2/60),t2%60
  );
}

and pass that array

x.domain(categories)

An alternative would be to transform the "time" values of your original json data into a real time value, not an string. But that's another SO post.

Upvotes: 0

Lars Kotthoff
Lars Kotthoff

Reputation: 109272

To define the domain as you currently have it, use this code.

 x.domain(json.map(function(d) {return d["time"];} ));

The reason the usual functions for formatting time axes (and indeed min and max) are not working is that your dates are just strings as far as Javascript is concerned. You need to parse them into dates to be able to use the time specific axis stuff. For that you'll need to decide whether to take the start or end point of an interval.

The documentation has more on parsing and formatting dates and times.

Upvotes: 4

Related Questions