Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3.js- How to format tick values as quarters instead of months

Tags:

date

axis

d3.js

I have a set of data in quarters. here is the array:

var dataGDP = [
{date:  "Q1-2008",  GDPreal:    "2.8"},
{date:  "Q2-2008",  GDPreal:    "0.6"},
{date:  "Q3-2008",  GDPreal:    "-2.1"},
{date:  "Q4-2008",  GDPreal:    "-4.3"},
{date:  "Q1-2009",  GDPreal:    "-6.8"},
{date:  "Q2-2009",  GDPreal:    "-6.3"},
{date:  "Q3-2009",  GDPreal:    "-5"}
];

How do I get these dates to show up on my X axis like 1Q 2008, 2Q 2008, 3Q 2008..ect? my X axis uses a time based scale I'm not sure that there is a way to parse these dates as they are now using d3.time.format. I can however parse them if I use months instead like 01/2008, 04/2008... by using: parseDate = d3.time.format("%m/%Y").parse;

Should I write my dates in the array as months and then write a function to convert the months into quarters? or is there a way to keep the Q1..ect in array as it is now and parse the dates?

like image 695
NewToJS Avatar asked Oct 21 '22 19:10

NewToJS


1 Answers

Here's how I solved this for my data.

Note that I took off 10 seconds from the date (x.getTime() - 10000) to account for the data seeing 3/31/2015 as midnight on 4/1/2015, which throws off the calculation. Depending on your data, you may or may not have to do this.

    var xAxis = d3.svg.axis()
            .scale( x )
            .ticks( d3.time.months, 3 )
            .tickFormat( function ( x ) {
                             // get the milliseconds since Epoch for the date
                             var milli = (x.getTime() - 10000);

                             // calculate new date 10 seconds earlier. Could be one second, 
                             // but I like a little buffer for my neuroses
                             var vanilli = new Date(milli);

                             // calculate the month (0-11) based on the new date
                             var mon = vanilli.getMonth();
                             var yr = vanilli.getFullYear();

                             // return appropriate quarter for that month
                             if ( mon <= 2 ) {
                                 return  "Q1 " + yr;
                             } else if ( mon <= 5 ) {
                                 return  "Q2 " + yr;
                             } else if ( mon <= 8 ) {
                                 return  "Q3 " + yr;
                             } else {
                                 return "Q4 " + yr;
                             }
                         } )
            .orient( "bottom" );
like image 179
MaxRocket Avatar answered Oct 28 '22 23:10

MaxRocket