MarcoSuma
MarcoSuma

Reputation: 59

Highcharts: how to move item legend position dynamically

I have this pie chart:

Pie chart

On the mouseover event of any slice, I have to select that slice and hide legend items except the one corresponding the slice selected, as the picture below:

enter image description here

Now, what I want is to change dynamically the legend item position and to put it on the top of the legend box.

Please, could you help me?

I post my code below:

function disegnaComposizionePTF_pie(grafico, seriesName, chartData, urlImg) {
$(document).find('.title-row').find('#btnPie').attr('class','iconPieSelected');
$(document).find('.title-row').find('#btnPie').attr('src',urlImg);

$(document).find('.title-row').find('#btnBar').attr('class','iconBar');
$(document).find('.title-row').find('#btnBar').attr('src',urlImg);

var originalStr = null;
var currentLegendColor = null;
var data = chartData;

$(grafico).highcharts({
    chart: {
        plotBackgroundColor: null,
        plotBorderWidth: null,
        plotShadow: false,
        type: 'pie'
    },
    title: {
        text: null
    },
    credits: {
        enabled: false
    },
    tooltip: {
        formatter: myFormatter
    },
    legend: {
        useHTML: true,
        align: 'right',
        layout: 'vertical',
        verticalAlign: 'middle',
        x: -50,
        labelFormatter: function() {
            var legendName = this.name;
            var match = legendName.match(/.{1,15}/g);
            return match.toString().replace(/\,/g,"<br/>");
        }
    },
    plotOptions: {
        pie: {
            allowPointSelect: true,
            cursor: 'pointer',
            innerSize: '60%',
            size: '100%',
            dataLabels: {
                enabled: false
            },
            showInLegend: true,
            point: {
                events: {
                    mouseOver: function() {
                        console.log("mouseover");
                        this.select(true);
                        originalStr = this.legendItem.textStr; 
                        currentLegendColor = this.legendItem.color;

                        var pos = -1;
                        for (i in this.series.data) {
                            var p = this.series.data[i];
                            if (p.name != this.name) {
                                p.legendSymbol.hide();
                                p.legendGroup.hide();
                            } else {
                                pos = i;
                            }
                        }
                        this.legendItem.textSetter(data[pos].longName);
                        var currentPos = this.series.data[pos].legendIndex;
                        console.log(currentPos);
                    },
                    mouseOut: function() {
                        console.log("mouseout");
                        this.select(false);
                        this.legendItem.textSetter(originalStr);
                        for (i in this.series.data) {
                            var p = this.series.data[i];
                            if (p.name != this.name) {
                                p.legendSymbol.show();
                                p.legendGroup.show();
                            }
                        }                           
                    }
                }
            }
        }
    },
    series: [{
        name: seriesName,
        colorByPoint: true,
        data: chartData
    }]
});

}

Upvotes: 0

Views: 1687

Answers (1)

Paweł Fus
Paweł Fus

Reputation: 45079

How about a bit different solution? In the current one, it will be pain to manage all of the items, orders, positions etc. Instead I suggest to hide legend and render it that place some customized label: http://jsfiddle.net/3k9zd9r0/

Of course, that requires a bit of polishing, but it is only about building proper string (str variable):

    plotOptions: {
        pie: {
            dataLabels: {
                enabled: false
            },
            point: {
                events: {
                    mouseOver: function () {
                        var chart = this.series.chart,
                            legend = chart.legend,
                            legendGroup = legend.group,
                            str = [ // build string for legend place
                                '<span style="color: ',
                                  this.color,
                                ';">\u25CF </span>',
                                 this.name,
                                '<br>\u25CF ',
                                'Milk',
                                '<br>\u25CF ',
                                'Other info'
                            ].join('');

                        this.select(true); 
                        legendGroup.hide(); // hide legend

                        this.series.customLabel = chart.renderer.label(str, legendGroup.attr('translateX'), legendGroup.attr('translateY')).add(); // add customized label
                    },
                    mouseOut: function () {
                        var chart = this.series.chart,
                            legend = chart.legend;

                        this.select(false);
                        legend.group.show(); // show back legend

                        if (this.series.customLabel) {
                            this.series.customLabel = this.series.customLabel.destroy(); // destroy customized label
                        }
                    }
                }
            }
        }
    },

Upvotes: 3

Related Questions