2
votes

I have a Highcharts line chart and a number of dynamic series, like this: https://jsfiddle.net/km0jjxue/6/

var chart = Highcharts.chart('container', {
    series: [{
       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],
       visible: true,
    }, {
       data: [129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4],                        
       visible: true,
    }, {
       data: [83.6, 78.8, 98.5, 93.4, 106.0, 84.5, 105.0, 104.3, 91.2, 83.5, 106.6, 92.3],
       visible: false,
    }, {
       data: [42.4, 33.2, 34.5, 39.7, 52.6, 75.5, 57.4, 60.4, 47.6, 39.1, 46.8, 51.1],        			 
       visible: false,
    }, {
       data: [48.9, 38.8, 39.3, 41.4, 47.0, 48.3, 59.0, 59.6, 52.4, 65.2, 59.3, 51.2],
       visible: false,
    }],
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>

<div id="container" style="height: 400px"></div>

I also have a filter, which reloads the chart with new data according to what I select in this filter.

The problem happens when I deselect or select other series in the chart and then change an option in my filter, causing the chart to redraw with the new data and only the first two series are visible again.

What can I do that if I select, for example, Series 3 and Series 4 making their chart data visible, and then choose another option in my filter, so that when the chart reloads with the new data I still have Series 3 and 4 selected as well (and not only Series 1 and Series 2)?

1
This is my first question and I received a downvote. I tried to simplify my problem, but if there are things I can do to make this question better, please let me know. Thank you! - Carolina Knoll
Since we can't see your filter, or know what exactly it does, it is difficult to give a accurate answer. But one idea would be to store series visibility outside of the chart. E.g. by using show/hide events to set some outside parameter. That way, when you apply your filter, you can also apply visibility on the different series. - ewolden
Please share the code of the filter (as @ewolden suggested). - Kamil Kulig

1 Answers

1
votes

I had similar problem recently. However, I had data coming from the server unlike yours. You can use the JavaScript Cookies in order to save the state of the series. And instead of specifying the state as

visible: true/false

you can get the saved state from the cookie instead.

Set the state using plotOptions.series.events.legendItemClick and cookie as

plotOptions: {
        series: {
            events: {
                legendItemClick: function () {
                    var visibility = '',
                        seriesIndex = this._i;
                    $.each(this.chart.series, function(i,v) {
                        if(i == seriesIndex) {
                            visibility += v.visible ? 'fX' : 'tX';
                        } else {
                            visibility += v.visible ? 'tX' : 'fX';
                        }
                    });
                    saveSeriesState(visibility);
                }
            }
        }
    }

On every click of the Legend Item, the legendItemClick event will be triggered which will go through all your series and checks for visibility. It then stores the correct visibility value in the correct index as string which will later be parsed to determine true or false. It will save the state of all the series in an array and sends it to store in a cookie as an array.

JS for saving the cookie

function saveSeriesState(cvalue) {
    var d = new Date();
    d.setTime(d.getTime() + (365*24*60*60*1000)); // 1 year cookie
    var expires = "expires="+d.toUTCString();
    document.cookie = "SeriesVisibility=" + cvalue + "; " + expires;
}

JS for getting the cookie

function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';'),
        len = ca.length;
    for(var i=0; i<len; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1);
        if (c.indexOf(name) == 0) { 
            var ret = c.substring(name.length,c.length);
            ret = ret.split('X');
            $.each(ret, function(i,v) {
                ret[i] = (v === 'f') ? false : true;
            });
            return ret;
        }
    }
    return [true,true,true,true];
}

As you can see it will return an array which contains the visibility for each series. It will go through the array of strings and splits the saved fX or tX. here f means false and t means true. With reference to that, ret array will hold the saved state which is then returned to the calling function.

Then you can call the getCookie function when your page loads and store the visibilities in an array as

var visibility = getCookie("SeriesVisibility");

Then in your series, instead of doing

visible: true/false

do

visible: visibility[0]

Please have a look at this http://jsfiddle.net/umrtd5rs/3/

Helped me with my issue. However, since my data were coming from server, I had to improvise.