Google chart only loads on refresh of page - javascript

Am a beginner using google charts/js. My google chart below loads fine, however there are times when the chart area loads blank html, and when I refresh the page it displays correctly.
I'm not sure why this is. It seems to do this on all browsers. This seems to indicate it could be with Mozilla, but the problem persists...
<script type="text/javascript">
google.charts.load('current', {
packages: ['corechart']
}).then(function drawChart() {
<?php
$imei = $bboxx_imei;
$result = shell_exec('Daily_Data_Retriever_ishackweb.py ' . $imei.' '. $end.' '.$start); #imei=sys.arg[1] end=sys.arg[2] start=sys.arg[3]
?>
var jsonData = <?php echo $result; ?> //{"Charge Current, (A)":{"2017-11-16T00:00:00.000Z":0.001373312,"2017-11-16T00:01:00.000Z":0.001373312,"2017-11-16T00:02:00.000Z":0.001373312,"2017-11-16T00:03:00.000Z":0.001373312,"2017-11-16T00:04:00.000Z":0.001373312},"Battery Voltage, (V)":{"2017-11-16T00:00:00.000Z":12.9267109178,"2017-11-16T00:01:00.000Z":12.9267109178,"2017-11-16T00:02:00.000Z":12.9267109178,"2017-11-16T00:03:00.000Z":12.9267109178,"2017-11-16T00:04:00.000Z":12.9267109178}};
var chartCols = ['Datetime'];
Object.keys(jsonData).forEach(function (column) {
chartCols.push(column);
});
// build list of date
var dateValues = [];
Object.keys(jsonData).forEach(function (column) {
Object.keys(jsonData[column]).forEach(function (dateValue) {
if (dateValues.indexOf(dateValue) === -1) {
dateValues.push(dateValue);
}
});
});
// build chart data
var chartData = [chartCols];
dateValues.forEach(function (dateValue) {
var row = [new Date(dateValue)];
Object.keys(jsonData).forEach(function (column) {
row.push(jsonData[column][dateValue] || null);
});
chartData.push(row);
});
var data = google.visualization.arrayToDataTable(chartData);
var options = {
chartArea: {width:'90%', height:'85%'},
//title: 'Battery Voltage and Panel Charge',
curveType: 'function',
legend: { position: 'bottom' },
vAxes: {0: {viewWindowMode:'explicit',
viewWindow:{
max:16,
min:11
},
gridlines: {color: 'transparent'},
},
1: {viewWindowMode:'explicit',
viewWindow:{
max:5,
min:0
},
},
},
series: {0: {targetAxisIndex:1},
1: {targetAxisIndex:0},
},
};
var chart = new google.visualization.LineChart(document.getElementById('line_chart'));
chart.draw(data, options);
$(window).resize(function(){
drawChart()
});
});
</script>

when using a function inline / anonymously, although you can provide a name,
you will not be able to call that same function again, by it's name
google.charts.load('current', {
packages: ['corechart']
}).then(function drawChart() { // <-- cannot call this again, no name needed
...
instead, declare the function separately, then pass a reference where needed,
using the name of the function
google.charts.load('current', {
packages: ['corechart']
}).then(drawChart);
$(window).resize(drawChart);
function drawChart() {
...
}
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(drawChart);
$(window).resize(drawChart);
function drawChart() {
var jsonData = {"Charge Current, (A)":{"2017-11-16T00:00:00.000Z":0.001373312,"2017-11-16T00:01:00.000Z":0.001373312,"2017-11-16T00:02:00.000Z":0.001373312,"2017-11-16T00:03:00.000Z":0.001373312,"2017-11-16T00:04:00.000Z":0.001373312},"Battery Voltage, (V)":{"2017-11-16T00:00:00.000Z":12.9267109178,"2017-11-16T00:01:00.000Z":12.9267109178,"2017-11-16T00:02:00.000Z":12.9267109178,"2017-11-16T00:03:00.000Z":12.9267109178,"2017-11-16T00:04:00.000Z":12.9267109178}};
var chartCols = ['Datetime'];
Object.keys(jsonData).forEach(function (column) {
chartCols.push(column);
});
// build list of date
var dateValues = [];
Object.keys(jsonData).forEach(function (column) {
Object.keys(jsonData[column]).forEach(function (dateValue) {
if (dateValues.indexOf(dateValue) === -1) {
dateValues.push(dateValue);
}
});
});
// build chart data
var chartData = [chartCols];
dateValues.forEach(function (dateValue) {
var row = [new Date(dateValue)];
Object.keys(jsonData).forEach(function (column) {
row.push(jsonData[column][dateValue] || null);
});
chartData.push(row);
});
var data = google.visualization.arrayToDataTable(chartData);
var options = {
chartArea: {width:'90%', height:'85%'},
//title: 'Battery Voltage and Panel Charge',
curveType: 'function',
legend: { position: 'bottom' },
vAxes: {
0: {
viewWindowMode:'explicit',
viewWindow:{
max:16,
min:11
},
gridlines: {color: 'transparent'},
},
1: {
viewWindowMode:'explicit',
viewWindow:{
max:5,
min:0
},
},
},
series: {
0: {targetAxisIndex:1},
1: {targetAxisIndex:0},
},
};
var chart = new google.visualization.LineChart(document.getElementById('line_chart'));
chart.draw(data, options);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="line_chart"></div>

Related

google chart change color of individual histogram data points

I have the following code (see codepen) that allows me to change the color of each individual histogram data point after the chart is drawn. It works as intended. However, the colors mess up after the user hovers over the data points. What's going on and how can I fix it?
google.charts.load('current', {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var rawData = [
['Dinosaur', 'Length', 'color'],
['Acrocanthosaurus (top-spined lizard)', 12.2, 'red'],
['Albertosaurus (Alberta lizard)', 9.1, 'green'],
['Allosaurus (other lizard)', 12.2, 'green'],
];
// sort data by 'Length'
var data = google.visualization.arrayToDataTable(rawData);
data.sort([{column: 1}]);
var options = {
title: 'Lengths of dinosaurs, in meters',
legend: { position: 'none' },
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.Histogram(container);
google.visualization.events.addListener(chart, 'ready', function () {
var observer = new MutationObserver(function () {
var index = 0;
var item = 1;
Array.prototype.forEach.call(container.getElementsByTagName('rect'), function (rect) {
if (rect.getAttribute('fill') === '#3366cc') {
rect.setAttribute('fill', rawData[item][2]);
item++
}
index++;
});
});
observer.observe(container, {
childList: true,
subtree: true
});
});
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
in the observer, need to check for all colors...
switch (rect.getAttribute('fill')) {
case '#3366cc':
case 'red':
case 'green':
rect.setAttribute('fill', rawData[item][2]);
item++
break;
}
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function drawChart() {
var rawData = [
['Dinosaur', 'Length', 'color'],
['Acrocanthosaurus (top-spined lizard)', 12.2, 'red'],
['Albertosaurus (Alberta lizard)', 9.1, 'green'],
['Allosaurus (other lizard)', 12.2, 'green'],
];
// sort data by 'Length'
var data = google.visualization.arrayToDataTable(rawData);
data.sort([{column: 1}]);
var options = {
title: 'Lengths of dinosaurs, in meters',
legend: { position: 'none' },
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.Histogram(container);
google.visualization.events.addListener(chart, 'ready', function () {
var observer = new MutationObserver(function () {
var index = 0;
var item = 1;
Array.prototype.forEach.call(container.getElementsByTagName('rect'), function (rect) {
switch (rect.getAttribute('fill')) {
case '#3366cc':
case 'red':
case 'green':
rect.setAttribute('fill', rawData[item][2]);
item++
break;
}
index++;
});
});
observer.observe(container, {
childList: true,
subtree: true
});
});
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Javascript charts as input

I have a requirement as below.
I need to input time series data (day data) using a graph. The data is usually like below but the profile can be changed depending upon the situation.
Right now the data is being manually entered in textboxes which makes it very difficult.
I am wondering whether there are solutions that let user draw on a chart and generate the data in the back. In other words, the user picks certain points and the profile is drawn.
see following working snippet, click on the chart to add a data point...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable({
"cols": [
{"label": "x", "type": "number"},
{"label": "y", "type": "number"}
]
});
var axisMax = 10;
var ticks = [];
for (var i = 0; i <= axisMax; i = i + 0.5) {
ticks.push(i);
}
var options = {
chartArea: {
bottom: 64,
height: '100%',
left: 64,
top: 24,
width: '100%'
},
hAxis: {
format: '0.0',
textStyle: {
fontSize: 9
},
ticks: ticks,
title: data.getColumnLabel(0),
viewWindow: {
min: 0,
max: axisMax
}
},
height: 600,
legend: {
position: 'top'
},
pointSize: 4,
vAxis: {
format: '0.0',
textStyle: {
fontSize: 9
},
ticks: ticks,
title: data.getColumnLabel(1),
viewWindow: {
min: 0,
max: axisMax
}
}
};
var tableDiv = document.getElementById('table_div');
var table = new google.visualization.Table(tableDiv);
var chartDiv = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(chartDiv);
var chartLayout = null;
google.visualization.events.addListener(chart, 'ready', function () {
chartLayout = chart.getChartLayoutInterface();
});
google.visualization.events.addListener(chart, 'click', function (sender) {
data.addRow([
chartLayout.getHAxisValue(sender.x),
chartLayout.getVAxisValue(sender.y)
]);
drawChart();
});
function drawChart() {
chart.draw(data, options);
table.draw(data);
}
window.addEventListener('resize', drawChart, false);
drawChart();
},
packages:['corechart', 'table']
});
div {
text-align: center;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<div id="table_div"></div>

change tooltip name(current & previous) in google diff chart

I want to create a google diff chart for a survey. that will show the total number of user and survey given users.
My javascript code is:-
google.charts.load('current', {packages: ['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var overallData = [];
var givenData = [];
overallData.push(['Department', 'Total Users']);
givenData.push(['Department', 'Given feedback']);
for (var i in data) {
overallData.push([data[i].department_name, data[i].emp_count]);
givenData.push([data[i].department_name, data[i].upward_done]);
}
var oldData = google.visualization.arrayToDataTable(overallData);
var newData = google.visualization.arrayToDataTable(givenData);
var colChartDiff = new google.visualization.ColumnChart(document.getElementById('feedback_dept_chart'));
var options = {
fontName: 'Calibri',
legend: 'none',
height: 200,
width: 960,
vAxis: {title: 'No of employee'},
tooltip: {isHtml: false}
};
var diffData = colChartDiff.computeDiff(oldData, newData);
colChartDiff.draw(diffData, options);
And data is :-
[{"department_name":"Design","emp_count":1,"upward_done":1},
{"department_name":"Management","emp_count":1,"upward_done":0},
{"department_name":"Technology","emp_count":3,"upward_done":2}]
The problem with diff chart is it is showing tooltip named "current" and "previous". And I want to change it by "total users" and "survey given users".
Any help will be appreciated.
Thanks
Add below code for tooltip into options
diff: {
oldData: { opacity: 1, color: 'yellow',
tooltip:{
prefix:'Label 1'
}
},
newData: { opacity: 1, widthFactor: 1,
tooltip:{
prefix:'Label 2'
}
}
}

Google charts into JQuery Tab draw issue

I am currently trying to move Google charts in which the data is being pulled from the server-side via socket.io and drawing them into JQuery UI Tabs.
The issue am having is that the first report that gets drawn in works fine and looks fine.
The 2nd looks quite wrong, I think its something to do with how am drawing the tables maybe but am unable to find a solution, this issue does not happen when am simply drawing it into divs outside the JQuery UI tabs.
This is the current code I have right now:
jQuery(function ($) {
var socket = io.connect();
var result = [];
google.charts.load('current', {
packages : ['bar']
});
$(function() {
$( "#tabs" ).tabs();
});
socket.on("SQLdipo", function (valueArr) {
google.charts.setOnLoadCallback(drawMaterial);
var data = valueArr;
function drawMaterial() {
var result = [['Call Disposition', 'Answered', 'No Answer', 'Busy','Failed']].concat(valueArr);
var options = {
height: 350,
chart: {
title: 'Agent Call Dispositions',
subtitle: 'Agent call states',
}
};
var chartdata = new google.visualization.arrayToDataTable(result);
var chart1 = new google.charts.Bar(document.getElementById('chartDipo'));
chart1.draw(chartdata, options);
}
});
socket.on("SQLmins", function (valueArr) {
google.charts.setOnLoadCallback(drawChart);
var data = valueArr;
function drawChart() {
var result = [['Total Mins', 'Active','Inactive']].concat(valueArr);
var options = {
height: 350,
chart: {
title: 'Agent Activity in seconds',
subtitle: 'Agent Duration Activity',
}
};
var chartdata = new google.visualization.arrayToDataTable(result);
var chart2 = new google.charts.Bar(document.getElementById('chartMins'));
chart2.draw(chartdata, options);
}
});
});
I have made a configured a JS fiddle to emulate the issue am having HERE
the problem is the chart is hidden when it is initially drawn.
you could set specific size options or...
wait until the tab is activated, before drawing the chart for the first time, as in this example...
$(document).ready(function() {
$("#tabs").tabs({
activate: function(event, ui){
switch (ui.newTab.index()) {
case 0:
drawMaterial();
break;
case 1:
drawChart();
break;
}
}
});
google.charts.load('current', {
callback: drawMaterial,
packages: ['bar']
});
function drawMaterial() {
var data = google.visualization.arrayToDataTable([
['Call Disposition', 'Answered', 'No Answer', 'Busy', 'Failed'],
['1000', 4, 0, 2, 0],
['1001', 4, 2, 0, 0],
['1002', 6, 0, 0, 0]
]);
var options = {
height: 350,
chart: {
title: 'Agent Call Dispositions',
subtitle: 'Agent call states',
}
};
var chart1 = new google.charts.Bar(document.getElementById('chartDipo'));
chart1.draw(data, options);
}
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Call Disposition', 'Answered', 'No Answer', 'Busy', 'Failed'],
['1000', 4, 0, 2, 0],
['1001', 4, 2, 0, 0],
['1002', 6, 0, 0, 0]
]);
var options = {
height: 350,
chart: {
title: 'Agent Call Dispositions',
subtitle: 'Agent call states',
}
};
var chart1 = new google.charts.Bar(document.getElementById('chartMins'));
chart1.draw(data, options);
}
});
<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="tab-div" id="tabs">
<ul>
<li>Call Disposition</li>
<li>Agent Activity</li>
</ul>
<div id="tabs-1">
<div class="report-style" id="chartDipo"></div>
</div>
<div id="tabs-2">
<div class="report-style" id="chartMins"></div>
</div>
</div>
I have modified it with my own code based of the suggestion you gave #Whitehat which works fine but it means I have to use globals which I believe is not recommended.
What are your thoughts on this or any suggested changes or improvements?
jQuery(function ($) {
//Global Varibles
var socket = io.connect();
var result = [];
google.charts.load('current', {
packages : ['bar']
});
$("#tabs").tabs({
activate: function(event, ui){
switch (ui.newTab.index()) {
case 0:
drawMaterial();
break;
case 1:
drawChart();
break;
}
}
});
socket.on("SQLdipo", function (valueArr) {
google.charts.setOnLoadCallback(drawMaterial);
data1 = valueArr;
});
socket.on("SQLmins", function (valueArr) {
google.charts.setOnLoadCallback(drawChart);
data2 = valueArr;
});
function drawMaterial() {
var result = [['Call Disposition', 'Answered', 'No Answer', 'Busy','Failed']].concat(data1);
var options = {
height: 350,
chart: {
title: 'Agent Call Dispositions',
subtitle: 'Agent call states',
}
};
var chartdata = new google.visualization.arrayToDataTable(result);
var chart1 = new google.charts.Bar(document.getElementById('chartDipo'));
chart1.draw(chartdata, options);
}
function drawChart() {
var result = [['Total Mins', 'Active','Inactive']].concat(data2);
var options = {
height: 350,
chart: {
title: 'Agent Activity in seconds',
subtitle: 'Agent Duration Activity',
}
};
var chartdata = new google.visualization.arrayToDataTable(result);
var chart2 = new google.charts.Bar(document.getElementById('chartMins'));
chart2.draw(chartdata, options);
}
});

Animate Google Chart from JSON

All of the examples on how to animate don't cover if the chart is created by JSON data. They all use static data. (See Transition Animation.)
This is my code that gets my data via JSON.
<script type="text/javascript">
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawChart);
function drawChart() {
$.post('/Weight/WeightAreaChartData', {}, function (data) {
var tdata = new google.visualization.arrayToDataTable(data);
var options = {
title: 'Weight Lost & Gained This Month',
hAxis: { title: 'Day of Month', titleTextStyle: { color: '#1E4A08'} },
vAxis: { title: 'Lbs.', titleTextStyle: { color: '#1E4A08' } },
chartArea: { left: 50, top: 30, width: "75%" },
colors: ['#FF8100'],
animation:{
duration: 1000,
easing: 'in'
},
};
var chart = new google.visualization.AreaChart(
document.getElementById('chart_div')
);
chart.draw(tdata, options);
});
}
</script>
I have a button that redraws the chart successfully. However, it doesn't animate. How can I make the chart animate? Thank you for your help.
$('#myBtn').click(function () {
drawChart();
});
Maybe cause you're creating the chart everytime?
Try to make chart a global variable and try again
As eluded to by #FelipeFonseca, you're overwriting the chart each time #myBtn is clicked. Try doing this instead:
(function (global, undef) {
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawChart);
var options = {
title: 'Weight Lost & Gained This Month',
hAxis: { title: 'Day of Month', titleTextStyle: { color: '#1E4A08'} },
vAxis: { title: 'Lbs.', titleTextStyle: { color: '#1E4A08' } },
chartArea: { left: 50, top: 30, width: "75%" },
colors: ['#FF8100'],
animation:{
duration: 1000,
easing: 'in'
}
};
var chart;
function drawChart() {
$.post('/Weight/WeightAreaChartData', {}, function (data) {
var tdata = new google.visualization.arrayToDataTable(data);
if (!chart) {
chart = new google.visualization.AreaChart(
document.getElementById('chart_div')
);
}
chart.draw(tdata, options);
});
}
})(this);

Categories