Google Charts API

Tables: Tooltips & Popups

Introduction

Wouldn't it be nice to have a tootip or popup when a table cell is hovered over? As standard, the entire row is highlighted when any cell in the row is hovered over but tooltips are not natively supported in table charts.

This page is an investigation in how to create tooltips and popup overlays when a table cell is hovered over, something that has been asked about both in the API user-supported group and on Stack Overflow.

The question recently came up again in another post in the API user-supported group and so this page was created.

Example: Modal Long Text

This example was prompted by idan in the Google Visualization API Group who wanted to limit the number of characters in a cell. The data comes from a Google Sheet. Not surprisingly, the ability to show the longer text when the cell was hovered over was also asked for.

The code goes through the data cells checking the length of the contents of each one and shortens them if needed. The values are read and the formatted value written, so .getValue and .setFormattedValue are used.

Each cell is given a unique class name based on the row and column numbers. Id's do not appear to be accepted.

Event handlers are added to the table (not the div it is in), to listen for mouseover and mouseout, The class of the cell is collected and manipulated to extract the row and column numbers. These are then used to get the full text which appears in a modal window.

The code for the above table is:


    <script type="text/javascript">
	var modalText = (function() {
    google.charts.load('current', {'packages':['table']});
    google.charts.setOnLoadCallback(drawChart);
	
    function drawChart() {
	   var queryString = encodeURIComponent('SELECT A,B,C ORDER BY A');
	   var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1tswaWUAbeBijHq4o505w0h7TmbD-qGhR3jBactcbGq0/gviz/tq?gid=1950745726&headers=1&tq=' + queryString);
       query.send(handleQueryResponse);
    }

    function handleQueryResponse(response) {
       if (response.isError()) {
         alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
         return;
      }
		
      var quotes = response.getDataTable();
		
	  var totalRows = quotes.getNumberOfRows();
	  var totalCols = quotes.getNumberOfColumns();
	  var maxLength = 50;

	  for (i = 0; i < totalRows; i++) { 
	     for (j = 1; j < totalCols; j++) {
		 // Set the cell's formatted (displayed) text from the cell's value 
	     var quote = quotes.getValue(i, j);
	     if (quote.length >= maxLength) {
	  	    quote = quote.slice(0,maxLength) + "...";
		    quotes.setFormattedValue(i,j,quote);
	     }
		 // Set the cell's classname
		 quotes.setProperty(i,j,"className","r"+i+"c"+j);
	  }	  
	  }
		
	  var classNames = {};
	  var options = {'cssClassNames': classNames};
		 
      var chart = new google.visualization.Table(document.getElementById('quotes_div'));
      chart.draw(quotes, options);
		
	  // Add event listeners for the table. Need mouseover and mouseout 
	  let tableClass = document.getElementsByClassName("google-visualization-table");
		
	  tableClass[0].addEventListener("mouseover", function( event ) {
		var cellClass = event.target.className;
		// cellClass is two texts, what we added and what Google puts in there 
		var startLetter = cellClass.charAt(0);
		if (startLetter == "r") {
		   // We just need what we put in the cell class	
		   cellClass = cellClass.split(" ")[0];
		   // cellClass is going to be an r followed by some numbers, then a c followed by some more numbers, need to extract the row and column numbers
		   // Split cellClass at c 
		   splitClass = cellClass.split("c");
		   var rownum = parseInt(splitClass[0].slice(1));
		   var colnum = parseInt(splitClass[1]);
		   var longText = quotes.getValue(rownum,colnum);
		   document.getElementById("popup_div").innerHTML = "<p>" + longText + "</p>";
		   document.getElementById("popup_div").style.display = "inline-block";
	}
	}, false);
		
	tableClass[0].addEventListener("mouseout", function( event ) {
       document.getElementById("popup_div").innerHTML = "";
	   document.getElementById("popup_div").style.display = "none";
	}, false);

	}
	})();
	</script>
  

The CSS for the modal div windows is:


<style>
#popup_div {
   display: none;
   position: fixed;
   top: 50px;
   border: solid black 1px;
   padding: 10px;
   background-color: #fff;
   z-index: 99999;
   width: 70%;
   margin: 0 auto;
}
</style>

The above code will work no matter how the table is sorted or paged because the information to display the popup is taken from the cell itself. WhiteHat came up with another method in Google Visualization table chart click and return row / column values not working with paging enabled on Stack Overflow

Gotchas

When positioning the modal window be careful of using mouse coordinates to create a tooltip effect. Some phones will not behave as expected!

This page created March 6, 2021; last modified March 22, 2021