简体   繁体   中英

Use only hour and minutes on x-axis on D3.js

I have a data set that looks like this:

data_set=[{date: '2012,09,04,10,54,53'},
{date: '2012,09,05,10,58,57'},
{date: '2012,09,11,10,44,05'},
{date: '2012,09,04,11,25,30'},
{date: '2012,09,04,10,28,55'},
{date: '2012,09,04,12,30,17'},
{date: '2012,09,04,11,14,23'},
{date: '2012,09,04,12,16,10'},
{date: '2012,09,04,11,57,46'},
{date: '2012,09,04,11,15,53'},
{date: '2012,09,04,11,25,43'},];

I'm trying to make a scatter plot where the x-axis is the time of day, not the full date. How do I get the x-axis to show only a 24 period and how do I get the date points to plot appropriately along the x-axis? Sound I be trying to use d3.time.scale() or should I simply use d3.linear.scale() and work around the problem in formatting? What I'd like to do is have each day of the week be a different point along the y-axis. An example plot is here . In this example, 10=Monday, 20=Tuesday, etc. The different symbols represent the different days of the month for that particular day of the week.

So I've written the following functions to pull the date out of my string and particularly the hours and minutes:

var date_format = d3.time.format("%Y,%m,%d,%H,%M,%S");                                                                                                                               
var time_format = d3.time.format("%X");                                                                                                                                              

Using these functions I've written the following statements:

dd = date_format.parse('2012,01,02,12,39,45')
Mon Jan 02 2012 12:39:45 GMT-0800 (PST)
time_format(dd)
"12:39:45"

So in the console I can see that I've taken a string, converted it to a date and then used that date to generate a time. d3.time.scale() does not seem to accept the time I pass to it when I try to set the domain.

http://i.imgur.com/DRtSW.png "completed plot"

Your dataset is a JSON array [...] , containing objects that are key-value pairs {date: '...'} .

The value in this pairing is a comma-separated string.

You could loop through the array and (for example) pull out the hour and minutes values, building a new dataset:

var new_data = [];
for (var idx = 0; idx < data_set.length; idx++) {
    var datum = data_set[idx];
    var date_value = datum.date;
    var date_elements = date_value.split(",");
    var hour = date_elements[3];
    var minutes = date_elements[4];
    var new_date = {};
    new_date.date = hour + "," + minutes;
    new_data.push(new_date);
};

Then you could pass your d3 code the modified dataset new_data , which only contains hour and minute data.

EDIT

If it is useful, you might want to edit the code above to change the format of a new_date object instance to something that a d3 function can consume. I'm honestly not too familiar with the date/time portion of the API, so some changes may be needed. I'm just trying to show in a generic way what you could do to pre-process your data array, to build an array with the data that you need.

Alex Reynolds: Did you mean

    new_date.date = hour + ":" + minutes;

?

Also you can provide the time scale with a format function that will format the ticks to hour and minute. See https://github.com/mbostock/d3/wiki/Time-Formatting and https://github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickFormat

D3 (or maybe JavaScript in general) doesn't seem to do time of day very well without requiring a date object. My solution is to store time of day as an integer number of minutes since 00:00:00 (or seconds if I want the accuracy). In minutes it's an int between 0 and 1440.

If you need to convert from string time (like "00:00:00") then this may help:

time = (parseInt(d.x.split(':')[0]) * 60)  + parseInt(d.x.split(':')[1]);

If your data is an int already then in your tickformat you can use this:

.tickFormat(function(d) { 
  return Math.floor((d)/60) + ":" + ((d)%60);
});

or

.tickFormat(function(d) { 
  return padZero(Math.floor((d)/60)) + ":" + padZero((d)%60));
});

where padZero is your own function that pads leading zeros so that you don't get "1:30" or "0:0" but "01:30" and "00:00"

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