I made a chart using ChartJS that would fetch data from a server being hosted on a microcontroller connected to a few devices streaming data into a CSV every seconds. The chart works fine and shows the correct data except that it doesn't update/animate the graph unless you refreshed the page. I'd like to make it so that the chart pushes and animates the new data without the refreshing.
I've found a couple of answers but none would work for me. I found this video as well
drawChart();
// setup
async function drawChart() {
const datapoints = await getData();
const data = {
labels: datapoints.labels,
datasets: [{
label: 'Solar Voltage',
data: datapoints.solar.voltage,
borderColor: [
'rgba(255, 159, 28, 1)'
],
tension: 0.15,
yAxisID: 'y'
},
{
label: 'Solar Current',
data: datapoints.solar.current,
borderColor: [
'rgba(254, 215, 102, 1)'
],
tension: 0.15,
yAxisID: 'y1'
}
]
};
Chart.defaults.font.family = "Verdana";
// config
const config = {
type: 'line',
data,
options: {
scales: {
y: {
beginAtZero: true,
display: true,
position: 'left',
title: {
display: true,
text: 'voltage'
}
},
y1: {
beginAtZero: true,
display: true,
position: 'right',
grid: {
drawOnChartArea: false
},
title: {
display: true,
text: 'current'
}
}
}
}
};
// render init block
const myChart = new Chart(
document.getElementById('solar-graph'),
config
);
}
async function getData() {
//arrays to store data
const labels = [];
const solar = {
voltage: [],
current: []
};
const battery = {
voltage: []
};
//fetch csv
const url = '/data';
const response = await fetch(url, {
'content-type': 'text/csv;charset=UTF-8'
});
const tabledata = await response.text();
//parse csv
//split by row
const table = tabledata.split('\n').slice(1);
//split by column
table.forEach(row => {
const column = row.split(',');
labels.push(column[1]);
solar.voltage.push(column[2]);
solar.current.push(column[3]);
battery.voltage.push(column[4]);
});
return {
labels,
solar,
battery
};
}
edit: i fixed it
updateChart();
let labels = [];
let solar = {
voltage: [],
current: []
};
let battery = {
voltage: []
};
//push new values every 1.5 seconds
function updateChart() {
setInterval(getData, 1500);
}
async function getData() {
//fetch csv from url
const url = '/data';
fetch(url, {
'content-type': 'text/csv;charset=UTF-8'
})
.then(data => data.text(), error => console.warn("Failed to fetch data"))
.then(tabledata => {
//split by row
const table = tabledata.split('\n').slice(1);
//get last row
const row = table[table.length - 1].split(',');
//display 30 data points on the graph at anytime
if (myChart.data.labels.length > 30) {
myChart.data.labels.shift();
myChart.data.datasets[0].data.shift();
myChart.data.datasets[1].data.shift();
}
//update chart
myChart.data.labels.push(row[1]);
myChart.data.datasets[0].data.push(row[2]);
myChart.data.datasets[1].data.push(row[3]);
//update array
labels.push(row[1]);
solar.voltage.push(row[2]);
solar.current.push(row[3]);
battery.voltage.push(row[4]);
myChart.update();