JSRoot Tooltip Question

Hi all,
I have a question regarding the tooltip functionality in JSRoot. I currently have a TGraph plotting arrays x_data and y_data against each other. Both are pulled from the same TTree using TSelector. I also have array z_data, once more pulled from the same TTree. Currently, when I hover over a point in my graph, it displays “graph”, “x= [x value at the point]”, and “y= [y value at the point]”. I would also like it so that the tooltip displays the corresponding z value from the z_data array. There do not appear to be any examples of this in the JSRoot APIs, so I was wondering if it is possible.

An abbreviated version of my code is below (it will draw the graph upon clicking a submit button defined in the HTML)

<!DOCTYPE html>
<html lang="en">

  <head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <script id="JSRootLoad" src="https://root.cern/js/5.7.1/scripts/JSRootCore.min.js?" type="text/javascript"></script>
    
    <script id="loadDraw1" type='text/javascript'>
      function handleClick() {
	  event.preventDefault();
	  var filename1 = "https://root.cern/js/files/hsimple.root";
	  JSROOT.OpenFile(filename1, function(file){ // open file
	      file.ReadObject("ntuple;1", function(tree) { // read from tree
		  var selector = new JSROOT.TSelector();
		  selector.AddBranch("px","xaxis"); //pull the branches i want
		  selector.AddBranch("py","yaxis");
		  selector.AddBranch("pz","zaxis");

		  var x_data = []; //define arrays for data
		  var y_data = [];
		  var z_data = [];
		  var npoints = 0;

		  selector.Begin = function(){
		  }

		  selector.Process = function() {
		      x_data.push(this.tgtobj.xaxis); //push branches into arrays
		      y_data.push(this.tgtobj.yaxis);
		      z_data.push(this.tgtobj.zaxis);
		      
		      npoints ++;
		  }

		  selector.Terminate = function() {
		      var graph1 = JSROOT.CreateTGraph(npoints,x_data, y_data); //define graph
		      JSROOT.redraw("drawing1",graph1,"P"); //draw graph
		      
		  }
		  document.getElementById("drawing1").innerHTML = ""; //clear drawing div
		  tree.Process(selector); //run the code
	      });
	  });
      }
      
    </script>
    <body>
      <form id="drawIt", onsubmit="return handleClick()">
	<input name="Submit" type="submit" value="Draw">
      </form>
	<div id = "drawing1" style ="width:800px; height:600px"></div>
    </body>
</html>

Thank you,
Steve

Hi Steve,

This is not documented feature, but is possible.
When you draw TGraph object, TGraphPainter is created.
It has method which provides tooltip information for the graph point.

You could overwrite this method, providing array of string values, like:

JSROOT.redraw("drawing1",graph1,"P", function(painter) {
   painter.TooltipText = function(d) {
       return ["title", "indx:" + d.indx, "x:" + d.x, "y:" + d.y ];
   }
});

Regards,
Sergey

Thank you! That is very helpful! I see it works well for the x axis value and y axis value, so how would I go about having the tooltip display the data that isn’t plotted, z_data? I tried putting in d.z_data to the TooltipText function, but this returned “undefined” on the tooltip.

Of course, there is no d.z data. You have to assign extra points to painter and do something like:

painter.extra_points = gr2.fY;

...

painter.TooltipText = function(d) {
    return ["title", "indx:" + d.indx, "x:" + d.x, "y:" + d.y, "z:" + this.extra_points[d.indx] ];
}

Of course, you should check yourself, how points from different TGraphs are placed and if simple index can be used for that

That worked perfectly! Thank you!

Hi Sergey,
This worked very well with a TGraph, but I noticed that when I switched my TGraph to a TMultiGraph, the TooltipText reverted back to the default. Looking through the JSRoot source code seems to indicate that TMultiGraphPainter does not have a TooltipText method. Is there some way to achieve a similar effect on my MultiGraph?
Thank you!

This is more tricky.
When TMultiGraph painter used, it creates N painters for each graph.
You could access them via mgpainter.painters array.
And for each graph painter you have to redefine TooltipText function individually.
Like:

JSROOT.redraw("drawing1",mg, "", function(mgpainter) {
   mgpainter.painters.forEach(function(painter) {
      painter.TooltipText = function(d) {
          return ["title", "indx:" + d.indx, "x:" + d.x, "y:" + d.y ];
      }
   });
});

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.