51

I'm using nvd3, but I think this is a general d3.js question about time scale and formatting. I've created a simple example that illustrates the problem (see code below):

If I omit .tickFormat for the xAxis, it works fine without date formatting. With the example below I get the error:

Uncaught TypeError: Object 1326000000000 has no method 'getMonth'

nv.addGraph(function() {

    var chart = nv.models.lineChart();

    chart.xAxis
         .axisLabel('Date')
         .rotateLabels(-45)
         .tickFormat(d3.time.format('%b %d')) ;

     chart.yAxis
         .axisLabel('Activity')
         .tickFormat(d3.format('d'));

     d3.select('#chart svg')
         .datum(fakeActivityByDate())
       .transition().duration(500)
         .call(chart);

     nv.utils.windowResize(function() { d3.select('#chart svg').call(chart) });

     return chart;
});

function days(num) {
    return num*60*60*1000*24
}

/**************************************
 * Simple test data generator
 */

function fakeActivityByDate() {
    var lineData = [];
    var y = 0;
    var start_date = new Date() - days(365); // One year ago

    for (var i = 0; i < 100; i++) {
        lineData.push({x: new Date(start_date + days(i)), y: y});
        y = y + Math.floor((Math.random()*10) - 3);
    }

    return [
        {
            values: lineData,
            key: 'Activity',
            color: '#ff7f0e'
        }
    ];
 }

The example (now fixed) is in nvd3 with date axis.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Ultrasaurus
  • 2,450
  • 2
  • 25
  • 43
  • 1
    You should create a [jsFiddle](http://jsfiddle.net/) for your example when asking questions like this. It makes it easier for people answering questions to see your code example working live and easily editable. – seliopou Dec 27 '12 at 20:10
  • This is a good idea. I tried making one, but the css looks like it is not applied: http://jsfiddle.net/ultrasaurus/x7epG/3/ -- anyone know what I did wrong? – Ultrasaurus Dec 27 '12 at 22:24
  • Looks like the fiddle isn't working any longer. The libraries that it references now 404. – Michael Cordingley Oct 28 '15 at 14:39

2 Answers2

63

Try creating a new Date object before the tick for the x-axis gets passed to the formatter:

.tickFormat(function(d) { return d3.time.format('%b %d')(new Date(d)); })

See the documentation for d3.time.format to see how you can customize the formatting string.

seliopou
  • 2,836
  • 18
  • 19
  • Thanks! That works, updated the example here: http://ultrasaurus.github.com/nvd3-simpleline/date_axis.html -- but can you explain *why* it works? and why are the tick marks at week intervals? (fine for my purpose, but would like to understand) – Ultrasaurus Dec 27 '12 at 22:14
  • @Ultrasaurus Glad I could help. If I've answered your question, you should accept my answer to mark the question as answered for others to see. – seliopou Dec 27 '12 at 22:20
  • 2
    Quick comment which helped me: date objects are in milliseconds in Javascript, so I needed to ensure my chart data (being generated by a Python API) was producing x values in milliseconds (since the epoch) for JS/d3 to parse and format my x axis values properly. – Dawngerpony Oct 30 '13 at 12:24
  • 1
    If you're having an issue with the tick marks or chart grid not being lined up with whole date values, check out how to fix it here: https://groups.google.com/d/msg/d3-js/OGsyiNDfywo/EpmvLg5ydY4J – stefan.natchev Nov 15 '13 at 19:31
  • I wanted to use just integers, so I wanted to share my relatively simple addition to this: chart.tickFormat(function(d) { if (d % 1 == 0) { return(d); } }) – Brian Underwood Oct 12 '14 at 09:23
34

Adding on to seliopou's answer, to correctly align the dates with the x-axis, try this:

chart.xAxis
      .tickFormat(function(d) {
          return d3.time.format('%d-%m-%y')(new Date(d))
      });

  chart.xScale(d3.time.scale()); //fixes misalignment of timescale with line graph
rtexal
  • 476
  • 6
  • 8
  • I had to use `d3.time.scale.utc()` as per [this answer](https://groups.google.com/d/msg/d3-js/OGsyiNDfywo/EpmvLg5ydY4J) – Matt Feb 11 '15 at 22:31
  • 4
    I had misalignment problem with timescale as well. This solution fixed my problem. Thank you very much!!! – David Gao Jul 16 '15 at 19:12