I wanted to arrange data annotations on google chart following the instructions I found here, and google documentation. And this is what I have now:
https://jsfiddle.net/u6tn97km/
I couldn't place the data values and data points together. Instead data values are all stacked together. How can I fix this problem?
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn('number', 'values');
data.addColumn({id:'i0', type:'number', role:'interval'});
data.addColumn({id:'i1', type:'number', role:'interval'});
data.addColumn({id:'i2', type:'number', role:'interval'});
data.addColumn({id:'i2', type:'number', role:'interval'});
data.addColumn({id:'i2', type:'number', role:'interval'});
data.addColumn({id:'i2', type:'number', role:'interval'});
data.addRows([
[1, 19,4,7,17,20,24,26],
[2, 13,2,10,11,15,20,25],
[3, 14,7,10,10,17,20,25],
[4, 14,4,8,11,16,26,27],
[5, 12,5,8,10,13,19,21],
[6, 13,1,10,10,15,20,25],
[7, 18,7,11,13,22,23,24],
[8, 17,3,9,12,22,25,26],
[9, 25,12,20,24,26,26,27],
[10, 16,6,8,15,16,17,23],
[11, 12,1,3,6,18,18,26],
[12, 12,1,3,12,12,18,19]]);
// The intervals data as narrow lines (useful for showing raw source data)
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'
}, 3, {
calc: 'stringify',
sourceColumn: 3,
type: 'string',
role: 'annotation'
}, 4, {
calc: 'stringify',
sourceColumn: 4,
type: 'string',
role: 'annotation'
}, 5, {
calc: 'stringify',
sourceColumn: 5,
type: 'string',
role: 'annotation'
}, 6, {
calc: 'stringify',
sourceColumn: 6,
type: 'string',
role: 'annotation'
}, 7, {
calc: 'stringify',
sourceColumn: 7,
type: 'string',
role: 'annotation'
} ]);
var options_bars = {
title: 'Bars, default',
curveType: 'function',
series: [{'color': '#D9544C'}],
intervals: { style: 'bars', pointSize: 9, barWidth: 1, shortBarWidth:0.5},
'tooltip' : { trigger: 'none'},
enableInteractivity: false,
annotations: { stemColor: 'white', textStyle: { fontSize: 10 } },
pointSize: 8,
legend: 'none',
};
var chart_lines = new google.visualization.LineChart(document.getElementById('chart_lines'));
// chart_lines.draw(data, options_bars);
chart_lines.draw(view, options_bars);
}
and HTML:
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_lines" style="width: 900px; height: 500px;"></div>
annotations are placed above the series they represent,
since the interval columns are roles and not series,
all the annotations are stacked above the one point
to place the annotations in the desired location,
we can add additional, hidden series to the chart,
and an annotation above the new series
add the new series as a column on the data view,
then add the annotation after the new series...
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, 3, 4, 5, 6, 7, { // new series start here, after all the original columns
calc: function (dt, row) {
return dt.getValue(row, 2);
},
type: 'number'
}, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}, {
calc: function (dt, row) {
return dt.getValue(row, 3);
},
type: 'number'
}, {
calc: 'stringify',
sourceColumn: 3,
type: 'string',
role: 'annotation'
}, {
...
to hide the new series, use the series option to change the type to scatter, and set the pointSize to zero
series: {
1: {
pointSize: 0,
type: 'scatter'
},
2: {
pointSize: 0,
type: 'scatter'
},
...
see following working snippet...
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn('number', 'values');
data.addColumn({id:'i0', type:'number', role:'interval'});
data.addColumn({id:'i1', type:'number', role:'interval'});
data.addColumn({id:'i2', type:'number', role:'interval'});
data.addColumn({id:'i2', type:'number', role:'interval'});
data.addColumn({id:'i2', type:'number', role:'interval'});
data.addColumn({id:'i2', type:'number', role:'interval'});
data.addRows([
[1, 19,4,7,17,20,24,26],
[2, 13,2,10,11,15,20,25],
[3, 14,7,10,10,17,20,25],
[4, 14,4,8,11,16,26,27],
[5, 12,5,8,10,13,19,21],
[6, 13,1,10,10,15,20,25],
[7, 18,7,11,13,22,23,24],
[8, 17,3,9,12,22,25,26],
[9, 25,12,20,24,26,26,27],
[10, 16,6,8,15,16,17,23],
[11, 12,1,3,6,18,18,26],
[12, 12,1,3,12,12,18,19]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, 3, 4, 5, 6, 7, {
calc: function (dt, row) {
return dt.getValue(row, 2);
},
type: 'number'
}, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}, {
calc: function (dt, row) {
return dt.getValue(row, 3);
},
type: 'number'
}, {
calc: 'stringify',
sourceColumn: 3,
type: 'string',
role: 'annotation'
}, {
calc: function (dt, row) {
return dt.getValue(row, 4);
},
type: 'number'
}, {
calc: 'stringify',
sourceColumn: 4,
type: 'string',
role: 'annotation'
}, {
calc: function (dt, row) {
return dt.getValue(row, 5);
},
type: 'number'
}, {
calc: 'stringify',
sourceColumn: 5,
type: 'string',
role: 'annotation'
}, {
calc: function (dt, row) {
return dt.getValue(row, 6);
},
type: 'number'
}, {
calc: 'stringify',
sourceColumn: 6,
type: 'string',
role: 'annotation'
}, {
calc: function (dt, row) {
return dt.getValue(row, 7);
},
type: 'number'
}, {
calc: 'stringify',
sourceColumn: 7,
type: 'string',
role: 'annotation'
}]);
var options_bars = {
title: 'Bars, default',
colors: ['#d9544c'],
curveType: 'function',
series: {
1: {
pointSize: 0,
type: 'scatter'
},
2: {
pointSize: 0,
type: 'scatter'
},
3: {
pointSize: 0,
type: 'scatter'
},
4: {
pointSize: 0,
type: 'scatter'
},
5: {
pointSize: 0,
type: 'scatter'
},
6: {
pointSize: 0,
type: 'scatter'
},
7: {
pointSize: 0,
type: 'scatter'
}
},
intervals: {style: 'bars', pointSize: 9, barWidth: 1, shortBarWidth: 0.5},
tooltip : {trigger: 'none'},
enableInteractivity: false,
annotations: {stemLength: 2, stemColor: 'transparent', textStyle: {fontSize: 10}},
pointSize: 8,
legend: 'none',
};
var chart_lines = new google.visualization.LineChart(document.getElementById('chart_lines'));
chart_lines.draw(view, options_bars);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_lines" style="width: 900px; height: 500px;"></div>
Related
I have a formatted label displayed on the bars on my chart.
This value also gets formatted in the tooltip. Is there a way to show the unformatted, raw value on the tooltip, while keeping it formatted on the label?
https://jsfiddle.net/67u052kL/1/
var formatter = new google.visualization.NumberFormat({
pattern: 'short'
});
formatter.format(data, 1);
formatter.format(data, 3);
only format the annotation value.
to accomplish, use a custom function for the annotation role, instead of the 'stringify' function.
and you can use the formatter's formatValue method, to format a single value.
view.setColumns([0, 1, {
calc: function (dt, row) {
return formatter.formatValue(dt.getValue(row, 1));
},
type: 'string',
role: 'annotation'
}, 2, 3, {
calc: function (dt, row) {
return formatter.formatValue(dt.getValue(row, 3));
},
type: 'string',
role: 'annotation'
}]);
see following working snippet...
google.charts.load('50', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Team' , 'Actual', { role: 'style'}, 'Target'],
['Alpha' , 35976, 'color: #F6931D', 90000],
['Beta' , 40542, 'color: #FDCB2F', 104167],
['Gamma' , 111227, 'color: #8AC659', 205000],
['Delta' , 238356, 'color: #32A242', 205000],
['Epsilon', 170555, 'color: #3A81C2', 354167]
]);
var formatter = new google.visualization.NumberFormat({
pattern: 'short'
});
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
return formatter.formatValue(dt.getValue(row, 1));
},
type: 'string',
role: 'annotation'
}, 2, 3, {
calc: function (dt, row) {
return formatter.formatValue(dt.getValue(row, 3));
},
type: 'string',
role: 'annotation'
}]);
var options = {
title: {position: 'none'},
orientation: 'vertical',
animation: {duration : 600, startup: 'true', easing:'out'},
annotations: {highContrast: 'true'},
legend: {position: 'none'},
// theme: 'material',
chartArea:{top:5, right: 25, width: '70%', height: '90%'},
hAxis: {format:'short'},
// vAxis: {textPosition:'in'},
// bar: {groupWidth: '90%'},
seriesType: 'bars',
series: {
1: {type: 'bars', color: 'lightgray'}
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chartContentPane'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chartContentPane"></div>
I'm a bit new with google charts, I was playing around to learn it but I got two problems with my chart:
1) I'm not sure why the second chart (red) displays without animation
2) How can I extend the annotation lines with the values to the top of my graph?
The best case would be that the values are shown under the chart title
<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 data1 = new google.visualization.DataTable();
data1.addColumn('number', 'x');
data1.addColumn('number', 'green');
data1.addRows([
[0.005, 3],
[0.006, 6],
[0.007, 5],
[0.008, 8],
[0.009, 2],
[0.010, 5],
[0.011, 5],
[0.012, 4],
[0.013, 8]
]);
var data2 = new google.visualization.DataTable();
data2.addColumn('number', 'x');
data2.addColumn('number', 'red');
data2.addRows([
[0.016, 5],
[0.017, 1],
[0.018, 3],
[0.019, 9],
[0.020, 4],
[0.021, 5],
[0.022, 7],
[0.023, 7],
[0.024, 3]
]);
var joinedData = google.visualization.data.join(data1, data2, 'full',
[[0, 0]], [1], [1]);
var options = {
title: 'Playground',
colors: ['#007F01', '#FE0002'],
interpolateNulls: true,
hAxis: {
title: 'Price',
titleTextStyle: {
color: '#333'
},
direction: 1,
format: 'decimal'
},
vAxis: {
direction: 1
},
orientation: 'horizontal',
// customize colum
series: {
0: {type: "area"},
1: {type: "area"},
},
// legend: {position : 'left'},
animation: {
startup: true,
duration: 1000,
easing: 'out',
}
};
var view = new google.visualization.DataView(joinedData);
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.ComboChart(document.getElementById('chart_div'));
chart.draw(view, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 100%; height: 500px;"></div>
</body>
</html>
Here you can run it:
jsfiddle
there is bug within google charts when working with data views and animation.
an easy fix is to convert the view back to a data table when drawing the chart...
view.toDataTable()
e.g.
chart.draw(view.toDataTable(), options);
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data1 = new google.visualization.DataTable();
data1.addColumn('number', 'x');
data1.addColumn('number', 'green');
data1.addRows([
[0.005, 3],
[0.006, 6],
[0.007, 5],
[0.008, 8],
[0.009, 2],
[0.010, 5],
[0.011, 5],
[0.012, 4],
[0.013, 8]
]);
var data2 = new google.visualization.DataTable();
data2.addColumn('number', 'x');
data2.addColumn('number', 'red');
data2.addRows([
[0.016, 5],
[0.017, 1],
[0.018, 3],
[0.019, 9],
[0.020, 4],
[0.021, 5],
[0.022, 7],
[0.023, 7],
[0.024, 3]
]);
var joinedData = google.visualization.data.join(data1, data2, 'full',
[[0, 0]], [1], [1]);
var options = {
title: 'Playground',
colors: ['#007F01', '#FE0002'],
interpolateNulls: true,
hAxis: {
title: 'Price',
titleTextStyle: {
color: '#333'
},
direction: 1,
format: 'decimal'
},
vAxis: {
direction: 1
},
orientation: 'horizontal',
// customize colum
series: {
0: {type: "area"},
1: {type: "area"},
},
// legend: {position : 'left'},
animation: {
startup: true,
duration: 1000,
easing: 'out',
}
};
var view = new google.visualization.DataView(joinedData);
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.ComboChart(document.getElementById('chart_div'));
chart.draw(view.toDataTable(), options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 100%; height: 500px;"></div>
UPDATE
as for extending the annotation lines,
you can change the length,
but this will just increase the size of each,
and they still will not be aligned at the top
annotations: {
stem: {
length: 10
}
},
the only way would be to modify the chart manually, after it draws
you can move the labels and increase the height of the lines
but this will create two issues
1) the chart will move them back, anytime there is interactivity, such as hovering the labels or data points
to fix, you can use a MutationObserver
this will override the settings, every time the chart tries to move them back
2) if you use chart method getImageURI to get an image of the chart, the changes will not appear
to fix this, use html2canvas to get the image instead of the chart method
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data1 = new google.visualization.DataTable();
data1.addColumn('number', 'x');
data1.addColumn('number', 'green');
data1.addRows([
[0.005, 3],
[0.006, 6],
[0.007, 5],
[0.008, 8],
[0.009, 2],
[0.010, 5],
[0.011, 5],
[0.012, 4],
[0.013, 8]
]);
var data2 = new google.visualization.DataTable();
data2.addColumn('number', 'x');
data2.addColumn('number', 'red');
data2.addRows([
[0.016, 5],
[0.017, 1],
[0.018, 3],
[0.019, 9],
[0.020, 4],
[0.021, 5],
[0.022, 7],
[0.023, 7],
[0.024, 3]
]);
var joinedData = google.visualization.data.join(data1, data2, 'full',
[[0, 0]], [1], [1]);
var options = {
annotations: {
stem: {
length: 10
}
},
title: 'Playground',
colors: ['#007f01', '#fe0002'],
interpolateNulls: true,
hAxis: {
title: 'Price',
titleTextStyle: {
color: '#333'
},
direction: 1,
format: 'decimal'
},
vAxis: {
direction: 1
},
orientation: 'horizontal',
// customize colum
series: {
0: {type: "area"},
1: {type: "area"},
},
// legend: {position : 'left'},
animation: {
startup: true,
duration: 1000,
easing: 'out',
}
};
var view = new google.visualization.DataView(joinedData);
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.ComboChart(container);
var observer = new MutationObserver(moveAnnotations);
observer.observe(container, {
childList: true,
subtree: true
});
function moveAnnotations() {
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
var labels = container.getElementsByTagName('text');
var labelSize = 0;
Array.prototype.forEach.call(labels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
if (options.colors.indexOf(label.getAttribute('fill')) > -1) {
labelSize = (parseFloat(label.getAttribute('font-size')) / 2);
label.setAttribute('y', chartBounds.top + labelSize);
}
}
});
var stems = container.getElementsByTagName('rect');
Array.prototype.forEach.call(stems, function(stem) {
if ((parseInt(stem.getAttribute('height')) === options.annotations.stem.length) && (stem.getAttribute('fill') === '#999999')) {
var height = parseFloat(stem.getAttribute('y')) - chartBounds.top;
stem.setAttribute('height', height);
stem.setAttribute('y', chartBounds.top + labelSize);
}
});
}
chart.draw(view.toDataTable(), options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
notes:
1) the move function (moveAnnotations) uses colors from the options in order to identify the annotation labels from the rest of the chart labels
the chart changes all colors to lowercase, so had to change colors in options to lowercase
2) move function also uses option annotations.stem.length to identify the annotation lines
I'm using Google visualization stacked bars chart to show a lot of information of my process.
I am trying to do three things necessary to correctly display information.
1) Show the total at the top of the column;
2) When the total value of the column does not fit in the bar, it is next to it, allowing the reading of all items.
3) Display a companion line that will show the total of impacted records (not present in the chart currently)
My necessity:
I have "L. ratio" for each column, bur the value isn't in the chart.
What I've Done:
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawStacked);
function drawStacked() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'week');
data.addColumn('number', 'L0');
data.addColumn('number', 'L1');
data.addColumn('number', 'L2');
data.addColumn('number', 'L3');
data.addColumn('number', 'L4');
data.addColumn('number', 'L5');
data.addRows([
['W1', 15, 0, 0, 0, 0, 0],
['W2', 75, 60, 20, 0, 0, 0],
['W3', 133, 90, 35, 21, 0, 0],
['W4', 95, 110, 23, 28, 13, 2],
['W5', 83, 80, 60, 40, 20, 15]
/*[{v: [12, 0, 0], f: '12 pm'}, 5, 2.25],
[{v: [13, 0, 0], f: '1 pm'}, 6, 3],
[{v: [14, 0, 0], f: '2 pm'}, 7, 4],
[{v: [15, 0, 0], f: '3 pm'}, 8, 5.25],
[{v: [16, 0, 0], f: '4 pm'}, 9, 7.5],
[{v: [17, 0, 0], f: '5 pm'}, 10, 10],*/
]);
var view = new google.visualization.DataView(data);
view.setColumns([0,
1, {
calc: function (dt, row) {
return dt.getValue(row, 1);
},
type: "number",
role: "annotation"
},
2, {
calc: function (dt, row) {
return dt.getValue(row, 2);
},
type: "number",
role: "annotation"
},
3, {
calc: function (dt, row) {
return dt.getValue(row, 3);
},
type: "number",
role: "annotation"
},
4, {
calc: function (dt, row) {
return dt.getValue(row, 4);
},
type: "number",
role: "annotation"
},
5, {
calc: function (dt, row) {
return dt.getValue(row, 5);
},
type: "number",
role: "annotation"
},
6, {
calc: function (dt, row) {
return dt.getValue(row, 5);
},
type: "number",
role: "annotation"
},
{
calc: function (dt, row) {
return 0;
},
label: "Total",
type: "number",
},
{
calc: function (dt, row) {
return dt.getValue(row, 1) + dt.getValue(row, 2) +
dt.getValue(row, 3) + dt.getValue(row, 4) +
dt.getValue(row, 5);
},
type: "number",
role: "annotation"
}
]);
var options = {
//title: 'Motivation and Energy Level Throughout the Day',
animation:{
duration: 1000,
easing: 'out',
startup: true
},
legend: {
position: 'rigth'
//maxLines: 3
},
series: {
6: {
annotations: {
alwaysOutside: true,
stem: {
color: "transparent",
},
textStyle: {
color: "#000000",
}
},
enableInteractivity: true,
tooltip: "none",
visibleInLegend: false,
axisTitlesPosition: 'in'
}
},
isStacked: true,
vAxis: {
//title: 'Rating (scale of 1-10)',
viewWindow: {
max: 600
}
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(view, options);
};
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I am trying to display the value of each bar and then the total value of all bars in a stacked bar chart The problem is, I get the last bar's value and the total both outside the bar. If I do not show the total, I get the value inside the bar. Using the code below the the last two annotations are outside the second bar even when the second bar is long enough to show its label.
<html>
<head>
<base target="_top">
</head>
<body>
<h3>Registrations</h3>
<div id="registrations_chart"></div>
</body>
</html>
<script>
google.charts.load('current', {'packages':['corechart', 'bar', 'gauge', 'table']});
google.charts.setOnLoadCallback(drawStackedBar);
function drawStackedBar() {
var myHeight = 350;
var data = new google.visualization.DataTable();
data.addColumn('string', 'Registrations');
data.addColumn('number', 'Regular');
data.addColumn('number', 'Work Study');
data.addRows([
['Adult', 20, 12],
['Teen', 3, 0]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0,
1, {
calc: function (dt, row) {
return dt.getValue(row, 1);
},
type: "number",
role: "annotation"
},
2, {
calc: function (dt, row) {
return dt.getValue(row, 2);
},
type: "number",
role: "annotation"
},
// series 1
{
calc: function (dt, row) {
return dt.getValue(row, 1) + dt.getValue(row, 2);
},
type: "number",
role: "annotation"
}
]);
var options = {
animation:{
duration: 1000,
easing: 'out',
startup: true
},
title: 'Registrations',
backgroundColor: 'transparent',
height: myHeight, width: 500,
legend: {
position: 'top',
maxLines: 3
},
bar: { groupWidth: '75%' },
isStacked: true
};
var chart = new google.visualization.BarChart(document.getElementById('registrations_chart'));
chart.draw(view, options);
}
</script>
If I removed the last option in the setColumns to make that section read as follows:
view.setColumns([0,
1, {
calc: function (dt, row) {
return dt.getValue(row, 1);
},
type: "number",
role: "annotation"
},
2, {
calc: function (dt, row) {
return dt.getValue(row, 2);
},
type: "number",
role: "annotation"
},
// series 1
{
calc: function (dt, row) {
return dt.getValue(row, 1) + dt.getValue(row, 2);
},
type: "number",
role: "annotation"
}
]);
I get the labels where I want them without the Total, as shown below
What I am after is to add the Total to the end and the Labels consistently inside as shown below:
I have tried too many methods to remember or list here, but am not getting the Total at the end. How can I get this last Label to appear and keep the others inside the bar when they will fit there? Note that I have made the red bar longer than the blue one and the numbers still displayed as shown.
you could add another series column for the total
then hide it from the chart with the following options...
enableInteractivity: false,
tooltip: "none",
visibleInLegend: false
this will allow the annotations from the other values to perform normally
the total annotation will always show outside,
but need to adjust a few options to keep it from overwriting others...
annotations: {
stem: {
color: "transparent",
length: 28
},
textStyle: {
color: "#000000",
}
},
see following working snippet...
google.charts.load('50', {
packages:['corechart']
}).then(function () {
var myHeight = 350;
var data = new google.visualization.DataTable();
data.addColumn('string', 'Registrations');
data.addColumn('number', 'Regular');
data.addColumn('number', 'Work Study');
data.addRows([
['Adult', 20, 12],
['Teen', 3, 0]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0,
1, {
calc: function (dt, row) {
return dt.getValue(row, 1);
},
type: "number",
role: "annotation"
},
2, {
calc: function (dt, row) {
return dt.getValue(row, 2);
},
type: "number",
role: "annotation"
},
{
calc: function (dt, row) {
return 0;
},
label: "Total",
type: "number",
},
{
calc: function (dt, row) {
return dt.getValue(row, 1) + dt.getValue(row, 2);
},
type: "number",
role: "annotation"
}
]);
var options = {
animation:{
duration: 1000,
easing: 'out',
startup: true
},
title: 'Registrations',
backgroundColor: 'transparent',
height: myHeight, width: 500,
legend: {
position: 'top',
maxLines: 3
},
bar: { groupWidth: '75%' },
isStacked: true,
series: {
2: {
annotations: {
stem: {
color: "transparent",
length: 28
},
textStyle: {
color: "#000000",
}
},
enableInteractivity: false,
tooltip: "none",
visibleInLegend: false
}
}
};
var chart = new google.visualization.BarChart(document.getElementById('registrations_chart'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="registrations_chart"></div>
EDIT
there are no standard options for annotation position
but you can move them manually, once the chart's 'ready' event fires
or in this case, the 'animationfinish' event
see following working snippet,
the total annotations are moved down...
google.charts.load('50', {
packages:['corechart']
}).then(function () {
var myHeight = 350;
var data = new google.visualization.DataTable();
data.addColumn('string', 'Registrations');
data.addColumn('number', 'Regular');
data.addColumn('number', 'Work Study');
data.addRows([
['Adult', 20, 12],
['Teen', 3, 0]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0,
1, {
calc: function (dt, row) {
return dt.getValue(row, 1);
},
type: "number",
role: "annotation"
},
2, {
calc: function (dt, row) {
return dt.getValue(row, 2);
},
type: "number",
role: "annotation"
},
{
calc: function (dt, row) {
return 0;
},
label: "Total",
type: "number",
},
{
calc: function (dt, row) {
return dt.getValue(row, 1) + dt.getValue(row, 2);
},
type: "number",
role: "annotation"
}
]);
var options = {
animation:{
duration: 1000,
easing: 'out',
startup: true
},
title: 'Registrations',
backgroundColor: 'transparent',
height: myHeight, width: 500,
legend: {
position: 'top',
maxLines: 3
},
bar: { groupWidth: '75%' },
isStacked: true,
series: {
2: {
annotations: {
stem: {
color: "transparent",
},
textStyle: {
color: "#000000",
}
},
enableInteractivity: false,
tooltip: "none",
visibleInLegend: false
}
}
};
var chart = new google.visualization.BarChart(document.getElementById('registrations_chart'));
google.visualization.events.addListener(chart, 'animationfinish', function () {
$('#registrations_chart text[fill="#000000"]').each(function (index, annotation) {
if (!isNaN(parseFloat(annotation.textContent))) {
var yCoord = parseFloat($(annotation).attr('y'));
$(annotation).attr('y', yCoord + 18);
}
});
});
chart.draw(view, 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="registrations_chart"></div>
I've got a column google chart where I have four bars for each month. In the view set, in order to put the values on the top of each bar, I added an annotation for each one as following:
view.setColumns([0, 1,
{
id:"col1",
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" }, 2,
{
id:"col1",
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}, 3,
{
id:"col1",
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}, 4,
{
id:"col1",
calc: "stringify",
sourceColumn: 4,
type: "string",
role: "annotation"
}
]);
I also added four buttons, for each column, to hide them. When I use the function hideColumns, it receives an array of indexes to identify the columns I want to hide. However, when I click on the button to hide the column, its annotation value keeps displayed on the chart and goes to a neighbor column. How do I hide the column and the annotation at the same time avoiding this? I tried assigning an id to the object column (annotation) and use it in the hideColumns function, but the function only receives an array of indexes.
This is the piece of code to hide the column number 1:
var hideAtv = document.getElementById("hideAtividades");
hideAtv.onclick = function()
{
view.hideColumns([1]);
chart.draw(view, options);
}
Thanks in advance
the annotation column should always follow the series column in the data table...
so if you want to hide column 1, also hide column 2...
var hideAtv = document.getElementById("hideAtividades");
hideAtv.onclick = function()
{
view.hideColumns([1, 2]);
chart.draw(view, options);
}
EDIT
when using DataView.hideColumns, the column references are for the data table
so it must not handle hiding calculated columns, e.g. annotation columns here
as such, instead of using hideColumns, use setColumns as used initially,
just without the column to be hidden
you can get the column definitions back by using DataView.getViewColumns
then check if the column should be visible...
if (columnDef.hasOwnProperty('sourceColumn')) {
if (columnDef.sourceColumn !== 1) {
viewColumns.push(columnDef);
}
} else if (columnDef !== 1) {
viewColumns.push(columnDef);
}
view.setColumns(viewColumns);
see following working snippet, here the same function is used to hide columns,
based on the button's value attribute
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['x', 'y0', 'y1', 'y2', 'y3'],
['Mon', 20, 28, 38, 45],
['Tue', 31, 38, 55, 66],
['Wed', 50, 55, 77, 80],
['Thu', 77, 77, 66, 50],
['Fri', 68, 66, 22, 15]
]);
var view = new google.visualization.DataView(data);
var columns = [0, 1,
{
id:"col1",
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 2,
{
id:"col1",
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}, 3,
{
id:"col1",
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}, 4,
{
id:"col1",
calc: "stringify",
sourceColumn: 4,
type: "string",
role: "annotation"
}
];
view.setColumns(columns);
var options = {
chartArea: {
top: 12,
left: 32,
bottom: 60,
right: 8,
height: '100%',
width: '100%'
},
height: 496,
legend: {
position: 'bottom'
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
chart.draw(view, options);
document.getElementById('hideSeries1').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries2').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries3').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries4').addEventListener('click', hideColumn, false);
document.getElementById('resetSeries').addEventListener('click', resetSeries, false);
function hideColumn(e) {
var hideColumn = parseInt(e.target.value);
var viewColumns = [];
view.getViewColumns().forEach(function (columnDef) {
if (columnDef.hasOwnProperty('sourceColumn')) {
if (columnDef.sourceColumn !== hideColumn) {
viewColumns.push(columnDef);
}
} else if (columnDef !== hideColumn) {
viewColumns.push(columnDef);
}
});
view.setColumns(viewColumns);
chart.draw(view, options);
}
function resetSeries(e) {
view.setColumns(columns);
chart.draw(view, options);
}
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<button id="hideSeries1" value="1">Hide Series 1</button>
<button id="hideSeries2" value="2">Hide Series 2</button>
<button id="hideSeries3" value="3">Hide Series 3</button>
<button id="hideSeries4" value="4">Hide Series 4</button>
<button id="resetSeries">Reset All Series</button>
note: the above snippet keeps previously hidden buttons hidden, by using...
view.getViewColumns().forEach
to allow only one column to be hidden at a time, use...
columns.forEach
see following snippet for the latter...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['x', 'y0', 'y1', 'y2', 'y3'],
['Mon', 20, 28, 38, 45],
['Tue', 31, 38, 55, 66],
['Wed', 50, 55, 77, 80],
['Thu', 77, 77, 66, 50],
['Fri', 68, 66, 22, 15]
]);
var view = new google.visualization.DataView(data);
var columns = [0, 1,
{
id:"col1",
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 2,
{
id:"col1",
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}, 3,
{
id:"col1",
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}, 4,
{
id:"col1",
calc: "stringify",
sourceColumn: 4,
type: "string",
role: "annotation"
}
];
view.setColumns(columns);
var options = {
chartArea: {
top: 12,
left: 32,
bottom: 60,
right: 8,
height: '100%',
width: '100%'
},
height: 496,
legend: {
position: 'bottom'
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
chart.draw(view, options);
document.getElementById('hideSeries1').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries2').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries3').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries4').addEventListener('click', hideColumn, false);
document.getElementById('resetSeries').addEventListener('click', resetSeries, false);
function hideColumn(e) {
var hideColumn = parseInt(e.target.value);
var viewColumns = [];
columns.forEach(function (columnDef) {
if (columnDef.hasOwnProperty('sourceColumn')) {
if (columnDef.sourceColumn !== hideColumn) {
viewColumns.push(columnDef);
}
} else if (columnDef !== hideColumn) {
viewColumns.push(columnDef);
}
});
view.setColumns(viewColumns);
chart.draw(view, options);
}
function resetSeries(e) {
view.setColumns(columns);
chart.draw(view, options);
}
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<button id="hideSeries1" value="1">Hide Series 1</button>
<button id="hideSeries2" value="2">Hide Series 2</button>
<button id="hideSeries3" value="3">Hide Series 3</button>
<button id="hideSeries4" value="4">Hide Series 4</button>
<button id="resetSeries">Reset All Series</button>