Reputation: 1353
I am working with chart.js
and moment.js
to show a chart with x-axis
as time.
I had some problems with plotting this axis and I asked this question.
@uminder solved it. This is his code,
var sData = {
datasets: [{
label: 'Dataset1',
data: [{
x: '09:00',
y: 88
}, {
x: '09:10',
y: 89
}, {
x: '09:13',
y: 86
}, {
x: '09:23',
y: 86
},
{
x: '09:26',
y: 85
}, {
x: '09:29',
y: 83
}
]
}, {
label: 'Dataset2',
data: [{
x: '09:02',
y: 88
}, {
x: '09:13',
y: 89
}, {
x: '09:14',
y: 86
}, {
x: '09:20',
y: 86
},
{
x: '09:24',
y: 85
}, {
x: '09:29',
y: 83
}
]
}]
}
sData.datasets[0].data = formatData(sData.datasets[0].data)
sData.datasets[1].data = formatData(sData.datasets[1].data)
function formatData(oldData) {
var newData = []
for (var i = 0; i < oldData.length; i++) {
var currentData = {}
currentData.x = moment(oldData[i].x, "HH:mm")
currentData.y = oldData[i].y
newData.push(currentData)
}
return newData
}
var options = {
responsive: true,
scales: {
xAxes: [{
type: 'time',
}]
},
tooltips: {
callbacks: {
title: (tooltipItem, data) => moment(tooltipItem[0].label).format('HH:mm')
}
}
}
var ctx = document.getElementById('bateria_graf').getContext('2d');
let chart = new Chart(ctx, {
type: 'line',
data: sData,
options: options
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.1.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="bateria_graf"></canvas>
The problem is that when I execute the snippet, the x-axis
appears like shown in the following image,
When I paste his solution in my program, it appears like the following image,
and when I pass my own datasets
it appears like this,
Why is the format changing evertime? Why is it showing the date of today? I only want hour:minute
in 24H format.
The datatsets
in the third image that I'm passing are like this,
[{
'label': 'Node1',
'borderColor': '#4c59b4',
'data': [{'x': '12:22', 'y': 86}, {'x': '12:32', 'y': 86}, {'x': '12:43', 'y': 85}, {'x': '12:53', 'y': 85}]
}, {
'label': 'Node2',
'borderColor': '#786f91',
'data': [{'x': '09:08', 'y': 86}, {'x': '09:19', 'y': 86}, {'x': '09:29', 'y': 86}, {'x': '09:39', 'y': 86}, {'x': '09:49', 'y': 86}, {'x': '10:00', 'y': 86}, {'x': '10:10', 'y': 86}, {'x': '10:20', 'y': 86}, {'x': '10:30', 'y': 86}, {'x': '10:40', 'y': 86}, {'x': '10:51', 'y': 86}, {'x': '11:01', 'y': 86}, {'x': '11:11', 'y': 86}, {'x': '11:21', 'y': 86}, {'x': '11:31', 'y': 86}, {'x': '11:42', 'y': 86}, {'x': '11:52', 'y': 86}, {'x': '12:02', 'y': 86}, {'x': '12:12', 'y': 86}, {'x': '12:22', 'y': 86}, {'x': '12:32', 'y': 86}, {'x': '12:42', 'y': 86}, {'x': '12:52', 'y': 86}, {'x': '13:03', 'y': 86}, {'x': '13:13', 'y': 86}, {'x': '13:24', 'y': 86}, {'x': '13:34', 'y': 86}, {'x': '13:44', 'y': 86}, {'x': '13:54', 'y': 86}, {'x': '14:04', 'y': 86}, {'x': '14:14', 'y': 86}, {'x': '14:24', 'y': 86}, {'x': '14:35', 'y': 86}, {'x': '14:45', 'y': 86}, {'x': '14:55', 'y': 86}, {'x': '15:05', 'y': 87}, {'x': '15:16', 'y': 87}, {'x': '15:26', 'y': 87}, {'x': '15:46', 'y': 87}, {'x': '16:07', 'y': 87}, {'x': '16:17', 'y': 87}, {'x': '16:27', 'y': 87}]
}]
Upvotes: 0
Views: 144
Reputation: 26150
To force your chart to always display time units in the desired format, you can define the time unit as follows.
xAxes: [{
type: 'time',
time: {
unit: 'minute'
}
}]
Note that the default display format of time unit 'minute'
is 'h:mm a'
(i.e. "11:44 am"). In case, you want to define another format, you may do it using displayFormats
.
xAxes: [{
type: 'time',
time: {
displayFormats: {
minute: 'h:mm'
}
}
}]
This results in the following runnable code snippet:
var sData = {
datasets: [{
'label': 'Node1',
'borderColor': '#4c59b4',
'data': [{'x': '12:22', 'y': 86}, {'x': '12:32', 'y': 86}, {'x': '12:43', 'y': 85}, {'x': '12:53', 'y': 85}]
}, {
'label': 'Node2',
'borderColor': '#786f91',
'data': [{'x': '09:08', 'y': 86}, {'x': '09:19', 'y': 86}, {'x': '09:29', 'y': 86}, {'x': '09:39', 'y': 86}, {'x': '09:49', 'y': 86}, {'x': '10:00', 'y': 86}, {'x': '10:10', 'y': 86}, {'x': '10:20', 'y': 86}, {'x': '10:30', 'y': 86}, {'x': '10:40', 'y': 86}, {'x': '10:51', 'y': 86}, {'x': '11:01', 'y': 86}, {'x': '11:11', 'y': 86}, {'x': '11:21', 'y': 86}, {'x': '11:31', 'y': 86}, {'x': '11:42', 'y': 86}, {'x': '11:52', 'y': 86}, {'x': '12:02', 'y': 86}, {'x': '12:12', 'y': 86}, {'x': '12:22', 'y': 86}, {'x': '12:32', 'y': 86}, {'x': '12:42', 'y': 86}, {'x': '12:52', 'y': 86}, {'x': '13:03', 'y': 86}, {'x': '13:13', 'y': 86}, {'x': '13:24', 'y': 86}, {'x': '13:34', 'y': 86}, {'x': '13:44', 'y': 86}, {'x': '13:54', 'y': 86}, {'x': '14:04', 'y': 86}, {'x': '14:14', 'y': 86}, {'x': '14:24', 'y': 86}, {'x': '14:35', 'y': 86}, {'x': '14:45', 'y': 86}, {'x': '14:55', 'y': 86}, {'x': '15:05', 'y': 87}, {'x': '15:16', 'y': 87}, {'x': '15:26', 'y': 87}, {'x': '15:46', 'y': 87}, {'x': '16:07', 'y': 87}, {'x': '16:17', 'y': 87}, {'x': '16:27', 'y': 87}]
}]
}
sData.datasets[0].data = formatData(sData.datasets[0].data)
sData.datasets[1].data = formatData(sData.datasets[1].data)
function formatData(oldData) {
var newData = []
for (var i = 0; i < oldData.length; i++) {
var currentData = {}
currentData.x = moment(oldData[i].x, "HH:mm")
currentData.y = oldData[i].y
newData.push(currentData)
}
return newData
}
var options = {
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'minute'
}
}]
},
tooltips: {
callbacks: {
title: (tooltipItem, data) => moment(tooltipItem[0].label).format('HH:mm')
}
}
}
var ctx = document.getElementById('bateria_graf').getContext('2d');
let chart = new Chart(ctx, {
type: 'line',
data: sData,
options: options
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="bateria_graf"></canvas>
UPDATE
NEA made the following comment to this answer:
(...) I don't understand is why is printing, before the time the day of today. This is confusing, because my info is not from today (...).
The reason is that in above code, the time is parsed using Moment.js
.
moment(oldData[i].x, "HH:mm")
When the parsed string does not contain information about the date, Moment.js
assumes it to be of the current date. It has to make an assumption because the parsed object is basically a wrapper for Date
. Please run the code snippet below and check the console output.
const m = moment("11:44", "HH:mm");
console.log(m);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Upvotes: 2