chart.js

Make time series show last date in axis?


So in Chart.js i have a time series based on a range of dates. The chart can't show all the dates as axis label so it shows a reasonable selection. It always shows the first date on the left but not always the last date at the right end of the axis.

For example my date range could be every day from 01-jan to 30-jul. The axis will start at 01-jan but the end date might be 27 28 or 29 jul.

To me the end date is more important than the start date. Is there a way to show the last date reliably and let the start date be the one that varies?


Solution

  • This could be solved by implementing your own ticks.maxTicksLimit on the xAxis. You would have to proceed as follows.

    1. Define the xAxis as a time cartesian axis that accepts the data as an array of data points using objects containing x and y properties each.
    2. Generate a labels array out of the dates contained in your data. This array should contain the starting day and end day together with a number of equally spread days between both (see function createLabels in the code snippet below).
    3. Tell Chart.js to generate ticks on the xAxis from given labels by defining tick.sources: 'labels'.

    const data = [];
    let date = Date.parse('2020-01-01');
    for (let day = 1; day <= 31; day++) {
      date = new Date(date);
      date.setDate(day);
      data.push({
        x: date,
        y: Math.floor((Math.random() * 6) + 1)
      })
    };
    
    const maxTicksLimit = 8;
    function createLabels() {
      const days = data.map(o => o.x);
      const startTime = days[0];
      const endTime = days[days.length - 1];
      const tickGap = data.length / (maxTicksLimit - 1);
      const labels = [startTime];
      for (let i = 1; i < maxTicksLimit - 1; i++) {
        labels.push(days[Math.floor(i * tickGap)]);
      }
      labels.push(endTime);
      return labels;
    }
    
    new Chart('myChart', {
      type: 'line',
      data: {
        labels: createLabels(),
        datasets: [{
          label: 'My Dataset',
          fill: false,
          data: data,
          borderColor: 'blue'
        }]
      },
      options: {
        scales: {
          xAxes: [{
            type: 'time',
            time: {
              unit: 'day'
            },
            ticks: {
              source: 'labels'
            }      
          }],
          yAxes: [{
            ticks: {
              beginAtZero: true
            }
          }]
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
    <canvas id="myChart" height="90"></canvas>