3👍
The problem is that the library doesn’t know who to handle the x
values that you are giving, only if you are using a linear axis (numerical data) it will be able to do this correctly without other options.
There are two ways to solve this,
Option 1 – Define a category
axis
Since you know the values that will be on the labels you can set them with the type: 'category'
, so library knows where to put the points correctly like the following example:
var chart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: "Data 1",
data: [{
x: '2018-2',
y: 98
}, {
x: '2018-4',
y: 74
}, {
x: '2018-5',
y: 52
}],
}, {
label: "Data 2",
data: [{
x: '2018-3',
y: 25
}, {
x: '2018-5',
y: 52
}],
}]
},
options: {
scales: {
xAxes: [{
type: 'category',
labels: ['2018-2', '2018-3', '2018-4', '2018-5']
}]
},
tooltips: {
mode: 'x',
callbacks: {
title: function(tooltipItems, data) {
let tI = tooltipItems[0];
return data.datasets[tI.datasetIndex].data[tI.index].x;
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>
Option 2 – Transform the labels into dates
Another possible solution will be to transform the labels from text into Date()
with moment like moment("2018-2")
and then set a min
and max
as ticks
value, and also the display format, with something like:
xAxes: [{
type: 'time',
time: {
displayFormats: {
quarter: 'YYYY-MM'
}
}
}]
This is in overall a more complex solution.
Update – fix, wrong tooltip title
As mention the first solution will lead to when a user hover a point the title of the tooltip will be different from the x
label, that is because that point carries a wrong index
value (this index
is used to return the label position).
In attempting to solve this, and since the Scatter
charts create a similar result with what we are trying to achieve, I have locked up at the controller of this type here, but without luck, because in this situations or the title is ignored or the value is also wrong.
So what I came up with is something like this:
tooltips: {
mode: 'x', // optional
callbacks: {
title: function(tooltipItems, data) {
let tI = tooltipItems[0];
return data.datasets[tI.datasetIndex].data[tI.index].x;
}
}
}
Basically instead of searching the index in the labels array, it will get the original x
data value.