Google Column Chart with two columns - javascript

How to approach a column chart when having month and year.
My data is in this format
['Group','Count','Month','Year'],
['A',10,'February',2015],
['B',8,'February',2015],
['C',15,'February',2016]
Aim is to create a column chart which has X-axis as Month and Y-axis as Count. Now X-axis should have Count for years grouped by month.
Something like this -
I tried to simply pass the above data to see what I can get, but I get error.
Any way to assign Axis the values based on year grouped by month ?
JsFiddle of Google Chart Example

just need three columns, something like this...
['Month', '2015', '2016'],
['Jan', 10, 15],
['Feb', 12, 18],
['Mar', 14, 21],
['Apr', 16, 24]
then you can use a DataView to add the annotations, via calculated columns...
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}]);
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Month', '2015', '2016'],
['Jan', 10, 15],
['Feb', 12, 18],
['Mar', 14, 21],
['Apr', 16, 24]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}]);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(view, {});
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
all google charts require a specific DataFormat
meaning, manipulation is required if your data does not already exist in this format
the visualization library does offer some Data Manipulation Methods, such as group()
which could be used to transform the data into the required format
1) group the data by Month and Year
2) create a new DataTable with the Month column
3) add a column for each Year from the grouped table
4) add the rows for each month
see following working snippet, using the data from the question...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Group', 'Count', 'Month', 'Year'],
['A', 10, 'February', 2015],
['B', 8, 'February', 2015],
['C' , 15, 'February', 2016]
]);
// group by month / year
var dataGroup = google.visualization.data.group(
data,
[2, 3],
[{column: 1, aggregation: google.visualization.data.sum, type: 'number', label: 'Count'}]
);
dataGroup.sort([{column: 0},{column: 1}]);
// build final data table
var yearData = new google.visualization.DataTable({
cols: [
{label: 'Month', type: 'string'}
]
});
// add column for each year
var years = dataGroup.getDistinctValues(1);
for (var i = 0; i < years.length; i++) {
yearData.addColumn(
{label: years[i], type: 'number'}
);
}
// add row for each month
var rowMonth = null;
var rowIndex = null;
for (var i = 0; i < dataGroup.getNumberOfRows(); i++) {
if (rowMonth !== dataGroup.getValue(i, 0)) {
rowMonth = dataGroup.getValue(i, 0);
rowIndex = yearData.addRow();
yearData.setValue(rowIndex, 0, rowMonth);
}
for (var x = 1; x < yearData.getNumberOfColumns(); x++) {
if (yearData.getColumnLabel(x) === dataGroup.getValue(i, 1).toString()) {
yearData.setValue(rowIndex, x, dataGroup.getValue(i, 2));
}
}
}
var view = new google.visualization.DataView(yearData);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
chart.draw(view);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Related

How to show a value in google chart [duplicate]

I need to put labels over my google.chart.Bar (not google.visualization.BarChart) the chart is correctly visualized but only shows values on mouse over the bars,please helpme!.
without mouse over
with mouse over
the data is taked from hidden inputs... here the code :
var data3 = new google.visualization.arrayToDataTable([
['Ambitos', 'Programados', 'Terminados',{ role: 'style' }],
['ex', parseInt(document.getElementById("sumex").value),(parseInt(document.getElementById("sumex").value))-( parseInt(document.getElementById("sumpex").value)),document.getElementById("sumex").value],
['ma', parseInt(document.getElementById("summa").value),(parseInt(document.getElementById("summa").value))-( parseInt(document.getElementById("sumpma").value)),document.getElementById("summa").value],
['mo', parseInt(document.getElementById("summo").value),(parseInt(document.getElementById("summo").value))-( parseInt(document.getElementById("sumpmo").value)),document.getElementById("summo").value],
['re', parseInt(document.getElementById("sumre").value),(parseInt(document.getElementById("sumre").value))-( parseInt(document.getElementById("sumpre").value)),document.getElementById("sumre").value],
['tx', parseInt(document.getElementById("sumtx").value),(parseInt(document.getElementById("sumtx").value))-( parseInt(document.getElementById("sumptx").value)),document.getElementById("sumtx").value]]);
var view3 = new google.visualization.DataView(data3);
view3.setColumns([0,1,2,
{ calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation" },3]);
var options3 = {
legend: { position: "none" },
chart: {
title: 'Resumen General',
subtitle: 'programados v/s terminados'},
series: {},
axes: { y: {
distance: {label: ''}, } },
chartArea : { width:"95%", height:"80%"} };
var chart3 = new google.charts.Bar(document.getElementById('barras'));
chart3.draw(data3, options3);
p.d. sorry for my bad english!
unfortunately, annotations (bar labels) are not supported on Material charts
recommend using Core chart, with the following option instead...
theme: 'material'
an separate annotation column should be added for each series column,
that should have annotations
when using a DataView to add annotation columns,
be sure to draw the chart using the view (view3),
instead of the original data table (data3)
see following working snippet...
google.charts.load('current', {
callback: function () {
var data3 = new google.visualization.arrayToDataTable([
['Ambitos', 'Programados', 'Terminados',{ role: 'style' }],
['ex', 8,(8)-(6),''],
['ma', 6,(6)-(4),''],
['mo', 4,(4)-(2),''],
['re', 2,(2)-(1),''],
['tx', 1,(1)-(0),'']]);
var view3 = new google.visualization.DataView(data3);
view3.setColumns([0,
1,
{
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
},
2,
{
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
},
3
]);
var options3 = {
legend: { position: "none" },
chart: {
title: 'Resumen General',
subtitle: 'programados v/s terminados'
},
series: {},
axes: {
y: {
distance: {label: ''},
}
},
chartArea : {
width:"95%",
height:"80%"
},
theme: 'material'
};
var chart3 = new google.visualization.ColumnChart(document.getElementById('barras'));
chart3.draw(view3, options3);
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="barras"></div>
note: list of options unavailable to Material --> Tracking Issue for Material Chart Feature Parity

Moving annotations on Bar Chart with Negative Values Google Chart

I am using google charts within an MVC project.
I am looking to implement a bar chart that has negative values.
I would like the annotations on the negative portion of the chart to be on the same side as the end of the bar (just like the positive, see image below, green box is where I would like annotations to be).
I cant seem to find any documentation on how this can be achieved.
Is it possible to move the annotation to the other side?
there are no standard config options that will move the annotations
but you can move them manually
however, the chart will actually move them back whenever activity occurs,
such as on bar hover
have to use a MutationObserver, or something, to keep them there
use chart methods --> getChartLayoutInterface().getXLocation(value)
to find the location
also, need to adjust the axis window to leave room for the labels
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable({
cols: [
{label: 'x', type: 'string'},
{label: 'y0', type: 'number'},
],
rows: [
{c:[{v: 'Omega'}, {v: -0.95}]},
{c:[{v: 'Large'}, {v: -0.92}]},
{c:[{v: 'Medium'}, {v: 2.76}]},
{c:[{v: 'Tiny'}, {v: 2.03}]}
]
});
var options = {
annotations: {
alwaysOutside: true,
stem: {
color: 'transparent'
},
textStyle: {
color: '#000000'
}
},
hAxis: {
// leave room for annotation
viewWindow: {
min: data.getColumnRange(1).min - 1
}
},
legend: {
position: 'none'
}
};
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}]);
var container = document.getElementById('chart');
var chart = new google.visualization.BarChart(container);
// move annotations
var observer = new MutationObserver(function () {
$.each($('text[text-anchor="start"]'), function (index, label) {
var labelValue = parseFloat($(label).text());
// only negative -- and -- not on tooltip
if ((labelValue < 0) && ($(label).attr('font-weight') !== 'bold')) {
var bounds = label.getBBox();
var chartLayout = chart.getChartLayoutInterface();
$(label).attr('x', chartLayout.getXLocation(labelValue) - bounds.width - 8);
}
});
});
observer.observe(container, {
childList: true,
subtree: true
});
chart.draw(view, options);
},
packages: ['corechart']
});
<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="chart"></div>

how to use boolean type column in Google calendar charts?

I want to depict build status (Pass or fail) using a boolean type(true/false) on google's Calendar type charts. I am using the below HTML code for the same. But I am getting a red flag prompting me to add 2 columns . Any suggestions what could be wrong in this snippet ?
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {packages:["calendar"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'date', id: 'Date' });
dataTable.addColumn({ type: 'boolean',id :'pass/fail', role:'certainty' });
dataTable.addRows([
[ new Date(2012, 3, 13), true ],
[ new Date(2012, 3, 14), true ],
[ new Date(2012, 3, 15), true ],
[ new Date(2012, 3, 16), true ],
[ new Date(2012, 3, 17), false ]
// Many rows omitted for brevity.
]);
var chart = new google.visualization.Calendar(document.getElementById('calendar_basic'));
var options = {
title: "Build Execution Analytics",
height: 350,
};
chart.draw(dataTable, options);
}
</script>
</head>
<body>
<div id="calendar_basic" style="width: 1000px; height: 350px;"></div>
</body>
</html>
each chart type has a specific Data Format
Calendar charts do not accept a boolean column
from the reference, allowed columns are...
column 0 -- date, datetime, or timeofday
column 1 -- number
column n -- string -- role: tooltip (optional)
I would suggest using a certain number for pass and another for fail
google.charts.load('current', {
callback: function () {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'date', id: 'Date' });
dataTable.addColumn({ type: 'number', id :'pass/fail' });
dataTable.addRows([
[ new Date(2012, 3, 13), 100 ], // pass
[ new Date(2012, 3, 14), 100 ], // pass
[ new Date(2012, 3, 15), 100 ], // pass
[ new Date(2012, 3, 16), 100 ], // pass
[ new Date(2012, 3, 17), 0 ] // fail
]);
var chart = new google.visualization.Calendar(document.getElementById('calendar_basic'));
chart.draw(dataTable, {
title: 'Build Execution Analytics',
height: 350,
});
},
packages:["calendar"]
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="calendar_basic"></div>

How to retain tooltip when pivoting Google Visualization DataTable

I'm using some great code from #asgallant to pivot a Google DataTable for use in a line chart. His code is here: http://jsfiddle.net/asgallant/HkjDe/
In my original DataTable I have a 4th column however that is a tooltip string. When I pivot the table with his code my tooltip if no longer available. I would like to use the tooltips provided and for the cells that are 'created' use some standard tooltip text. Here is what my version of the initial table setup looks like.
var data = new google.visualization.DataTable();
data.addColumn('number', 'A');
data.addColumn('string', 'B');
data.addColumn('number', 'C');
data.addColumn({type: 'string', role: 'tooltip'});
data.addRows([
[1, 'foo', 6, 't1'],
[2, 'foo', 2, 'hello'],
[3, 'foo', 1, 't2'],
[4, 'foo', 3, 'test'],
[1, 'bar', 7, 't3'],
[2, 'bar', 3, 'again'],
[1, 'baz', 8, 't4'],
[2, 'baz', 4, 'and'],
[2, 'cad', 5, 't5'],
[3, 'cad', 6, 'again'],
[1, 'qud', 9, 'x'],
[5, 'qud', 1, 'z']
]);
Can anyone provide some assistance?
-- UPDATE --
Edited the initial addRows statement to be more representative of my data model.
In order to preserve the tooltips, you need to add tooltip columns to the view and pivot data:
for (var i = 0; i < distinctValues.length; i++) {
viewColumns.push({
type: 'number',
label: distinctValues[i],
calc: (function (x) {
return function (dt, row) {
// return values of C only for the rows where B = distinctValues[i] (passed into the closure via x)
return (dt.getValue(row, 1) == x) ? dt.getValue(row, 2) : null;
}
})(distinctValues[i])
});
groupColumns.push({
column: (i * 2) + 1,
type: 'number',
label: distinctValues[i],
aggregation: google.visualization.data.sum
});
// add columns for the tooltips
viewColumns.push({
type: 'string',
calc: (function (x) {
return function (dt, row) {
// return values of the tooltip column only for the rows where B = distinctValues[i] (passed into the closure via x)
return (dt.getValue(row, 1) == x) ? dt.getValue(row, 3) : null;
}
})(distinctValues[i])
});
groupColumns.push({
column: (i * 2) + 2,
type: 'string',
aggregation: function (values) {
return values.join('');
}
});
}
The group function does not handle column roles properly, so you have to set them afterwards:
// fix the tooltip column roles, since the group function won't create them properly
for (var i = 1; i < pivotedData.getNumberOfColumns(); i++) {
if (pivotedData.getColumnType(i) == 'string') {
pivotedData.setColumnProperty(i, 'role', 'tooltip');
}
}
See example: http://jsfiddle.net/asgallant/HkjDe/23/

Programmatically Pivoting the Google Visualization dataTable

I excited with this fiddle and I tried to create the same kind with reference to that fiddle. My modified sample is given in here and i'm trying to create a view as follows.
var distinctValues = data.getDistinctValues(2);
var viewColumns = [1];
var groupColumns = [];
// build column arrays for the view and grouping
for (var i = 0; i < distinctValues.length; i++) {
viewColumns.push({
type: 'number',
label: distinctValues[i],
aggregation: google.visualization.data.count
});
groupColumns.push({
column: i+1,
type: 'number',
//label: distinctValues[i],
aggregation: google.visualization.data.sum
});
}
But my aim is to create a pivot table something like as follows.
['Column1', 'Column2', 100, 200, 300, 400],
['A', 'bar', 0, 1, 1, 0],
['A', 'baz', 0, 0, 1, 0],
['A', 'foo', 3, 1, 0, 0],
['B', 'baz', 0, 1, 0, 0],
['B', 'cad', 1, 0, 1, 1],
['B', 'qud', 1, 1, 1, 2]
How can I proceed?
You have to change a few things in your code. First, the viewColumns needs to contain both columns 0 and 1 to start if you want Column1 and Column2 to both be in the output. Then, you need to adjust the columns you add to the viewColumns: each one needs a calc parameter which calculates the value in the column. In this case, you want to compare the value of the column to distinctValues[i] and return 1 when they match and 0 when they don't. In the aggregation function for groupColumns, use sum instead of count:
var distinctValues = data.getDistinctValues(2);
var viewColumns = [0, 1];
var groupColumns = [];
// build column arrays for the view and grouping
for (var i = 0; i < distinctValues.length; i++) {
viewColumns.push({
type: 'number',
label: distinctValues[i],
calc: (function (x) {
return function (dt, row) {
return (dt.getValue(row, 2) == x) ? 1 : 0;
}
})(distinctValues[i])
});
groupColumns.push({
column: i+2,
type: 'number',
//label: distinctValues[i],
aggregation: google.visualization.data.sum
});
}
Then, in the grouping function, pass columns 0 and 1 in the first array:
var pivotedData = google.visualization.data.group(view, [0, 1], groupColumns);
See these changes working here: http://jsfiddle.net/asgallant/DUn6B/1/

Categories

Resources