Placing Multilple Google Charts on webpage from MYSQL Data - php
I have been able to show a google chart from mysql data, but when I add the second chart I am only able to see the data from the 2nd array(for 2nd chart) I used json_encode on in my php script. If I change the order of the array encoding so that the 2nd chart's array is now encoded first I no longer see it, but now the first chart is visible. Can anyone see the issue? Maybe I should use column charts instead of material charts??
here is my javascript:
<script type="text/javascript">
google.setOnLoadCallback(drawCharts);
function drawCharts() {
drawChartA();
drawChartB();
}
function drawChartB(){
var data = new google.visualization.DataTable(<?=$jsonTable?>);
var options = {
chart: {
title: 'Calls for <?php echo $cLabel;?>',
subtitle: 'Something to put Here',
},
annotations:{
textStyle:{
fontName: 'Times-Roman',
fontSize: 12,
bold: true,
italic: false
}
},
width: 1200,
height: 600,
};
var chart = new
google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
function drawChartA(){
var data = new google.visualization.DataTable(<?=$jsonTable_ct?>);
var options = {
chart: {
title: 'Calls for <?php echo $cLabel;?>',
subtitle: 'Something to put Here',
},
annotations:{
textStyle:{
fontName: 'Times-Roman',
fontSize: 12,
bold: true,
italic: false
}
},
width: 1200,
height: 600,
isStacked: 'true',
};
var chart = new google.charts.Bar(document.getElementById('chart_div_ct'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
</script>
my json_encoded files are:
{"cols":[{"label":"Time Interval","type":"string"},{"label":"Calls - All Offices","type":"number"}],"rows":[{"c":[{"v":"05:00"},{"v":1}]},{"c":[{"v":"06:00"},{"v":3}]},{"c":[{"v":"07:00"},{"v":9}]},{"c":[{"v":"07:30"},{"v":22}]},{"c":[{"v":"08:00"},{"v":82}]},{"c":[{"v":"08:30"},{"v":68}]},{"c":[{"v":"09:00"},{"v":97}]},{"c":[{"v":"09:30"},{"v":48}]},{"c":[{"v":"10:00"},{"v":56}]},{"c":[{"v":"10:30"},{"v":70}]},{"c":[{"v":"11:00"},{"v":75}]},{"c":[{"v":"11:30"},{"v":53}]},{"c":[{"v":"12:00"},{"v":56}]},{"c":[{"v":"12:30"},{"v":48}]},{"c":[{"v":"13:00"},{"v":22}]},{"c":[{"v":"13:30"},{"v":42}]},{"c":[{"v":"14:00"},{"v":40}]},{"c":[{"v":"14:30"},{"v":60}]},{"c":[{"v":"15:00"},{"v":69}]},{"c":[{"v":"15:30"},{"v":65}]},{"c":[{"v":"16:00"},{"v":73}]},{"c":[{"v":"16:30"},{"v":37}]},{"c":[{"v":"17:00"},{"v":20}]},{"c":[{"v":"17:30"},{"v":10}]},{"c":[{"v":"18:00"},{"v":10}]},{"c":[{"v":"18:30"},{"v":2}]},{"c":[{"v":"19:00"},{"v":1}]},{"c":[{"v":"19:30"},{"v":2}]},{"c":[{"v":"20:00"},{"v":1}]},{"c":[{"v":"20:30"},{"v":1}]}]}
and the other is here: (they both work so reviewing this may not be necessary)
{"cols":[{"label":"Time Interval","type":"string"},{"label":"NP Calls","type":"number"},{"label":"DR Calls","type":"number"},{"label":"RE Today Calls","type":"number"},{"label":"RE Future","type":"number"},{"label":"ACCT","type":"number"},{"label":"EMER","type":"number"},{"label":"Other Calls","type":"number"}],"rows":[{"c":[{"v":"05:00"},{"v":0},{"v":0},{"v":0},{"v":0},{"v":0},{"v":0},{"v":1}]},{"c":[{"v":"06:00"},{"v":0},{"v":0},{"v":1},{"v":0},{"v":0},{"v":0},{"v":0}]},{"c":[{"v":"07:00"},{"v":0},{"v":0},{"v":0},{"v":0},{"v":0},{"v":0},{"v":2}]},{"c":[{"v":"07:30"},{"v":2},{"v":0},{"v":3},{"v":0},{"v":0},{"v":1},{"v":2}]},{"c":[{"v":"08:00"},{"v":9},{"v":3},{"v":11},{"v":5},{"v":0},{"v":4},{"v":23}]},{"c":[{"v":"08:30"},{"v":1},{"v":2},{"v":13},{"v":7},{"v":2},{"v":4},{"v":14}]},{"c":[{"v":"09:00"},{"v":3},{"v":1},{"v":15},{"v":11},{"v":6},{"v":3},{"v":23}]},{"c":[{"v":"09:30"},{"v":0},{"v":0},{"v":4},{"v":6},{"v":5},{"v":0},{"v":16}]},{"c":[{"v":"10:00"},{"v":1},{"v":3},{"v":2},{"v":10},{"v":2},{"v":0},{"v":17}]},{"c":[{"v":"10:30"},{"v":5},{"v":1},{"v":1},{"v":10},{"v":2},{"v":3},{"v":23}]},{"c":[{"v":"11:00"},{"v":5},{"v":3},{"v":7},{"v":11},{"v":10},{"v":1},{"v":23}]},{"c":[{"v":"11:30"},{"v":4},{"v":1},{"v":2},{"v":6},{"v":2},{"v":0},{"v":18}]},{"c":[{"v":"12:00"},{"v":3},{"v":0},{"v":5},{"v":11},{"v":2},{"v":0},{"v":21}]},{"c":[{"v":"12:30"},{"v":5},{"v":1},{"v":4},{"v":4},{"v":4},{"v":1},{"v":5}]},{"c":[{"v":"13:00"},{"v":2},{"v":1},{"v":3},{"v":2},{"v":2},{"v":0},{"v":6}]},{"c":[{"v":"13:30"},{"v":2},{"v":0},{"v":1},{"v":3},{"v":1},{"v":0},{"v":15}]},{"c":[{"v":"14:00"},{"v":5},{"v":3},{"v":1},{"v":5},{"v":3},{"v":1},{"v":4}]},{"c":[{"v":"14:30"},{"v":3},{"v":1},{"v":5},{"v":6},{"v":6},{"v":0},{"v":19}]},{"c":[{"v":"15:00"},{"v":3},{"v":1},{"v":4},{"v":8},{"v":4},{"v":1},{"v":22}]},{"c":[{"v":"15:30"},{"v":8},{"v":1},{"v":0},{"v":10},{"v":4},{"v":0},{"v":22}]},{"c":[{"v":"16:00"},{"v":6},{"v":5},{"v":1},{"v":12},{"v":3},{"v":2},{"v":20}]},{"c":[{"v":"16:30"},{"v":3},{"v":4},{"v":3},{"v":7},{"v":3},{"v":1},{"v":7}]},{"c":[{"v":"17:00"},{"v":1},{"v":0},{"v":0},{"v":4},{"v":1},{"v":0},{"v":5}]},{"c":[{"v":"17:30"},{"v":0},{"v":1},{"v":0},{"v":1},{"v":1},{"v":0},{"v":1}]},{"c":[{"v":"18:00"},{"v":1},{"v":0},{"v":1},{"v":0},{"v":0},{"v":0},{"v":2}]},{"c":[{"v":"18:30"},{"v":0},{"v":0},{"v":0},{"v":1},{"v":0},{"v":0},{"v":0}]}]}Can
It's most likely the same issue that was reported in google-visualization-issues repository.
There are at least two solution available at the moment:
Option 1. Render charts synchronously
The general idea is to render chart synchronously. Since draw function is asyncronous, we utilize ready event handler for that purpose.
Place ready event handler in every function before draw function invocation:
if (typeof ready != "undefined") google.visualization.events.addOneTimeListener(chart, 'ready', ready);
and change drawChartN() function signature to drawChartN(ready)
Then replace:
function drawCharts() {
drawChartA();
drawChartB();
}
with:
function drawCharts() {
drawChartA(function(){
drawChartB();
});
}
PhpFiddle
Option 2. Using the frozen version loader.
Since
The rollout of the v43 candidate release that would fix this problem
switch to using the frozen version loader.
Steps:
1)Add a reference to loader: <script
src="//www.gstatic.com/charts/loader.js"></script>
2)Then load a 43 version of library: google.charts.load("43",{packages:["corechart","bar"]});
3)Replace:
function drawCharts() {
drawChartA();
drawChartB();
}
with
google.charts.setOnLoadCallback(drawChartA);
google.charts.setOnLoadCallback(drawChartB);
Related
how to display google comparison chart vertically
in my project i need to show graph on particular place, i used to google bar charts for comparison, i get the graph but it appears on horizontally, but i need the graph in vertically, i tried from morning on wards but no luck, please help. Thanks in advance. Below is the my code <script type="text/javascript"> google.charts.setOnLoadCallback(drawChart); imagepath_comparison=""; function drawChart() { var data = google.visualization.arrayToDataTable([<?=$data;?>]); var options = { title: 'GRAPH ANALYSIS', vAxis: {title: "SUBJECTS"}, hAxis: { title: "MARKS" } }; var chart3 = new google.visualization.BarChart (document.getElementById("columnchart_material")); google.visualization.events.addListener(chart3, 'ready', function () { imagepath_comparison=chart3.getImageURI(); drawChart1(); }); chart3.draw(data, options); } </script>
it was very simple thing need to change for displaying the results,i used ColumnChart in place of Barchart at that time my problem is solved. my code after changing is <script type="text/javascript"> google.charts.setOnLoadCallback(drawChart); imagepath_comparison=""; function drawChart() { var data = google.visualization.arrayToDataTable([<?=$data;?>]); var options = { title: 'GRAPH ANALYSIS', vAxis: {title: "SUBJECTS"}, hAxis: { title: "MARKS" } }; var chart3 = new google.visualization.BarChart (document.getElementById("columnchart_material")); google.visualization.events.addListener(chart3, 'ready', function () { imagepath_comparison=chart3.getImageURI(); drawChart1(); }); chart3.draw(data, options); } </script>
PHP array into google charts
I need a little help putting PHP data into google charts. I have created a simple array $chart_arr = array($year, $new_balance); json_encode($chart_arr); If I run <?php echo json_encode($chart_arr);?> I see the following: [2015,1150] [2016,1304.5] [2017,1463.635] [2018,1627.54405] [2019,1796.3703715], so I think (?) I am getting the right numbers encoded from my forloop that generates $year and $new_balance. I want to chart these numbers in google chart <script type="text/javascript"> google.load("visualization", "1", {packages:["corechart"]}); google.setOnLoadCallback(drawChart); function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Year'); data.addColumn('number', 'Balance'); data.addRows([ <?php echo json_encode($chart_arr);?> ]); Or alternatively: data.addRows([ <?php echo $chart_arr;?> ]); And then continues... var options = { title: 'My Savings', curveType: 'function', legend: { position: 'bottom' } }; var chart = new google.visualization.LineChart(document.getElementById('curve_chart')); chart.draw(data, options); } displaying as... <div class="grid-container"> <div class="grid-100 grid-parent"> <div id="curve_chart" style="width: 100%; height: auto"></div> </div> </div> I have tried a number of variations but am either not getting the data into the chart or not getting a chart to display. Could someone help me to show where I am going wrong? I saw another related post that used the following code: $chartsdata[$i] = array($testTime, $testNb); echo json_encode($chartsdata); var jsonData = $.ajax({ url: "test.php", dataType: "json", async: false }).responseText; var obj = JSON.stringify(jsonData); data.addRows(obj); Is this the approach I need to be looking at? Thanks in advance
i see you haven't found out how to do it after your first question, so i've made you a working example here, hope this helps you Dave :). If you've got some questions about this, feel free to ask! <?php //create array variable $values = []; //pushing some variables to the array so we can output something in this example. array_push($values, array("year" => "2013", "newbalance" => "50")); array_push($values, array("year" => "2014", "newbalance" => "90")); array_push($values, array("year" => "2015", "newbalance" => "120")); //counting the length of the array $countArrayLength = count($values); ?> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript"> google.load("visualization", "1", {packages:["corechart"]}); google.setOnLoadCallback(drawChart); function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Year'); data.addColumn('number', 'Balance'); data.addRows([ <?php for($i=0;$i<$countArrayLength;$i++){ echo "['" . $values[$i]['year'] . "'," . $values[$i]['newbalance'] . "],"; } ?> ]); var options = { title: 'My Savings', curveType: 'function', legend: { position: 'bottom' } }; var chart = new google.visualization.LineChart(document.getElementById('curve_chart')); chart.draw(data, options); } </script> <div class="grid-container"> <div class="grid-100 grid-parent"> <div id="curve_chart" style="width: 100%; height: auto"></div> </div> </div>
I have dealt quite a bit with the Google Charts API recently and I have a few recommendations. The PHP code that you have written should largely work, but it does require that your Javascript code be embedded in a PHP page. Maybe that is okay for your purposes, but I mostly recommend keeping your Javascript separate from your PHP. Some developers may be comfortable with one, but not the other, so mixing the two languages could become a maintenance issue. Now, that pretty much leaves you with using AJAX to retrieve your JSON charts data. This is a good approach, but I do not like the code that you featured in your question for a few reasons. Firstly, the code uses async: false which will remove your user's control of the browser while the data is being fetched. In other words, the browser will appear to freeze until the data is returned from the AJAX request. Also, I do not understand the whole .responseText convention. I understand what the code is accomplishing; I just fail to understand why the author chose that particular approach. Here is what I would do instead. $.ajax({ url: "test.php", dataType: "JSON", data: [any POST parameters that you need here], type: "POST", success: function(json) { var jsonData = JSON.parse(json); // jsonData will be a Javascript object or array. data.addRows(jsonData); drawChart(); }, error: function(jxqhr) { // Handle a bad AJAX call } }); So how does this help your application overall? Well, in your server side code, you can handle any errors (i.e. bad user input) by responding to the AJAX call with a HTTP 500 error and the AJAX call can communicate the problem to your user. Furthermore, when your page loads, the rest of the page will continue loading while your AJAX call is off fetching data. JS Fiddle
json_encode works just fine, you can put it in a variable like var grafica = <?php echo json_encode($grafica); ?> ; (look my example below) or just like you put it in your example, except that the only problem in it, is that you have double brackets, the ones inside jaso_encode($chart_arr) object and the externals data.addRows([ ... ]), that gives you [[...]] and generates and error, take off the brackets, try it like this: data.addRows( <?php echo json_encode($chart_arr);?> ); and not this data.addRows([ <?php echo json_encode($chart_arr);?> ]); I have included and example of how I am using it, be aware that in the documentation, (which in my opinion could be better) they placed the entire code in the <head> section because they have all the data there, but that may cause problems in real working examples, I only placed the CDN (Content Delivery Network) of google chart in the <head> and in the <body> all the Javascript code after the PHP code, not included in this example for clarity purposes, then the <div> but this last could go before the script tags. The order is important because you need to get the data first before constructing the graph. I hope this helps. <!DOCTYPE html> <head> <meta charset="utf-8"/> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> </head> <body> <script type="text/javascript"> google.charts.load("current", {packages:["corechart"]}); google.charts.setOnLoadCallback(drawChart); function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'fecha'); // Implicit domain column. data.addColumn('number', 'peso'); // Implicit data column. data.addColumn({type:'string', role:'annotation'}); // columna para anotaciones data.addColumn({type:'string', role:'style'}); // comumna para estilo var grafica = <?php echo json_encode($grafica); ?> ; data.addRows(grafica); var options = { title:'Peso Total', width:600,height:400, colors: ['#C0C0C0'], curveType: 'function', legend: 'none', pointSize: 12, annotations: { textStyle: { fontName: 'Times-Roman', fontSize: 32, color: '#99ff99', opacity: 0.5, } } }; var chart = new google.visualization.LineChart(document.getElementById('chart_div')); chart.draw(data, options); } </script> <div id="chart_div" style="margin: 80px auto; width: 650px; height: 450px; border: 2px solid #4CAF50; border-radius: 20px; padding:5px; "></div> </html>
PHP code and 2 While calling the same query
I need some help. I have some info in my db that I want to show in 2 charts using Google charts script. Both scripts works but not when I use both scripts in a same page.. I bet is a problem with the while that are both equals since I need to show the same info. If I delete the first while the second loop start to work, but if no, the first just work. The app works well because if I hardcode the values by hand and without the while works well both.. Here's the code: <!-- First Chart start here: --> <script type="text/javascript"> google.load("visualization", "1", { packages: ["corechart"] }); google.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([ ['Formato', 'Cantidad'], <? php //da problema si hay 2 while while ($DatRDV = mysql_fetch_array($nrollos)) { echo "['".$DatRDV['Formato']. "',".$DatRDV['nRollos']. "],"; } ?> ]); var options = { title: 'Formato de Rollos' }; var chart = new google.visualization.PieChart(document.getElementById('chart_div')); chart.draw(data, options); } </script> <!-- Second chart start here: --> <script type="text/javascript"> function drawVisualization() { // Create and populate the data table. var JSONObject = { cols: [{ id: 'format', label: 'Formato', type: 'string' }, { id: 'cantidad', label: 'Cantidades', type: 'number' }], rows: [ <? php while ($DatRDV = mysql_fetch_array($nrollos)) { echo "{c:[{v: '".$DatRDV['Formato']. "'}, {v: ".$DatRDV['nRollos']. "}]},"; } ?> ] }; var data = new google.visualization.DataTable(JSONObject, 0.5); // Create and draw the visualization. visualization = new google.visualization.Table(document.getElementById('table')); visualization.draw(data, { 'allowHtml': true }); } google.setOnLoadCallback(drawVisualization); </script>
try; mysql_data_seek($nrollos,0); before the 2nd loop
Google charts api after ajax call
I've got a problem with the visualization of data with google's charts api after an ajax call. First I made an ajax call and fetched a json object. After that I want to extract some data out of the json and draw a gauge chart. Getting the json and extracting the data works fine, but when I try to load the chart, the body gets removed and I get a blank/white screen. Does anyone knows what I am doing wrong? I also tried to hard code values for the chart instead of taking the json values (but kept the ajax call before loading the chart), but it didn't work neither. function loadStats(){ var http = getRequestObject(); var city = "berlin"; http.open("GET", "getTwitterSentiments.php?city="+city, true); http.onreadystatechange=function() { getStatistic(http) }; http.send(null); } function getStatistic(request) { if ((request.readyState == 4) && (request.status == 200)) { var data = request.responseText; var JSONStats = eval("(" + data + ")"); loadGauge(JSONStats.sentiment_index); } function loadGauge(sentiment){ google.load('visualization', '1', {packages:['gauge']}); google.setOnLoadCallback(drawGauge); function drawGauge() { var data = google.visualization.arrayToDataTable([ ['Label', 'Value'], ['Test', sentiment] ]); var options = { width: 100, height: 100, redFrom: 0, redTo: 45, yellowFrom: 45, yellowTo: 55, greenFrom: 55, greenTo: 100, minorTicks: 10 }; var chart = new google.visualization.Gauge(document.getElementById('testgchart')); chart.draw(data, options); } }
Try using the callback feature of google.load() function. For instance, for your code, try the following: function loadGauge(sentiment){ google.load('visualization', '1.0', {'packages':['gauge'], 'callback': drawGauge}); } function drawGauge(){ ... chart.draw(data, options); } For more information, check the 'Dynamic loading' section of Google Loader Developer Guide: https://developers.google.com/loader/#Dynamic If i understand correctly, calling loadGauge() multiple times will not cause multiple trips to Google servers to load the required APIs, but just once.
I guess your element testgchart is not load in the DOM yet, your code should work. I made an example from your code : <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://www.google.com/jsapi"></script> <script> function loadGauge(val){ google.load('visualization', '1', {packages:['gauge']}); google.setOnLoadCallback(drawGauge); function drawGauge() { var data = google.visualization.arrayToDataTable([ ['Label', 'Value'], ['Test', val], ]); var options = { width: 100, height: 100, redFrom: 0, redTo: 45, yellowFrom: 45, yellowTo: 55, greenFrom: 55, greenTo: 100, minorTicks: 10 }; var chart = new google.visualization.Gauge(document.getElementById('average')); chart.draw(data, options); } } </script> </head> <body> <div id="average"></div> <script>loadGauge(99)</script> </body> </html> But it doesn't work if you delete this line <script>loadGauge(99)</script> and replace the body tag with <body onload="loadGauge(99)">. Your probably doing something similar. If your sure the element testgchart is present then put a log in loadGauge and tell me if it really get called by getStatistic.
How can I unbind JQZOOM in my JQuery Script?
I have this script at the moment, which changes an image when a thumbnail has been changed. I then want JQZOOM to be added to that new image. However, if I put it inside the Onclick event, it gets slower and slower the more times you click on it... I guess because its running multiple instances. Is there anyway to unbind the JQZOOM from something then rebind it to something else? Here is my jquery at the moment: var options = { zoomWidth: 400, zoomHeight: 325, xOffset: 25, yOffset: 0, position: "right", lens: true, zoomType: "reverse", imageOpacity: 0.5, showEffect: "fadein", hideEffect: "fadeout", fadeinSpeed: "medium", title: false }; $('.jqzoom').jqzoom(options); $('.single-zoom-image').click ( function () { $('#bigProductImage').attr("src", $(this).attr("zoom")); $('.jqzoom').attr("href", $(this).attr("extrazoom")); }); Thanks in advance if anyone can help me. Cheers!
This can be done as follows: Modify jqzoom1.0.1.js where the other mouse functions are (around line 90) //Handle clicked thumbnails changing the zoomed image $(this).bind('changeimage', function(){ smallimage = new Smallimage( $("img", this) ); largeimage = new Largeimage(a[0].href); smallimage.loadimage(); }); Call the zoomer as follows: $(document).ready(function(){ var options = { zoomWidth: 300, zoomHeight: 200, xOffset: 30, yOffset: 0, position: 'right', title: false, showPreload: false }; //Handle clicking on the thumbnails, swap the mainimage and recycle the zoomer $('.seemore').bind('click', function(e) { e.preventDefault(); $('.jssProductFullImage').attr('src', $(this).attr('href')); $('.zoomer').attr('href', $(this).attr('href') ); //Recall the zoomer to update the page $('.zoomer').trigger('changeimage'); }); $('.zoomer').jqzoom(options); });
$('.jqzoom').removeData('jqzoom'); Did the job for me.