most charts in the 'corechart'
package,
have methods for getting the position of various chart elements.
first, get the chart's layout interface...
var chartLayout = chart.getChartLayoutInterface();
the layout interface has method --> getBoundingBox(id)
where id
is a string id of the chart element.
to find the position of a point, use this format for id
--> point#series#row
-- point#0#0
we can use chart event onmouseover
to know when a point has been hovered,
and the tooltip is being shown.
the onmouseover
event sends an argument with the row and column from the data table,
of the point that is being hovered.
as such, we can get the layout, find the point, and position the tooltip.
google.visualization.events.addListener(chart, 'onmouseover', function (sender) {
// ensure point is hovered
if (sender.row !== null) {
var padding = 16;
var chartLayout = chart.getChartLayoutInterface();
var pointBounds = chartLayout.getBoundingBox('point#' + (sender.column - 1) + '#' + sender.row);
var tooltip = chart.getContainer().getElementsByClassName('google-visualization-tooltip');
if (tooltip.length > 0) {
var tooltipBounds = tooltip[0].getBoundingClientRect();
tooltip[0].style.top = (pointBounds.top - tooltipBounds.height - padding) + 'px';
tooltip[0].style.left = ((pointBounds.left + (pointBounds.width / 2)) - (tooltipBounds.width / 2)) + 'px';
}
}
});
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = new google.visualization.DataTable({
"cols": [
{"label": "x", "type": "number"},
{"label": "y", "type": "number"}
],
"rows": [
{"c":[{"v": 2015}, {"v": 1}]},
{"c":[{"v": 2016}, {"v": 2}]},
{"c":[{"v": 2017}, {"v": 3}]},
{"c":[{"v": 2018}, {"v": 4}]},
{"c":[{"v": 2019}, {"v": 5}]},
{"c":[{"v": 2020}, {"v": 6}]}
]
});
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
google.visualization.events.addListener(chart, 'onmouseover', function (sender) {
// ensure point is hovered
if (sender.row !== null) {
var padding = 16;
var chartLayout = chart.getChartLayoutInterface();
var pointBounds = chartLayout.getBoundingBox('point#' + (sender.column - 1) + '#' + sender.row);
var tooltip = chart.getContainer().getElementsByClassName('google-visualization-tooltip');
if (tooltip.length > 0) {
var tooltipBounds = tooltip[0].getBoundingClientRect();
tooltip[0].style.top = (pointBounds.top - tooltipBounds.height - padding) + 'px';
tooltip[0].style.left = ((pointBounds.left + (pointBounds.width / 2)) - (tooltipBounds.width / 2)) + 'px';
}
}
});
var options = {
chartArea: {
bottom: 32,
left: 32,
right: 32,
top: 48,
width: '100%',
height: '100%'
},
hAxis: {
format: '0',
ticks: data.getDistinctValues(0)
},
legend: {
position: 'top'
},
pointSize: 4,
tooltip: {
isHtml: true,
trigger: 'both'
}
};
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>