I have flask app with
#app.route('/dash_data')
def dash_data():
***
return jsonify({'key' : dashDetails})
which return nice json string
{"key":[["Food",50],["Health",10],["Restaurants",2],["Sports",20],["Taxi",5]]}
My google chart script expects
[
['Food', 50],
['Health', 10],
['Restaurants', 2],
['Sports', 20],
['Taxi', 5]
]
and it has the following way to pass this data to the chart:
var testData = $.get('/dash_data');
var tm = test_data.done(function (resp){ return resp;})
var dataArray = tm.responseJSON.key
var data = google.visualization.arrayToDataTable(dataArray);
However, the console output is
Uncaught (in promise) TypeError: Cannot read property 'key' of undefined at drawChart
Where is my mistake?
The full google-chart js file:
google.charts.load("current", {packages:["corechart"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var test_data = $.get('/dash_data');
var tm = test_data.done(function (resp){return resp;})
var t = tm.responseJSON.key
var data = google.visualization.arrayToDataTable(t);
var options = {
title: 'Expences 12.2020',
pieHole: 0.4,
width: 380,
height: 200
};
var chart = new google.visualization.PieChart(document.getElementById('exp_month_chart'));
chart.draw(data, options);
}
Thank you.
$.get runs asynchronously,
so you need to wait for the done callback before trying to draw the chart...
google.charts.load("current", {
packages: ["corechart"]
}).then(function () {
$.get('/dash_data').done(function (resp) {
var data = google.visualization.arrayToDataTable(resp.key);
var options = {
title: 'Expences 12.2020',
pieHole: 0.4,
width: 380,
height: 200
};
var chart = new google.visualization.PieChart(document.getElementById('exp_month_chart'));
chart.draw(data, options);
});
});
in the post above,
var t = tm.responseJSON.key
runs before
var tm = test_data.done(function (resp){return resp;})
is finished...
Related
I have this 2 googlecharts in my program:
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
var matrix = [];
for(var i=0; i<50; i++) {
matrix[i] = new Array(2);
}
var j=0;
$.getJSON("x.json",function(data){
$.each(data, function(key, val){
matrix[j][0]=(val.y);
matrix[j][1]=(val.z);
j++;
});
});
// Draw the chart and set the chart values
function drawChart() {
var data = google.visualization.arrayToDataTable([
['a', 'b'],
[matrix[0][0], matrix[0][1]],
[matrix[1][0], matrix[1][1]],
[matrix[2][0], matrix[2][1]],
[matrix[3][0], matrix[3][1]],
[matrix[4][0], matrix[4][1]]
]);
// Set chart options
var options = {'title':'h',
'width':900,
'height':400,
is3D: true,
};
// Display the chart inside the <div> element with id="piechart"
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
</script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);
var matrix = [];
for(var i=0; i<50; i++) {
matrix[i] = new Array(2);
}
var j=0;
$.getJSON("x.json",function(data){
$.each(data, function(key, val){
matrix[j][0]=(val.y);
matrix[j][1]=(val.z);
j++;
});
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
["Element", "Density", { role: "style" } ],
[matrix[0][0], matrix[0][1], "red"],
[matrix[1][0], matrix[1][1], "yellow"],
[matrix[2][0], matrix[2][1], "green"],
[matrix[3][0], matrix[3][1], "grey"]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2]);
var options = {
title: "k",
width: 800,
height: 300,
bar: {groupWidth: "95%"},
legend: { position: "none" }
};
var chart = new google.visualization.ColumnChart(document.getElementById("columnchart_values"));
chart.draw(view, options);
<!--options-->
}
</script>
<div id="columnchart_values" style="width: 900px; height: 800px; display: inline-block;"></div>
</div>
I want to change the background color of both.
I've tryed some of the solutions for background color change, like adding the background color to the options, adding a chart area and using the chart.draw(data, google.charts.Bar.convertOptions(options)) method.
But the chart simple disapears.
Any solution for this?
You can change Google Chart Color By write in backgroundColor in your option, for example -by using your code-:
var options = {
'backgroundColor': 'blue',
};
var chart = new
google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
for your first snippet code, you can check this work color in fiddle
I have a google chart. I have enabled the user to drag and zoom by using the option below.
var options = {
explorer:
{
keepInBounds: true,
actions: ['dragToZoom', 'rightClickToReset']
}
I also have the listen below which hides / shows a series when its legend is clicked.
google.visualization.events.addListener(chart, 'select', showHideSeries);
This all works fine. What I am trying to figure out is to know when a user has either zoomed in or right click to reset. Is there an event or way of knowing this?
The reason I want to know is because I want to get the min & max x-axis values and perform a calculation. I can get these values using the function below, which was posted in this post
function getCoords() {
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
return {
x: {
min: chartLayout.getHAxisValue(chartBounds.left),
max: chartLayout.getHAxisValue(chartBounds.width + chartBounds.left)
},
y: {
min: chartLayout.getVAxisValue(chartBounds.top),
max: chartLayout.getVAxisValue(chartBounds.height + chartBounds.top)
}
};
}
Here is j fiddle example my example
Update
Apologise I think I missed off a important part of information. So my ajax function gets the data from a server and then calls a function to draw the chart.
$(document).ready(function () {
// $.ajax(...);});
I have added the additional code in my function that draws the chart. However the chart no longer loads. I get this error message,
Uncaught error: container is not defined.
It happens on the second line of code below.
var chartDiv = document.getElementById('chartScore')
var chart = new google.visualization.AreaChart(document.getElementById(chartDiv));
If I take out the code below the chart does plot.
google.visualization.events.addListener(chart, 'ready', function () {
var zoomLast = getCoords();
var observer = new MutationObserver(function () {
var zoomCurrent = getCoords();
if (JSON.stringify(zoomLast) !== JSON.stringify(zoomCurrent)) {
zoomLast = getCoords();
console.log('zoom event');
}
});
observer.observe(chartDiv, {
childList: true,
subtree: true
});
});
function getCoords() {
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
return {
x: {
min: chartLayout.getHAxisValue(chartBounds.left),
max: chartLayout.getHAxisValue(chartBounds.width + chartBounds.left)
},
y: {
min: chartLayout.getVAxisValue(chartBounds.top),
max: chartLayout.getVAxisValue(chartBounds.height + chartBounds.top)
}
};
}
Its now working
I removed
var chartDiv = document.getElementById('chartScore')
and changed
observer.observe(chartDiv, {
to
observer.observe(document.getElementById('chartScore'), {
you can use a mutation observer to know when the zoom event occurs
the mutation observer will actually let you know when anything on the chart has changed
which means it will fire when a point is hovered or selected, etc...
but you can keep track of the current zoom level and determine when it changes
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
[0, 6],
[1, 7],
[2, 8],
[3, 9],
[4, 5]
], true);
var options = {
pointSize: 4,
explorer: {
keepInBounds: true,
actions: ['dragToZoom', 'rightClickToReset']
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var zoomLast = getCoords();
var observer = new MutationObserver(function () {
var zoomCurrent = getCoords();
if (JSON.stringify(zoomLast) !== JSON.stringify(zoomCurrent)) {
zoomLast = getCoords();
console.log('zoom event');
}
});
observer.observe(container, {
childList: true,
subtree: true
});
});
function getCoords() {
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
return {
x: {
min: chartLayout.getHAxisValue(chartBounds.left),
max: chartLayout.getHAxisValue(chartBounds.width + chartBounds.left)
},
y: {
min: chartLayout.getVAxisValue(chartBounds.top),
max: chartLayout.getVAxisValue(chartBounds.height + chartBounds.top)
}
};
}
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I'm trying to display three Google Chart Gauges on a page to represent data from three temperature sensors. I have a JS function GetCurrentTemperature that returns the three temperature values in an array. I want the gauges to update at regular intervals. I've had this working fine with a single gauge, but when I try and use setInterval for the three charts, they're not updating. The code I'm using is listed below.
function drawTemperatureGauges() {
var currentTemp = GetCurrentTemperature();
var gaugeCount = currentTemp.length;
var options = {
width: 200,
height: 200,
redFrom: 65,
redTo: 80,
yellowFrom: 50,
yellowTo: 65,
minorTicks: 5,
max: 80
};
for(var i=0; i<gaugeCount; i++) {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Temp', currentTemp[i] ]
]);
var divName = 'gauge'.concat(i+1).concat('_div');
var chart = new google.visualization.Gauge(document.getElementById(divName));
chart.draw(data, options);
setInterval(function() {
var cTemp = GetCurrentTemperature();
data.setValue(0, 1, cTemp[i]);
chart.draw(data, options);
}, 2000);
}
}
I assume it's because I'm using i inside the anonymous setInterval function. I've looked at posts related to closures and also ones that specify the use of let rather than var but I still can't work out what syntax I need.
Any pointers greatly appreciated
Bbz
did you try locking in a closure like this?
for(var i=0; i<gaugeCount; i++) {
drawGauge(i);
}
function drawGauge(i) {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Temp', currentTemp[i] ]
]);
var divName = 'gauge'.concat(i+1).concat('_div');
var chart = new google.visualization.Gauge(document.getElementById(divName));
chart.draw(data, options);
setInterval(function() {
var cTemp = GetCurrentTemperature();
data.setValue(0, 1, cTemp[i]);
chart.draw(data, options);
}, 2000);
}
I want to show google chart using data that i acquired from SQL server using javascript. But i got IE error "Unable to get property arrayToDataTable" even i already add google chart JS. I already check the data by alert it, and the data is ok. How to fix this?
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
var array = loadData();
google.load("visualization", "1.1", {packages:["bar"]});
google.setOnLoadCallback(drawChart(array));
function loadData(){
var array = [
['Year', 'Sales', 'Expenses', 'Profit']
];
//Connection
var connection = new ActiveXObject("ADODB.Connection") ;
var connectionstring="Provider=SQLOLEDB.1;Password=Password1234;Persist Security Info=True;User ID=sa;Initial Catalog=all_data;Data Source=172.16.11.90";
connection.Open(connectionstring);
var rs = new ActiveXObject("ADODB.Recordset");
rs.Open("SELECT * FROM bar_chart", connection);
rs.MoveFirst;
while(!rs.eof)
{
array.push([rs.fields(0), parseInt(rs.fields(1)), parseInt(rs.fields(2)), parseInt(rs.fields(3))]);
rs.movenext;
}
rs.close;
connection.close;
return array;
}
function drawChart(x) {
alert(x[4][3]);
var data = google.visualization.arrayToDataTable(x);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017'
},
bars: 'horizontal' // Required for Material Bar Charts.
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(data, options);
}
</script>
And here is my html:
<body>
<div id="barchart_material" style="width: 900px; height: 500px;"></div>
</body>
This error occurs since google.setOnLoadCallback function expects a callback as an argument.
Replace:
var array = loadData();
google.setOnLoadCallback(drawChart(array));
In this case drawChart function is invoked immediately without
waiting google visualization API to load
with:
google.setOnLoadCallback(function () {
var array = loadData();
drawChart(array);
});
Example
google.load("visualization", "1.1", { packages: ["bar"] });
google.setOnLoadCallback(function () {
var data = generateData();
drawChart(data);
});
function generateData() {
var data = [
['Year', 'Sales', 'Expenses', 'Profit']
];
for (var year = 2000; year < 2010; year++) {
data.push([year.toString(), getRandomArbitrary(100, 200), getRandomArbitrary(100, 400), getRandomArbitrary(100, 500)]);
}
return data;
}
function drawChart(data) {
var dataTable = google.visualization.arrayToDataTable(data);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017'
},
bars: 'horizontal' // Required for Material Bar Charts.
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(dataTable, options);
}
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="barchart_material" style="width: 900px; height: 500px;"></div>
This is a followup to a question I've already asked on StackOverflow. So please make sure you read that one to get the whole picture:
Multiple Instances of Google Visualizations Chart Inside Separate Divs
So in an attempt to make this whole thing dynamic, I wrote the following code:
var containers = document.getElementsByClassName('gaugeWrapper');
console.log(containers);
google.load('visualization', '1', { packages: ['gauge'] });
for(var i = 0; i < containers.length; i++) {
var id = containers[i].getAttribute('id');
var name = containers[i].getAttribute('data-name');
var value = containers[i].getAttribute('data-value');
google.setOnLoadCallback(function () { drawChart(id, name, value) });
}
function drawChart(id, name, value) {
console.log(id);
console.log(name);
console.log(value);
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
[name, value]
]);
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom: 75, yellowTo: 90,
minorTicks: 5
};
var chart = new google.visualization.Gauge(document.getElementById(id));
chart.draw(data, options);
}
This does not work. The problem is that the console outputs the data of the last div only. Which means that the function is being called 5 (containers.length) times with the same set of parameters.
UPDATE:
As per Ateszki's answer, here's my updated code:
google.load('visualization', '1', { packages: ['gauge'] });
google.setOnLoadCallback(drawChart);
function drawChart() {
var containers = document.getElementsByClassName('gaugeWrapper');
for (var i = 0; i < containers.length; i++) {
var id = containers[i].getAttribute('id');
var name = containers[i].getAttribute('data-name');
var value = containers[i].getAttribute('data-value');
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
[name, value]
]);
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom: 75, yellowTo: 90,
minorTicks: 5
};
var cont = document.getElementById(id);
console.log(cont);
var chart = new google.visualization.Gauge(cont);
chart.draw(data, options);
}
}
Unfortunately, I still couldn't get it to work, yet. Now nothing renders on the screen, although my console.log's seem to output the right things...
Any explanations/suggestions?
The function that you are binding onload is overwriting the previous one.
Maybe you can store the values in another object and load them all at once in one function.
Ok the following has solved the problem:
google.load('visualization', '1', { packages: ['gauge'] });
google.setOnLoadCallback(drawChart);
function drawChart() {
var containers = $('.gaugeWrapper');
containers.each(function (index, elem) {
var id = $(elem).attr('id');
var name = $(elem).data('name');
var value = $(elem).data('value');
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
[name, value]
]);
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom: 75, yellowTo: 90,
minorTicks: 5
};
var cont = document.getElementById(id);
var chart = new google.visualization.Gauge(cont);
chart.draw(data, options);
});
I do not know how it differs from the code in the updated section of the question except for the fact that I am now using jQuery to grab the values I'm looking for...