Our Blog

Cognos How-To: Popups on Hover

There are many cases when you want more details when hovering over an element on the page. Maybe you want to see a graph when hovering over a crosstab intersection, or a larger chart when hovering over a microchart, or maybe even a static notice when hovering over a marker in a chart. All this, and more, is now possible!

First, an example:

Magnifying Microcharts

The user wanted to zoom in on the chart when hovering over it. What happens is that there is a hidden field next to the chart with the country ID. The function will automatically attach an onmouseover event to the microcharts to unhide and reposition a div with same id as the country code. The div that pops up was created using a repeater, HTML items, and a master/detail chart. The popup div has a onmouseleave event that hides the popup chart.

The main functions used are:

The vast majority of the script is dedicated to fading in/out the div.

Next the script to apply the onmouseover function:
<script>
var list = window['oCV'+'_THIS_'].getRV().getCV().getLayoutElementFromLid('Countries List'+'_THIS_')
, charts = list.getElementsByTagName('span')
, code;

for(var i = 0;i<charts.length;i++){
if(!charts[i].getAttribute('chartContainer')) continue;
charts[i].parentNode.firstChild.style.display='none';
code = charts[i].previousSibling.innerHTML;
charts[i].onmouseover = function() {
var x=findPos(this)[0], y=findPos(this)[1], targ = document.getElementById(this.parentNode.firstChild.innerHTML)
, h = findPos(document.getElementById('RVContent'+'_THIS_'))[1] ;
paulScripts.prepFader(document.getElementById(this.parentNode.firstChild.innerHTML));
targ.style.visible='hidden';
targ.style.display='block';

targ.style.left = x - targ.offsetWidth/2;
if (targ.style.left<0) targ.style.left=0;
targ.style.top = y-h - targ.offsetHeight/2;
if(parseInt(targ.style.top) <h) targ.style.top=0;
targ.style.visible='visible';
targ.style.display='none';
}
charts[i].onmouseout = function() {
paulScripts.prepFader(document.getElementById(this.parentNode.firstChild.innerHTML),1);
}
}

</script>

The prepFader function ensures that the popup chart only appears after the user hovers for 500 ms, without it, sliding the cursor over will cause all of popup charts to appear.

Now for something a little more interesting.

Let’s start with a boring chart.

Boring Chart

Not doing much, but let’s say that we want a list to magically appear, filtered based on wherever the user is hovering.

Filtering A List

Just like that!

The trick here is identifying the context of the area. You could try attempting to parse the text from the tooltip, but that will only end in tears and frustration. Instead, Cognos has some very useful built in functions for this.

To start with, the function prepArea. As before, I don’t want the list appearing until the user stops moving the cursor – 500 ms is sufficient.

paulScripts.prepArea= (function(elm,cancel){
var timer;
return function(elm,cancel){
clearTimeout(timer);
if(cancel==1) return true;
timer = window.setTimeout(
function(){
oCV.getSelectionController().setSelectedChartArea(elm);
var nodeValues = oCV.getSelectionController().getSelectedObjectsJsonContext()[0]['com.ibm.widget.context']['values'];
paulScripts.filterList(nodeValues['Region'],nodeValues['Month'])
}
,500);
return true
};
})();

Call it once to start the timer, call it again with the flag 1 to stop it.

Once the timer finishes, it triggers a few Cognos internal functions. setSelectedChartArea is the equivalent to selecting a cell in a crosstab or list. The only real difference is that the area doesn’t get that annoying yellow background.

With the area selected, we can then use getSelectedObjectJsonContext. That function will return something like:

[{"com.ibm.widget.context":{"values":{"Region":["Americas"]}},"com.ibm.widget.context.report.select":{"select":{"selectedItem":"Region","itemSpecification":{"/content/folder[@name='Samples']/folder[@name='Cubes']/package[@name='Sales and Marketing (cube)']/model[@name='2008-07-25T15:28:38.072Z']":{"values":[{"caption":"Americas","mun":"[sales_and_marketing].[Retailers].[Retailers].[Region]->:[PC].[@MEMBER].[710]","use":"Americas"}]}}}}}]

That’s an object sitting in an array. If there was more than one object selected, we’d get multiple elements in that top array. But since it’s difficult to hover over two things simultaneously, we’ll assume that won’t happen. Now that we have the values, we’re calling a function called filterList.

paulScripts.filterList = function(region,month){
//Regions is 0 column
//Month is 1 column
var total = 2;
if(!region) total--;
if(!month) total--;
if(total==0) return false;
var rows = list.getElementsByTagName('tr');
for(var i =1;i<rows.length;i++){
var err=0;
if(region && rows[i].getElementsByTagName('td')[0].innerText == region) err++;
if(month && rows[i].getElementsByTagName('td')[1].innerText == month) err++;
if(err>=total) {rows[i].style.display=''} else {rows[i].style.display='none'}
}
paulScripts.fader.open(list);
}

This is a bit hacky because I’m rushed. If region or month is null, then the total will be less. I take the list, and loop through the rows testing the inner text of each cell against the selected region or month. If it matches, err increases. If err is less than the expected results. It will hide the row.

Finally, the events are attached to the chart areas and all is well.

for(var i=0;i<areas.length;i++){
areas[i].onmouseover=function() {paulScripts.prepArea(this)};
areas[i].onmouseout=function() {paulScripts.prepArea(this,1)};
}

report

This entry was posted in Technical Concepts and Ideas, Tips and tricks. Bookmark the permalink.

Comments are closed.

PerformanceG2 Menu