user2128
user2128

Reputation: 640

Display tooltip on hovering over the legend using Highcharts and jQuery-ui tooltip plugin

I am trying to display tooltip on hovering over the legends. Highcharts doesnt have the function to do so hence i figured that using jquery tooltip plugin I will be able to do so. The graph is generated dynamically using realtime data. As the data is added, the series is generated and simultaneously the series is added in the Legend section. There might be the case that series name is too big and would be truncated.In such condition, I would like to display the entire series name in the form of tooltip when hovered over the name. Can anyone please give me any suggestion for how to go about it? Thanks, :) My chart code is given below:

var chartConfig = {
                    chart: {
                        zoomType: 'x',
                        marginTop: 24,
                        borderWidth: 1,
                        borderRadius: 6,
                        borderColor: '#ccc',
                        backgroundColor: '#F5F5F5',
                        resetZoomButton: {
                            theme: {
                                display: 'none'
                            }
                        },
                        events: {
                            selection: function(event){
                                if (event.xAxis) {
                                    $scope.zoomStart = Math.floor(event.xAxis[0].min).toString();
                                    $scope.zoomEnd = Math.floor(event.xAxis[0].max).toString();
                                    $scope.zoomed = true;
                                    $scope.$apply();
                                }
                            },
                            load: function(){
                                console.log("successfully loaded");
                                                console.log(chartConfig.legend.text);

                            },//load
                            addSeries: function(){
                                var chart = this;
                                legend = chart.legend;
                                console.log('Series added '+legend.allItems.length);
                            }
                        }
                    },
                    colors: [
                        '#a6a8ab', //very light grey - severity 0
                        '#7bc043', //light green - severity 1
                        '#6798c7', //blue - severity 2
                        '#edbe1c', //yellow - severity 3
                        '#ed6a1c', //Red - severity 4
                        '#ed1c24', //Dark red - severity 5
                        '#17A768', //green
                        '#E7E737', //yellow
                        '#F1AD1D', //orange
                        '#F76C27', //darker orange
                        '#E73F3F', //red
                        '#781800', //darker red
                        '#A8A8A8', //grey
                        '#BBAE93', //yellowish grey
                        '#EBEFC9', //yellow almost white
                        '#424242', //dark grey
                        '#A8C0D8', //bluish grey
                        '#08050E'  //nearly black, slightly purple
                    ],
                    yAxis: {
                        min: 0,
                        title: {

                            style: {
                                color: '#6D869F',
                                fontSize: '12px',
                                fontWeight: 'normal'
                            }
                        },
                        stackLabels: {
                            enabled: false
                        }
                    },
                    xAxis: {
                        type: 'datetime',
                        title: {
                            text: $filter('i18n')('_EventTimeLabel_'),
                            style: {
                                color: '#6D869F',
                                fontSize: '12px',
                                fontWeight: 'normal'
                            }
                        },
                        labels: {
                            rotation: -45,
                            align: 'right',
                            style: {
                                fontSize: '10px',
                                fontWeight: 'normal'
                            },
                            formatter: function() {
                                return Highcharts.dateFormat('%H:%M:%S', this.value);
                            }
                        },
                        events: {
                            afterSetExtremes: function(event) {
                                reloadLegend();
                            }

                     }//event ends
                 },
                    legend: {
                        title: {
                            text: $scope.criteria.eventfieldName
                        },
                        layout: 'vertical',
                        align: 'right',
                        x: 0,
                        y: 0,
                        verticalAlign: 'top',
                        floating: false,
                        backgroundColor: 'white',
                        borderColor: '#CCC',
                        borderWidth: 1,
                        shadow: false,
                        itemStyle: {
                            //cursor: 'pointer',
                            fontSize: '11px'
                        },
                        labelFormatter: function() {
                            // this function populates the legend with a total value over the points
                            // this makes sense for count, but you can't just add up eps per interval to get a total
                            // it should probably be an average
                            // Figure 6 intervals with sev 0 at 1 eps, it would total 6 eps, if divided by 6 intervals = 1
                            var i, len, total = 0, intervals = 0;
                            if (this.points) {
                                // during zoom and on updates
                                len = this.points.length;
                                for (i = 0; i < len; i++) {
                                    // limit the data points considered viewable in zoom - not accurate
                                    if (this.points[i].x > this.xAxis.min && this.points[i].x < this.xAxis.max) {
                                        total += this.points[i].y;
                                        intervals++;
                                    }
                                }
                                debug.log('labelFormatter points',this.name,total,intervals);
                            } else {
                                // seems like only during initial load
                                len = this.yData.length;
                                for (i = 0; i < len; i++) {
                                    total += this.yData[i];
                                    intervals++;
                                }
                                debug.log('labelFormatter yData',this.name,total,intervals);
                            }

                            var precision = 0;
                            if ($scope.modalData.countType === 'Event Count per Second') {
                                if (intervals < 1) {
                                    //ensure no divide by zero
                                    intervals = 1;
                                }
                                total = total/intervals;
                                precision = Math.floor(Math.log($scope.displayIntervalTime * intervals)/Math.log(10))-2;
                            }

                            var nameLabel = this.name;
                            if (nameLabel === highCardinalitySelector) {
                                nameLabel = otherLabel;
                            }

                            return truncateLegend(nameLabel,16)+'(' + total.toFixed(precision) + ')';
                        }, 
                        itemMarginTop: 2,
                        enabled: $scope.legendEnabled
                    },
                    tooltip: {
                        formatter: function() {
                            var content;
                            content = '<strong>'+ $filter('i18n')('_EventTimeLabel_') +':</strong> ' + Highcharts.dateFormat('%H:%M:%S', this.x) + '<br/>';

                            var nameLabel = this.series.name;
                            if (nameLabel === highCardinalitySelector) {
                                nameLabel = otherLabel;
                            }

                            content += '<strong>' + $scope.criteria.eventfieldName + ':</strong> ' + nameLabel + '<br/><strong>' + eventCountTypeLabel + ':</strong> ' + this.y.toFixed(decimals) + '<br/>';
                            if ($scope.modalData.chartType == 'Stacked Bar 2D') {
                                content += '<strong>'+ $filter('i18n')('_TotalLabel_') +':</strong> ' + this.point.stackTotal.toFixed(decimals) + '<br/>';
                            }
                            return content;
                        },
                        style: {
                            color: '#333',
                            fontSize: '11px',
                            padding: '8px'
                        },
                        borderColor: '#CCC',
                        followPointer: true
                    },
                    series: series,
                    title: '',
                    exporting: {
                        enabled: false
                    },
                    credits: {
                        enabled: false
                    },
                    plotOptions: {
                        series: {
                            cursor: 'pointer',
                            point: {
                                events: {
                                    click: function() {
                                        var searchStr = '(' + $scope.criteria.filter + ')';

                                        // Add on the tenant filter if selected for view by default tenant
                                        if($scope.activeview.tenant) {
                                            searchStr += ' AND (rv39:"' + $filter('escChars')($scope.activeview.tenant) +'")';
                                        }

                                        if ($scope.legendEnabled) {
                                            // the null entry has been selected
                                            if(this.series.name == nullString) {
                                                searchStr += ' AND NOT (notnull:' + $scope.criteria.eventfield + ')';
                                            } else if(this.series.name != highCardinalitySelector) {
                                                // a non-null entry has been selected
                                                searchStr += ' AND (' + $scope.criteria.eventfield + ':"' + $filter('escChars')(this.series.name) + '")';
                                            } else {
                                                //the other entry '*' has been selected
                                                var excludeStr = '';
                                                var hasNullMember = false;
                                                for(i=0;i<series.length;i++) {
                                                    if(series[i].name == nullString)
                                                    {
                                                        hasNullMember = true;
                                                    } else if (series[i].name != highCardinalitySelector) {
                                                        excludeStr += $scope.criteria.eventfield + ':"' + $filter('escChars')(series[i].name) + '" ';
                                                    }
                                                }
                                                // exclude the ones we know and the null ones if they exist
                                                searchStr += ' AND NOT (' + excludeStr + ')';
                                                if (hasNullMember) {
                                                    searchStr += ' AND notnull:' + $scope.criteria.eventfield;
                                                }
                                            }
                                        }

                                        debug.log(searchStr);
                                        $scope.launchSearch(searchStr, this.x.toString(), (this.x + $scope.displayIntervalTime).toString());
                                    }
                                }
                            }
                        }
                    }
                };

Hovering Part:

var redrawChart = function() {
    console.log("Redraw function working");
    var chart = $element.find('.highcharts').highcharts(); //this could be better
    if (chart) {
        chart.redraw();
        legend=chart.legend;

        for (var i = 0, len = legend.allItems.length; i < len; i++) {
                     (function(i) {
                         var item = legend.allItems[i].legendItem;
                         item.on('mouseover', function (e) {
                             //show custom tooltip here

                             console.log("mouseover-" + chart.series[i].name);
                             chart.tooltip.refresh(chart.series[i].data[i]);

                             //$element(".tooltip[data-series='" + chart.series[i].name + "']"+"saloni").css({left:event.clientX, top:event.clientY}).show();
                            // chart.tooltip.refresh("its working");
                         }).on('mouseout', function (e) {
                             //hide tooltip

                             console.log("mouseout" + chart.series[i].name);
                            // chart.tooltip.hide();
                         });
                     })(i);

                 }//for loop

    }
    debug.log('chart redraw:', chart?'yes':'no');
};

So the hovering is working as i wanted it to be. I have managed to display it in the console. But the tricky part is to display it in the tooltip form. How do i generate the tooltip box such that it is displayed next to the legend?

Upvotes: 0

Views: 1991

Answers (1)

Nishith Kant Chaturvedi
Nishith Kant Chaturvedi

Reputation: 4769

A simpler solution is already on SO , See code below and refer existing fiddle at this fiddle

 events: {
            load: function () {
                var chart = this,
                    legend = chart.legend;

                for (var i = 0, len = legend.allItems.length; i < len; i++) {
                    (function(i) {
                        var item = legend.allItems[i].legendItem;
                        item.on('mouseover', function (e) {
                            //show custom tooltip here
                            console.log("mouseover" + i);
                        }).on('mouseout', function (e) {
                            //hide tooltip
                            console.log("mouseout" + i);
                        });
                    })(i);
                }

            }
        }

Upvotes: 1

Related Questions