Chart.js plot live data - javascript

I am receiving live stocks data from a websocket and pushing the data into an array. I want to plot a line graph with live data.
let aaplArr = new Array(); // creating an empty array
let rowData = x.Data[0].RowData[4]; // this the data received from the websocket
aaplArr.push(rowData); // pushing data into array
let graphPoints = (arr) => {
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
data: arr,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
],
borderWidth: 1
}]
},
});
I want to call the graphPoints(aaplArr) function. I'm not getting the data on the graph. How do I get around this?
I have used HTML canvas for the graph and need to keep reloading the graph for every new value in the array.

You are trying to create the chart again everytime which is inneficient and afaik not even possible, if I am correct chart.js throws an error that the canvas is already in use, to achieve what you want you need to create the chart once outside the function, store in in a variable and then in your graphPoints function you call myChart.data.datasets[0].data.push(...arr) after that you can call the update method on chart.js like so: mychart.update() this will make chart.js update and render all the new values.

Related

How to load Json data onto a Charts.js chart

I would like to display the data variable "temp" which is listed by ID under (.list) on the following Json (http://api.openweathermap.org/data/2.5/forecast?lat=53.4808&lon=2.2426&appid=4ce23fd03d1558816c3ef6efb6a5ec30&units=metric) as an x axis variable on this chart:
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'My First dataset',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: [0, 10, 5, 2, 20, 30, 45]
}]
},
// Configuration options go here
options: {}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<canvas id="myChart"></canvas>
The chart currently functions alone without the Json data. How would I import this specified data so that it can replace the "data: [0, 10, 5, 2, 20, 30, 45]" variables?
Assuming your main stumbling block is retrieving the data from the API, all you need are three steps:
Making a network request to the URL you posted, usually done using fetch. This asks the openweathermap website to send you some data.
const response = await fetch('http://api.openweathermap.org/data/2.5/forecast?lat=53.4808&lon=2.2426&appid=4ce23fd03d1558816c3ef6efb6a5ec30&units=metric');
This will give you an object of type Response, which is not what you want since it includes HTTP headers etc. which you have no use for. You want the JSON data sent as part of the response.
Extracting the JSON
const data = await response.json()
Parsing the JSON variable for the temp values
const chartData = data.list.map((object) => object.main.temp)
Explanation: The JSON object returned by the API contains a "list" array that itself contains a "main" attribute, that finally contains the temp you're looking for. "json.list" access the list, the map is taking each object and creating a new array (I believe) containing the "temp" value inside the "main" object.
Lmk if that wasn't clear!

Update chart in Chart js

import Chart from "chart.js"
let AnalyticsChart = {
buildChart() {
let ctx = document.getElementById("analyticsChart");
let labels = ["sent", "delivered", "undelivered", "clicks"];
let total_sent = parseInt(document.getElementById("total-sent").dataset.totalSent);
let delivered = parseInt(document.getElementById("deilvered-count").dataset.deliveredCount);
let undelivered = parseInt(document.getElementById("undelivered-count").dataset.undeliveredCount);
let clicks = parseInt(document.getElementById("total-clicks").dataset.totalClicks);
let counts = [total_sent, delivered, undelivered, clicks]
let chart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: labels,
datasets: [{
data: counts,
backgroundColor: [
'rgba(54, 162, 235, 0.5)',
'rgba(255, 206, 86, 0.5)',
'rgba(255, 99, 132, 0.5)',
'rgba(75, 192, 192, 0.5)'
]
}]
},
options: {
}
});
},
update(){
}
}
export default AnalyticsChart
in this code I want to add update function to update chart.
I want to pass chart variable to update function how can I do this?
like this
update(chart) {
let total_sent = parseInt(document.getElementById("total-sent").dataset.totalSent);
let delivered = parseInt(document.getElementById("deilvered-count").dataset.deliveredCount);
let undelivered = parseInt(document.getElementById("undelivered-count").dataset.undeliveredCount);
let clicks = parseInt(document.getElementById("total-clicks").dataset.totalClicks);
let counts = [total_sent, delivered, undelivered, clicks]
chart.data.datasets.forEach((dataset) => {
dataset.data.push(counts) # How can I put individual counts value?
});
chart.update();
}
My questions
1. How can I pass chart variable in buildChart() to update function as parameter.
2. how can I put individual counts element in dataset.data.push(counts)?
I'm not familiar the way of your implement.
But it seems like java, so you need member variable, and access them using this from each function.
let AnalyticsChart = {
chart: null,
buildChart() {
/** omit **/
this.chart = new Chart(ctx, {
~
update() {
/** omit **/
this.chart.update();
I'm sorry I don't quite understand the question2.
Do you want to push the data, rather than update? If so, you can't do it just prepare the value. (I mean, you need labels, background...)
If you just want to update the chart, that is a piece of cake
this.chart.data.datasets.forEach((dataset) => {
dataset.data = counts;
});
Remember, you have one datasets.
If datasets is not dynamically, I think there's no need to loop.
this.chart.data.datasets[0].data = counts;

Unable to plot JSON to chartJS

I'm trying to plot a dataset into a chartJS line chart:
This is my data:
[{"close":0.00786609},{"close":0.00784},{"close":0.00784},
{"close":0.00780507},{"close":0.007816},{"close":0.00781599},
{"close":0.00780166},{"close":0.00778403},{"close":0.00782001},
{"close":0.0078},{"close":0.00778},{"close":0.007799},
{"close":0.00775057},{"close":0.0077688},{"close":0.00775001}]
This is my code:
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
datasets: [{
label: "My First dataset",
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: <%= JSON.stringify(prices) %>,
}]
},
// Configuration options go here
options: {}
});
How can I fix this?
You have configured your chart to be of type "line". The documentation for this type specifies that a dataset's data can be an Array of Numbers or an Array of Points, where a Point is an Object with a x property and a y property.
Your data is a JSON stringified Array of objects, each with a close property.
You need to map your prices Array into an Array of Numbers. In JavaScript, this could be done as:
prices.map(function (price) {
return price.close;
});
I have created a fiddle as an example.

Chartjs: old data being displayed

I'm currently having a problem which seems to be well known already, but of the answer provided none have worked so far for me.
Whenever I'm hovering over the line in a linegraph, the chart changes back to a chart displayed before as shown in the GIF below:
https://i.stack.imgur.com/cmknf.gif
The solution which seemed the best to me so far is destroying the chart before creating a new one if it's not the first set of data. (bool 'first' and chart 'pauzeAmountChart' are global variables)
function setupAvgPauseGraph(currVideo, currData) {
if (!first) {
pauzeAmountChart.destroy();
}
first = false;
var ctx = document.getElementById("pauzeduurChart");
...
avgPauseChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Gemiddelde pauzeduur / seconde',
data: data,
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [
{ticks: {min: 0, stepSize: step}}],
xAxes: [
{scaleLabel: {display: true, labelString: 'Seconden in video'}}]
},
elements: {point: {radius: 0}}
}
});
}
However, when it's not the first dataset, thus getting to the line 'pauzeAmountChart.destroy()' AND which means the chart already has been initialized and filled with data before, I get this error:
http://prntscr.com/e57x4a
I'm unfortunately not sure what this error means, and Google didn't help me any further either.
Also, when I keep switching between the data the error appears again + 1 more time compared to the previous time the error appeared. Which means it's not actually destroying the graph? (So try #x to show the data gives x errors)
Please let me know if you need any more information.
Thank you in advance!
[EDIT]
Thanks to Guus Punt it's fixed! With a few adjustments, it works now. See below for solution:
function setupPauzeAmountGraph(currVideo, currData) {
var ctx = document.getElementById("aantalPauzesChart");
...
if (pauzeAmountChart != undefined) {
pauzeAmountChart.chart.config.data.labels = labels;
pauzeAmountChart.chart.config.data.datasets[0].data = data;
pauzeAmountChart.update();
} else {
pauzeAmountChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Aantal pauzes / seconde',
data: data,
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [
{ticks: {min: 0, stepSize: step}}],
xAxes: [
{scaleLabel: {display: true, labelString: 'Seconden in video'}}]
},
elements: {point: {radius: 0}}
}
});
}
}
I would need to run your example to be sure but maybe the following would help.
Instead of destroying the chart you can add and remove datasets,
Remove dataset before adding new data
data.labels = []; //Empty label array
data.datasets.splice(0, 1);//Removes first dataset
Add new dataset and labels
Update chart
pauzeAmountChart.update();
I have a working example which retrieves new data from a webapi and updates every 10 seconds, if this isnt sufficient

Chart.Js is keeping old data after AJAX call

I'm using VueJS 2.0, Laravel 5.3 and Chart.JS
I build the page by making AJAX requests with vue.js to Laravel to get the data and it returns a JSON object (some pages make multiple AJAX calls for different data sets). On the page in question the chart is built fine but when the user changes the date the page updates but chart.js still keeps the data from the previous date, which can be seen when rolling the mouse over the old area. Its the same
To better explain this I have a gif video here: http://recordit.co/reNXqjzjtr as you can see, it shows data from the 2017-01-08 which is correct for the date selected but when moving the mouse towards the centre it shows the old data from the default date 2017-01-09.
The function to make the AJAX request to Laravel(PHP):
fetchEvents: function (date = null) {
this.loading = true;
this.$http.get('data/daily/' + this.selectedDate).then(function (response) {
this.data = response.body;
this.selectedDate = this.data.date;
this.drawChart();
this.loading = false;
}, function (error) {
console.log(error);
});
},
This function then calls darwChart():
drawChart: function () {
// code for Pie charts here, mostly the same as below
// Compare against past dates
var ctx3 = document.getElementById("previousDaysPolar");
var data = [this.data.nxt_summary.total_count,
this.data.total_previous_week.data,
this.data.total_previous_month.data,
this.data.total_previous_year.data];
var previousDays = new Chart(ctx3, {
type: 'polarArea',
data: {
labels: ['Selected Date: ' + this.data.date,
'Previous Week: ' + this.data.total_previous_week.date,
'Previous Month: ' + this.data.total_previous_month.date,
'Previous Year: ' + this.data.total_previous_year.date],
datasets: [{
label: 'Order types',
data: data,
backgroundColor: [
'rgba(96, 110, 103, 0.2)',
'rgba(202, 207, 0, 0.2)',
'rgba(191, 180, 143, 0.2)',
'rgba(242, 239, 233, 0.2)'
],
borderColor: [
'rgba(96, 110, 103, 1)',
'rgba(202, 207, 0, 1)',
'rgba(191, 180, 143, 1)',
'rgba(242, 239, 233, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: true
}
});
}
As you can see from the video, this function seems to be working as expecting because it is updating the data and the data is past to the chart. Any ideas why its keeping the old data as well as the new?
I think you need to clear the chart before drawing it with new data. That way new chart is drawn with the updated data only. From chart.js docs:
.clear()
Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
// Will clear the canvas that myLineChart is drawn on
myLineChart.clear();
// => returns 'this' for chainability
See the documentation for prototype methods

Categories