How to skip empty rows from displaying in a google bar chart? - charts

I find that empty rows are being displayed too in a google bar chart.

You could exclude empty rows from google.visualization.DataTable like this:
function excludeEmptyRows(dataTable)
{
var view = new google.visualization.DataView(dataTable);
var rowIndexes = view.getFilteredRows([{column: 1, maxValue: 0}]); //get rows with 0 values
view.hideRows(rowIndexes); //hide empty rows
return view.toDataTable();
}
Example
google.load('visualization', '1', {packages: ['corechart', 'bar']});
google.setOnLoadCallback(drawBasic);
function drawBasic() {
var data = google.visualization.arrayToDataTable([
['City', '2010 Population',],
['New York City, NY', 8175000],
['Los Angeles, CA', 3792000],
['Chicago, IL', 2695000],
['Houston, TX', 2099000],
['Philadelphia, PA', 1526000],
['---', 0]
]);
var options = {
title: 'Population of Largest U.S. Cities',
chartArea: {width: '50%'},
hAxis: {
title: 'Total Population',
minValue: 0
},
vAxis: {
title: 'City'
},
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(excludeEmptyRows(data), options);
}
function excludeEmptyRows(dataTable)
{
var view = new google.visualization.DataView(dataTable);
var rowIndexes = view.getFilteredRows([{column: 1, maxValue: 0}]); //get rows with 0 values
view.hideRows(rowIndexes); //hide empty rows
return view.toDataTable();
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="chart_div"></div>

Related

Set Automatic Tooltip 0dp Percentage on Google Donut Chart

Using Google Charts Donut Chart it handily produces a tooltip with a calculated percentage along with the text descriptor and base count.
However I'd like to adjust this to 0dp but can't see a way to do this in the documentation without doing HTML tooltips which seem to be overkill for a simple rounding of a decimal point.
You can see the issue here, where it's shown to 1dp as there's more to it, however, here it's rounded to 0dp due to it being an integer:
So, for consistency and ease for viewers, I'd like to just round this all off at 0dp.
The code I'm using is:
<html>
<head>
<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);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['NPS', 'Count'],
['Detractor', 25],
['Neutal', 31],
['Promoter', 48],
]);
var options = {
legend: 'none',
pieSliceText: 'none',
pieHole: 0.7,
slices: {
0: { color: '#232944' },
1: { color: '#a5a5a5' },
2: { color: '#a9d136' }
}
};
var chart = new google.visualization.PieChart(document.getElementById('donutchart'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="donutchart" style="width: 900px; height: 500px;"></div>
</body>
</html>
there is not an option to format the percentage value shown in the tooltip.
the only option is a custom tooltip.
see following working snippet.
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['NPS', 'Count'],
['Detractor', 25],
['Neutal', 31],
['Promoter', 48],
]);
var groupData = google.visualization.data.group(
data,
[{column: 0, type: 'string', modifier: function () {return 'Total';}}],
[{
column: 1,
type: 'number',
label: 'Total',
aggregation: google.visualization.data.sum
}]
);
var total = groupData.getValue(0, 1);
var formatNumber = new google.visualization.NumberFormat({
pattern: '#,##0'
});
var formatPercent = new google.visualization.NumberFormat({
pattern: '#,##0%'
});
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
var label = dt.getValue(row, 0);
var value = dt.getValue(row, 1);
var percent = '';
if (total > 0) {
percent = ' (' + formatPercent.formatValue(value / total) + ')';
}
return label + '\n' + formatNumber.formatValue(value) + percent;
},
role: 'tooltip',
type: 'string'
}]);
var options = {
legend: 'none',
pieSliceText: 'none',
pieHole: 0.7,
slices: {
0: { color: '#232944' },
1: { color: '#a5a5a5' },
2: { color: '#a9d136' }
},
tooltip: {
textStyle: {
bold: true
}
}
};
var chart = new google.visualization.PieChart(document.getElementById('donutchart'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="donutchart"></div>

Format number with . as thousand separator and no decimals

I've alreayd checked here:
https://groups.google.com/forum/#!topic/google-visualization-api/4qCeUgE-OmU
https://developers.google.com/chart/interactive/docs/querylanguage#Format
https://developers.google.com/chart/interactive/docs/reference#numberformatter
I want to display the number on the x-axis in a graph drawn with Google Charts with no decimals and a . as the thousand separator.
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
title: 'Price (€)', format: '#.###'
}
};
So 3200 should be shown as 3.200
I've already tried for the format variable:
#.#
#.###
#
since the format option will not work in this situation,
you can provide your own ticks for vAxis...
use object notation for each tick
{
v: value,
f: formattedValue
}
use google's NumberFormat class...
var formatNumber = new google.visualization.NumberFormat({
fractionDigits: 0,
groupingSymbol: '.'
});
format each tick using the formatValue method
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn('number', 'y');
data.addRows([
[1, 3000],
[2, 3100],
[3, 3200],
[4, 3300],
[5, 3400],
]);
var formatNumber = new google.visualization.NumberFormat({
fractionDigits: 0,
groupingSymbol: '.'
});
var columnRange = data.getColumnRange(1);
var ticks = [];
for (var i = columnRange.min; i <= columnRange.max; i=i+100) {
ticks.push({
v: i,
f: formatNumber.formatValue(i)
});
}
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
ticks: ticks,
title: 'Price (€)'
}
};
var container = document.getElementById('chart');
var chart = new google.visualization.LineChart(container);
chart.draw(data, options);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

google chart show only integer on vaxis that starts with zero, equal spacing, non repeat data points

I am using google Chart:
I have to show only integer on vaxis that starts with zero, equal spacing, non repeat data points.
I tried following
vAxis: {
gridlines: {
count: -1
},
viewWindow: {
min: 0
},
format: '#'
},
but getting -1, 0, 1 data points on vaxis.
use option --> vAxis.ticks -- to show specific axis labels
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages: ['corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn('number', 'y');
var ticksY = [];
for (var i = 0; i <= 20; i++) {
data.addRow([i, i]);
ticksY.push(i);
}
var options = {
legend: 'none',
vAxis: {
ticks: ticksY
},
height: 600
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ScatterChart(container);
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google Chart: Pie Chart Slice based on legends

google.load('visualization', '1.1', {
packages : [ 'controls' ]
});
google.load('visualization', '1', {
packages : [ 'table' ]
});
google.load('visualization', '1.0', {
'packages' : [ 'corechart' ]
});
google.setOnLoadCallback(drawVisualization);
function drawVisualization() {
var data = [{tagId:'2a:10',isSafe:'Safe'},{tagId:'dd:80',isSafe:'Unsafe'},{tagId:'0a:07',isSafe:'Safe'},{tagId:'29:11',isSafe:'Safe'}];
var dataArray = [];
var datatable = new google.visualization.DataTable();
datatable.addColumn('string', 'TagID');
datatable.addColumn('string', 'Status');
$.each(data, function(i, obj) {
dataArray.push([ obj.tagId, obj.isSafe]);
});
datatable.addRows(dataArray);
var tagDivPicker = new google.visualization.ControlWrapper({
'controlType' : 'CategoryFilter',
'containerId' : 'tag_control_div',
'options' : {
filterColumnIndex : 0,
'ui' : {
'labelStacking' : 'vertical',
'allowTyping' : false,
'allowMultiple' : false
//,'cssClass':'form-control1 input-sm m-bot15'
}
}
});
var table_data = new google.visualization.ChartWrapper({
'chartType' : 'Table',
'containerId' : 'table_data',
'view' : {
'columns' : [ 0, 1]
}
});
var dataGroupColumnChart = google.visualization.data.group(
datatable, [1], [{
'column': 1,
'aggregation': google.visualization.data.count,
'type': 'number'
}]);
var pieChart = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'pie_chart',
'dataTable': dataGroupColumnChart,
options: {
'width': 600,
'height': 400,
title: 'Total Compliance',
slices: {0: {color: 'green'}, 1:{color: 'red'}}
}
});
pieChart.draw();
// Create the dashboard.
var dashboard = new google.visualization.Dashboard(document
.getElementById('dashboard'))
.bind([ tagDivPicker ],
[ table_data ]);
dashboard.draw(datatable);
google.visualization.events.addListener(tagDivPicker, 'statechange', function(event) {
pieChart.setDataTable(google.visualization.data.group(
// get the filtered results
table_data.getDataTable(),
[2], [{
'column': 2,
'aggregation': google.visualization.data.count,
'type': 'number'
}]
));
// redraw the pie chart to reflect changes
pieChart.draw();
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div style="float: left;" id="table_data"></div>
<div style="float: right;" id="pie_chart"></div>
<div id="tag_control_div"></div>
</div>
Context:
I'm using Google Chart dashboard and aggregation for manipulating the of chart. Currently I am able to change the dashboard data based on multiple filters which includes a Pie Chart and CategoryFilter.
When I select the CategoryFilter and if there is only one slice available then Pie chart takes the first slice color which is not the nice user interface.
For Example, below data suggests Safe-Unsafe Chart. So the legends color will be green for safe and red for unsafe.
Problem Statement:
Now if there are no safe records available then pie chart supposed to show slice with RED color but the chart takes first slice as default color if there are no records for second slice or legend.
Data:
[{"tagId":"2a:10","isSafe":"Safe"},{"tagId":"dd:80","isSafe":"Unsafe"},{"tagId":"0a:07","isSafe":"Safe"},{"tagId":"29:11","isSafe":"Safe"}]
1. don't need both jsapi and loader.js
plus, according to the release notes...
The version of Google Charts that remains available via the jsapi loader is no longer being updated consistently. Please use the new gstatic loader (loader.js) from now on.
this will change the load statement to...
google.charts.load('current', {
callback: drawVisualization,
packages: ['controls', 'corechart', 'table']
});
(you can include the callback in the load statement)
2. since the pie chart is being drawn separately, agg the data from the table chart,
each time the 'ready' event is fired
then assign the slice colors, according to the row values in the table chart, using the colors option
see following working snippet...
google.charts.load('current', {
callback: drawVisualization,
packages: ['controls', 'corechart', 'table']
});
function drawVisualization() {
var data = [{tagId:'2a:10',isSafe:'Safe'},{tagId:'dd:80',isSafe:'Unsafe'},{tagId:'0a:07',isSafe:'Safe'},{tagId:'29:11',isSafe:'Safe'}];
var dataArray = [];
var datatable = new google.visualization.DataTable();
datatable.addColumn('string', 'TagID');
datatable.addColumn('string', 'Status');
$.each(data, function(i, obj) {
dataArray.push([obj.tagId, obj.isSafe]);
});
datatable.addRows(dataArray);
var tagDivPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'tag_control_div',
options: {
filterColumnIndex: 0,
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: true
}
}
});
var table_data = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table_data',
view: {
columns: [0, 1]
}
});
var dashboard = new google.visualization.Dashboard(document
.getElementById('dashboard'))
.bind([tagDivPicker], [table_data])
.draw(datatable);
google.visualization.events.addListener(table_data, 'ready', function () {
var colors = {
Safe: 'green', Unsafe: 'red'
};
var pieColors = [];
var dataGroupColumnChart = google.visualization.data.group(
table_data.getDataTable(), [1], [{
column: 1,
aggregation: google.visualization.data.count,
type: 'number'
}]);
for (var i = 0; i < dataGroupColumnChart.getNumberOfRows(); i++) {
pieColors.push(colors[dataGroupColumnChart.getValue(i, 0)]);
}
var pieChart = new google.visualization.ChartWrapper({
chartType: 'PieChart',
containerId: 'pie_chart',
dataTable: dataGroupColumnChart,
options: {
width: 600,
height: 400,
title: 'Total Compliance',
colors: pieColors
}
});
pieChart.draw();
});
}
.float {
display: inline-block;
padding: 4px;
vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div class="float" id="table_data"></div>
<div class="float" id="tag_control_div"></div>
<div id="pie_chart"></div>
</div>

Google Charts, Line Chart with Date Range Filter

I am using a line chart, which allows selective visibility of the Y series data on the chart by clicking the legend. Something like the Google Finance charts which allows you to add different stocks onto the chart.
I want to add a date range filter like at the bottom of the Annotation Chart in this example:
https://developers.google.com/chart/interactive/docs/gallery/annotationchart
but it just displays a blank screen.
Here's my code for the Line Chart:
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['annotationchart']}]}"></script>
<script type='text/javascript'>
google.load("visualization", "1", {packages:["corechart"]});
google.load('visualization', '1', { packages : ['controls'] } );
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Date', 'Sales', 'Expenses'],
['2004', 1000, 400],
['2005', 1170, 460],
['2006', 660, 1120],
['2007', 1030, 540],
['2014', 1230, 40]
]);
var options = {
width: 900,
height: 600,
title: 'Company Performance',
displayAnnotations: true,
series: series
}
var chart = new google.visualization.LineChart(document.getElementById('chart_div')); //line chart
chart.draw(data, options);
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is null, we clicked on the legend
if (sel[0].row == null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
}
</script>
</head>
<body>
<div id='chart_div' style='width: 900px; height: 600px;'></div>
</body>
</html>
You should use a dashboard with a chartwrapper for the LineChart and a daterangefilter as a ControlWrapper instead of initializing the chart as you do (You aren't even calling the daterangefilter).