How to show an Empty Google Chart when there is no data? - google-visualization

Consider drawing a column chart and I don't get any data from the data source, How do we draw an empty chart instead of showing up a red colored default message saying "Table has no columns"?

What I do is initialize my chart with 1 column and 1 data point (set to 0). Then whenever data gets added I check if there is only 1 column and that it is the dummy column, then I remove it. I also hide the legend to begin so that it doesn't appear with the dummy column, then I add it when the new column gets added.
Here is some sample code you can plug in to the Google Visualization Playground that does what I am talking about. You should see the empty chart for 2 seconds, then data will get added and the columns will appear.
var data, options, chart;
function drawVisualization() {
data = google.visualization.arrayToDataTable([
['Time', 'dummy'],
['', 0],
]);
options = {
title:"My Chart",
width:600, height:400,
hAxis: {title: "Time"},
legend : {position: 'none'}
};
// Create and draw the visualization.
chart = new google.visualization.ColumnChart(document.getElementById('visualization'));
chart.draw(data,options);
setTimeout('addData("12:00",10)',2000);
setTimeout('addData("12:10",20)',3000);
}
function addData(x,y) {
if(data.getColumnLabel(1) == 'dummy') {
data.addColumn('number', 'Your Values', 'col_id');
data.removeColumn(1);
options.legend = {position: 'right'};
}
data.addRow([x,y]);
chart.draw(data,options);
}​

A even better solution for this problem might be to use a annotation column instead of a data column as shown below. With this solution you do not need to use any setTimeout or custom function to remove or hide your column. Give it a try by pasting the given code below into Google Code Playground.
function drawVisualization() {
var data = google.visualization.arrayToDataTable([
['', { role: 'annotation' }],
['', '']
]);
var ac = new google.visualization.ColumnChart(document.getElementById('visualization'));
ac.draw(data, {
title : 'Just a title...',
width: 600,
height: 400
});
}
​

The way I did this was by disabling the pie slices, turning off tooltips, stuffing in a pretend value and making it gray. I'm sure there are more clever ways to do this, but this worked for me where the other methods didn't.
The only drawback is that it sets both items in the legend to gray as well. I think you could perhaps just add a third item, and make it invisible on the legend only. I liked this way though.
function drawChart() {
// Define the chart to be drawn.
data = new google.visualization.DataTable();
data.addColumn({type: 'string', label: 'Result'});
data.addColumn({type: 'number', label: 'Count'});
data.addRows([
['Value A', 0],
['Value B', 0]
]);
var opt_pieslicetext = null;
var opt_tooltip_trigger = null;
var opt_color = null;
if (data.getValue(1,1) == 0 && data.getValue(0,1) == 0) {
opt_pieslicetext='none';
opt_tooltip_trigger='none'
data.setCell(1,1,.1);
opt_color= ['#D3D3D3'];
}
chart = new google.visualization.PieChart(document.getElementById('mydiv'));
chart.draw(data, {sliceVisibilityThreshold:0, pieSliceText: opt_pieslicetext, tooltip: { trigger: opt_tooltip_trigger }, colors: opt_color } );
}

Related

Google charts error:every row given must be either null or an array

I am working on a website that is intended to show some basic Google charts. The data comes from a text file that i retrieve through Ajax. It's got a x, y value and an annotation field. The data looks like this:
[[-0.8, -0.47, "100-005-10"],
[-0.7, -0.46, "100-005-9"],
[-0.6, -0.45, "100-005-8"],
[-0.5, -0.44, "100-005-7"]]
Here's my code:
<script >
var xmlhttp = new XMLHttpRequest();
var array;
xmlhttp.onreadystatechange = function() {
array = this.responseText;
};
xmlhttp.open("GET", "array.array", true);
xmlhttp.send();
google.charts.load("current", {packages:["corechart"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable($.parseJSON(array), true)
data.addColumn('number', 'x');
data.addColumn('number', 'y');
data.addColumn({type: 'string', role: 'annotation'});
data.addRow(array);
var options = {
legend: 'none',
colors: ['#087037'],
selectionMode: 'single',
tooltip: {trigger: 'selection'},
pointSize: 12,
animation: {
duration: 200,
easing: 'inAndOut',
}
};
var chart = new google.visualization.ScatterChart(document.getElementById('animatedshapes_div'));
chart.draw(data, options);
}
</script>
When i run the code, i get this error message:
Error: If argument is given to addRow, it must be an array, or null
I just don't know how to transform the plain text from the ajax response to an array.
try using JSON.parse to convert the string to an actual array...
data.addRows(JSON.parse(array));
In one of the case, need to add Square brackets []
self.tableValues.forEach((row: any) => {
if(row) {
dataTable.addRows([row]); // <-- row is array; so try [row]
}
});

"Table has no rows" Error in Google Charts Histogram

I am working with Google Histogram chart. It working fine with some data sets but not for other data sets. And it raise an error "Table has no rows" even my input is correct.
Here i am reading a csv file column wise and pass to visualization page.
for eg: I am reading 2 csv column here and passing to visualization page. Here my input to Google histogram is
var inputdata1 = [["val","d"],["val","2"],["val","2"],["val","1"],["val","2"],["val","2"],["val","1"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","1"],["val","2"]];
and this working fine and gives histogram for me.
while I am passing other 2 columns.Here my input to Google histogram is
var inputdata2 = [["val","b"],["val","3"],["val","3"],["val","3"],["val","5"],["val","1"],["val","12"],["val","7"],["val","11"],["val","1"],["val","7"],["val","6"],["val","16"],["val","11"],["val","21"],["val","12"],["val","1"],["val","22"],["val","16"],["val","1"],["val","21"],["val","11"],["val","6"],["val","11"],["val","15"],["val","12"],["val","12"]];
while executing this, it raise an error that "Table has no rows" . Please check my fiddle.
Any help would be greatly appreciated.
Thank you in Advance.
In fact neither inputdata1 nor inputdata2 contain JSON data that are supported by histogram chart.
According to the documentation the following formats are supported:
Data Format
There are two ways to populate a histogram datatable. When there's
only one series:
var data = google.visualization.arrayToDataTable([
['Name', 'Number'],
['Name 1', number1],
['Name 2', number2],
['Name 3', number3],
...
]);
...and when there are multiple series:
var data = google.visualization.arrayToDataTable([
['Series Name 1', 'Series Name 2', 'Series Name 3', ...],
[series1_number1, series2_number1, series3_number1, ...],
[series1_number2, series2_number2, series3_number2, ...],
[series1_number3, series2_number3, series3_number3, ...],
...
]);
Having said that you might want to convert the second column into number format:
var inputJson = [["val","b"],["val","3"],["val","3"],["val","3"],["val","5"],["val","1"],["val","12"],["val","7"],["val","11"],["val","1"],["val","7"],["val","6"],["val","16"],["val","11"],["val","21"],["val","12"],["val","1"],["val","22"],["val","16"],["val","1"],["val","21"],["val","11"],["val","6"],["val","11"],["val","15"],["val","12"],["val","12"]];
var chartJson = inputJson.map(function(item,i){
if(i == 0)
return item;
else {
return [item[0],parseInt(item[1])];
}
});
var data = google.visualization.arrayToDataTable(chartJson);
Once the data is converted the chart will be rendered properly.
Working example
google.load('visualization', '1.1', {
'packages': ['corechart']
});
google.setOnLoadCallback(drawStuff);
function drawStuff() {
var inputJson = [["val","b"],["val","3"],["val","3"],["val","3"],["val","5"],["val","1"],["val","12"],["val","7"],["val","11"],["val","1"],["val","7"],["val","6"],["val","16"],["val","11"],["val","21"],["val","12"],["val","1"],["val","22"],["val","16"],["val","1"],["val","21"],["val","11"],["val","6"],["val","11"],["val","15"],["val","12"],["val","12"]];
var chartJson = inputJson.map(function(item,i){
if(i == 0)
return item;
else {
return [item[0],parseInt(item[1])];
}
});
var data = google.visualization.arrayToDataTable(chartJson);
//The below input data works fine.
//var data = google.visualization.arrayToDataTable([["val","d"],["val","2"],["val","2"],["val","1"],["val","2"],["val","2"],["val","1"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","2"],["val","1"],["val","2"]]);
// Set chart options
var options = {
width: 400,
height: 300,
histogram: {
bucketSize: 0.1
}
};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.Histogram(document.getElementById('chart_div'));
chart.draw(data, options);
};
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script src="chart.js"></script>
<div id="chart_div"></div>

Change color of a bar in google columnchart

I am using columnchart to generate a chart . Below is the code:
function drawActiveJobsChart() {
var i=0;
var j=0;
var data = new google.visualization.DataTable();
data.addColumn('string','Systems');
data.addColumn('number', 'Counts');
$.getJSON('SubSystemNumbers.action', function(json) {
$.each( json.SysActNum, function( key, val ) {
i++;
});
data.addRows(i);
$.each( json.SysActNum, function( key, val ) {
if (val>=30) {
data.setProperty(j,1,'style','color:red');
}
data.setValue(j, 0,key);
data.setValue(j, 1,val);
j++;
});
});
var options = {
title: 'System Numbers',
width:900, height:400,
allowHtml: true,
hAxis: {title: 'Systems', titleTextStyle: {color: 'red'},textStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById(chartDiv));
chart.draw(data, options);
}
Now i have added logic to change the bar color to red when return val is greater than 30 . I tried running in debug and code is executing fine but bar is not showing in red . Please suggest ! Help is appreciated
Setting the "style" property of a cell is not going to change the color of a bar, you need to add a "style" role column to your DataTable:
var data = new google.visualization.DataTable();
data.addColumn('string','Systems');
data.addColumn('number', 'Counts');
data.addColumn({type: 'string', role: 'style'});
and add the style information to this column:
$.getJSON('SubSystemNumbers.action', function(json) {
$.each( json.SysActNum, function( key, val ) {
var style = (val >= 30) ? 'color: red' : null;
data.addRow([key, val, style]);
});
});
see working example based on your code here: http://jsfiddle.net/asgallant/dGYs7/
Just in case somebody else runs in to the same issue as me:
I had a similar problem where I couldn't change the color of specific bars in a bar-chart. I did as the documentation said, and tried the answer here by asgallant, but nothing worked.
Turned out, I just needed to change google.charts.Bar to google.visualization.ColumnChart.

Modify appearance of DataTable role in a Google Chart

I have a column chart for which I use the certainty role to indicate that a value is uncertain. This is visualized as a non-solid fill of the column. However, this appearance is a little too subtle, so I want to make it a little bit clearer. Is there a way to hook into the charts API, or specify options for a role, that can modify it's appearance?
The API does not support modifying the appearance of the uncertain columns. You can make a feature request to add support for modifying the appearance of uncertain elements.
Edit:
You can hack around the problem if your chart meets certain criteria (namely, you are using a Bar or ColumnChart with either 1 series of data or the "isStacked" option set to true; or a SteppedArea chart; or a LineChart/ScatterChart showing data points only [no lines]. LineCharts [with lines] and AreaCharts can be made to work, but it involves a lot more effort to make it happen. Other charts may be possible, but I haven't thought about how to make it work with them).
To make this work, you create a boolean column for your data (it doesn't have to have the "certainty" role, but assigning the role doesn't hurt anything either). Then you create a DataView or set the "view" parameter of a ChartWrapper to create one series of data for values where the boolean is true, and one series for values where the boolean is false, like this:
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Value');
data.addColumn('boolean', 'Boolean');
data.addRows([
['Germany', 700, true],
['USA', 300, true],
['Brazil', 400, false],
['Canada', 500, true],
['France', 600, false],
['Russia', 800, true]
]);
var chart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
dataTable: data,
options: {
// setting the "isStacked" option to true fixes the spacing problem
isStacked: true,
height: 300,
width: 600,
series: {
0: {
// options for Boolean = true
color: '#3366cc'
},
1: {
// options for Boolean = false
color: '#0099c6',
visibleInLegend: false
}
}
},
view: {
columns: [0, {
type: 'number',
label: data.getColumnLabel(1),
calc: function (dt, row) {
// return value if Boolean is true
return (dt.getValue(row, 2)) ? dt.getValue(row, 1) : null;
}
}, {
type: 'number',
label: data.getColumnLabel(1),
calc: function (dt, row) {
// return value if Boolean is false
return (dt.getValue(row, 2)) ? null : dt.getValue(row, 1);
}
}]
}
});
chart.draw();
}
See example: http://jsfiddle.net/asgallant/Xzbw5/

Google Visualization API Format Secondary Y-axis different from Primary Y-Axis

I have some data that I am trying to display using the Google Visualization API (Google Chart Tools). I have been able to create the graph and it looks great except that the Secondary Y-Axis should be displayed as percentages instead of regular numbers. Here is my code and an image of what is produced.
google.load('visualization', '1', {packages: ['corechart']});
function drawVisualization() {
//Some raw data (not necessarily accurate)'
var data = google.visualization.arrayToDataTable([
['AuditPeriod', 'Audit Count', 'Fail Percentage'],
['02-11-2012', 0, 0],
['02-18-2012', 0, 0],
['02-25-2012', 0, 0],
...
['07-21-2012', 1476, .233062],
['07-28-2012', 1651, .253180],
['08-04-2012', 2217, .210645]
]);
var options = {
vAxis: [0: {format: '#,###'}, 1: {format: '#%'}],
hAxis: { title: "Week", format: 'm/d/y'},
series: {
0:{ type: "bars", targetAxisIndex: 0 },
1: { type: "line", targetAxisIndex: 1}
}
}
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
google.setOnLoadCallback(drawVisualization);
If I set vAxis:{format: '#%'} then both axes are formated as Percentages which I don't want. Is there a way to format the second axis different form the first?
Posted this question on the Google Visualization Group and got the answer.
asgallant
You almost had it, use vAxes instead of vAxis when formatting multiple axes:
vAxes: {
0: {format: '#,###'},
1: {format: '#%'}
}​