Using Google Charts (haven\'t migrated to the Material ones yet), one can make tooltips require a click by using the {trigger: \'selection\'}
option. However, u
based on dennisr2000's answer I did this:
function onChartSelection(e) {
var selection = chart.getSelection([e]); //note: if currently selected datapoint is clicked, selection is emptied ([] received)
var dataPointIndex = (selection.length != 0)? selection[0].row : -1; //using -1 for deselection
if (_chartSelectionChangedCallback != null)
_chartSelectionChangedCallback(dataPointIndex);
}
function plotElevationsDistances(elevations, distances, selectionCallback) {
//console.log('elevations: ', JSON.stringify(elevations));
//console.log('distances: ', JSON.stringify(distances));
chart =
//new google.visualization.ColumnChart(document.getElementById('chart_div'));
/**/new google.visualization.LineChart(document.getElementById('chart_div'));
// Add data selection handler:
google.visualization.events.addListener(chart, 'select', onChartSelection);
google.visualization.events.addListener(chart, 'onmouseover', function(e){
chart.setSelection([{row: e.row, column: e.column}]);
onChartSelection(e);
});
var data = new google.visualization.DataTable();
//data.addColumn('string', '# Marker');
/**/data.addColumn('number', 'Distance (km)');
data.addColumn('number', 'Elevation (m)');
data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
var elevationCount = elevations.length;
for (var i = 0; i < elevationCount; i++)
data.addRow([
/*''*/distances[i],
elevations[i],
'<div class="chartTooltip" onClick="$(this).closest(\'.google-visualization-tooltip\').hide()">Distance: <strong>' + distances[i] + ' km</strong><br />Elevation: <strong>' + elevations[i] + ' m</strong></div><div class="chartTooltipCloseBtn" onClick="$(this).closest(\'.google-visualization-tooltip\').hide()" draggable="false" title="Close" aria-label="Close" type="button" onClick ><img class="chartTooltipCloseBtnImg" src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224px%22%20height%3D%2224px%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22%23000000%22%3E%0A%20%20%20%20%3Cpath%20d%3D%22M19%206.41L17.59%205%2012%2010.59%206.41%205%205%206.41%2010.59%2012%205%2017.59%206.41%2019%2012%2013.41%2017.59%2019%2019%2017.59%2013.41%2012z%22%2F%3E%0A%20%20%20%20%3Cpath%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%0A%3C%2Fsvg%3E%0A"></button>'
]);
chart.draw(data, chartOptions);
}
combined with these styles:
.chartTooltip {
margin:10px;
text-align: left;
}
.chartTooltipCloseBtn {
background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%;
display: block;
border: 0px none;
margin: 0px;
padding: 0px;
position: absolute;
cursor: pointer;
-moz-user-select: none;
top: -6px;
right: -6px;
width: 30px;
height: 30px;
outline: currentcolor none medium;
opacity: 0.6;
}
.chartTooltipCloseBtn:hover {
opacity: 1;
}
.chartTooltipCloseBtnImg {
.pointer-events: none;
display: block;
width: 14px;
height: 14px;
margin: 8px;
}
The styles are based on the x shown by Google Maps infoboxes
Note the two listeners (I didn't want to clear selection on hover, but instead reselect the hovered point) and the "onClick" attribute in the tooltip.
Note that I have the close action on both the tooltip (useful for touch screens) AND on the x button for mouse users with a hover effect on that button as the maps infobox also does (maps infobox doesn't seem to close on touch btw, just with the x button)
The callback I have in onChartSelection is cause setSelection on the chart via the API doesn't seem to fire a selection event, only manual actions do. So like that I do selection on hover as if the user had clicked on the data point and the tooltip is shown immediately and persists (like a combined "selection" and "focus" mode for the "tooltip.trigger", which Google isn't providing out of the box)
I was able to get something similar to work: not to get the tooltip to vanish when you click away, but when you click on the tooltip iteself. Maybe you can add a close button to the tooltip.
First, it has to be an html tooltip:
tooltip: { isHtml: true }
Then you must add the following somewhere in the string html that you pass to the chart (assuming jQuery):
$("<div></div>").attr("onclick", "$(this).closest('.google-visualization-tooltip').hide()")
Or something similar if you're not using jQuery. This only seems to work for an inner div of the html content you pass for the tooltip, so this needs to be a child div.
Also, you will need to add the following event handler to the chart:
google.visualization.events.addListener(chart, "onmouseover", function(event){
chart.setSelection(null);
});
Otherwise the tooltip will pop back up when you hover the chart.
You could attach a click
event handler for the body
element to clear the chart's selection as demonstrated below:
Example
google.setOnLoadCallback(drawChart);
var chart;
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Fixations'],
['2015', 80],
['2016', 90],
['2017', 100],
['2018', 90],
['2019', 80], ]);
var options = {
tooltip: {
isHtml: true,
trigger: 'selection'
},
legend: {
position: 'none'
},
bar: {
groupWidth: '90%'
},
colors: ['#A61D4C'],
enableInteractivity: true
};
chart = new google.visualization.ColumnChart(document.getElementById('tooltip_rotated'));
chart.draw(data, options);
addEvent(document.querySelector('body'),'click',clearSelection);
}
function clearSelection (e) {
if (!document.querySelector('#tooltip_rotated').contains(e.srcElement)) {
chart.setSelection();
}
}
function addEvent(element, evnt, funct){
if (element.attachEvent)
return element.attachEvent('on'+evnt, funct);
else
return element.addEventListener(evnt, funct, false);
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['corechart']}]}"></script>
<div id="tooltip_rotated" style="width: 400px; height: 400px;"></div>