Incubator-echarts: Tooltips should not leave (window)

Created on 27 Jan 2017  ·  7Comments  ·  Source: apache/incubator-echarts

echarts_screen

When using a chart near the edge of your browser window, it may get cut off. I've tried setting confine: true, but this does not give the desired effect, since then it will be completely isolated in the chart div. This may not be a problem for large charts, but for small sparkline charts it is a problem.

Since I think this is unintended behaviour (I can't think of a reason why a tooltip would display outside of your window), I think this is a bug.

I am using the latest eCharts (3.4.0) with Google Chrome (55.0.2) on Windows 10

stale

Most helpful comment

Thanks for your reply, and pointing me to the English docs. I didn't even know the English docs for eCharts 3 were already available.

Well, confine: true does not work for sparklines, see:

chart_confine

It completely overlaps the chart. Also, one thing I really like about eCharts is the ability for tooltips to be outside of the chart canvas. You do not see that often in charting libraries.

All 7 comments

Thanks for your reply, and pointing me to the English docs. I didn't even know the English docs for eCharts 3 were already available.

Well, confine: true does not work for sparklines, see:

chart_confine

It completely overlaps the chart. Also, one thing I really like about eCharts is the ability for tooltips to be outside of the chart canvas. You do not see that often in charting libraries.

@JeffreyRoosendaal - were you able to fix this?

@JeffreyRoosendaal Interested in this as well, it makes no sense to display the tooltip outside of the window.

Hi,

This remains an issue on the latest version (4.5.0). I am not sure why this was marked as stale, as there is currently no sufficient solution.

For anyone else struggling with this, I've written a function for the position callback that solves this. It first attempts to place the tool-tip to the top right of the mouse position. If it overflows to the right, it flips it to the left. If it then overflows to the left, it places it a fixed distance from the left edge of the window (since there's no better placement on the X axis at this point). And vice versa for top and bottom placement, with the fallback here placing it a fixed distance from the top edge of the window.

Notes:

  • The efficiency of this can probably be improved
  • Feel free to make a pull request incorporating this into the default tool-tip position logic. Please comment here if you do, because I might do it myself at a later stage.
{
    tooltip: {
        position: function (canvasMousePos, params, tooltipDom, rect, sizes) {
            var margin = 10; // How far away from the mouse should the tooltip be
            var overflowMargin = 5; // If no satisfactory position can be found, how far away from the edge of the window should the tooltip be kept

            // The chart canvas position
            var canvasRect = tooltipDom.parentElement.getElementsByTagName('canvas')[0].getBoundingClientRect();

            // The mouse coordinates relative to the whole window
            // The first parameter to the position function is the mouse position relative to the canvas
            var mouseX = canvasMousePos[0] + canvasRect.x;
            var mouseY = canvasMousePos[1] + canvasRect.y;

            // The width and height of the tooltip dom element
            var tooltipWidth = sizes.contentSize[0];
            var tooltipHeight = sizes.contentSize[1];

            // Start by placing the tooltip top and right relative to the mouse position
            var xPos = mouseX + margin;
            var yPos = mouseY - margin - tooltipHeight;

            // The tooltip is overflowing past the right edge of the window
            if (xPos + tooltipWidth >= document.documentElement.clientWidth) {

                // Attempt to place the tooltip to the left of the mouse position
                xPos = mouseX - margin - tooltipWidth;

                // The tooltip is overflowing past the left edge of the window
                if (xPos <= 0)

                    // Place the tooltip a fixed distance from the left edge of the window
                    xPos = overflowMargin;
            }

            // The tooltip is overflowing past the top edge of the window
            if (yPos <= 0) {

                // Attempt to place the tooltip to the bottom of the mouse position
                yPos = mouseY + margin;

                // The tooltip is overflowing past the bottom edge of the window
                if (yPos + tooltipHeight >= document.documentElement.clientHeight)

                    // Place the tooltip a fixed distance from the top edge of the window
                    yPos = overflowMargin;
            }

            // Return the position (converted back to a relative position on the canvas)
            return [xPos - canvasRect.x, yPos - canvasRect.y]
        }
    }
}

when you have more than one chart in a row the above solution can not help you. I changed a condition for tooltip position as below :

{
    tooltip: {
        position: function(canvasMousePos: any, params: any, tooltipDom: any, rect: any, sizes: any) {
            debugger;
            var margin = 10; // How far away from the mouse should the tooltip be
            var overflowMargin = 5; // If no satisfactory position can be found, how far away from the edge of the window should the tooltip be kept

            // The chart canvas position
            var canvasRect = tooltipDom.parentElement.getElementsByTagName("canvas")[0].getBoundingClientRect();

            // The mouse coordinates relative to the whole window
            // The first parameter to the position function is the mouse position relative to the canvas
            var mouseX = canvasMousePos[0] + canvasRect.x;
            var mouseY = canvasMousePos[1] + canvasRect.y;

            // The width and height of the tooltip dom element
            var tooltipWidth = sizes.contentSize[0];
            var tooltipHeight = sizes.contentSize[1];

            // Start by placing the tooltip top and right relative to the mouse position
            var xPos = mouseX + margin;
            var yPos = mouseY - margin - tooltipHeight;
            console.log('xPos: ', xPos);
            console.log('yPos: ', yPos);
            console.log('xPos-tooltip: ', xPos - tooltipWidth);

            // The tooltip is overflowing past the right edge of the window
            if (Math.abs(tooltipDom.closest('.GridCardContent').clientWidth - canvasMousePos[0]) < tooltipWidth) {
                // Attempt to place the tooltip to the left of the mouse position
                xPos = mouseX - margin - tooltipWidth;

                // The tooltip is overflowing past the left edge of the window
                if (xPos <= 0)
                    // Place the tooltip a fixed distance from the left edge of the window
                    xPos = overflowMargin;
            }

            // The tooltip is overflowing past the top edge of the window
            if (yPos <= 0) {
                // Attempt to place the tooltip to the bottom of the mouse position
                yPos = mouseY + margin;

                // The tooltip is overflowing past the bottom edge of the window
                if (yPos + tooltipHeight >= tooltipDom.closest('.GridCardContent').clientHeight)
                    // Place the tooltip a fixed distance from the top edge of the window
                    yPos = overflowMargin;
            }

            // Return the position (converted back to a relative position on the canvas)
            return [xPos - canvasRect.x, yPos - canvasRect.y];
        },
    }
}
Was this page helpful?
0 / 5 - 0 ratings