简体   繁体   中英

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, 在此处输入图片说明

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. 在此处输入图片说明

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM