Remove Custom Tooltip on mouseout Google Chart - javascript

I'm using a timeline google chart. Based on this question, I'm trying to add functionality to remove the tooltip ONLY when the mouse moves out of the tooltip. My function below removes it successfully once but and then throws errors afterwards. In addition, im looking for it to ONLY be removed after the mouse moves out of the tooltip.
google.visualization.events.addListener(chart, 'onmouseout', function (e) {
if ( chart.ttclone.parentNode != null) {
chart.ttclone.parentNode.removeChild(chart.ttclone)
}
});
Below is the entire snippet. What is the correct way to do this?
google.charts.load('current', {
callback: function () {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': {'html': true}});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', 'test', createToolTip(), new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', 'test', createToolTip(), new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', 'test', createToolTip(), new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
//select-handler
google.visualization.events.addListener(chart, 'select', function(e) {
//the built-in tooltip
var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
//remove previous clone when there is any
if (chart.ttclone) {
chart.ttclone.parentNode.removeChild(chart.ttclone)
}
//create a clone of the built-in tooltip
chart.ttclone = tooltip.cloneNode(true);
//create a custom attribute to be able to distinguish
//built-in tooltip and clone
chart.ttclone.setAttribute('clone', true);
//inject clone into document
chart.ttclone.style.pointerEvents = 'auto';
tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
});
function createToolTip() {
var mainDiv = '<div style="z-index: 1000;">';
var list =
'<ul class="google-visualization-tooltip-action-list">' +
'<li class="google-visualization-tooltip-action">' +
'<span style="font-family: Arial; font-size: 12px; color: rgb(0, 0, 0); margin: 0px; text-decoration: none; font-weight: bold;">' +
'Contact' +
'</span>' +
'</li>' +
'</ul>';
var endMainDiv = '</div>';
var tooltip = mainDiv + list + endMainDiv;
return tooltip;
}
google.visualization.events.addListener(chart, 'onmouseout', function (e) {
if ( chart.ttclone.parentNode != null) {
chart.ttclone.parentNode.removeChild(chart.ttclone)
}
});
chart.draw(dataTable, {tooltip: {isHtml: true }});
},
packages: ['timeline']
});
.google-visualization-tooltip {
opacity: 0 !important;
max-width: 200px !important;
}
.google-visualization-tooltip[clone] {
opacity: 1 !important;
}
html,
body,
timeline {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline" style="height:90%"></div>

I'm thinking you want to listen for 'onmouseout' on the tooltip,
rather than the chart
chart.ttclone.parentNode.addEventListener('mouseout', ...
also -- chart.ttclone.parentNode seems to throw both mouseover & mouseout multiple times
which could cause an error if you try removeChild multiple times
instead, try style.display = 'none', or something similar...
see following working snippet...
google.charts.load('current', {
callback: function () {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': {'html': true}});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', 'test', createToolTip(), new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', 'test', createToolTip(), new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', 'test', createToolTip(), new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
//select-handler
google.visualization.events.addListener(chart, 'select', function(e) {
//the built-in tooltip
var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
//remove previous clone when there is any
if (chart.ttclone) {
chart.ttclone.parentNode.removeChild(chart.ttclone)
}
//create a clone of the built-in tooltip
chart.ttclone = tooltip.cloneNode(true);
//create a custom attribute to be able to distinguish
//built-in tooltip and clone
chart.ttclone.setAttribute('clone', true);
//inject clone into document
chart.ttclone.style.pointerEvents = 'auto';
tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
chart.ttclone.parentNode.addEventListener('mouseout', function () {
chart.ttclone.style.display = 'none';
}, false);
chart.ttclone.parentNode.addEventListener('mouseover', function () {
chart.ttclone.style.display = 'block';
}, false);
});
function createToolTip() {
var mainDiv = '<div style="z-index: 1000;">';
var list =
'<ul class="google-visualization-tooltip-action-list">' +
'<li class="google-visualization-tooltip-action">' +
'<span style="font-family: Arial; font-size: 12px; color: rgb(0, 0, 0); margin: 0px; text-decoration: none; font-weight: bold;">' +
'Contact' +
'</span>' +
'</li>' +
'</ul>';
var endMainDiv = '</div>';
var tooltip = mainDiv + list + endMainDiv;
return tooltip;
}
chart.draw(dataTable, {tooltip: {isHtml: true }});
},
packages: ['timeline']
});
.google-visualization-tooltip {
opacity: 0 !important;
max-width: 200px !important;
}
.google-visualization-tooltip[clone] {
opacity: 1 !important;
}
html,
body,
timeline {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline" style="height:90%"></div>

Related

Google Chart Resize on Window Resize

How can I get my google chart to resize properly, currently it gets bigger when I expand the window but it does not shrink when i shrink the window. Essentially I've wrapped the entire google chart in a resize function but it isn't quite right:
function resize() {
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Type' });
dataTable.addColumn({ type: 'string', id: 'Organisation' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ 'Work Experience', 'GE', new Date(2010, 8, 1 ), new Date(2011, 8, 30) ],
[ 'Work Experience', 'Shell', new Date(2015, 2, 1), new Date(2016, 1, 1) ],
[ 'Work Experience', 'British Gas', new Date(2016, 1, 1), new Date(2017, 9, 1) ],
[ 'Work Experience', 'British Telecom', new Date(2017, 9, 1), new Date() ],
[ 'Work Experience', 'University', new Date(2011, 8, 30), new Date(2015, 2,1) ]
]);
var options = {
timeline: {showRowLabels: false},
backgroundColor: '#161616',
barLabelStyle: { fontName: 'Roboto', color: '#ffffff' },
height: 100,
hAxis: {textStyle:{color: '#ffffff'}}
};
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
label.setAttribute('fill', '#ffffff');
}
});
});
google.visualization.events.addListener(chart, 'ready', function () {
var rects = container.getElementsByTagName('rect');
Array.prototype.forEach.call(rects, function(rect) {
// find chart <rect> element
if ((rect.getAttribute('x') === '0') && (rect.getAttribute('y') === '0')) {
// remove stroke from last <rect> element
rect.setAttribute('stroke', 'none');
rect.setAttribute('stroke-width', '0');
}
});
});
chart.draw(dataTable, options);
}
}
window.onload = resize;
window.onresize = resize;
when resizing, you need to clear the chart, before re-drawing.
if the chart is not cleared, it can prevent the chart's container from shrinking.
then when re-drawn, it is the same size.
(this all depends on the page layout, but clearing will resolve most issues)
use method --> chart.clearChart()
also, the load callback only needs to be called once per page load.
no need to include the load statement in the resize event handler.
and, google's load statement will wait for the page to load by default.
and can be used in place of --> window.onload
see following working snippet...
google.charts.load('current', {
packages: ['timeline']
}).then(function () {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Type' });
dataTable.addColumn({ type: 'string', id: 'Organisation' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
['Work Experience', 'GE', new Date(2010, 8, 1 ), new Date(2011, 8, 30)],
['Work Experience', 'Shell', new Date(2015, 2, 1), new Date(2016, 1, 1)],
['Work Experience', 'British Gas', new Date(2016, 1, 1), new Date(2017, 9, 1)],
['Work Experience', 'British Telecom', new Date(2017, 9, 1), new Date()],
['Work Experience', 'University', new Date(2011, 8, 30), new Date(2015, 2,1)]
]);
var options = {
timeline: {showRowLabels: false},
backgroundColor: '#161616',
barLabelStyle: {fontName: 'Roboto', color: '#ffffff'},
height: 100,
hAxis: {textStyle:{color: '#ffffff'}}
};
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
label.setAttribute('fill', '#ffffff');
}
});
var rects = container.getElementsByTagName('rect');
Array.prototype.forEach.call(rects, function(rect) {
// find chart <rect> element
if ((rect.getAttribute('x') === '0') && (rect.getAttribute('y') === '0')) {
// remove stroke from last <rect> element
rect.setAttribute('stroke', 'none');
rect.setAttribute('stroke-width', '0');
}
});
});
window.addEventListener('resize', drawChart);
drawChart();
function drawChart() {
chart.clearChart();
chart.draw(dataTable, options);
}
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>

How to set different color by row in TimeLine Google charts?

I have a timeline chart made with Google charts, what I do is send a json with color values ​​and other information, the size of the json is variable, what I want to do is that each row is painted with the color it has in the json, implement the following:
dataTable.addColumn({type: 'string', role: 'style'});
But it seems not to work, it gives me automatic colors.
The following is an image of my graph with the colors thrown by defautl, and not with the colors that I have in the json.
For example in this case, 'Production' has to be orange and 'Fusion' has to be purple.
This is my code:
function drawChart() {
$(".timeline").each(function () {
var obje = {{ devicejson|safe }};
var elem = $(this),
id = elem.attr('id');
var container = document.getElementById(id);
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', id: 'Role'});
dataTable.addColumn({type: 'string', id: 'Name'});
dataTable.addColumn({type: 'date', id: 'Start'});
dataTable.addColumn({type: 'date', id: 'End'});
dataTable.addColumn({type: 'string', id: 'TimeEst'});
dataTable.addColumn({type: 'string', role: 'style'});
for (n = 0; n < obje.length; ++n) {
if (obje[n].device_id == id) {
dataTable.addRows([
['Department', obje[n].digitaloutput_user_description, new Date('"' + obje[n].startdatetime + '"'), new Date('"' + obje[n].enddatetime + '"'), obje[n].lighstate_user_description, obje[n].color],
]);
var options = {
tooltip: {isHtml: true},
timeline: {
showRowLabels: false,
},
avoidOverlappingGridLines: false,
{#hAxis: {format: 'dd-MMM-yyyy HH:mm:ss'}#}
};
}
}
for (n = 0; n < obje.length; ++n) {
if (obje[n].device_id == id) {
console.log(obje[n].color)
}
}
var formatTime = new google.visualization.DateFormat({
pattern: 'yyyy-MM-dd HH:mm:ss a'
});
var view = new google.visualization.DataView(dataTable);
view.setColumns([0, 1, {
role: 'tooltip',
type: 'string',
calc: function (dt, row) {
// build tooltip
var dateBegin = dt.getValue(row, 2);
var dateEnd = dt.getValue(row, 3);
var oneHour = (60 * 1000);
var duration = (dateEnd.getTime() - dateBegin.getTime()) / oneHour;
var tooltip = '<div><div class="ggl-tooltip"><span>';
tooltip += dt.getValue(row, 0) + ':</span> ' + dt.getValue(row, 1) + '</div>';
tooltip += '<div class="ggl-tooltip"><div>' + formatTime.formatValue(dateBegin) + ' - ';
tooltip += formatTime.formatValue(dateEnd) + '</div>';
tooltip += '<div><span>Duration: </span>' + duration.toFixed(0) + ' minutes</div>';
tooltip += '<div><span>Estate: </span>' + dt.getValue(row, 5) + '</div></div>';
return tooltip;
},
p: {html: true}
}, 2, 3]);
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function (label) {
label.setAttribute('font-weight', 'normal');
});
});
chart.draw(view.toDataTable(), options);
})
}
on the timeline chart, the style role will only work when used as the third column (column index 2).
see following working snippet...
google.charts.load('current', {
'packages': ['timeline']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({
type: 'string',
id: 'Bar'
});
dataTable.addColumn({ // <-- add style role here...
type: 'string',
role: 'style'
});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', 'test1', 'cyan', new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', 'test2', 'magenta', new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', 'test3', 'lime', new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
chart.draw(dataTable);
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline" style="height: 180px;"></div>

Why does style.display change the size of my div when set to 'block'?

I have 3 divs each one containing a google timeline chart.
3 buttons to toggle between each of the 3 divs.
I use javascript to hide the 2 other divs and show one.
If I set all of the divs to show they all have the same length and width.
However, when I start toggling in between them, only the one that started as display: 'block' keeps the same size and the rest become much smaller when toggled to show.
I've already tried setting the div size in my javascript functions, didn't work.
When I inspect element on one of the toggled divs it shows 400px for width.
google.charts.load('current', {
'packages': ['timeline']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline2');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
chart.draw(dataTable);
}
google.charts.setOnLoadCallback(drawChart2);
function drawChart2() {
var container = document.getElementById('timeline3');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
chart.draw(dataTable);
}
google.charts.setOnLoadCallback(drawChart3);
function drawChart3() {
var container = document.getElementById('timeline4');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
chart.draw(dataTable);
}
function showMonth() {
document.getElementById('timeline3').style.display = 'none';
document.getElementById('timeline4').style.display = 'none';
document.getElementById('timeline2').style.display = 'block';
}
function showWeek() {
document.getElementById('timeline3').style.display = 'block';
document.getElementById('timeline4').style.display = 'none';
document.getElementById('timeline2').style.display = 'none';
}
function showDay() {
document.getElementById('timeline3').style.display = 'none';
document.getElementById('timeline4').style.display = 'block';
document.getElementById('timeline2').style.display = 'none';
}
#timeline2 {
height: 300px;
width: 1791px;
background-color: red;
}
#timeline3 {
display: none;
height: 300px;
width: 1791px;
background-color: blue;
}
#timeline4 {
display: none;
height: 300px;
width: 1791px;
background-color: pink;
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<button class='monthb' onclick="showMonth()">Month</button>
<button class='weekb' onclick="showWeek()">Week</button>
<button class='dayb' onclick="showDay()">Day</button>
<br />
<div id="timeline2"></div>
<div id="timeline3"></div>
<div id="timeline4"></div>
It seems like the chart's width is determined by examining the width of its container. However if the container isn't visible, it cannot properly determine the width.
Consider hiding the div after each chart.draw(). (These could afford to be refactored to remove some duplicate logic but for sake of the demonstration, I've simply added it to the two charts that are supposed to start as hidden.)
google.charts.load('current', {
'packages': ['timeline']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline2');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
chart.draw(dataTable);
}
google.charts.setOnLoadCallback(drawChart2);
function drawChart2() {
var container = document.getElementById('timeline3');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
chart.draw(dataTable);
document.getElementById('timeline3').style.display = 'none';
}
google.charts.setOnLoadCallback(drawChart3);
function drawChart3() {
var container = document.getElementById('timeline4');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
chart.draw(dataTable);
document.getElementById('timeline4').style.display = 'none';
}
function showMonth() {
document.getElementById('timeline3').style.display = 'none';
document.getElementById('timeline4').style.display = 'none';
document.getElementById('timeline2').style.display = 'block';
}
function showWeek() {
document.getElementById('timeline3').style.display = 'block';
document.getElementById('timeline4').style.display = 'none';
document.getElementById('timeline2').style.display = 'none';
}
function showDay() {
document.getElementById('timeline3').style.display = 'none';
document.getElementById('timeline4').style.display = 'block';
document.getElementById('timeline2').style.display = 'none';
}
#timeline2 {
height: 300px;
width: 1791px;
}
#timeline3 {
height: 300px;
width: 1791px;
}
#timeline4 {
height: 300px;
width: 1791px;
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<button class='monthb' onclick="showMonth()">Month</button>
<button class='weekb' onclick="showWeek()">Week</button>
<button class='dayb' onclick="showDay()">Day</button>
<br />
<div id="timeline2"></div>
<div id="timeline3"></div>
<div id="timeline4"></div>

Add hyperlink to custom tooltip in Google Charts

Using this workaround, I was able to mimic showing tooltip upon selection for a google timeline chart. This issue is that I plan on having a mail to link in the tooltip for the user to click on. However, in my function creatToolTip(), the tooltip is created but I'm unable to click on the contact link. What is the correct way to do this?
EDIT: I also tried Google's tooltip actions but it is not supported in timeline charts.
google.setOnLoadCallback(drawVisualization);
function drawVisualization() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': {'html': true}});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', 'test', createToolTip(), new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', 'test', createToolTip(), new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', 'test', createToolTip(), new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
//select-handler
google.visualization.events.addListener(chart, 'select', function(e) {
//the built-in tooltip
var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
//remove previous clone when there is any
if (chart.ttclone) {
chart.ttclone.parentNode.removeChild(chart.ttclone)
}
//create a clone of the built-in tooltip
chart.ttclone = tooltip.cloneNode(true);
//create a custom attribute to be able to distinguish
//built-in tooltip and clone
chart.ttclone.setAttribute('clone', true);
//inject clone into document
tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
});
chart.draw(dataTable, {tooltip: {isHtml: true }});
}
function createToolTip() {
var mainDiv = '<div >';
var list =
'<ul class="google-visualization-tooltip-action-list">' +
'<li class="google-visualization-tooltip-action">' +
'<span style="font-family: Arial; font-size: 12px; color: rgb(0, 0, 0); margin: 0px; text-decoration: none; font-weight: bold;">' +
'Contact' +
'</span>' +
'</li>' +
'</ul>';
var endMainDiv = '</div>';
var tooltip = mainDiv + list + endMainDiv;
return tooltip;
}
.google-visualization-tooltip {
opacity: 0 !important;
max-width: 200px !important;
}
.google-visualization-tooltip[clone] {
opacity: 1 !important;
}
html,
body,
timeline {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['timeline']}]}"></script>
<div id='timeline' style="height:90%"></div>
looks like pointer-events are set to 'none' by default
change to 'auto' before injecting the clone back into the dom
//inject clone into document
chart.ttclone.style.pointerEvents = 'auto';
tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
see following working snippet...
google.charts.load('current', {
callback: function () {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': {'html': true}});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', 'test', createToolTip(), new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', 'test', createToolTip(), new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', 'test', createToolTip(), new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
//select-handler
google.visualization.events.addListener(chart, 'select', function(e) {
//the built-in tooltip
var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
//remove previous clone when there is any
if (chart.ttclone) {
chart.ttclone.parentNode.removeChild(chart.ttclone)
}
//create a clone of the built-in tooltip
chart.ttclone = tooltip.cloneNode(true);
//create a custom attribute to be able to distinguish
//built-in tooltip and clone
chart.ttclone.setAttribute('clone', true);
//inject clone into document
chart.ttclone.style.pointerEvents = 'auto';
tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
});
function createToolTip() {
var mainDiv = '<div style="z-index: 1000;">';
var list =
'<ul class="google-visualization-tooltip-action-list">' +
'<li class="google-visualization-tooltip-action">' +
'<span style="font-family: Arial; font-size: 12px; color: rgb(0, 0, 0); margin: 0px; text-decoration: none; font-weight: bold;">' +
'Contact' +
'</span>' +
'</li>' +
'</ul>';
var endMainDiv = '</div>';
var tooltip = mainDiv + list + endMainDiv;
return tooltip;
}
chart.draw(dataTable, {tooltip: {isHtml: true }});
},
packages: ['timeline']
});
.google-visualization-tooltip {
opacity: 0 !important;
max-width: 200px !important;
}
.google-visualization-tooltip[clone] {
opacity: 1 !important;
}
html,
body,
timeline {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline" style="height:90%"></div>

Customize onmouseover event in Google Chart

I am using Google Developer Chart called Timeline to create some charts. I was able to render a basic version of the charts successfully, but I want to customize the onmouseover event to display certain block information. I haven't been able to find any examples of how to customize this functionality though.
Currently, my table code looks like this:
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['timeline']}]}"></script>
<script language="Javascript" type="text/javascript">
google.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'RowLabel' });
dataTable.addColumn({ type: 'string', id: 'BlockLabel' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
["SAT 2B", "Task 1", new Date(2015,01,01), new Date(2015,01,02)],
["SAT 2B", "Task 1", new Date("2015-03-10 05:10:39.010000"), new Date("2015-03-15 05:10:39.010000")],
["SAT 2C", "Task 1", new Date("2015-04-10 05:10:39.010000"), new Date("2015-04-15 05:10:39.010000")],
]);
var formatter = new google.visualization.DateFormat({pattern:'yyyy/DDD-HH:mm:ss'});
formatter.format(dataTable,2);
formatter.format(dataTable,3);
var options = {
timeline: { colorByRowLabel: true }
};
chart.draw(dataTable,options);
}
</script>
<div>
<h4><p class="text-center">A Timeline</p></h4>
<div id="timeline" style="width: 95%;"></div>
</div>
I want to be able to display the BlockLabel, Start, and End date when the user mouses over a given block in the timeline. Can anyone help me out with how to do that? The timeline code is described here.
In order to customize Google Chart tooltip the column with tooltip role is intended, but it seems Timeline chart does not support it.
The following example shows how to override tooltip content once you hover over data element:
google.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'RowLabel' });
dataTable.addColumn({ type: 'string', id: 'BlockLabel' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
["SAT 2B", "Task 1", new Date(2015, 01, 01), new Date(2015, 01, 02)],
["SAT 2B", "Task 1", new Date("2015-03-10 05:10:39.010000"), new Date("2015-03-15 05:10:39.010000")],
["SAT 2C", "Task 1", new Date("2015-04-10 05:10:39.010000"), new Date("2015-04-15 05:10:39.010000")]
]);
var formatter = new google.visualization.DateFormat({ pattern: 'yyyy/DDD-HH:mm:ss' });
formatter.format(dataTable, 2);
formatter.format(dataTable, 3);
var options = {
timeline: { colorByRowLabel: true }
};
chart.draw(dataTable, options);
google.visualization.events.addListener(chart, 'onmouseover', function(e) {
setTooltipContent(dataTable,e.row);
});
}
function setTooltipContent(dataTable,row) {
if (row != null) {
var content = '<div class="custom-tooltip" ><h1>' + dataTable.getValue(row, 0) + '</h1><div>' + dataTable.getValue(row, 1) + '</div></div>'; //generate tooltip content
var tooltip = document.getElementsByClassName("google-visualization-tooltip")[0];
tooltip.innerHTML = content;
}
}
div.google-visualization-tooltip {
width: auto;
height:auto;
background-color: #ccccff;
color: #000000;
text-align: center;
vertical-align: middle;
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['timeline']}]}"></script>
<div>
<h4><p class="text-center">A Timeline</p></h4>
<div id="timeline" style="width: 95%;"></div>
</div>
JSFiddle

Categories

Resources