0

I have this chart setup:

const data = [{
    name: "series1",
    series: [{
            date: "2016-01-31T00:00:00.000Z",
            value: 8
        },
        {
            date: "2016-02-28T00:00:00.000Z",
            value: 10
        },
        {
            date: "2016-03-30T00:00:00.000Z",
            value: 12
        },
        {
            date: "2016-04-31T00:00:00.000Z",
            value: 15
        },
         {
            date: "2016-05-31T00:00:00.000Z",
            value: 14
        },
        {
            date: "2016-06-30T00:00:00.000Z",
            value: 16
        },
        {
            date: "2016-07-31T00:00:00.000Z",
            value: 17
        }
    ]
}, {
    name: "series2",
    series: [{
            date: "2016-01-31T00:00:00.000Z",
            value: 5
        },
        {
            date: "2016-02-28T00:00:00.000Z",
            value: 7
        },
        {
            date: "2016-03-30T00:00:00.000Z",
            value: 10
        },
        {
            date: "2016-04-31T00:00:00.000Z",
            value: 13
        },
         {
            date: "2016-05-31T00:00:00.000Z",
            value: 12
        },
        {
            date: "2016-06-30T00:00:00.000Z",
            value: 14
        },
        {
            date: "2016-07-31T00:00:00.000Z",
            value: 15
        }       
    ]
}];

new Chart(document.getElementById('myChart'), {
    type: 'line',
    data: {
        datasets: [
          {
              label: data[0].name,
              fill: false,
              backgroundColor: 'red',
              borderColor: 'red',
              data: data[0].series.map(x => ({ x: new Date(x.date), y: x.value }))
          }, {
              label: data[1].name,
              fill: false,
              backgroundColor: 'green',
              borderColor: 'green',
              data: data[1].series.map(x => ({ x: new Date(x.date), y: x.value }))
          }
        ]
    },
    options: {
        responsive: true,
        title: {
            display: false
        },
        legend: {
            display: true,
            position: 'top'
        },
        tooltips: { 
            mode: 'index', 
            intersect: true 
        },
        scales: {
            xAxes: [{
                type: 'time',
                time: {
                    unit: 'month',
                    displayFormats: {
                        'month': 'MMM YYYY',
                    },
                    tooltipFormat: 'MMM YYYY'
                }
            }],
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>

The problem is that position of the x-axis labels is not in sync with the line chart data points. Need help.

Sergino
  • 10,128
  • 30
  • 98
  • 159

1 Answers1

0

The problem is that all date values correspond to the last day of a month. I added the function toFirstDayOfMonth in your code sample to further transform the data in order to obtain the expected result.

function toFirstDayOfMonth(dateString) {
  const date = new Date(dateString);
  date.setDate(1);
  return date;
}

Alternatively you could also write this function as follows to only consider the year and month of your date string.

function toFirstDayOfMonth(dateString) {      
  return new Date(dateString.substring(0, 7));
}

Please have a look at the amended code.

const data = [{
    name: "series1",
    series: [{
            date: "2016-01-31T00:00:00.000Z",
            value: 8
        },
        {
            date: "2016-02-28T00:00:00.000Z",
            value: 10
        },
        {
            date: "2016-03-31T00:00:00.000Z",
            value: 12
        },
        {
            date: "2016-04-30T00:00:00.000Z",
            value: 15
        },
         {
            date: "2016-05-31T00:00:00.000Z",
            value: 14
        },
        {
            date: "2016-06-30T00:00:00.000Z",
            value: 16
        },
        {
            date: "2016-07-31T00:00:00.000Z",
            value: 17
        }
    ]
}, {
    name: "series2",
    series: [{
            date: "2016-01-31T00:00:00.000Z",
            value: 5
        },
        {
            date: "2016-02-28T00:00:00.000Z",
            value: 7
        },
        {
            date: "2016-03-31T00:00:00.000Z",
            value: 10
        },
        {
            date: "2016-04-30T00:00:00.000Z",
            value: 13
        },
         {
            date: "2016-05-31T00:00:00.000Z",
            value: 12
        },
        {
            date: "2016-06-30T00:00:00.000Z",
            value: 14
        },
        {
            date: "2016-07-31T00:00:00.000Z",
            value: 15
        }       
    ]
}];

function toFirstDayOfMonth(dateString) {
  const date = new Date(dateString);
  date.setDate(1);
  return date;
}

new Chart(document.getElementById('myChart'), {
    type: 'line',
    data: {
        datasets: [
          {
              label: data[0].name,
              fill: false,
              backgroundColor: 'red',
              borderColor: 'red',
              data: data[0].series.map(x => ({ x: toFirstDayOfMonth(x.date), y: x.value }))
          }, {
              label: data[1].name,
              fill: false,
              backgroundColor: 'green',
              borderColor: 'green',
              data: data[1].series.map(x => ({ x: toFirstDayOfMonth(x.date), y: x.value }))
          }
        ]
    },
    options: {
        responsive: true,
        title: {
            display: false
        },
        legend: {
            display: true
        },
        tooltips: { 
            mode: 'x'
        },
        scales: {
            xAxes: [{
                type: 'time',
                distribution: 'series',
                time: {
                    unit: 'month',
                    tooltipFormat: 'MMM YYYY'
                }
            }]            
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.4.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="90"></canvas>
uminder
  • 23,831
  • 5
  • 37
  • 72
  • any thoughts on this two? https://stackoverflow.com/questions/60132970/how-to-always-display-the-test-x-axis-labels and https://stackoverflow.com/questions/60132952/how-to-disable-chartjs-tooltip-on-mibile-devices-and-small-screens – Sergino Feb 09 '20 at 02:21
  • @sreginogemoh on the time scale, the last day of the month is much closer to the label of the following month than to the one of its own month. – uminder Feb 09 '20 at 08:00