5π
I see a couple of issues here.
1) Since you want your X axis to be a time scale, then you should leave your X data value as a moment
object. Your current implementation is creating a moment
object from a date string and then formatting it back to a string. When you do this, chart.js then takes the string and tries to create a moment
object internally when it builds the chart.
Therefore, It is best to keep the data as either a Date
or Moment
object and use the time scale configuration properties to determine how the data is displayed on the chart. This prevents chart.js from having to construct the moment
object and guess at the string format.
2) You are using the pre-2.0 way to create a chart when you use Chart.Scatter
. Instead you should use the new style (new Chart()
) and pass in a type
property.
Here is a modified version of you code that results in no browser warnings and works in Chrome and Firefox (I did not test in Opera).
var getData = function() {
var dummyDataset = [
'2007-11-09T00:00:00.000Z',
'2006-08-04T00:00:00.000Z',
'2006-08-06T00:00:00.000Z',
'2008-01-10T00:00:00.000Z'
];
return dummyDataset.map(function(datum) {
var myMoment = moment(datum);
return {
x: myMoment,
y: parseInt(myMoment.format('YYYY')),
};
});
};
var ctx = document.getElementById("chart1").getContext("2d");
var myScatter = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: "My First dataset",
borderColor: 'rgb(255, 99, 132)',
fill: false,
pointRadius: 4,
pointHoverRadius: 8,
showLine: false,
data: getData()
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Random Data'
},
legend: {
display: true,
labels: {
fontSize: 10,
boxWidth: 20
}
},
elements: {
point: {
pointStyle: 'rect'
}
},
hover: {
mode: 'nearest'
},
scales: {
xAxes: [{
type: 'time',
position: 'bottom',
scaleLabel: {
display: true,
labelString: 'Months'
},
time: {
unit: 'month',
displayFormats: {
month: 'MM'
},
}
}],
yAxes: [ {
type: 'linear',
ticks: {
min: 2005,
max: 2015,
stepSize: 1
},
scaleLabel: {
display: true,
labelString: 'Year'
}
}]
}
}
});
You can see it in action at this forked codepen.
One other thing to keep in mind is that because your data spans multiple years, you will see duplicate months on the X axis. Remember, a time scale is used to plot dates so even if you only display the months, a data point with the same month but with different years will not be plotted at the same location.
If you are actually only wanting to show month string/number values in the X axis, then you should not use the time
scale at all and use the linear
scale instead. Then when you build your data values, you would extract the month from the data (the same way you are already doing for your Y value).
var getData = function() {
var dummyDataset = [
'2007-11-09T00:00:00.000Z',
'2006-08-04T00:00:00.000Z',
'2006-08-06T00:00:00.000Z',
'2008-01-10T00:00:00.000Z'
];
return dummyDataset.map(function(datum) {
var myMoment = moment(datum);
return {
x: parseInt(myMoment.format('MM')),
y: parseInt(myMoment.format('YYYY')),
};
});
};
0π
So in addition to jordanβs answer
I changed my labels and x axis from
['01.01', '02.01', ...] to [1,2,...]
and
from type: 'time' to type: 'linear'
And to make it map not only by month but also by day. I had to make date objects to correct floats. 05.20 to 5.66
const date = datum.key;
const day = parseInt(moment(date).format('DD')) / 30 * 100;
const fullDate = parseFloat(moment(date).format('MM') + '.' + Math.round(day))
// 05.10 would be 5.3 (10 of 30 is 33%)
{
x: fullDate,
y: parseInt(moment(date).format('YYYY'))
date: date, // for tooltip
count: count // for tooltip
}
And i also had to make corrections to my tooltips
callbacks: {
title: function([tooltipItem], data) {
const tooltipInfo = getTooltip(tooltipItem, data.datasets);
return tooltipInfo.date;
},
label: function(tooltipItem, data) {
const tooltipInfo = getTooltip(tooltipItem, data.datasets);
return i18n.t('chart.count') + ': ' + tooltipInfo.count;
},
}
corresponding tooltip dataset
function getTooltip(tooltipItem, datasets) {
return datasets[tooltipItem.datasetIndex].data.find(datum => {
return datum.x === tooltipItem.xLabel && datum.y === tooltipItem.yLabel;
});
}