0
votes

I have a system with lots of highcharts which can be positioned basically anywhere on the page. Some are very small (e.g. 50px x 50px). I see we can set tooltip.outside : true

tooltip: {
    outside: true
}

This stops the tooltip taking over the whole chart container by breaking it out of the chart and into the window. However this can cause overflow issues with the window when you're near the edge of the page and I personally prefer a static tooltip.

I'd like to always fix the tooltip to float above the chart, top left with a bit of padding, which for my application will almost always be visible and will avoid overflow issues, e.g.;

Top left

I've looked into setting a custom positioner, however, as the "outside" tooltip is now part of the window and not relative to the chart, the positioner sets a fixed position, which isn't suitable for my application. I'd like the tooltip to always be above the chart regardless of mouse or scroll positions.

Of course I could add a custom element and position it above the chart myself, then applying the tooltip to that, but we have a lot of charts and this seems cumbersome.

Tooltip outside Fiddle

Suggestions? Thanks

2

2 Answers

0
votes

What about using the positioner callback without setting the 'outside' option? It will set the wanted position inside the chart area.

Demo: https://jsfiddle.net/BlackLabel/gabjwd2e/

API: https://api.highcharts.com/highcharts/tooltip.positioner

0
votes

After a bit of poking around in the highstock Tooltip.prototype.getPosition code, it turns out what I needed was this.point.chart.pointer.getChartPosition();

        tooltip: {
            distance: 40,
            outside: true,
            positioner: function () {
                var point = this;
                var chart = point.chart;
                var chartPosition = chart.pointer.getChartPosition();
                var distance = point.distance;

                //Position relative to renderTo container
                return {
                    x: chartPosition.left - distance,
                    y: chartPosition.top - distance - (point.options.useHTML == true ? point.label.div.offsetHeight : point.label.height)
                }

                //Alternatively - Position relative to chart plot (ignoring legend)
                var containerScaling = chart.containerScaling;
                var scaleX = function (val) {
                    return (containerScaling ? val * containerScaling.scaleX : val);
                };
                var scaleY = function (val) {
                    return (containerScaling ? val * containerScaling.scaleY : val);
                };

                return {
                    x: chartPosition.left - distance + scaleX(chart.plotLeft),
                    y: chartPosition.top - distance + scaleY(chart.plotTop) - point.label.height
                }
            },
        },

See working fiddle.

I find it odd that this method is attached to pointer, but it's what I was after.

One thing to note, in the fiddle I use point.label.height, if useHTML:true; use point.label.div.height.