Search code examples
highchartsdonut-chart

Highcharts donut hover all area


I created a Pie Donut chart with highcharts, it works well. Now what I want to do is when I hover an area, I want to highlight its parents and children and also to have all their data in the tooltip.

Here is my chart :

https://jsfiddle.net/whoknows/q9srL6o7/2/

And here is what I'd like to do :

http://i.imgur.com/AMr42dO.png

Thanks.


Solution

  • It is possible to use setState in mouseOver and mouseOut events of points to set hover state for multiple points. Tooltip formatter can also display multiple points that will match criteria. I have added hoverGroup variable to each point to find those points for setting states and for tooltip. Example: http://jsfiddle.net/q9srL6o7/4/

    $(function () {
        var chart;
        $(document).ready(function () {
            var colors = ["#00bcd4", "#00838f", "#69f0ae", "#f4511e", "#d81b60", "#1e88e5"],
                categories = ['Site #1', 'Site #2', 'Site #3', 'Site #4', 'Site #5'],
                data = [{
                    y: 55.11,
                    color: colors[0],
                    drilldown: {
                        name: 'Site #1',
                        categories: ['Leisure', 'Business'],
                        data: [45.01, 10.1],
                        drilldown: {
                            name: 'In/Out',
                            categories: ['In', 'In', 'Out', 'Out'],
                            data: [32.97, 12.04, 6.1, 4]
                        }
                    }
                }, {
                    y: 21.63,
                    color: colors[1],
                    drilldown: {
                        name: 'Site #2',
                        categories: ['Leisure', 'Business'],
                        data: [13.12, 8.51],
                        drilldown: {
                            name: 'In/Out',
                            categories: ['In', 'In', 'Out', 'Out'],
                            data: [8.53, 4.59, 3.12, 5.39]
                        }
                    }
                }, {
                    y: 11.94,
                    color: colors[2],
                    drilldown: {
                        name: 'Site #3',
                        categories: ['Leisure', 'Business'],
                        data: [9.91, 2.03],
                        drilldown: {
                            name: 'In/Out',
                            categories: ['In', 'In', 'Out', 'Out'],
                            data: [5.91, 4, 1, 1.03]
                        }
                    }
                }, {
                    y: 7.15,
                    color: colors[3],
                    drilldown: {
                        name: 'Site #4',
                        categories: ['Leisure', 'Business'],
                        data: [4.55, 2.6],
                        drilldown: {
                            name: 'In/Out',
                            categories: ['In', 'In', 'Out', 'Out'],
                            data: [4, 0.55, 0.75, 1.85]
                        }
                    }
                }, {
                    y: 4.17,
                    color: colors[4],
                    drilldown: {
                        name: 'Site #5',
                        categories: ['Leisure', 'Business'],
                        data: [2.49, 1.68],
                        drilldown: {
                            name: 'In/Out',
                            categories: ['In', 'In', 'Out', 'Out'],
                            data: [1.46, 1.03, 0.45, 1.23]
                        }
                    }
                }],
                siteData = [],
                trafficData = [],
                inoutData = [],
                inoutColors = ['#faba59', '#f79f45', '#8cd260', '#5cc064'];
    
            for (var i = 0; i < data.length; i++) {
                siteData.push({
                    name: categories[i],
                    y: data[i].y,
                    color: data[i].color,
                    hoverGroup: i
                });
    
                for (var j = 0; j < data[i].drilldown.data.length; j++) {
                    trafficData.push({
                        name: data[i].drilldown.categories[j],
                        y: data[i].drilldown.data[j],
                        color: j === 0 ? '#f06e4a' : '#36a061',
                        hoverGroup: i
                    });
                }
    
                for (var k = 0; k < data[i].drilldown.drilldown.data.length; k++) {
                    inoutData.push({
                        name: data[i].drilldown.drilldown.categories[k],
                        y: data[i].drilldown.drilldown.data[k],
                        color: inoutColors[k],
                        hoverGroup: i
                    });
                }
            }
    
            // Create the chart
            var chart = new Highcharts.Chart({
                chart: {
                    renderTo: 'container',
                    type: 'pie'
                },
                showInLegend: false,
                legend: {
                    enabled: false
                },
                credits: {
                    enabled: false
                },
                title: {
                    enabled: false,
                    text: ''
                },
                yAxis: {
                    title: {
                        text: 'Total percent market share'
                    }
                },
    
                plotOptions: {
                    pie: {
                        shadow: false,
                        point: {
                            events: {
                                mouseOver: function () {
                                    var hoverGroup = this.hoverGroup,
                                        series = this.series.chart.series;
                                    $.each(series, function (i, s) {
                                        $.each(s.points, function (j, p) {
                                            if (p.hoverGroup == hoverGroup) p.setState('hover');
                                        });
                                    });
                                },
                                mouseOut: function () {
                                    var series = this.series.chart.series;
                                    $.each(series, function (i, s) {
                                        $.each(s.points, function (j, p) {
                                            p.setState('');
                                        });
                                    });
                                }
                            }
                        }
                    }
                },
                tooltip: {
                    valueSuffix: '',
                    formatter: function () {
                        var ret = '',
                            once = true,
                            hoverGroup = this.point.hoverGroup,
                            series = this.series.chart.series;
    
                        $.each(series, function (i, s) {
                            $.each(s.points, function (j, p) {
                                if (p.hoverGroup == hoverGroup) {
                                    ret = '<span style="color:' + p.color + ';">●</span> ' + p.name + ' :' + p.y + '<br/>' + ret;
                                }
                            });
                        });
                        return ret;
                    }
                },
                series: [{
                    name: 'In/Out',
                    data: inoutData,
                    size: '85%',
                    innerSize: '20%',
                    dataLabels: {
                        formatter: function () {
                            return null;
                        }
                    }
                }, {
                    name: 'Type de trafic',
                    data: trafficData,
                    size: '90%',
                    innerSize: '85%',
                    dataLabels: {
                        formatter: function () {
                            return null;
                        }
                    }
                }, {
                    name: 'Site',
                    data: siteData,
                    size: '100%',
                    innerSize: '90%',
                    dataLabels: {
                        formatter: function () {
                            return null;
                        }
                    }
                }]
            });
        });
    
    });