Search code examples
javascriptd3.jsrickshaw

Correct date format for Rickshaw


I'm using Rickshaw to build a line chart that will show speeds at different times.

My data looks like:

[{"x":1484124298856,"y":10},{"x":1484124300949,"y":10},{"x":1484124303142,"y":6},{"x":1484124305543,"y":7},{"x":1484124308544,"y":11},{"x":1484124310415,"y":8},{"x":1484124312038,"y":6},{"x":1484124313609,"y":10},{"x":1484124315152,"y":9},{"x":1484124316804,"y":4},{"x":1484124318638,"y":4},{"x":1484124320577,"y":8},{"x":1484124323127,"y":11},{"x":1484124325787,"y":3},{"x":1484124332703,"y":7},{"x":1484124340367,"y":2},{"x":1484124343787,"y":6},{"x":1484124348003,"y":9},{"x":1484124358932,"y":1},{"x":1484124363545,"y":9},{"x":1484124365670,"y":4},{"x":1484124367744,"y":6},{"x":1484124370212,"y":8},{"x":1484124372633,"y":2},{"x":1484124374960,"y":10},{"x":1484124377234,"y":9},{"x":1484124379623,"y":5},{"x":1484124382105,"y":4},{"x":1484124384763,"y":7},{"x":1484124387649,"y":5},{"x":1484124389965,"y":4},{"x":1484124391586,"y":3},{"x":1484124393010,"y":8},{"x":1484124394309,"y":10},{"x":1484124395588,"y":9},{"x":1484124396844,"y":10},{"x":1484124398047,"y":2},{"x":1484124399222,"y":1},{"x":1484124400324,"y":10},{"x":1484124401497,"y":4},{"x":1484124402787,"y":6},{"x":1484124405196,"y":2},{"x":1484124407560,"y":11},{"x":1484124409613,"y":2},{"x":1484124411312,"y":3},{"x":1484124412982,"y":3},{"x":1484124414386,"y":8},{"x":1484124415735,"y":6},{"x":1484124417047,"y":4},{"x":1484124418433,"y":8},{"x":1484124420174,"y":4},{"x":1484124423064,"y":5},{"x":1484124425978,"y":1},{"x":1484124428110,"y":9},{"x":1484124429807,"y":5},{"x":1484124431495,"y":9},{"x":1484124433077,"y":2},{"x":1484124434563,"y":1},{"x":1484124435975,"y":6},{"x":1484124437624,"y":6},{"x":1484124440760,"y":4},{"x":1484124444016,"y":6},{"x":1484124446655,"y":10},{"x":1484124448596,"y":2},{"x":1484124450839,"y":7},{"x":1484124452820,"y":6},{"x":1484124454660,"y":6},{"x":1484124456322,"y":10},{"x":1484124457993,"y":11},{"x":1484124459839,"y":5},{"x":1484124462118,"y":9},{"x":1484124464724,"y":6},{"x":1484124467396,"y":7},{"x":1484124470081,"y":3},{"x":1484124475097,"y":10},{"x":1484124484548,"y":2},{"x":1484124498625,"y":10},{"x":1484124526543,"y":2},{"x":1484124531178,"y":6},{"x":1484124536233,"y":11},{"x":1484124571541,"y":1},{"x":1484124595464,"y":7}]

Where X is the Time (in Unix seconds) and Y is the Speed (in MPH).

My X axis and Y axis is as follows:

var x_ticks = new Rickshaw.Graph.Axis.Time({
  graph: graph,
  orientation: 'bottom',
  timeFixture: new Rickshaw.Fixtures.Time.Local()
  element: document.getElementById('x_axis')
});

var y_ticks = new Rickshaw.Graph.Axis.Y({
  graph: graph,
  orientation: 'left',
  tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
  element: document.getElementById('y_axis')
});

And the main graph:

var graph = new Rickshaw.Graph({
  element: document.getElementById("speedGraph"),
  renderer: 'line',
  width: $('#speedGraph').width(),
  height: $('#speedGraph').height(),
  series: [
    {
      data: data,
      color: "#c05020"
    }
  ]
});
graph.render();

But I see incorrect dates on the X axis. For example the above data is all on the 11th Jan 2016 but at different times. However the labels I see on the graph are as follows:

image

According to the docs Rickshaw expects dates to be in Unix timestamps so should be understanding the data fine.

1. Why are the labels showing the wrong date?

2. How I can show the label on the axis as times? e.g: 9:00, 10:00, 11:00, etc.

This isn't just a formatting issue on the labels. Rickshaw is reading the timestamps wrong!


Solution

  • 1. X (13 digits) isn't a UNIX time-stamp (10 digit). As per your data, X is the total milliseconds from the ZERO-DAY day and time-stamp is the total SECONDS from the ZERO-DAY.
    So it has to be converted into a valid time-stamp.

    data.forEach(function (element) { element.x = Math.floor(element.x / 1000); });
    

    2. You can use a predefined configuration or write your custom. When timeUnit is not specified, the framework detects and sets a suitable unit.

    /* Using a predefined time unit formatting for x-axis ... */
    var xAxisUnit = new Rickshaw.Fixtures.Time().unit('minute');
    
    /* Custom time unit formatting for x-axis ... */
    var xAxisUnit = {
      name: 'custom',
      seconds: 30,
      formatter: function (d) {
        return d.getUTCMinutes() + 'm :' + d.getUTCSeconds() + 's';
      }
    }
    
    new Rickshaw.Graph.Axis.Time({
      graph: graph,
      timeFixture: new Rickshaw.Fixtures.Time.Local(),
      timeUnit: xAxisUnit
    });
    

    I have edited the rickshaw example to match your requirement:

      var data = [{ "x": 1484124298856, "y": 10 }, { "x": 1484124300949, "y": 10 }, { "x": 1484124303142, "y": 6 }, { "x": 1484124305543, "y": 7 }, { "x": 1484124308544, "y": 11 }, { "x": 1484124310415, "y": 8 }, { "x": 1484124312038, "y": 6 }, { "x": 1484124313609, "y": 10 }, { "x": 1484124315152, "y": 9 }, { "x": 1484124316804, "y": 4 }, { "x": 1484124318638, "y": 4 }, { "x": 1484124320577, "y": 8 }, { "x": 1484124323127, "y": 11 }, { "x": 1484124325787, "y": 3 }, { "x": 1484124332703, "y": 7 }, { "x": 1484124340367, "y": 2 }, { "x": 1484124343787, "y": 6 }, { "x": 1484124348003, "y": 9 }, { "x": 1484124358932, "y": 1 }, { "x": 1484124363545, "y": 9 }, { "x": 1484124365670, "y": 4 }, { "x": 1484124367744, "y": 6 }, { "x": 1484124370212, "y": 8 }, { "x": 1484124372633, "y": 2 }, { "x": 1484124374960, "y": 10 }, { "x": 1484124377234, "y": 9 }, { "x": 1484124379623, "y": 5 }, { "x": 1484124382105, "y": 4 }, { "x": 1484124384763, "y": 7 }, { "x": 1484124387649, "y": 5 }, { "x": 1484124389965, "y": 4 }, { "x": 1484124391586, "y": 3 }, { "x": 1484124393010, "y": 8 }, { "x": 1484124394309, "y": 10 }, { "x": 1484124395588, "y": 9 }, { "x": 1484124396844, "y": 10 }, { "x": 1484124398047, "y": 2 }, { "x": 1484124399222, "y": 1 }, { "x": 1484124400324, "y": 10 }, { "x": 1484124401497, "y": 4 }, { "x": 1484124402787, "y": 6 }, { "x": 1484124405196, "y": 2 }, { "x": 1484124407560, "y": 11 }, { "x": 1484124409613, "y": 2 }, { "x": 1484124411312, "y": 3 }, { "x": 1484124412982, "y": 3 }, { "x": 1484124414386, "y": 8 }, { "x": 1484124415735, "y": 6 }, { "x": 1484124417047, "y": 4 }, { "x": 1484124418433, "y": 8 }, { "x": 1484124420174, "y": 4 }, { "x": 1484124423064, "y": 5 }, { "x": 1484124425978, "y": 1 }, { "x": 1484124428110, "y": 9 }, { "x": 1484124429807, "y": 5 }, { "x": 1484124431495, "y": 9 }, { "x": 1484124433077, "y": 2 }, { "x": 1484124434563, "y": 1 }, { "x": 1484124435975, "y": 6 }, { "x": 1484124437624, "y": 6 }, { "x": 1484124440760, "y": 4 }, { "x": 1484124444016, "y": 6 }, { "x": 1484124446655, "y": 10 }, { "x": 1484124448596, "y": 2 }, { "x": 1484124450839, "y": 7 }, { "x": 1484124452820, "y": 6 }, { "x": 1484124454660, "y": 6 }, { "x": 1484124456322, "y": 10 }, { "x": 1484124457993, "y": 11 }, { "x": 1484124459839, "y": 5 }, { "x": 1484124462118, "y": 9 }, { "x": 1484124464724, "y": 6 }, { "x": 1484124467396, "y": 7 }, { "x": 1484124470081, "y": 3 }, { "x": 1484124475097, "y": 10 }, { "x": 1484124484548, "y": 2 }, { "x": 1484124498625, "y": 10 }, { "x": 1484124526543, "y": 2 }, { "x": 1484124531178, "y": 6 }, { "x": 1484124536233, "y": 11 }, { "x": 1484124571541, "y": 1 }, { "x": 1484124595464, "y": 7 }];
    
      /* converting to valid UNIX timestamp ...*/
      data.forEach(function (element) { element.x = Math.floor(element.x / 1000); })
      /* sorting in ASC to get MIN and MAX for Y-axis ... */
      data.sort(function (a, b) { return a.y - b.y; });
      /* creating a scale for Y-Axis with MIN and MAX of Y-Axis values ..*/
      var scale = d3.scale.linear().domain([data[0].y, data[data.length - 1].y]).nice();
     
      /* sorting data by X values in asending order.... */
      data.sort(function (a, b) { return a.x - b.x; });
    
      var graph = new Rickshaw.Graph({
        element: document.getElementById("chart"),
        renderer: 'line',
        series: [{
          color: 'steelblue',
          data: data,
          name: 'Series A',
          scale: scale
        }]
      });
    
      /* Using a predefined time unit formatting for x-axis ... */
      //var xAxisUnit = new Rickshaw.Fixtures.Time().unit('minute');
    
      /* Custom time unit formatting for x-axis ... */
      var xAxisUnit = {
        name: 'custom',
        seconds: 30,
        formatter: function (d) {
          /* formatting via minutes: seconds. NOTE UTC is being used, and those functions are from the default JS Date class .... */
          return d.getUTCMinutes() + 'm :' + d.getUTCSeconds() + 's';
        }
      }
    
      new Rickshaw.Graph.Axis.Time({
        graph: graph,
        timeFixture: new Rickshaw.Fixtures.Time.Local(),
        timeUnit: xAxisUnit
      });
    
      new Rickshaw.Graph.Axis.Y.Scaled({
        element: document.getElementById('axis0'),
        graph: graph,
        scale: scale,
        orientation: 'left',
        tickFormat: Rickshaw.Fixtures.Number.formatKMBT
      });
    
      new Rickshaw.Graph.HoverDetail({
        graph: graph
      });
    
      graph.render();
    #axis0 {
        position: absolute;
        height: 800px;
        width: 40px;
      }
      #axis1 {
        position: absolute;
        left: 1050px;
        height: 800px;
        width: 40px;
      }
      #chart {
        left: 50px;
        width: 1000px;
        position: absolute;
      }
    <link href="http://code.shutterstock.com/rickshaw/src/css/graph.css" rel="stylesheet"/>
    <link href="http://code.shutterstock.com/rickshaw/src/css/detail.css" rel="stylesheet"/>
    <link href="http://code.shutterstock.com/rickshaw/examples/css/lines.css" rel="stylesheet"/>
    
    <script src="http://code.shutterstock.com/rickshaw/vendor/d3.v3.js"></script>
    <script src="http://code.shutterstock.com/rickshaw/rickshaw.js"></script>
    
    <div id="axis0"></div>
    <div id="chart"></div>