Highcharts Series - want to show/hide all EXCEPT s

2019-01-31 08:03发布

By default Highcharts allows you to click on a data series set to hide it / unhide it.

A much more useful approach would be to do the reverse logic - ie to show only the selected series and hide/unhide the non-selected.

Looking at the example here ( http://jsfiddle.net/t2MxW/14/ ), it is clear one can 'intercept' the the 'legendItemClick' event, I am just not sure how to implement the require logic

One can replace the below script to obtain 3 data sets.

DESIRED SCENARIO: to be able to click on 'apples' and show/hide 'pears' and 'oranges' for example.

================= PASTE START =======================================

var chart = new Highcharts.Chart({
    chart: {
        renderTo: 'container'
    },
    xAxis: {
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },

    plotOptions: {
        series: {
            events: {
                legendItemClick: function(event) {
                    var visibility = this.visible ? 'visible' : 'hidden';
                    if (!confirm('The series is currently '+ 
                                 visibility +'. Do you want to change that?')) {
                        return false;
                    }
                }
            }
        }
    },

    series:[{name: 'apples',
            data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]},
    {name:'pears',
    data: [19.9, 81.5, 96.4, 119.2, 124.0, 166.0, 155.6, 138.5, 116.4, 144.1, 95.6, 54.4]},

           {name:'oranges',
    data: [119.9, 181.5, 46.4, 219.2, 24.0, 66.0, 255.6, 238.5, 16.4, 44.1, 95.6, 54.4]}
           ]   

});

标签: highcharts
6条回答
We Are One
2楼-- · 2019-01-31 08:54

I wanted to do something similar... I wanted to have it so that if you control-click (or cmd-click) a legend item, it would hide ALL OTHER items. (But leave normal clicks as their default behavior).

plotOptions: {
    series: {
        events: {
            legendItemClick: function(e) {
                // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items.
                var hideAllOthers = e.browserEvent.metaKey;
                if (hideAllOthers) {
                    var seriesIndex = this.index;
                    var series = this.chart.series;

                    for (var i = 0; i < series.length; i++) {
                        // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then
                        // call chart.redraw --- this is significantly faster since it involves fewer chart redraws
                        if (series[i].index === seriesIndex) {
                            if (!series[i].visible) series[i].setVisible(true, false);
                        } else {
                            if (series[i].visible) series[i].setVisible(false, false);
                        }
                    }
                    this.chart.redraw();
                    return false;
                }
            }
        }
    }
}
查看更多
淡お忘
3楼-- · 2019-01-31 08:54

If you want to keep the normal functionality but also be able to show/hide all then create a button or a link for a show_all()/hide_all() javascript method.

this method initializes a counter and starts the showing/hiding:

counter = 0;
setTimeout(process_hide, 1);

function process_hide()
{
    your_chart.series[counter].hide();
    counter+=1;
    if (counter < read_chart.series.length) {
        setTimeout(process_hide, 1);
    }
}

The reason you do this instead of just doing $.each(your_chart, function(i,v){v.hide()}) is that it locks up the UI - using the timeout you'll actually see the series being hidden one by one - and if you want to modify something else - like a process meter, it'll actually work.

查看更多
戒情不戒烟
4楼-- · 2019-01-31 08:58

Forked index's answer and added functionality to have individual toggles for each series. http://jsfiddle.net/c4Zd8/1/

$.each(allSeries, function(index, series) {
    if (selected == index) {
        if (series.visible == true) {
            series.hide();
        }
        else {
            series.show();
        }
    }
});
查看更多
成全新的幸福
5楼-- · 2019-01-31 09:00

Forked because I wanted behavior to change. Originally when a user selected two series and then tried to unselect one ... the whole series would swap visibility. I check to see if all other series are "all else visibile" or "all else not visible" first before swapping the visibility for the series.

http://jsfiddle.net/nd0dcdmz/3/

legendItemClick: function(e) {
    var seriesIndex = this.index;
    var series = this.chart.series;

    // test for if all other series besides one selected are visible or not visible
    var allElseVisible = series.every(
      s => (s.index == seriesIndex ? true : s.visible),
    );
    var allElseNotVisible = series.every(
      s => (s.index == seriesIndex ? true : !s.visible),
    );

    // if everything else is deselected or selected ... swap visibility
    // else swap the visibility of selected object.
    if (allElseVisible || allElseNotVisible) {
      series.map(s => {
        if (s.index != seriesIndex) {
          s.visible ? s.hide() : s.show();
        }
      });
    } else {
      return true;
    }

    return false; // overrides default behavior
},
查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-01-31 09:01

Every event in HighCharts contains this value which contains current element (series in this case). You can select all series using this.chart.series and handle them in any way you want. Try this function.

legendItemClick: function(event) {
    if (!this.visible)
        return false;

    var seriesIndex = this.index;
    var series = this.chart.series;

    for (var i = 0; i < series.length; i++)
    {
        if (series[i].index != seriesIndex)
        {
            series[i].visible ?
            series[i].hide() :
            series[i].show();
        } 
    }
    return false;
}

fiddle: https://jsfiddle.net/t2MxW/21971/

查看更多
我想做一个坏孩纸
7楼-- · 2019-01-31 09:08

Just sharing cause @igor's answer doesn't work on me, so I made adjustments, here's the fiddle (forked from the @igor's answer)

http://jsfiddle.net/index/Nkeep/

查看更多
登录 后发表回答