I have this piece of JavaScript code to load a Google chart:
<script type="text/javascript">
google.charts.load('current', {'packages':['line']});
setInterval(drawChart, 1000);
function drawChart() {
var jsonData = $.ajax({
url: "getData.php",
dataType:"json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
var options = {
chart: {
title: 'Box Office Earnings in First Two Weeks of Opening',
subtitle: 'in millions of dollars (USD)'
},
width: 900,
height: 500
};
var chart = new google.charts.Line(document.getElementById('chart'));
chart.draw(data, options);
}
</script>
This code loads the data from a Restful endpoint to draw the chart. The thing is that as this is a chart to monitor remote variables it has to continuously refresh itself to fetch and show the most recent data. It works well and the data is fetched and shown correctly, but the chart flickers endlessly, so what can I do to avoid the chart to flick on every data load?
Thanks in advance.
to prevent "flickering", save a reference to the chart,
and draw the same chart with new data
instead of creating a new chart every time
also, be sure to wait on the 'callback' before drawing charts
and highly recommend not using async: false on the $.ajax call
recommend setup as follows...
google.charts.load('current', {
callback: function () {
var chart = null;
var options = {
chart: {
title: 'Box Office Earnings in First Two Weeks of Opening',
subtitle: 'in millions of dollars (USD)'
},
width: 900,
height: 500
};
drawChart();
setInterval(drawChart, 1000);
function drawChart() {
$.ajax({
url: "getData.php",
dataType:"json",
}).done(function (jsonData) {
var data = new google.visualization.DataTable(jsonData);
if (chart==null)
chart = new google.charts.Line(document.getElementById('chart'));
chart.draw(data, options);
}).fail(function (jq, text) {
console.log(text);
});
}
},
packages: ['line']
});
note: also recommend not using a Material chart, several options don't work
otherwise, this would be an ideal scenario to introduce animation
Related
I am trying to create a bar chart with data for years 2009 to 2015 of enrolled students in given majors at universities in Mauritius. I am using the Javascript below and console.log(data) shows that the chart has been rendered. However, it does not display.
var dataPoints = [];
var myChart = document.getElementById('myChart').getContext('2d');
$('#all').click(function(){
$.get("http://api.worldbank.org/v2/countries/mus/indicators/SE.TER.ENRL?date=2009:2015", function(data) {
console.log(data);
$(data).find("wb:data").each(function () {
var $dataPoint = $(this);
var x = $dataPoint.find("wb:date").text;
console.log(x);
var y = $dataPoint.find("wb:value").text();
dataPoints.push({x: parseFloat(x), y: parseFloat(y)});
});
var chart = new CanvasJS.Chart("myChart", {
title: {
text: $(data).find("wb:indicator").text(),
},
data: [{
type: "column",
dataPoints: dataPoints,
}]
});
chart.render();
document.getElementById('myChart').style.display = "block";
});
});
This is the html. The canvas is initially set to display:none.
<canvas id="myChart">
</canvas>
Chart container should be a DOM and not Canvas. Please take a look at CanvasJS Documentation Page for more info. Changing <canvas id="myChart"> </canvas> to <div id="myChart"></div> and passing it to chart while creating it should work fine in your case.
You can also refer tutorial on Rendering Chart from XML Data from docs.
There are two different charting javascripts
chart.js
canvasjs
When someone transit from 1 to 2, this mistake occur.
I had difficulty using chart.js offline
So, I started with canvasjs
causing the mistake.
I have see that using google chart creates much RAM usage.
I must say that i have code somethink with javascript which lets the browser load every 7 seconds a new chart, it does give the Google Draw Chart function new data from a new file and the chart gets drawed, but this seems to create to much RAM usage on my PC. Does somebody know a trick how to avoid this? I think maybe the browser is saving all data from before in a cache or so, if that would not be done then maybe the RAM dont go so high after few minutes? Because now it does go higher and higher with few minutes it reach 100% and the browser stop working.
Here is my current code:
function drawVisualization()
{
//-- From this textfile the chart gets info which is the new symbol chart
var Textinhalt = $.ajax({ url: "Chartsettings.txt", contentType:"application/json", dataType:"json", async: false }).responseText;
var Setting = JSON.parse(Textinhalt);
Symbol=Setting.Selection[0].symbol;
Timeframe=Setting.Selection[0].timeframe;
Broker=Setting.Selection[0].broker;
//--Now the new data is been getting from php response file
var fileurl = "getData.php?symbol="+Symbol+"&timeframe="+Timeframe+"&broker="+Broker;
var jsonData = $.ajax({
url: fileurl,
contentType:"application/json",
dataType:"json",
async: false
}).responseText;
var array=$.parseJSON(jsonData);
//--Now new data have been saved into array and will be draw
var data =google.visualization.arrayToDataTable(array,true);
var options = {
legend: 'none'
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
//--If this function is clicked the google charts get refreshed every 7 seconds and i did see that my browser creates more and more RAM usuage till it goes over 100% and stops working
function PlayCharts()
{
drawVisualization();
setTimeout(PlaySignals, 7000);
}
part of the problem could be that you are creating a new chart every time
instead of drawing the same chart with new data
recommend changing the scope a little,
move the chart variables outside of drawVisualization
but you have to wait until google is loaded until creating
not sure what you're page on load function looks like
also, async: false on $.ajax is deprecated
recommend setup similar to following...
// move declarations outside of drawVisualization
var chart;
var options = {
legend: 'none'
};
// load google charts
google.charts.load('current', {
packages:['corechart']
}).then(function () {
// create chart
chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
// move other on page load functions here
// google.charts.load can be used instead of --> $(document).ready
});
function drawVisualization() {
//-- From this textfile the chart gets info which is the new symbol chart
var Textinhalt = $.ajax({ url: "Chartsettings.txt", contentType:"application/json", dataType:"json", async: false }).responseText;
var Setting = JSON.parse(Textinhalt);
Symbol=Setting.Selection[0].symbol;
Timeframe=Setting.Selection[0].timeframe;
Broker=Setting.Selection[0].broker;
//--Now the new data is been getting from php response file
var fileurl = "getData.php?symbol="+Symbol+"&timeframe="+Timeframe+"&broker="+Broker;
$.ajax({
url: fileurl,
contentType: 'application/json',
dataType: 'json'
}).done(function (jsonData) {
var array = $.parseJSON(jsonData);
//--Now new data have been saved into array and will be draw
var data = google.visualization.arrayToDataTable(array, true);
// draw same chart
chart.draw(data, options);
});
}
function PlayCharts() {
drawVisualization();
setTimeout(PlaySignals, 7000);
}
I have Chart.js set up with a form so that it takes input fields from the form and after clicking Submit/Update button, it generates a donut chart using those numbers from the input fields as data points.
The issue is how can I get the form or Chart.js to run once and generate a donut chart with the input fields numbers when its on the page (on page load).
The form input fields are already filled with numbers/data via HTML5 Local Storage).
I've tried jQuery .submit(); on page load but nothing happens. I appreciate any help. Thank you.
EDIT: I've gone ahead and created a fiddle to re-create the issue.
$(document).ready(function () {
$("#submit-btn").click(function (e) {
e.preventDefault();
var outputyearly = $('#outputyearly');
var amount = parseInt($('#amount').val().replace(/,/g, ''), 10);
var rate = parseFloat($('#rate').val(), 10);
var term = parseFloat($('#term').val(), 10);
// Some math calculations code
if (window.onload.myDoughnutChart != null) {
window.onload.myDoughnutChart.destroy();
}
var ctx = document.getElementById("myChart").getContext("2d");
window.onload.myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: options
});
});
});
You can put the code that draws the chart in a function and call that function on both the $(document).ready and $("#submit-btn").click event, like this:
function drawChart() {
var outputyearly = $('#outputyearly');
var amount = parseInt($('#amount').val().replace(/,/g, ''), 10);
var rate = parseFloat($('#rate').val(), 10);
var term = parseFloat($('#term').val(), 10);
//Destroy the dougnut chart here, not sure how it's accessible, but it won't work through window.onload
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, {
type: 'doughnut',
data: data,
options: options
});
}
$(document).ready(function() {
drawChart();
$("#submit-btn").click(function (e) {
e.preventDefault();
drawChart();
});
});
Note that $(document).ready already imposes the code inside of it to be executed when the page is done, so putting a window.onload inside of it won't make any difference.
I am trying to abstract some of my JavaScript code by adding functions as objects of properties. The ultimate goal is a dynamic way to render data using Google charts. Below is my charts object which right now works when I call it on the page. This is assuming a separate config and util object which have some other methods:
app.charts = {
init: function(){
// Load the Visualization API and the piechart package, wait until loaded
google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(this.createChart);
},
createChart: function(){
// draw charts to their id
chartData = app.utils.getAjax(s.urls.dashUrl, function(data){
// Convert to a table
var jsonDataTable = new google.visualization.DataTable(data);
// Select html element and draw the chart
var chartJson = new google.visualization.BarChart(document.getElementById('json'));
chartJson.draw(jsonDataTable);
this.dataTable();
});
},
dataTable: function(){
console.log("whatever");
}
};
What i would like to do is abstract the var chartJson = new google.visualization.BarChart(document.getElementById('json')); line so that I can give an option and switch to different charts instead of hard coding every chart I want (and thus make it so I can let the user choose chart type.
Whenever I try and write another method, I get a google.visualization is undefined error. I don't see why though because I don't call anything until after the google load callback in init.
To start simple I tried to take have the dataTable: function return a new new google.visualization.DataTable(data); and I received ReferenceError: dataTable is not defined.
I am not sure what is going on that these values can't be found or used, any help appreciated.
I've just just writing some code thinking you meant one thing but I'm not sure it is now reading follow up comments... I'm posting it anyway just FYI:
app.charts = {
init: function(){
// Load the Visualization API and the piechart package, wait until loaded
google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(this.createChart);
},
createChart: function(){
// draw charts to their id
chartData = app.utils.getAjax(s.urls.dashUrl, function(data){
// Convert to a table
var jsonDataTable = new google.visualization.DataTable(data);
// Select html element and draw the chart
var input = document.getElementById('user-input').value;
this.chartType(input);
this.dataTable();
});
},
dataTable: function(){
console.log("whatever");
},
chartType: function(input){
switch(input)
{
case 'whatever':
var chartJson = new google.visualization.BarChart(document.getElementById('json'));
chartJson.draw(jsonDataTable);
break;
case 'whatever2':
// etc
break;
}
}
};
HTML
<select id="user-input">
<option value="whatever">whataver</option>
<option value="whatever2">whataver2</option>
</select>
I'm trying to get multiple chats on the same page, each one using a different spreadsheet url for its data source.
The code below works ok, but I really want to have multiple urls for different data ranges and show a different chart each time.
When I tried this originally, it only ever showed the last chart I tried to draw.
I’ve reworked the script (which still works) to move closer to a situation where I’ve got multiple sets of data for the multiple charts and their locations. It’s not quite there though. This was based on the following post:
How to add two Google charts on the one page?
I think I need to pass the multiple sets of data as attributes of the handleQueryResponse function but I don’t know how to do that.
I was trying to get it to work for just one set of data first, and if that works ok, add multiple sets of data into it.
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
(function() { // Begin scoping function
// vars Global to my code, invisible outside the scoping function
// Set chart options
// I'll be using multiple options for different charts, options1, options2 etc.
var options1 = {'title':'Light & Temperature data - Last 24 Hours',
'width':750,
'height':400,
'curveType': 'function',
'backgroundColor':'ffe599',
"hAxes":[{"title":"Time"}],
"vAxes":[{"title":"Temp in °C -- Light Levels"}]};
//I think I will need containerID1, containerID2 etc. one for each chart
var containerID = 'chart_div1';
//same for chartType1, chartType2
var chartType = 'LINECHART';
// Load the Visualization API and the core chart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the chart, passes in the data and
// draws it.
function drawChart() {
//I'm going to have multiple urls and each one will be the source for a seperate chart
var query1 = new google.visualization.Query(
'https://docs.google.com/spreadsheet/ccc?key=0ArGuv......&transpose=0&headers=1&range=L1%3AN500&gid=1');
query1.send(handleQueryResponse);
}
// how do I get containerID1, containerID2, chartType1, ChartType2 Options1, Options2 etc. into this function?
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var containerDiv = document.getElementById(containerID);
var chart = false;
// Instantiate and draw the chart, based on some the chartType and passing in the options.
if (chartType.toUpperCase() == 'BARCHART') {
chart = new google.visualization.BarChart(containerDiv);
}
else if (chartType.toUpperCase() == 'COLUMNCHART') {
chart = new google.visualization.ColumnChart(containerDiv);
}
else if (chartType.toUpperCase() == 'PIECHART') {
chart = new google.visualization.PieChart(containerDiv);
}
else if (chartType.toUpperCase() == 'LINECHART'){
chart = new google.visualization.LineChart(containerDiv);
}
if (chart == false) {
return false;
}
chart.draw(data, options1);
}
})(); // End scoping function
</script>
<!--Divs that will hold the charts - Only chart_div1 is in effect at the moment -->
<div id="chart_div1"></div>
<div id="chart_div2"></div>
You need two response handlers and two queries if you are querying two different data sources:
function drawChart() {
var query1 = new google.visualization.Query(url1);
query1.send(handleQueryResponse1);
var query2 = new google.visualization.Query(url2);
query2.send(handleQueryResponse2);
}