Search code examples
reactjschart.jsreact-chartjsreact-chartjs-2

scattered graph with xAxes of date react-chratjs-2


I'm trying to implement a graph with scattered date properties but chart is rendering all the dates with the same distance from each other.

{
    "ndvi values": [
        0.1158,
        0.1975,
        0.1913,
        0.2137,
        0.1603,
        0.13,
        0.246,
        0.249,
        0.1955,
        0.124,
        0.1854,
        0.2721,
        0.2095,
        0.1357,
        0.2444
    ],
    "Julian dates": [
        2458208.0,
        2458386.0,
        2458476.0,
        2458566.0,
        2458653.0,
        2458746.0,
        2458836.0,
        2458921.0,
        2459026.0,
        2459111.0,
        2458391.0,
        2458476.0,
        2458566.0,
        2458746.0,
        2458836.0
    ]
}

This is the json data that I get from back-end api,the date array is something like this [ 2018/2/12, 2018/218, 2018/5/19, 2019/1/1]. as you see the dates are ordered in the right and ascending way. is there any way making the graph steps more logical according to data that we have?


Solution

  • You should define your x-axis as a time cartesian axis and provide the data as individual points, where each element has a t and an y property (also take a look at this answer). Using Array.map(), this can be done as follows:

    data['Julian dates']
      .map((d, i) => ({ t: julianIntToDate(d), y: data['ndvi values'][i] }))
    

    Note that I use the julianIntToDate function provided by Stephane BOISSEAU in this answer to convert the Julian dates into regular dates.

    Please take a look at the runnable code below and see how it works. While this is plain JavaScript, it should be easy to make it also work with react-chartjs-2.

    const data = {
      'ndvi values': [0.1158, 0.1975, 0.1913, 0.2137, 0.1603, 0.13, 0.246, 0.249, 0.1955, 0.124, 0.1854, 0.2721, 0.2095, 0.1357, 0.2444],
      'Julian dates': [2458208.0, 2458386.0, 2458476.0, 2458566.0, 2458653.0, 2458746.0, 2458836.0, 2458921.0, 2459026.0, 2459111.0, 2458391.0, 2458476.0, 2458566.0, 2458746.0, 2458836.0]
    };
    
    // convert a Julian number to a Gregorian Date (S.Boisseau / BubblingApp.com / 2014)
    function julianIntToDate(n) {   
        var a = n + 32044;
        var b = Math.floor(((4*a) + 3)/146097);
        var c = a - Math.floor((146097*b)/4);
        var d = Math.floor(((4*c) + 3)/1461);
        var e = c - Math.floor((1461 * d)/4);
        var f = Math.floor(((5*e) + 2)/153);
    
        var D = e + 1 - Math.floor(((153*f) + 2)/5);
        var M = f + 3 - 12 - Math.round(f/10);
        var Y = (100*b) + d - 4800 + Math.floor(f/10);
        return new Date(Y,M,D);
    }
    
    new Chart('myChart', {
      type: 'scatter',
      data: {
        datasets: [{
          label: 'ndvi values',
          data: data['Julian dates'].map((d, i) => ({ t: julianIntToDate(d), y: data['ndvi values'][i] })),
          borderColor: 'blue',
        }]
      },
      options: {
        scales: {
          yAxes: [{
            ticks: {
              beginAtZero: true
            }
          }],
          xAxes: [{
            type: 'time',
            time: {
              unit: 'month',
              displayFormats: {
                month: 'YYYY/M'
              },
              tooltipFormat: 'YYYY/M/D'
            }
          }]
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"></script>
    <canvas id="myChart" height="90"></canvas>