Chart.js wrong x axis date time? - chart.js

I have script for chart.js like this:
<script>
var ctx = document.getElementById("chart0");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [2018-03-28,2018-03-29,2018-03-30,2018-03-31,2018-04-01,2018-04-02,2018-04-03,2018-04-04,2018-04-05,2018-04-06,2018-04-07,2018-04-08,2018-04-09,2018-04-10,2018-04-11,2018-04-12,2018-04-13,2018-04-14,2018-04-15,2018-04-16,2018-04-17,2018-04-18,2018-04-19,2018-04-20,2018-04-21,2018-04-22,2018-04-23,2018-04-24,2018-04-25,2018-04-26,2018-04-27],
datasets: [{
label: 'Impressions',
data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
xAxes: [{
ticks: {
min: '2018-03-28',
max: '2018-04-27'
}
}]
}
}
});
</script>
But the display chart showing wrong xasis like this image:
chart display wrong date time
Please help me to fix this. This is the first time I working with chart.js
Thanks in the best!

Modify the dataset like this:
datasets: [{
label: 'Impressions',
data: [
{
x: new Date('2018-03-28'),
y: 0
}, {
x: new Date('2018-03-29'),
y: 0
},
{
x: new Date('2018-03-30'),
y: 0
}
...
And the 'options' should be:
options: {
scales: {
xAxes: [{
type: 'time'
}]
}
}

Related

Displaying min/max range in hours Chart.js

I am having some issues when I am trying to display a min/max range of hours in the x-axis of a bar graph with Chart.js. Now it is showing the whole time range of 24 hours. I want the range to be between 06:00-23:00, but I can only access this if I declare a specific daterange aswell like this:
xAxes: {
ticks: {
},
type: 'time',
time: {
unit: 'hour',
displayFormats: {
hour: 'HH:mm',
},
},
min: '2022-10-21T06:00:00',
max: '2022-10-21T23:00:00',
},
But I want to display the time range, without having to declare a date range, and I thought it would be logic to declare it like this, but it is not:
min: 'YYYY-MM-DDT06:00:00',
max: 'YYYY-MM-DDT23:00:00',
Does anyone have any ideas how to solve this?
How I want it to be displayed
max and min are defined directly on the axis but not inside the time option.
For further information, consult Min Max Configuration from the Chart.js documentation.
Please take a look at below runnable code snippet and see how it works.
new Chart('chart', {
type: 'bar',
data: {
datasets: [{
label: '# of Votes',
data: [
{x: '2022-10-03T07', y: 10},
{x: '2022-10-03T08', y: 15},
{x: '2022-10-03T10', y: 8},
{x: '2022-10-03T12', y: 12},
{x: '2022-10-03T13', y: 13},
{x: '2022-10-03T18', y: 7}
],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
x: {
type: 'time',
time: {
unit: 'hour',
displayFormats: {
hour: 'HH:mm',
},
tooltipFormat: 'd MMM yyyy HH:mm'
},
min: '2022-10-03T06',
max: '2022-10-03T23'
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-adapter-moment/1.0.0/chartjs-adapter-moment.min.js"></script>
<canvas id="chart" height="85"></canvas>

vue3 chart.js Cannot read properties of null (reading 'getContext')

I'm new to Vue3 and Chart.js and I couldn't figure out how to solve this issue. I'm keep getting the same error over and over. Can someone please help me?
TypeError: Cannot read properties of null (reading 'getContext')
Here is my template:
<template>
<div class="border border-dark rounded container m-2">
<canvas id="myChart" width="400" height="400"></canvas>
</div>
</template>
and my script:
import Chart from 'chart.js/auto'
export default {
mounted() {
const ctx = document.getElementById("myChart").getContext('2d');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
console.log('mounted')
}
And I have one more question, when I run this code I get null. Is this normal?
console.log(document.getElementById("myChart"))

how to pause setInterval and resume if there is new data from database?

How to pause setInterval if all data from the database are loaded and resumes if there is new data from the database without manual page refresh? The problem with this if I will not use clearinterval(), it will keep on fetching the data repeatedly and will populate the chart with the same data.
<script>
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [{
label: '# of Votes',
data: [],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
$(document).ready(function(){
var timer = setInterval(function(){
var postt = $.ajax({
type:'GET',
url: "{% url 'post' %}",
success: function(response){
console.log(response.post)
var count = 0;
var total = response.post.length
for(var key in response.post)
{
myChart.data.labels.push(response.post[key].date);
myChart.data.datasets.forEach((dataset) => {
dataset.data.push(response.post[key].number);
myChart.update();
});
count++;
//}
console.log( myChart.data.labels.length)
}
console.log(count)
if(count == total){ // <--- stops the setInterval after all data are loaded.
clearInterval(timer)
}
},
error: function(response){
alert("Error")
}
})
//console.log(postt)
},1000);
});
</script>
The code works if I manually refresh the page but I want it to be in real-time. thanks

ChartJS Create New chart from variable

This seems pretty straightforward but I'm not understanding why it's not rendering the chart correctly. Is there a way to pass the configuration section below to a new chart as a variable? If I load the chart using the coding below it works perfectly. I've tried putting the configuration section into a variable and then placing that within the configuration section, surrounding it by brackets. When I do there's no errors it's just blank like it's not receiving it correctly.
new Chart(myCanvas, {type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}})
you must add document.getElementById("MyChart") inside Chart() object and you will get something like this
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.6.0/dist/chart.min.js"></script>
<canvas id="MyChart" width="400" height="200"></canvas>
<script>
new Chart(document.getElementById("MyChart"), {type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}})
;
</script>

How can I set ChartJS x-axis ticks at specified/fixed intervals?

I have a chart.js line chart where the x axis labels are plain old numbers, e.g. [2,4,15,45,90], which represent days on this chart. I don't want the x-axis ticks to mirror the data labels, i want the ticks to be at interval of 20. How can I achieve this?
This in my options does nothing:
xAxes: [ {
display: true,
position: 'bottom',
ticks: {
stepSize: 20,
min: 0,
max: 140
}
],
example here: jsfiddle
...the only (awful) way i found is to turn the numbers into dates and in the ticks callback, calculate the number of days difference. as seen here
You could use a scatter chart that accepts the data as individual points, objects with properties x and y. To turn a scatter chart back to a line chart, simply define showLine: true on each dataset.
To product data as individual points, you can defined labels outside of the chart and convert both value arrays using Array.map() as follows.
valueArray.map((v, i) => ({ x: labels[i], y: v }))
The last thing to do is defining xAxis.ticks as follows:
ticks: {
stepSize: 1,
autoSkip: false,
callback: value => value % 20 == 0 ? value : null,
min: labels[0],
max: labels[labels.length - 1],
maxRotation: 0
},
Please have a look at your amended code below:
const labels = [7, 14, 21, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 119, 126];
var myChart = new Chart('myChart', {
type: 'scatter',
data: {
datasets: [{
label: 'IC',
data: [9432.13209267, 1899.132847, 851.2122668, 3964.48968367, 9433, 8087.04121533, 1268.34642367, 825.29800317, 4271.00722867, 1157.57453933, 4928.214994, 783.88204033, 1846.623016, 4001.84214867, 709.70201067, 3917.61792167, 688.1571182].map((v, i) => ({ x: labels[i], y: v })),
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
showLine: true,
borderWidth: 1
},
{
label: 'Mtb',
data: [14241.41334667, 48348.08833, 5055.28134533, 7614.80689233, 14240, 24536.66203, 1083.99264, 144.72451603, 15968.94539333, 160.150183, 5127.77524033, 953.9963646, 0, 2989.36556, 21.32920023, 27.03159138, 60310.22952333].map((v, i) => ({ x: labels[i], y: v })),
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
showLine: true,
borderWidth: 1
}
]
},
options: {
scales: {
xAxes: [{
display: true,
position: 'bottom',
ticks: {
stepSize: 1,
autoSkip: false,
callback: value => value % 20 == 0 ? value : null,
min: labels[0],
max: labels[labels.length - 1],
maxRotation: 0
},
// afterBuildTicks: (axis, ticks) => [0, 20, 40, 60, 80, 100, 120],
scaleLabel: {
display: true,
labelString: 'Days from initial test',
fontSize: 16
}
}],
yAxes: [{
display: true,
position: 'left',
ticks: {
beginAtZero: true,
stepSize: 10000,
min: 0,
max: 70000
},
scaleLabel: {
display: true,
fontSize: 16
}
},
{
display: true,
position: 'right',
ticks: {
beginAtZero: true,
stepSize: 10000,
min: 0,
max: 70000
},
scaleLabel: {
display: true,
fontSize: 16
}
},
]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>