André Gasparin
André Gasparin

Reputation: 21

How to use dates as X axis with Chart.js even when there is no Y axis value related

I would like the chart to always have a value on the final X axis,

I can't use it as "distribution: 'series'" because it goes out of scale,

I can't always guess which value to put as "time: {min / max}" so that it exceeds the last value, and I also can't manually define what data will be displayed on the Y axis.

Is it possible to define data like the following example?

X axis values:

1 - 2020-04-01
2 - 2020-04-03
3 - 2020-04-08
4 - 2020-04-10
5 - 2020-04-15

With Y axis such as:

x   x           x  x       x
|_____________|____________|__
04-01       04-07         04-15

Right now, I defined these three values on the axis 04-01 / 04-07 / 04-15 manually, even if none of the data has 04-07 as date.

enter image description here

Upvotes: 2

Views: 2028

Answers (1)

uminder
uminder

Reputation: 26150

From your code I see that you tried different approaches, including ticks.autoskip and ticks.maxTicksLimit. Both of these option limit the number of tick labels if required but don't guarantee that the last label corresponds to the last data point.

To solve this in a clean way, you have to implement your own ticks.maxTicksLimit on the xAxis. This can be done in the following way.

  1. Generate a labels array out of the times contained in your data. This array should contain the data start and end time and the specified number of equally spread times between both (see function createLabels in your amended code below).
  2. Tell Chart.js to generates ticks on the xAxis from given labels by defining tick.sources: 'labels'.

const data = [
  { t: new Date("2015-3-15 13:30"), y: 12 },
  { t: new Date("2015-3-25 13:20"), y: 21 },
  { t: new Date("2015-3-26 13:20"), y: 21 },
  { t: new Date("2015-3-27 13:20"), y: 21 },
  { t: new Date("2015-5-14 13:20"), y: 21 },
  { t: new Date("2015-7-25 14:12"), y: 32 },
  { t: new Date("2015-08-01 14:12"), y: 40 },
  { t: new Date("2015-08-10 14:12"), y: 40 },
  { t: new Date("2015-08-11 14:12"), y: 40 },
  { t: new Date("2015-09-20 14:12"), y: 40 }
];

function createLabels(maxTicksLimit) {
  const times = data.map(o => o.t.getTime());
  const startTime = times[0];
  const endTime = times[times.length -1];
  const tickGap = ( endTime - startTime) / (maxTicksLimit - 1);
  const labels = [startTime];
  for (let i = 1; i < maxTicksLimit - 1; i++) {
    labels.push(startTime + i * tickGap);
  }
  labels.push(endTime);
  return labels;
}

var myChart = new Chart(document.getElementById("examChart"), {
  type: 'line',
  data: {
    labels: createLabels(12),
    datasets: [{
      label: 'Demo',
      fill: false,
      data: data,
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255,99,132,1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  },
  options: {
    scales: {
      xAxes: [{
        type: 'time',
        ticks: {
          source: 'labels',
          minRotation: 45
        },
        time: {
          unit: 'day',
          displayFormats: {
            day: 'DD/MM/YYYY'
          },
          tooltipFormat: 'DD/MM/YYYY'
        }
      }],
      yAxes: [{
        ticks: {
          suggestedMin: 0
        },
        gridLines: {
          zeroLineColor: "rgba(0,255,0,1)"
        },
        scaleLabel: {
          display: true,
          labelString: 'y axis'
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
<div class="container" style="width:50%;">
  <canvas id="examChart"></canvas>
</div>

Upvotes: 2

Related Questions