Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Highcharts tooltip always on right side of cursor

Tags:

highcharts

I want to show the tooltip on the right side of the cursor.

I looked in the documentation/examples but I can't find a way to force the tooltips to stay on the right side of the cursor.

Can anyone tell me how to do it?

With tooltip positioner I only can set a default position.

like image 310
nelsonvarela Avatar asked Aug 15 '12 08:08

nelsonvarela


2 Answers

Tooltip positioner is much more than just default position. The function arguments contain info about your point position & tooltip dimensions, using which it should be fairly simple to position it to the right.

Highchart/stock allows you to define your alternate positioner as follows

tooltip:{
    positioner:function(boxWidth, boxHeight, point){
        ...
    }
}

Note that you have three arguments (boxWidth, boxHeight, point) at your disposal, these seem to be sufficient for most of the use cases to calculate a desired tooltip position. boxWidth and boxHeight are the width and height that your tooltip will require, hence you can use them for edge cases to adjust your tooltip and prevent it from spilling out of the chart or even worse getting clipped.

The default tooltip positioner that comes with highstock is as follows (Source)

/**
 * Place the tooltip in a chart without spilling over
 * and not covering the point it self.
 */
getPosition: function (boxWidth, boxHeight, point) {

    // Set up the variables
    var chart = this.chart,
        plotLeft = chart.plotLeft,
        plotTop = chart.plotTop,
        plotWidth = chart.plotWidth,
        plotHeight = chart.plotHeight,
        distance = pick(this.options.distance, 12), // You can use a number directly here, as you may not be able to use pick, as its an internal highchart function 
        pointX = point.plotX,
        pointY = point.plotY,
        x = pointX + plotLeft + (chart.inverted ? distance : -boxWidth - distance),
        y = pointY - boxHeight + plotTop + 15, // 15 means the point is 15 pixels up from the bottom of the tooltip
        alignedRight;

    // It is too far to the left, adjust it
    if (x < 7) {
        x = plotLeft + pointX + distance;
    }

    // Test to see if the tooltip is too far to the right,
    // if it is, move it back to be inside and then up to not cover the point.
    if ((x + boxWidth) > (plotLeft + plotWidth)) {
        x -= (x + boxWidth) - (plotLeft + plotWidth);
        y = pointY - boxHeight + plotTop - distance;
        alignedRight = true;
    }

    // If it is now above the plot area, align it to the top of the plot area
    if (y < plotTop + 5) {
        y = plotTop + 5;

        // If the tooltip is still covering the point, move it below instead
        if (alignedRight && pointY >= y && pointY <= (y + boxHeight)) {
            y = pointY + plotTop + distance; // below
        }
    } 

    // Now if the tooltip is below the chart, move it up. It's better to cover the
    // point than to disappear outside the chart. #834.
    if (y + boxHeight > plotTop + plotHeight) {
        y = mathMax(plotTop, plotTop + plotHeight - boxHeight - distance); // below
    }


    return {x: x, y: y};
}

With all the above information, I think you have sufficient tools to implement your requirement by simply modifying the function to make float to right instead of the default left.

I will go ahead and give you the simplest implementation of positioning tooltip to right, you should be able to implement the edge cases based on the aftermentioned default tooltip positioner's code

tooltip: {
    positioner: function(boxWidth, boxHeight, point) {         
        return {x:point.plotX + 20,y:point.plotY};         
    }
}

Read more @ Customizing Highcharts - Tooltip positioning

like image 167
Jugal Thakkar Avatar answered Oct 06 '22 20:10

Jugal Thakkar


The better solution to get your tooltip always on the right side of the cursor is the following:

function (labelWidth, labelHeight, point) { 
    return { 
        x: point.plotX + labelWidth / 2 + 20,
        y: point.plotY + labelHeight / 2 
    };
}
like image 34
Justin Avatar answered Oct 06 '22 20:10

Justin