Search code examples
colorshighchartstooltipvisible

Highcharts change crosshairs color by number of visible series


What we are trying to do is to:

  • display crosshairs only if number of visible series > 1 (color: black)
  • otherwise disable crosshairs or alternatively set color transparent

Here are our problems:

  • independent of the number of visible series the crosshairs is not shown for the first hover (but for all subsequent hovers)
  • our main problem is that the color is not changing although the console.log displays that the color is correctly set due to the number of visible series

Please see the fiddle: example

Thanks for your suggestions!

$(function () {
var chart = new Highcharts.Chart({
    chart: {
        type: 'area',
        renderTo: 'container'
    },
    title: {
        text: 'Historic and Estimated Worldwide Population Growth by Region'
    },
    subtitle: {
        text: 'Source: Wikipedia.org'
    },
    xAxis: {
        categories: ['1750', '1800', '1850', '1900', '1950', '1999', '2050'],
        tickmarkPlacement: 'on',
        title: {
            enabled: false
        }
    },
    yAxis: {
        title: {
            text: 'Billions'
        },
        labels: {
            formatter: function () {
                return this.value / 1000;
            }
        }
    },
    tooltip: {
        formatter: function () {

            // show crosshairs only if visible series >1, else transparent
            var nVisible = 0;
            for (var i = 0; i < chart.series.length; i++) {
                if (chart.series[i].visible) {
                    nVisible++;
                };
                if (nVisible > 1) {
                    break;
                };
            };

            if (nVisible > 1) {
                chart.options.tooltip.crosshairs = {
                    width: 1.5,
                    dashStyle: 'solid',
                    color: 'black'
                };
            } else {
                chart.options.tooltip.crosshairs = {
                    color: 'transparent'
                };

            };
            console.log(chart.options.tooltip.crosshairs.color);
            return this.y + ' Billions';
        },
        backgroundColor: 'rgba(255,255,255,0.95)'
    },
    plotOptions: {
        area: {
            stacking: 'normal',
            lineColor: '#666666',
            lineWidth: 1,
            marker: {
                lineWidth: 1,
                lineColor: '#666666'
            }
        }
    },
    series: [{
        name: 'Asia',
        data: [502, 635, 809, 947, 1402, 3634, 5268]
    }, {
        name: 'Africa',
        data: [106, 107, 111, 133, 221, 767, 1766]
    }, {
        name: 'Europe',
        data: [163, 203, 276, 408, 547, 729, 628]
    }, {
        name: 'America',
        data: [18, 31, 54, 156, 339, 818, 1201]
    }, {
        name: 'Oceania',
        data: [2, 2, 2, 6, 13, 30, 46]
    }]
});
});

Solution

  • Don't add crosshair in real time, instead when chart is initialized, enable crosshair and then manage color by attr() updating. For example: http://jsfiddle.net/D5DME/3/

    Code:

        tooltip: {
            crosshairs: [{
                width: 1.5,
                dashStyle: 'solid',
                color: 'black'
            }, false],
            formatter: function () {
    
                // show crosshairs only if visible series >1, else transparent
                var nVisible = 0;
                for (var i = 0; i < this.series.chart.series.length; i++) {
                    if (this.series.chart.series[i].visible) {
                        nVisible++;
                    };
                };
    
                if(this.series.chart.tooltip.crosshairs[0]) {
                    if (nVisible > 1) {
                        this.series.chart.tooltip.crosshairs[0].attr({
                            stroke: 'black'
                        });
                    } else {
                        this.series.chart.tooltip.crosshairs[0].attr({
                            stroke: 'rgba(0,0,0,0)'
                        });
                    }
                }
                return this.y + ' Billions';
            },
            backgroundColor: 'rgba(255,255,255,0.95)'
        },