0

How does google-visualization-tooltip calculate the left and top values for style ? example - on debugging i can see that :-

<div class="google-visualization-tooltip" style="width: 1px; height: 0px; left: 453.25px; top: 44.91px;"</div>

How can i calculate this relatively, so that the tooltip shows on top and is center aligned to the point that is hovered upon, irrespective of the width of the element?

N29
  • 141
  • 1
  • 17

1 Answers1

2

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>
WhiteHat
  • 59,912
  • 7
  • 51
  • 133