elow you will find my grouped and stacked barchart, this works so far fine. But how can I add the information of the grouped value.
If I roll over each block I get the value of this block, but I need the cumulation of the blocks.
Example: Block1: 1.000 Block2: 1.500 Block3: 1.000 Block4: 2.000
If I roll over the third block the value must be 3.500.
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.1', {'packages': ['bar']});
google.setOnLoadCallback(drawStuff);
function drawStuff() {
var data = new google.visualization.DataTable();
data.addColumn('string', '');
data.addColumn('number', 'level 1');
data.addColumn('number', 'level 2');
data.addColumn('number', 'level 3');
data.addColumn('number', 'level 4');
data.addColumn('number', 'current value');
data.addRows([
['Team1', {!Team1_l1}, {!Team1_l2}, {!Team1_l3}, {!Team1_l4}, {!Team1_cv}],
['Team2', {!Team2_l1}, {!Team2_l2}, {!Team2_l3}, {!Team2_l4}, {!Team2_cv}],
]);
var options = {
isStacked: true,
width: 890,
height: 500,
backgroundColor: '#F8F8F8',
chartArea: { backgroundColor: '#F8F8F8' },
chart: {
subtitle: 'current view of the incentive'
},
vAxis: {
format: 'decimal',
viewWindow: {
min: 0,
max: 30000000
}
},
series: {
4: { targetAxisIndex: 1 },
5: { targetAxisIndex: 1 }
}
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
</script>
<div id="chart_div"></div>
only way to change the tooltip is to provide a custom one using a tooltip column role
however, column roles are not support by Material charts (along with many other options)
google.charts.Bar --- packages: ['bar']
using a Classic chart is the only option...
google.visualization.ColumnChart --- packages: ['corechart']
to aggregate the values of each stack, provide a custom tooltip
use a DataView and the setColumns() method to dynamically add columns for the tooltips
to use custom html tooltip, must set property --> html: true -- on the column,
and set chart option --> tooltip: {isHtml: true}
there is a minor bug with DataView, it does not respect column properties
must convert back to a DataTable before drawing --> dataView.toDataTable()
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = new google.visualization.DataTable();
data.addColumn('string', '');
data.addColumn('number', 'level 1');
data.addColumn('number', 'level 2');
data.addColumn('number', 'level 3');
data.addColumn('number', 'level 4');
data.addColumn('number', 'current value');
data.addRows([
['Team1', 1000, 1500, 1000, 2000, 1800],
['Team2', 2000, 2500, 2000, 3000, 2800]
]);
var options = {
isStacked: true,
width: 890,
height: 500,
backgroundColor: '#F8F8F8',
chartArea: {
backgroundColor: '#F8F8F8'
},
chart: {
subtitle: 'current view of the incentive'
},
colors: ['#2196f3', '#42a5f5', '#64b5f6', '#90caf9', '#bbdefb'],
tooltip: {
isHtml: true
},
vAxis: {
format: 'decimal',
viewWindow: {
min: 0,
max: 15000
}
}
};
// number formatter
var formatNumber = new google.visualization.NumberFormat({
pattern: options.vAxis.format
});
// build data view columns
var viewColumns = [];
for (var col = 0; col < data.getNumberOfColumns(); col++) {
addColumn(col);
}
function addColumn(col) {
// add data table column
viewColumns.push(col);
// add tooltip column
if ((col > 0) && (col < (data.getNumberOfColumns() - 1))) {
viewColumns.push({
type: 'string',
role: 'tooltip',
calc: function (dt, row) {
// calculate aggregate
var aggregateValue = 0;
for (var aggCol = 1; aggCol <= col; aggCol++) {
aggregateValue += dt.getValue(row, aggCol);
}
// build custom tooltip
var tooltip = '<div class="ggl-tooltip"><div><span>';
tooltip += dt.getFormattedValue(row, 0) + '</span></div>';
tooltip += '<div>' + dt.getColumnLabel(col) + ': ';
tooltip += '<span>' + formatNumber.formatValue(aggregateValue) + '</span></div></div>';
return tooltip;
},
p: {html: true}
});
}
}
var dataView = new google.visualization.DataView(data);
dataView.setColumns(viewColumns);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
// use data view to draw chart
chart.draw(dataView.toDataTable(), options);
});
.ggl-tooltip {
background-color: #ffffff;
border: 1px solid #e0e0e0;
font-family: Arial, Helvetica;
font-size: 14px;
padding: 12px 12px 12px 12px;
}
.ggl-tooltip div {
margin-top: 4px;
}
.ggl-tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
note: jsapi should no longer be used to load the charts library,
according to the release notes...
The version of Google Charts that remains available via the jsapi loader is no longer being updated consistently. The last update, for security purposes, was with a pre-release of v45. Please use the new gstatic loader.js from now on.
this will only change the load statement, see above snippet...
Related
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>
From a research, I got that the tooltip that appears on Gannt Google Chart is not customizable, so I decided to override it capturing the hover event triggered by my gannt's rectangles as follow:
google.visualization.events.addListener(chart, 'onmouseover', function (e) {
openTooltip(data, e.row);
});
But now the problem is that the default tooltip popup still opens, how can I disable the default tooltip? (chart options/ custom jquery)
there aren't any options to remove the default tooltip on a Gantt chart
the tooltip is drawn using svg elements, which are added dynamically when you hover a bar
we can use a MutationObserver to know when the tooltip has been added
we can't remove the tooltip because it will break the chart
but we can make it invisible / all the elements transparent
see following working snippet...
google.charts.load('current', {
packages:['gantt']
}).then(function () {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Task ID');
data.addColumn('string', 'Task Name');
data.addColumn('date', 'Start Date');
data.addColumn('date', 'End Date');
data.addColumn('number', 'Duration');
data.addColumn('number', 'Percent Complete');
data.addColumn('string', 'Dependencies');
data.addRows([
['Research', 'Find sources',
new Date(2015, 0, 1), new Date(2015, 0, 5), null, 100, null],
['Write', 'Write paper',
null, new Date(2015, 0, 9), daysToMilliseconds(3), 25, 'Research,Outline'],
['Cite', 'Create bibliography',
null, new Date(2015, 0, 7), daysToMilliseconds(1), 20, 'Research'],
['Complete', 'Hand in paper',
null, new Date(2015, 0, 10), daysToMilliseconds(1), 0, 'Cite,Write'],
['Outline', 'Outline paper',
null, new Date(2015, 0, 6), daysToMilliseconds(1), 100, 'Research']
]);
var options = {
height: 275
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.Gantt(container);
google.visualization.events.addOneTimeListener(chart, 'ready', function () {
var observer = new MutationObserver(function (nodes) {
Array.prototype.forEach.call(nodes, function(node) {
if (node.addedNodes.length > 0) {
Array.prototype.forEach.call(node.addedNodes, function(addedNode) {
if ((addedNode.tagName === 'rect') && (addedNode.getAttribute('fill') === 'white')) {
addedNode.setAttribute('fill', 'transparent');
addedNode.setAttribute('stroke', 'transparent');
Array.prototype.forEach.call(addedNode.parentNode.getElementsByTagName('text'), function(label) {
label.setAttribute('fill', 'transparent');
});
}
});
}
});
});
observer.observe(container, {
childList: true,
subtree: true
});
});
chart.draw(data, options);
function daysToMilliseconds(days) {
return days * 24 * 60 * 60 * 1000;
}
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
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.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>
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).