Change Infragistics Chart Tooltip Position

In this post I will discuss how to set position of tooltip for Infragistics ASP.Net Charts. This has been a very annoying problem with ASP.Net charts that when you have a custom tooltip that has width and height that can cause the tooltip to be clipped and user not being able to see all the information in the tooltip. See the example below. I have a custom tooltip that displays a DIV which has a width of 400px. When I hover on column on right side, half of the tooltip is clipped by right side of the browser.

clipped chart tooltip

Infragistics exposes client side events for charts where you have access to the HTML element corresponding to the tooltip. I thought I could handle these events and then try to set position CSS style to move the tooltip to a location so that tooltip always stays in the view depending on height and width of the browser view. Well I spent few hours fighting with DOM and trying to set x and y position of tooltip DIV. Well nothing worked.

Finally I went to good old debugging using IE Developer Tools and see what actually was happening in Infragistics javascript code itself. Well there was my answer. Well not answer to my problem but cause of the problem. Infragistics handles MOUSEMOVE event in their onmousemove. At the bottom of this function, I found this piece of code:

var ttof = this.TooltipOverflow ? 
    this.TooltipOverflow : tooltip_ref_body.getAttribute("igTtOf");
 switch (ttof) {
     case "None":
       IGB.SetXScrollContainerSafe(tooltip_ref_body, x);
       IGB.SetYScrollContainerSafe(tooltip_ref_body, y);
       break;
     case "ClientArea":
       IGB.SetXClientOverflowSafe(tooltip_ref_body, x);
       IGB.SetYClientOverflowSafe(tooltip_ref_body, y);
       break;
     case "ChartArea":
       locx = x - IGB.GetPageX(baseImageRef);
       locy = y - IGB.GetPageY(baseImageRef);
       IGB.SetXOverflowSafe(tooltip_ref_body, x, locx, baseImageRef);
       IGB.SetYOverflowSafe(tooltip_ref_body, y, locy, baseImageRef);
       break;
}

On every mousemove Infragistics javascript code keeps resetting the location of tooltip DIV. And this position is calculated based on position of mouse. It did not matter how much position of tooltip I set, it will keep resetting back to position of mouse in this mousemove event handler. After thinking through, I came up with 3 solutions.

  1. Modify Infragistics ig_webchart.js to calculate x and y position based on size of tooltip DIV and keep it in view.
  2. Add your own DIV element on the page. In showTooltip event from IG, hide the original tooltip and then use its position to show your DIV.
  3. Add a DIV on your page at some fixed location which is always in view. Then in Showtooltip event handler sets it visibility and data in it and hide original tooltip DIV.

Option 2 and 3 looked like choices that would not require me to change Infragistics code itself. But it depends a lot on Infragistics event handler. And if Infragistics changed it handling that would mean I will have to modify my code again. So I decided to change ig_Webchart.js file in Infragistics code itself. By doing so I would be able to fix this problem for good for all charts. I think this is one feature that Infragistics should have implemented in first place.

The fix is pretty simple. In onmousemove function, based on mouse position, tooltip DIV size and browser view height and width, calculate position so that tooltip DIV comes in view. Then set the position value on tooltip div. After the changes I made, the code looked like below.

var thisTooltipPos = this.calculateTooltipPosition(evt, id);
var ttof = this.TooltipOverflow ? 
 this.TooltipOverflow : tooltip_ref_body.getAttribute("igTtOf");
switch (ttof) {
  case "None":
     if (thisTooltipPos.x == -1 && thisTooltipPos.y == -1) {
      IGB.SetXScrollContainerSafe(tooltip_ref_body, x);
      IGB.SetYScrollContainerSafe(tooltip_ref_body, y);
     }
     else {
      IGB.SetXScrollContainerSafe(tooltip_ref_body, thisTooltipPos.x);
      IGB.SetYScrollContainerSafe(tooltip_ref_body, thisTooltipPos.y);
     }
     break;
     ..
     ..
}

In my calculateTooltipPosition function, I calculate position of tooltip to keep it in view and then set it on tooltip div. You can see from the examples below that tooltip alwas stays in view inside browser window.

Wrapping Text in tooltip

Another problem you will run into with tooltip is that when you have long text string, it will not wrap in the DIV if you want to control the width of DIV so that it is not too wide. The problem is that tooltip div has its position CSS style set to absolute. That takes this DIV element out of normal flow of the page. Then text-wrap does not work. This can be accomplished, you will just have to set appropriate style on containing div. For example in my custom tooltip format I have set CSS styles as shown below:

StockPriceChart.Tooltips.FormatString = "<div style='overflow:hidden;
white-space:normal;
width:200px;
text-wrap:normal;' id='stepchartTooltipId<DATA_ROW>'>
<p style='float:right;right-margin:1px;width:190px;position:relative;'><DATA_ROW>" +
GetMockTooltip() + "</p></div>";

Set overflow:hidden and white-space:normal and set a fixed width for inner paragraph as well.

wrap tooltip text

If you need some help with this, feel free to contact me.

comments powered by Disqus

Blog Tags