Update Chart using ChartJS - VueJS - javascript

so I'm having some problems when trying to update a chart using VueJS and ChartJS. I'm currently running a ajax request (using axios) and trying to draw a chart from the data returned.
The problem is when trying to draw the chart I get the following error: TypeError: Cannot read property 'getContext' of undefined at eval (App.vue?26cd:520). I don't really know why this is happening, I've read some other posts but still can't seem to get it working. This is the code I'm using:
<template>
<button #click="myFunction()">Click Me</button>
<canvas ref="myChart"></canvas>
</template>
-----------------------------------------------------------
methods: {
myFunction () {
var self = this
axios.post('http://localhost/link/to/file.php', {
// Post params here
}).then(response => {
var ctxChart = self.$refs.myChart.getContext('2d')
var myChart = new Chart(ctxChart, {
type: 'pie',
data: {
labels: ['Label 1', 'Label 2', 'Label 3', 'Label 4'],
datasets: [{
label: 'Label here',
data: [response.data['data1'], response.data['data2'], response.data['data3'], response.data['data4']],
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)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)'
],
borderWidth: 1
}]
},
options: {
}
})
}).catch(e => {
console.log(e)
})
}
}
Any help is greatly appreciated! :)

I had similar problem. I solved it by wrapping everything with nextTick
self.$nextTick(() => {
var ctxChart = self.$refs.myChart.getContext('2d')
...
});

Related

Chart Js function (Chart.js) is stuck in a loop

I am trying to use Chart.js in my HTML document(main.html) by calling the the javascript function form a separate javascript file (home.js).
The HTML looks as follows:
{% block head %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<script type="text/javascript" src="/static/js/home.js"></script>
{% endblock %}
{% block body %}
<div>
<canvas id='myChart'></canvas>
</div>
<script>
Chart(data, document.getElementById('myChart'))
</script>
The js file looks as follows:
function Chart(data, ctx){
console.log("JS")
var 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: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
}
When I do that it somehow keeps executing the the function (ie. stuck in a loop, I checked that by using console.log('JS'). I did not figure out why it keeps doing that. The chart is never displayed.
If I add the function directly in the html in a tag it works flawlessly, but I'd rather want the js separate from the html.
I use flask as web framework and that is where the variable 'data' is coming from. Any tips or ideas?
Thanks and regards
PS: I don't use 'data' at the moment because I don't even get the chart running (it will be the result of db query later.
First, two problems unrelated to your infinite loop problem:
In main.html, the data param you are sending to Chart.js is undefined. Presumably you will fix that in your actual code.
In the selector you send to Chart.js, you are sending the canvas – document.getElementById('myChart') – when you should be sending the canvas context – document.getElementById('myChart').getContext('2d')
Once those are fixed, you could potentially be rendering a chart, but you get an infinite loop because you have called your own function Chart when that's also the name of the Chart.js function (where it says var myChart = new Chart(ctx, ...). Just change your function name to something else.
Here's an example where I just put in an empty array for data and changed your function name to drawChart.
function drawChart(data, ctx){
var 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: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
}
drawChart([], document.getElementById('myChart').getContext('2d'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id='myChart'></canvas>
NB: The script error that shows up in the console log is because of cross-origin scripting on StackOverflow and is something you can fix on your own site.

How to pass a state variable into a function in React?

It is widely known that it is possible to declare state variables in react js files and have those state variables appear in the render() function.
However, I am faced with an application in which I have to get the value of certain state variables and pass their values into an object called "data" (see code below) that feeds into a component that makes tables (like bar charts, graphs, etc.). I am attempting to use a GET request from HTTP to get the values of the state variables, which works fine (I hope), but the state variables simply won't go into the data array data: []. I would appreciate some help. Further code is down below.
constructor(props) {
super(props);
this.state = {
teacher_name: '',
confusion: 0,
surprised: 0,
happy: 0,
sad: 0,
}
componentDidMount() {
axios.get('http://localhost:8000/api/school/frames/' + localStorage.getItem('first_name') + '_' + localStorage.getItem('last_name'))
.then(response =>
{
this.setState({teacher_name: response.teacher_name, confusion: response.confusion, surprised: response.surprised, happy: 100, sad: response.sad})
console.log(response)
})
.catch(error => {
console.log(error)
})
}
data = {
labels: ["Happy", "Sad", "Surprised", "Confused"],
datasets: [this.state.happy(), {
label: '# of Votes',
data: [**ATTEMPTING TO PUT STATE VARIABLES HERE**],
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,
fill: false
}]
};
data =[{this.state.yourState}]
or
var myData = this.state.yourState
data = {
labels: ["Happy", "Sad", "Surprised", "Confused"],
datasets: [this.state.happy(), {
label: '# of Votes',
data: [{myData}],
...
}
or
var myData = this.state.yourState
data = {
labels: ["Happy", "Sad", "Surprised", "Confused"],
datasets: [this.state.happy(), {
label: '# of Votes',
data: [myData],
...
}

Getting 'Chart is not defined' error when using chart.js in Meteor

I am using the official chart.js atmosphere package in my meteor application. I've tried running an example chart to see if I can pull it up however I am getting an issue saying "ReferenceError: Chart is not defined"
Here are the steps I took to installing the atmosphere package and running the code to produce the chart.
Installed the package with meteor add chart:chart
In my HTML I added the canvas tag calling the chart with it's informaiton
In the JS I added the function that creates the chart along with its relevant information
When I go to the page however, I just get an empty 400x400 image which is the canvas but there is no content there where the chart is supposed to be. Could someone assist me in figuring out what step I'm missing in order to get the chart to appear?
HTML
<template name="Home_page">
<canvas id="myChart" width="400" height="400"></canvas>
</template>
JS
import './home-page.html';
Template.Home_page.onRendered(function homePageOnRendered() {
var ctx = document.getElementById("myChart").getContext("2d");
var 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: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
});
Ok I forgot to add
import Chart from 'chart.js'
in the top of my js file. That fixed it.

Can't get bar chart colors in Chart js working in React Js

This is my first time working with Chart Js and I managed to get it displaying on my page but the keys 'label', 'backgroundColor', 'borderColor', and 'borderWidth' won't display. The keys 'labels' and 'data' work just fine as I can see the labels and the bars in the chart. I tried assigning the non-displaying keys to variables just like 'labels' and 'data' to see if it would work that way but no luck. I also tried passing hex colors and regular color names like red, blue, etc. but that didn't work either. If anyone could provide some assistance it would be greatly appreciated, thanks!
'use strict';
import React, { Component } from 'react';
var Chart = require("react-chartjs").Bar;
class BarChart extends Component {
capitalize(name) {
return name.charAt(0).toUpperCase() + name.slice(1);
}
render() {
var pokeLabels = this.props.stats.map((label) => {
return this.capitalize(label.stat.name)
})
var pokeDataSet = this.props.stats.map((set) => {
return set.base_stat
})
console.log(this.props.stats);
var data = {
labels: pokeLabels,
datasets: [
{
label: 'Pokemon Stats',
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,
data: pokeDataSet
}
]
}
return (
<div className='row'>
<div className='col-xs-12 col-sm-offset-3 col-xs-offset-0'>
<Chart data={data} width="600" height="250" redraw />
</div>
</div>
);
}
}
export default BarChart;
So I was able to get the colors working by doing this:
datasets: [
{
label: "My First dataset",
fillColor: ["rgba(0,10,220,0.5)","rgba(220,0,10,0.5)","rgba(220,0,0,0.5)","rgba(120,250,120,0.5)" ],
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: pokeDataSet
}
Hope this can help someone who has a similar issue!
The background color will change the color of the bars.
So, you can give different colors to different bar.
datasets: [
{
label: 'My First dataset',
backgroundColor: ['rgba(0,10,220,0.5)', 'rgba(220,0,10,0.5)'],
borderColor: 'rgba(0,0,0,1)',
data: pokeDataSet,
},
],

Chart.js addData is undefined when using SignalR

I'm attempting to call Chart.js's addData method from a signalR callback in order to dynamically add data to a chart based on server inputs. However, when the callback is triggered, the addData method on Chart.js is throwing an exception:
Uncaught TypeError: window.myChart.addData is not a function
Javascript:
var ctx = $("#myChart");
window.myChart = new Chart(ctx, {
type: 'line',
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: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
},
responsive: true
});
$(function () {
var chart = $.connection.chartHub;
chart.client.addPointToChart = function () {
window.myChart.addData([20], "Magenta");
};
$.connection.hub.start().done(function () {
chart.server.start();
});
});
C# (hub code)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace dvvWeb.Hubs
{
public class ChartHub : Hub
{
public void Start()
{
while (true)
{
Clients.All.addPointToChart();
System.Threading.Thread.Sleep(10000);
}
}
}
}
According to the documentation you should change your dataset directly and call update:
.update(duration, lazy) function to update your datas
// duration is the time for the animation of the redraw in miliseconds
// lazy is a boolean. if true, the animation can be interupted by other animations
myLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
myLineChart.update(); // Calling update now animates the position of March from 90 to 50.
I did a little test function on this fiddle:
setInterval(function(e) {
console.log(myDoughnutChart.data.datasets[0]);
myDoughnutChart.data.datasets[0].data.push(15);
myDoughnutChart.update();
}, 1000);
https://jsfiddle.net/Tintin37/weLoqyby/
Opened issue : https://github.com/chartjs/Chart.js/issues/1997
EDIT
For real time chart (I'm using signalr too, I use visjs)
http://visjs.org/examples/graph2d/15_streaming_data.html
Have a great day !

Categories

Resources