Chart.js xaxis formatter changes the value shown in the chart

Viewed 369

I'm creating a simple visualization that shows the evolution of the Temperature in the past 24h. It is shown in the picture.

enter image description here

In the x axis I'm showing the hours and I'm trying to format them so that 10 -> 10:00, and so on.

However, when I include the ticks.callback in the options, the chat shows as follows: it always starts at 0:00 while the correct chat, at this particular time starts at 12.

ticks: {
    callback: function(value, index, ticks) {
        return `${value}:00`;
    }
}

enter image description here

As you can see I've been able to format the y axis, but there is something different with the x axis.

This is the whole configuration of the chart, in case the error is there:

        const labels = this.extractLabels(this.props.data);
        const dataPoints = this.extractData(this.props.data);
        const data = {
            labels: labels,
            datasets: [{
                label: 'Avg. Temperature',
                data: dataPoints,
                fill: false,
                borderColor: 'rgb(75, 192, 192)',
                tension: 0.1
            }]
        };
        const options = {
            scales: {
                y: {
                    beginAtZero: true,
                    grace: '5%',
                    title: {
                        display: true,
                        text: 'Temperature',
                        font: {
                            size: 16
                        }
                    },
                    ticks: {
                        callback: function(value, index, ticks) {
                            return value + ' ºC';
                        }
                    }
                },
                x: {
                    title: {
                        display: true,
                        text: 'Date',
                        font: {
                            size: 16
                        }
                    },
                    ticks: {
                        callback: function(value, index, ticks) {
                            return `${value}:00`;
                        }
                    }
                }
            }
        };
        const config = {
            type: 'line',
            data: data,
            options: options,
        };

        this.temperatureChart = new Chart(this.chartRef.current, config);
2 Answers

As per the tip in the docs:

The category axis, which is the default x-axis for line and bar charts, uses the index as internal data format. For accessing the label, use this.getLabelForValue(value). API: getLabelForValue

so to get the right display value your callback needs to be this:

ticks: {
    callback: function(value, index, ticks) {
        return `${this.getLabelForValue(value)}:00`;
    }
}

You can edit the labels, but in my opinion a better solution would be to implement a Time cartesian axis. This would allow you to add more data without making changes to the labels. You would need to include a time adapter to make it work.

config:

const config = {
  type: 'line',
  data: data,
  options: { 
      scales: {
          xAxis: {
                type: 'time',
                
                ticks: {
                    source: 'labels', // get ticks from given labels
                },

                time: {
                    minUnit: 'minute', // smallest time format

                    displayFormats: {
                        minute: "HH:mm",
                        hour: "dd/MM HH:mm",
                        day: "dd/MM",
                        week: "dd/MM",
                        month: "MMMM yyyy",
                        quarter: 'MMMM yyyy',
                        year: "yyyy",
                    }
                }
            },
        },
    }
};

Here is a fiddle to show you how this would look: JSFiddle

Related