Google Combo Chart with multiple series, how to add custom HTML Tooltip - charts

I've Google combo chart and like to add a Tooltip. The icCube documention has an example how to add a HTML tooltip but this will not work for series, only the last item in the serie gets the tooltip. I found an answer how to do this, see this post.
But how can I achieve this in icCube?

for google charts, you can reference the Data Format of the specific chart
for most, the tooltip follows the series column
to have multiple series, each with it's own custom html tooltip,
add a column after each series column
NOTE: for custom html tooltips to work, the following must be in place...
the column must have property --> html: true
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
and the configuration options must include...
tooltip: {isHtml: true}
see following working snippet, the tooltip columns are loaded initially as null
then the tooltip is built based on the values in the series columns
google.charts.load('current', {
callback: function () {
var container = document.getElementById('chart_div');
var chart = new google.visualization.ComboChart(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', label: 'Year'});
// series 0
dataTable.addColumn({type: 'number', label: 'Category A'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
// series 1
dataTable.addColumn({type: 'number', label: 'Category B'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
// series 2
dataTable.addColumn({type: 'number', label: 'Category C'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
dataTable.addRows([
['2014', 1000, null, 2000, null, 3000, null],
['2015', 2000, null, 4000, null, 6000, null],
['2016', 3000, null, 6000, null, 9000, null],
]);
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
dataTable.setValue(i, 2, getTooltip(i, 1));
dataTable.setValue(i, 4, getTooltip(i, 3));
dataTable.setValue(i, 6, getTooltip(i, 5));
}
function getTooltip(rowIndex, columnIndex) {
return '<div class="ggl-tooltip"><span>' +
dataTable.getValue(rowIndex, 0) + ': </span>' +
dataTable.getFormattedValue(rowIndex, columnIndex) + '</div>';
}
chart.draw(dataTable, {
legend: {
position: 'bottom'
},
pointSize: 4,
seriesType: 'area',
series: {
2: {
pointSize: 12,
pointShape: {
type: 'star',
sides: 5,
dent: 0.6
},
type: 'scatter'
}
},
tooltip: {isHtml: true}
});
},
packages: ['corechart']
});
.ggl-tooltip {
border: 1px solid #E0E0E0;
font-family: Arial, Helvetica;
font-size: 10pt;
padding: 12px 12px 12px 12px;
}
.ggl-tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Related

Google Visualization Chart horizontal bar with target (vertical line

I would like to set up a small and light chart using Google Visualizion chart.
The idea would be to have an horizontal bar chart (this I know how to do) BUT combined with a vertical line showing if a target is exceeded or not.
The target can be different for each data.
In addition I would like to include an indicator (red/green) easily identifying who is under target and who is above (+ optinally a label just after the green/red dot).
Any idea how to proceed?
actually, you can just use a BarChart,
and change the series type for the last two columns...
series: {
1: {
type: 'line'
},
2: {
type: 'scatter'
}
}
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', id: 'x'});
dataTable.addColumn({type: 'number', id: 'bar'});
dataTable.addColumn({type: 'string', role: 'annotation'});
dataTable.addColumn({type: 'number', id: 'line'});
dataTable.addColumn({type: 'number', id: 'scatter'});
dataTable.addColumn({type: 'string', role: 'style'});
dataTable.addRows([
['', 300, '300', 300, 800, '#4caf50'],
['', 600, '600', 600, 800, '#f44336'],
['', 200, '200', 200, 800, '#4caf50'],
['', 150, '150', 150, 800, '#f44336'],
]);
var options = {
annotations: {
alwaysOutside: true,
textStyle: {
color: '#000000'
}
},
colors: ['#9e9e9e', '#2196f3'],
legend: 'none',
hAxis: {
gridlines: {
count: 0
},
textPosition: 'none'
},
series: {
1: {
lineWidth: 4,
type: 'line'
},
2: {
type: 'scatter'
}
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart'));
chart.draw(dataTable, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>
EDIT
to add custom labels next to the scatter points,
you can use chart method --> getChartLayoutInterface()
which has a method for --> getBoundingBox(id)
this can be used to find the position of a chart element.
where id is the string id of the point, in this format --> point#series#row -- point#0#0
on the chart's 'ready' event, we can position custom labels next to the points.
google.visualization.events.addListener(chart, 'ready', function (sender) {
var padding = 16;
var chartLayout = chart.getChartLayoutInterface();
var containerBounds = chart.getContainer().getBoundingClientRect();
for (var row = 0; row < dataTable.getNumberOfRows(); row++) {
var pointBounds = chartLayout.getBoundingBox('point#2#' + row);
var dataLabel = document.createElement('span');
dataLabel.className = 'data-label';
dataLabel.innerHTML = 'Label ' + row;
dataLabel.style.top = (containerBounds.top + pointBounds.top - (pointBounds.height / 2)) + 'px';
dataLabel.style.left = (containerBounds.left + pointBounds.left + pointBounds.width + padding) + 'px';
chart.getContainer().appendChild(dataLabel);
}
});
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', id: 'x'});
dataTable.addColumn({type: 'number', id: 'bar'});
dataTable.addColumn({type: 'string', role: 'annotation'});
dataTable.addColumn({type: 'number', id: 'line'});
dataTable.addColumn({type: 'number', id: 'scatter'});
dataTable.addColumn({type: 'string', role: 'style'});
dataTable.addRows([
['', 300, '300', 300, 800, '#4caf50'],
['', 600, '600', 600, 800, '#f44336'],
['', 200, '200', 200, 800, '#4caf50'],
['', 150, '150', 150, 800, '#f44336'],
]);
var options = {
annotations: {
alwaysOutside: true,
textStyle: {
color: '#000000'
}
},
colors: ['#9e9e9e', '#2196f3'],
legend: 'none',
hAxis: {
gridlines: {
count: 0
},
textPosition: 'none'
},
series: {
1: {
lineWidth: 4,
type: 'line'
},
2: {
type: 'scatter'
}
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart'));
google.visualization.events.addListener(chart, 'ready', function (sender) {
var padding = 16;
var chartLayout = chart.getChartLayoutInterface();
var containerBounds = chart.getContainer().getBoundingClientRect();
for (var row = 0; row < dataTable.getNumberOfRows(); row++) {
var pointBounds = chartLayout.getBoundingBox('point#2#' + row);
var dataLabel = document.createElement('span');
dataLabel.className = 'data-label';
dataLabel.innerHTML = 'Label ' + row;
dataLabel.style.top = (containerBounds.top + pointBounds.top - (pointBounds.height / 2)) + 'px';
dataLabel.style.left = (containerBounds.left + pointBounds.left + pointBounds.width + padding) + 'px';
chart.getContainer().appendChild(dataLabel);
}
});
chart.draw(dataTable, options);
});
.data-label {
position: absolute;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

Tooltip and annotation both in google chart

can we use tool-tip and annotations both in same chart in google bar chart? please share your experiences. thanks
annotations: {
textStyle: {
color: 'black',
fontSize: 11,
fontWeight: 'bold',
format: 'short',
},
alwaysOutside: true
},
tooltip: {
isHtml: true,
trigger: 'selection'
},
yes, you can use both tooltips and annotations in same chart
to do so, you use both annotation & tooltip column roles
in the data table, or data view, add the role after each data column it represents
data table
X, Y, annotation role, tooltip role
in the following example, a data view is used, so the tooltip can be built dynamically
in order to have html tooltips, two things must by in place.
the chart options must include...
tooltip: {
isHtml: true
}
and the column role must include a property...
p: {html: true}
however, there is a bug in google charts,
column properties are ignored when using a data view,
so we convert the data view to a data table when drawing...
chart.draw(view.toDataTable(), options); // <-- convert to data table
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
["Element", "Density"],
["Copper", 8.94],
["Silver", 10.49],
["Gold", 19.30],
["Platinum", 21.45]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
type: 'string',
role: 'annotation',
sourceColumn: 1,
calc: 'stringify'
}, {
type: 'string',
role: 'tooltip',
calc: function (dt, row) {
return '<div class="ggl-tooltip"><div><span>' + dt.getValue(row, 0) + '</span></div><div>' + dt.getColumnLabel(1) + ': <span>' + dt.getValue(row, 1) + '</span></div>';
},
p: {html: true}
}]);
var options = {
annotations: {
textStyle: {
color: 'black',
fontSize: 11,
fontWeight: 'bold',
},
alwaysOutside: true
},
tooltip: {
isHtml: true,
trigger: 'selection'
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart'));
chart.draw(view.toDataTable(), options);
});
.ggl-tooltip {
background-color: #ffffff;
border: 1px solid #e0e0e0;
font-family: Arial, Helvetica;
font-size: 14px;
padding: 8px;
}
.ggl-tooltip div {
margin-top: 6px;
}
.ggl-tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

Google Charts Bar Chart avoid overlappin annotations [duplicate]

I'm creating a stacked bar graph and need to show the label inside the stack. But Few of the label's are getting overlapped. for reference image
Can you please help me how to avoid overlapping using google charts ?
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<script type="text/javascript">
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawStacked);
function drawStacked() {
var data = new google.visualization.arrayToDataTable([['Time Period','XYZ',{ role: 'annotation'},'ABC',{ role: 'annotation'},{ role: 'annotation'},'Average'],
['Aug', 3754,'3754', 2089,'2089','5,843',4000],
['Sept', 900,'900', 200,'200', '100',4000],
['Oct', 2000,'2000', 4900,'4900', '6000',4000],
['Nov', 1700,'1700', 2200,'2200', '3900',4000],
['Dec', 2400,'2400', 2089,'2200', '4600',4000]
]);
var options = {
title: 'Overview of the Tickets',
isStacked: true,
orientation: 'horizontal',
hAxis: {
title: 'Time Period',
annotations: {}
},
vAxis: {
title: 'Number of Tickets'
},
seriesType: 'bars',
series: {2: {type: 'line'}}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
</html>
Regards,
Srikanth
first, it appears you have an extra annotation column in your data,
that doesn't appear to belong to a specific column
copied from question above...
var data = new google.visualization.arrayToDataTable([
[
'Time Period',
'XYZ',
{role: 'annotation'},
'ABC',
{role: 'annotation'},
{role: 'annotation'}, // <-- extra annotation?
'Average'
],
[
'Aug',
3754,
'3754',
2089,
'2089',
'5,843', // <-- extra annotation?
4000
],
...
]);
this could be part of the reason it's so cluttered
regardless, use the annotations configuration option for adjustments
the config option can be used for the entire chart, or just for a specific series
var options = {
// entire chart
annotations: {
textStyle: {
fontSize: 10
}
},
series: {
0: {
// series 0
annotations: {
stem: {
length: 0
},
},
},
1: {
// series 1
annotations: {
stem: {
length: 16
}
},
},
}
...
};
specifically, you can use a combination of annotations.textStyle.fontSize and annotations.stem.length to prevent overlapping
see following working snippet...
annotations.textStyle.fontSize is reduced for the entire chart
this allows the first annotation on the second column to fit within the bar
annotations.stem.length is set to zero (0) on the first series,
and 16 on the second...
(the extra annotation from the question has been removed)
google.charts.load('current', {
callback: drawStacked,
packages: ['corechart']
});
function drawStacked() {
var data = new google.visualization.arrayToDataTable([
['Time Period', 'XYZ', {role: 'annotation'}, 'ABC', {role: 'annotation'}, 'Average'],
['Aug', 3754, '3754', 2089, '2089', 4000],
['Sept', 900, '900', 200, '200', 4000],
['Oct', 2000, '2000', 4900, '4900', 4000],
['Nov', 1700, '1700', 2200, '2200', 4000],
['Dec', 2400, '2400', 2089, '2200', 4000]
]);
var options = {
annotations: {
textStyle: {
fontSize: 10
}
},
series: {
0: {
annotations: {
stem: {
length: 0
},
},
},
1: {
annotations: {
stem: {
length: 16
}
},
},
2: {
type: 'line'
}
},
hAxis: {
title: 'Time Period'
},
isStacked: true,
seriesType: 'bars',
title: 'Overview of the Tickets',
vAxis: {
title: 'Number of Tickets'
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
since the third annotation is needed as the total of the other two stacks,
recommend adding the series value for the total, in addition to the annotation column
and setting the total series type to 'line'
this will place the total annotation above the rest, for sure
so long as there is enough room on the chart to display the annotation above the bars
to ensure enough room above bars, find the max vAxis value, and add a value that will create enough room for the annotation
then set that value as vAxis.viewWindow.max
you can turn off the line and point, and hide the total series from the legend if needed
in my experience, it takes quite a bit of manipulation to get a complex google chart to display nicely
see the following working snippet, which incorporates the third, 'total', annotation...
google.charts.load('current', {
callback: drawStacked,
packages: ['corechart']
});
function drawStacked() {
var data = new google.visualization.arrayToDataTable([
['Time Period', 'XYZ', {role: 'annotation'}, 'ABC', {role: 'annotation'}, 'TOTAL', {role: 'annotation'}, 'Average'],
['Aug', 3754, '3,754', 2089, '2,089', 5843, '5,843', 4000],
['Sept', 900, '900', 200, '200', 1100, '1,100', 4000],
['Oct', 2000, '2,000', 4900, '4,900', 6900, '6,900', 4000],
['Nov', 1700, '1,700', 2200, '2,200', 3900, '3,900', 4000],
['Dec', 2400, '2,400', 2089, '2,089', 4489, '4,489', 4000]
]);
// find max for all columns to set top vAxis number
var maxVaxis = 0;
for (var i = 1; i < data.getNumberOfColumns(); i++) {
if (data.getColumnType(i) === 'number') {
maxVaxis = Math.max(maxVaxis, data.getColumnRange(i).max);
}
}
var options = {
annotations: {
textStyle: {
fontSize: 10
}
},
series: {
0: {
annotations: {
stem: {
length: 0
},
}
},
1: {
annotations: {
stem: {
length: 2
}
}
},
2: {
annotations: {
stem: {
color: 'transparent',
length: 16
}
},
color: 'black',
lineWidth: 0,
pointShape: 'square',
pointSize: 0,
type: 'line',
visibleInLegend: false
},
3: {
type: 'line'
}
},
hAxis: {
title: 'Time Period'
},
isStacked: true,
seriesType: 'bars',
title: 'Overview of the Tickets',
vAxis: {
title: 'Number of Tickets',
viewWindow: {
max: maxVaxis + 2000
}
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I think it happens because there's not enough vertical space for the labels.
Try this:
Save the highest value of the graph (let's call it maxNumber)
In the "options" set vAxis maxValue to be maxNumber plus a little more.
I have 4 horizontal lines in my graph so I wrote:
var options = {
title: chartTitle,
....... //Your options
vAxis: {
//Add more space in order to make sure the annotations are not overlapping
maxValue: maxNumber + maxNumber/4,
},

How to change properties of tooltip text?

I am new to google charts, trying to make calendar chart.
I am using this :
`google.charts.load('current', {'packages':['calendar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('date' , 'date');
dataTable.addColumn('number', 'num');
dataTable.addColumn({ type: 'string', role:'tooltip'});
dataTable.addRows([
[ new Date(2017, 11, 20), 150,'Hello'],
[ new Date(2017, 11, 21), 130,'Hello']
]);
var chart = new google.visualization.Calendar(document.getElementById('tooltip_action'));
var options = {
title: "Calendar Chart",
colors: ['#e0440e'],
height: 350
};
chart.draw(dataTable, options);
`
It is working fine. But when I move cursor to 20/12/2017 and 21/12/2017 it is showing 'Hello' in very small text and small size.
And when I move cursor to other dates it is showing in bigger.
I want to change height and width of this text.
How to change properties of this tooltip text ???
you can use html tooltips, then use a css class to style them
set the following option...
tooltip: {
isHtml: true
}
and column property --> p: {html: true}
dataTable.addColumn({ type: 'string', role:'tooltip', p: {html: true}});
see following working snippet...
google.charts.load('current', {
packages: ['calendar']
}).then(function () {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('date' , 'date');
dataTable.addColumn('number', 'num');
dataTable.addColumn({ type: 'string', role:'tooltip', p: {html: true}});
dataTable.addRows([
[ new Date(2017, 11, 20), 150,'<div class="tooltip">Hello</div>'],
[ new Date(2017, 11, 21), 130,'<div class="tooltip">Hello</div>']
]);
var chart = new google.visualization.Calendar(document.getElementById('tooltip_action'));
var options = {
title: "Calendar Chart",
colors: ['#e0440e'],
height: 350,
tooltip: {
isHtml: true
}
};
chart.draw(dataTable, options);
});
body {
overflow: auto;
}
#tooltip_action {
width: 1000px;
}
.tooltip {
font-size: 24px;
padding: 12px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="tooltip_action"></div>

Google Charts: Data label with suffix

I am just starting with using google charts. I have a question. I would like to add data labels to my columns, in fact I have succeeded in this. However, I would like to add a suffix to these labels (percentages %). I have tried to use NumberFormat, but then no chart appears. What am I doing wrong?
<script type="text/javascript" src="https://www.google.com/jsapi"></script><script type="text/javascript">
google.load('visualization', '1', { 'packages': ['corechart'] } );
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Kenmerk', 'Belangrijkheid', { role: 'style' } ],
['Uitstellen', 10, 'color: gray'],
['bijwerkingen', 20, 'color: yellow'],
['behandelingen', 30, 'color: red'],
['Schema', 40, 'color: blue']
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2]);
// Set chart options
var options = {
width: 800,
height: 600,
title: 'Uitslag',
vAxis: { title: 'belangrijkheid van elk kenmerk in percentages uitgedrukt', format: '#\'%\'', maxValue: '100', minValue: '0'},
legend: { position: 'none'},
bar: { groupWidth: '75%' },
};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.ColumnChart(document.getElementById("columnchart_values"));
chart.draw(view, options);
}
</script></p>
<div id="columnchart_values" style="width: 800px; height: 600px;">
</div>