67
votes

UPDATE: Here's a jsfiddle that shows the problem: http://jsfiddle.net/pynju/1/

Click on the blue column on Monday. When the detail-view loads, notice that 01-07 have 3 columns (expected 2). Click on the tallest bar to go back to the original view. Notice that the labels on the xAxis aren't being removed.

===============

I have a bar chart that has 2 series, displayed as pairs of bars, side by side.

series: [{
         showInLegend: false,
         data: dowChartData
      },{
         showInLegend: false,
         data: avgUserDowChartData
      }],

.

dowChartData = [                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   {
                y: 98.74,
                color: '#0072ff',
                drilldown: {
                   name: 'Category Engagement - Sunday',
                   categories: ['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23'],
                   data: [0,637,0,0,0,173,48.54,48.54,0,0,0,0,0,0,102.24,166.36,706.59,699.18,298.32,184.14,97.08,1539,0,1224.56],
                   color: '#0072ff',
                   data2: [506.80686467275,354.56354558498,333.25158689567,234.19283190879,234.82132336088,220.03247578171,222.86420797556,218.14034615202,170.42559544164,171.54776353196,249.24788461442,345.14915669555,206.65543589797,243.38811965637,367.02593304906,378.83677778129,467.45739743621,424.26264387522,639.60922934374,679.71299714907,373.26353846375,480.94380626458,551.82326068362,466.77469230724],
                   color2: '#C00'
                }
             }
AND SIMILAR

.

avgUserDowChartData = [                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         {
                y: 142.35,
                color: '#C00'
             },
AND SIMILAR

The initial data is day of week data with the X-axis being: Sunday - Monday - Tues - Wed - Thurs - Fri - Saturday

The initial series has a drilldown element with a new data & data2 (see above)

Using the drilldown demo code as an example, I have this code in place:

column: {
              borderWidth: 0,
            cursor: 'pointer',
            point: {
               events: {
                  click: function(event) {
                     var drilldown = this.drilldown;
                     if (drilldown) { // drill down
                        setChart(dowChart, drilldown.name, drilldown.categories, drilldown.data, drilldown.color, drilldown.data2, drilldown.color2);
                     } else { // restore
                        setChart(dowChart, '', dowCategories, dowChartData);
                     }
                  }
               }
            },

Set chart handler:

function setChart(chart, name, categories, data, color, data2, color2) {
      chart.xAxis[0].setCategories(categories);
//      chart.series[0].remove();
      for (var i = 0; i < chart.series.length; i++) {
          chart.series[i].remove();
      }
      chart.addSeries({
         showInLegend: false,
         name: name,
         data: data,
         color: color || 'white'
      });
      if (typeof(data2) != undefined && data2.length > 0) {
          chart.addSeries({
             showInLegend: false,
             name: name,
             data: data2,
             color: color2 || 'white'
          });
      }
   }

The initial chart display perfectly fine: initial display

When you click on any of the blue bars (the data set that has the drilldown), things get wonky for the first 7 x-axis items: drill down - broken display

It's as if the initial data sets aren't being removed by the code:

for (var i = 0; i < chart.series.length; i++) {
          chart.series[i].remove();
      }

When you click on any of the bars with the intention of resetting to the original data set/series: reset data to original set - broken display

So... it's clear that the remove series code I'm using isn't working. What's the best way to completely remove the data on the chart and the 2 series I need to display each time depending on what is clicked?

8
When are you calling your removal code?NT3RP
It's being called when a column from the original chart is clicked. It's a part of setData() that gets called in point -> events -> clickZ Jones

8 Answers

151
votes

try this to remove all chart series,

while(chart.series.length > 0)
    chart.series[0].remove(true);

it works for me. the code

for (var i = 0; i < chart.series.length; i++)

won't work because the chart.series.length is decreased each time remove() is called. That way, the i will never reach the expected length. Hope this helps.

42
votes

The following way the chart will not redraw every iteration.
So you'll get a better performance.

while( chart.series.length > 0 ) {
    chart.series[0].remove( false );
}

chart.redraw();
8
votes

Another way to remove all series in HighCharts with a for loop is to start from the end. Here's how to do it:

var seriesLength = chart.series.length;
for(var i = seriesLength - 1; i > -1; i--) {
    chart.series[i].remove();
}

I prefer to go this route because when using a HighStock chart, the navigator is usually the first series. I also prefer to keep a variable set to the navigator series. In that case, I'll do the following:

var seriesLength = chart.series.length;
var navigator;
for(var i = seriesLength - 1; i > -1; i--) {
    if(chart.series[i].name.toLowerCase() == 'navigator') {
        navigator = chart.series[i];
    } else {
        chart.series[i].remove();
    }
}

Now I can easily set the navigator series.

Here's an example of removing all series from a Highchart: http://jsfiddle.net/engemasa/srZU2/

Here's an example of resetting a HighStock chart with new data (including the navigator series): http://jsfiddle.net/engemasa/WcLQc/

1
votes

The reason for (var i = 0; i < chart.series.length; i++) doesn't work is because you're modifying the array while you're looping over it. To get around this, you can iterate over the array from right to left, so when you remove an element, the index of the array will still point to the last item in the array.

Using lodash's forEachRight, you can do:

_.forEachRight(chart.series, chartSeries => {
  chartSeries.remove(false);
});

chart.redraw();
0
votes

It may just be a simple matter of telling the chart to redraw. When you remove a series, try forcing the chart to redraw:

for (var i = 0; i < chart.series.length; i++) {
    chart.series[i].remove(true); //forces the chart to redraw
}
0
votes

var seriesLength = chart.series.length; for(var i = seriesLength -1; i > -1; i--) { chart.series[i].remove(); }

0
votes

You can also update and add a new series and if the new series is less than the current series then remove the series:

var hChart = $("#Chart").highcharts();

for (var i = 0; i < newSeries.length; i++) { //UPDATE-OLD/ADD-NEW SERIES
    if (hChart.series[i])
        hChart.series[i].update(newSeries[i]);
    else
        hChart.addSeries(newSeries[i]);
}

var serieslen = newSeries.length;
if (hChart.series[serieslen]) {
    var loopfrm = hChart.series.length - 1;
    for (var i = loopfrm; i >= serieslen; i--) {//REMOVE SERIES
        hChart.series[loopfrm].remove();
    }
}
-1
votes

I found the working solution. Try this:

for (var i = 0; i < chart.series.length; i++) {
   chart.series[0].remove();
}
chart.redraw();

It will completely remove all series.