[Chartjs]-Chart.js time scatter with true scale

1šŸ‘

āœ…

I find an easy solution.
First step is generate an array of labels with all dates included in the range of minimun and maximum value of your x.

const labels = [];
const help = moment(testPoints[0].x);

while (moment(help).isSameOrBefore(moment(testPoints[testPoints.length - 1].x))) {
  labels.push(help.format('YYYY-MM-DD HH:mm:ss'));
  help.add(1, 'day');
}

after that you can add the labels inside config.data like that

const config = {
  type: 'line',
  data: { 
    labels, 
    datasets: [s1]
  },

  options: {
    plugins: {
      ...
    }
  },
  ...
}

here below there is a working example

function generateDateLabelsFromDataset (dataset) {
  const labels = [];
  let max, min = undefined;
  for (const { x } of testPoints) { // I don't know if your dataset is ordered so i get the min and max for generate labels, if your data set is ordered min and max are the first and the last x value of your array
    if (!max || moment(x).isAfter(max)) max = moment(x);
    if (!min || moment(x).isBefore(min)) min = moment(x);
  }

  while (moment(min).isSameOrBefore(max)) {
    labels.push(min.format('YYYY-MM-DD HH:mm:ss'));
    min.add(1, 'day');
  }
  return labels;
}

const testPoints = [
  { x: '2017-01-06 00:00:00', y: '20' },
  { x: '2017-01-07 00:00:00', y: '17' },
  { x: '2017-01-08 00:00:00', y: '14' },
  { x: '2017-01-11 00:00:00', y: '7' },
];

const s1 = {
  label: 'Overall activity',
  borderColor: '#33b5e5',
  data: testPoints
};

const labels = generateDateLabelsFromDataset(testPoints)

const config = {
  type: 'line',
  data: {
    labels,
    datasets: [s1]
  },

  options: {
    plugins: {
      title: {
        display: true,
        text: 'Overall activity plot',
        font: {
          size: 20
        }
      }
    },
    legend: {
      display: false
    },
    scales: {
      xAxes: [{
        type: 'time',
        weight: 0,
        time: {
          unit: 'day'
        }
      }],
    }
  }
};

var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

<canvas id="myChart" width="200" height="200"></canvas>

new try

function generateDateLabelsFromDataset (dataset) {
  const labels = [];
  let max, min = undefined;
  for (const { x } of testPoints) { // I don't know if your dataset is ordered so i get the min and max for generate labels, if your data set is ordered min and max are the first and the last x value of your array
    if (!max || moment(x).isAfter(max)) max = moment(x);
    if (!min || moment(x).isBefore(min)) min = moment(x);
  }

  min.startOf('day'); // you can remove this 2 lines if you don't want the blank space before and after the segment
  max.endOf('day');

  while (moment(min).isSameOrBefore(max)) {
    labels.push(min.format('YYYY-MM-DD HH:mm:ss'));
    min.add(1, 'hour'); // here put your littler unit that you want (hour, minute, second ecc..)
  }
  return labels;
}

const testPoints = [
  { x: '2017-01-06 12:00:00', y: '20' },
  { x: '2017-01-07 00:00:00', y: '17' },
  { x: '2017-01-08 00:00:00', y: '14' },
  { x: '2017-01-11 00:00:00', y: '7' },
];

const s1 = {
  label: 'Overall activity',
  borderColor: '#33b5e5',
  data: testPoints
};

const labels = generateDateLabelsFromDataset(testPoints)

const config = {
  type: 'line',
  data: {
    labels,
    datasets: [s1]
  },

  options: {
    plugins: {
      title: {
        display: true,
        text: 'Overall activity plot',
        font: {
          size: 20
        }
      }
    },
    legend: {
      display: false
    },
    scales: {
      xAxes: [{
        type: 'time',
        weight: 0,
        time: {
          unit: 'day'
        },
        ticks: {
          callback: function(val, index) {
            // Hide the label of every 2nd dataset
            return index % 24 === 0 ? this.getLabelForValue(val) : ''; // is the hours, but if you want use minutes, you must change 24 in 24 * 60 if you want keep just the day like label
          }
        }
        
      }],
    }
  }
};

var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

<canvas id="myChart" width="200" height="200"></canvas>

Leave a comment