title: Highcharts - drill down to multiple series
body: <p>I have a parent chart that I need to drill down to a child chart with multiple series.  Here is a <em>toy exampl</em>e of what I would like to do.  (I know this does not work) </p>
  
  <blockquote>
    <p>Notice I'm trying to pass in an array of ids to display in the child chart.</p>
  </blockquote>
  
  <p>Does anybody know a way to do this?  If someone from Highcharts reads this, can this be added as a feature?</p>
  
  <pre><code>$(function () {    
  
  // Create the chart
  $('#container').highcharts({
      chart: {
          type: 'column'
      },
      title: {
          text: 'Basic drilldown'
      },
      xAxis: {
          type: 'category'
      },
  
      plotOptions: {
          column : {
              stacking : 'normal'
          }
      },
  
      series: [{
          name: 'Yearly Orders',
          data: [{
              name: 'Location 1',
              y: 100,
              drilldown: ['l1-wa', 'l1-wb']
          }, {
              name: 'Location 2',
              y: 150,
              drilldown: ['l2-wa', 'l2-wb']
          }]
      }],
      drilldown: {
          series: [{
              name: 'Widget A',
              type: 'line',
              id: 'l1-wa',
              data: [
                  {name: 'Qtr 1', y: 5},
                  {name: 'Qtr 2', y: 25},
                  {name: 'Qtr 3', y: 25},
                  {name: 'Qtr 4', y: 20}
              ]
          },{
              name: 'Widget B',
              type: 'line',
              id: 'l1-wb',
              data: [
                  {name: 'Qtr 1', y: 10},
                  {name: 'Qtr 2', y: 5},
                  {name: 'Qtr 3', y: 5},
                  {name: 'Qtr 4', y: 5}
              ]
          }, {
              name: 'Widget A',
              type: 'line',
              id: 'l2-wa',
              data: [
                  {name: 'Qtr 1', y: 25},
                  {name: 'Qtr 2', y: 5},
                  {name: 'Qtr 3', y: 5},
                  {name: 'Qtr 4', y: 15}
              ]
          },{
              name: 'Widget B',
              type: 'line',
              id: 'l2-wb',
              data: [
                  {name: 'Qtr 1', y: 30},
                  {name: 'Qtr 2', y: 30},
                  {name: 'Qtr 3', y: 15},
                  {name: 'Qtr 4', y: 25}
              ]
          } 
  
                  ]
      }
  })
  });
  </code></pre>
  
  <p>Here is a JSFiddle of this drilling down to just one series <a href="http://jsfiddle.net/F7z3D/2/" rel="nofollow noreferrer">http://jsfiddle.net/F7z3D/2/</a></p>
  
  <p><strong>EDIT - I extended Highcharts to give me some enhanced changes when drilling down. This is probably not the best code, but gets the point across.  This allows for changing of the x and y axes, changing the subtitle, and multiple series.</strong></p>
  
  <pre><code> $(function () {
  
   (function (H) {
       var noop = function () {},
       defaultOptions = H.getOptions(),
           each = H.each,
           extend = H.extend,
           format = H.format,
           wrap = H.wrap,
           Chart = H.Chart,
           seriesTypes = H.seriesTypes,
           PieSeries = seriesTypes.pie,
           ColumnSeries = seriesTypes.column,
           fireEvent = HighchartsAdapter.fireEvent,
           inArray = HighchartsAdapter.inArray;
  
       H.wrap(H.Chart.prototype, 'drillUp', function (proceed) {
  
           var chart = this,
               drilldownLevels = chart.drilldownLevels,
               levelNumber = drilldownLevels[drilldownLevels.length - 1].levelNumber,
               i = drilldownLevels.length,
               chartSeries = chart.series,
               seriesI = chartSeries.length,
               level,
               oldSeries,
               newSeries,
               oldExtremes,
               addSeries = function (seriesOptions) {
                   var addedSeries;
                   each(chartSeries, function (series) {
                       if (series.userOptions === seriesOptions) {
                           addedSeries = series;
                       }
                   });
  
                   addedSeries = addedSeries || chart.addSeries(seriesOptions, false);
                   if (addedSeries.type === oldSeries.type &amp;&amp; addedSeries.animateDrillupTo) {
                       addedSeries.animate = addedSeries.animateDrillupTo;
                   }
                   if (seriesOptions === level.seriesOptions) {
                       newSeries = addedSeries;
                   }
               };
  
  
           while (i--) {
  
               level = drilldownLevels[i];
                console.log(level.levelNumber);
               console.log(levelNumber);
               if (level.levelNumber === levelNumber) {
                   drilldownLevels.pop();
  
                   // Get the lower series by reference or id
                   oldSeries = level.lowerSeries;
  
                   if ($.isArray(oldSeries)) {
  
      if (chart.series) {
          while (chart.series.length &gt; 0) {
              chart.series[0].remove(false);
          }
      }
  
  
                       if (level.levelSubtitle) {
                           chart.setTitle(null, {text: level.levelSubtitle});
                       } else {
                           chart.setTitle(null, {
                               text: ''
                           });
                       }
  
                       if (chart.xAxis &amp;&amp; level.levelXAxis) {
                           while (chart.xAxis.length &gt; 0) {
                               chart.xAxis[0].remove(false);
                           }
                       }
                       if (chart.yAxis &amp;&amp; level.levelYAxis) {
                           while (chart.yAxis.length &gt; 0) {
                               chart.yAxis[0].remove(false);
                           }
                       }
  
                       if (level.levelYAxis) {
                           $.each(level.levelYAxis, function () {
                               chart.addAxis(this, false, false);
                           });
                       }
                       if (level.levelXAxis) {
                           $.each(level.levelXAxis, function () {
                               chart.addAxis(this, true, false);
                           });
                       }
                       $.each(level.levelSeriesOptions, function () {
                           chart.addSeries(this, false);
                       });
  
  
                   } else {
                       if (!oldSeries.chart) { // #2786
                           while (seriesI--) {
                               if (chartSeries[seriesI].options.id === level.lowerSeriesOptions.id) {
                                   oldSeries = chartSeries[seriesI];
                                   break;
                               }
                           }
                       }
                       oldSeries.xData = []; // Overcome problems with minRange (#2898)
  
                       each(level.levelSeriesOptions, addSeries);
  
                       fireEvent(chart, 'drillup', {
                           seriesOptions: level.seriesOptions
                       });
  
                       if (newSeries.type === oldSeries.type) {
                           newSeries.drilldownLevel = level;
                           newSeries.options.animation = chart.options.drilldown.animation;
  
                           if (oldSeries.animateDrillupFrom) {
                               oldSeries.animateDrillupFrom(level);
                           }
                       }
  
                       newSeries.levelNumber = levelNumber;
  
                       oldSeries.remove(false);
  
                       // Reset the zoom level of the upper series
                       if (newSeries.xAxis) {
                           oldExtremes = level.oldExtremes;
                           newSeries.xAxis.setExtremes(oldExtremes.xMin, oldExtremes.xMax, false);
                           newSeries.yAxis.setExtremes(oldExtremes.yMin, oldExtremes.yMax, false);
                       }
  
                   }
               }
           }
  
           this.redraw();
  
  
           if (this.drilldownLevels.length === 0) {
               console.log('destroy');
               this.drillUpButton = this.drillUpButton.destroy();
           } else {
               console.log('no destroy '+this.drilldownLevels.length);
               this.drillUpButton.attr({
                   text: this.getDrilldownBackText()
               })
                   .align();
           }
  
       });
  
       H.wrap(H.Chart.prototype, 'addSingleSeriesAsDrilldown', function (proceed, point, ddOptions) {
  
           if (!ddOptions.series) {
               proceed.call(this, point, ddOptions);
           } else {
  
               var thisChart = this;
  
               var oldSeries = point.series,
                   xAxis = oldSeries.xAxis,
                   yAxis = oldSeries.yAxis,
                   color = point.color || oldSeries.color,
                   pointIndex,
                   levelSeries = [],
                   levelSeriesOptions = [],
                   levelXAxis = [],
                   levelYAxis = [],
                   levelSubtitle,
                   level,
                   levelNumber;
  
               levelNumber = oldSeries.levelNumber || 0;
  
           //    ddOptions.series[0] = extend({
            //       color: color
           //    }, ddOptions.series[0]);
           //    pointIndex = inArray(point, oldSeries.points);
  
               // Record options for all current series
               each(oldSeries.chart.series, function (series) {
                   if (series.xAxis === xAxis) {
                       levelSeries.push(series);
                       levelSeriesOptions.push(series.userOptions);
                       series.levelNumber = series.levelNumber || 0;
                   }
               });
  
               each(oldSeries.chart.xAxis, function (xAxis) {
                   levelXAxis.push(xAxis.userOptions);
               });
  
               each(oldSeries.chart.yAxis, function (yAxis) {
                   levelYAxis.push(yAxis.userOptions);
               });
  
  
               if(oldSeries.chart.subtitle &amp;&amp; oldSeries.chart.subtitle.textStr){
                   levelSubtitle = oldSeries.chart.subtitle.textStr;
                   console.log(levelSubtitle);
               }
  
               // Add a record of properties for each drilldown level
               level = {
                   levelNumber: levelNumber,
                   seriesOptions: oldSeries.userOptions,
                   levelSeriesOptions: levelSeriesOptions,
                   levelSeries: levelSeries,
                   levelXAxis: levelXAxis,
                   levelYAxis: levelYAxis,
                   levelSubtitle: levelSubtitle,
                   shapeArgs: point.shapeArgs,
                   bBox: point.graphic.getBBox(),
                   color: color,
                   lowerSeriesOptions: ddOptions,
                   pointOptions: oldSeries.options.data[pointIndex],
                   pointIndex: pointIndex,
                   oldExtremes: {
                       xMin: xAxis &amp;&amp; xAxis.userMin,
                       xMax: xAxis &amp;&amp; xAxis.userMax,
                       yMin: yAxis &amp;&amp; yAxis.userMin,
                       yMax: yAxis &amp;&amp; yAxis.userMax
                   }
               };
  
               // Generate and push it to a lookup array
               if (!this.drilldownLevels) {
                   this.drilldownLevels = [];
               }
               this.drilldownLevels.push(level);
  
               level.lowerSeries = [];
  
               if (ddOptions.subtitle) {
                   this.setTitle(null, {text: ddOptions.subtitle});
               }else{
                   this.setTitle(null, {text: ''});
               }
  
               if (this.xAxis &amp;&amp; ddOptions.xAxis) {
                   while (this.xAxis.length &gt; 0) {
                       this.xAxis[0].remove(false);
                   }
               }
               if (this.yAxis &amp;&amp; ddOptions.yAxis) {
                   while (this.yAxis.length &gt; 0) {
                       this.yAxis[0].remove(false);
                   }
               }
  
  
               if (ddOptions.yAxis) {
                   if ($.isArray(ddOptions.yAxis)) {
                       $.each(ddOptions.yAxis, function () {
                           thisChart.addAxis(this, false, false);
                       });
                   } else {
                       thisChart.addAxis(ddOptions.yAxis, false, false);
                   }
               }
               if (ddOptions.xAxis) {
                   if ($.isArray(ddOptions.xAxis)) {
                       $.each(ddOptions.xAxis, function () {
                           thisChart.addAxis(this, true, false);
                       });
                   } else {
                       thisChart.addAxis(ddOptions.xAxis, true, false);
                   }
  
               }
  
  
  
               $.each(ddOptions.series, function () {
  
                   var newSeries = thisChart.addSeries(this, true);
                   level.lowerSeries.push(newSeries);
                   newSeries.levelNumber = levelNumber + 1;
       //            if (xAxis) {
      //                 xAxis.oldPos = xAxis.pos;
         //              xAxis.userMin = xAxis.userMax = null;
          //             yAxis.userMin = yAxis.userMax = null;
            //       }
  
              //     // Run fancy cross-animation on supported and equal types
               //    if (oldSeries.type === newSeries.type) {
                //       newSeries.animate = newSeries.animateDrilldown || noop;
                //       newSeries.options.animation = true;
                 //  }
               });
  
  
  
           }
       });
  
       H.wrap(H.Point.prototype, 'doDrilldown', function (proceed, _holdRedraw) {
  
           if (!$.isPlainObject(this.drilldown)) {
               proceed.call(this, _holdRedraw);
           } else {
               var ddChartConfig = this.drilldown;
               console.log(ddChartConfig);
               var ddSeries = ddChartConfig.series;
  
               var series = this.series;
               var chart = series.chart;
               var drilldown = chart.options.drilldown;
  
               var seriesObjs = [];
               for (var i = 0; i &lt; ddSeries.length; i++) {
                   if (!$.isPlainObject(ddSeries[i])) {
                       console.log(ddSeries[i]);
                       var j = (drilldown.series || []).length;
                       var seriesObj = null;
                       while (j-- &amp;&amp; !seriesObj) {
                           if (drilldown.series[j].id === ddSeries[i]) {
                               seriesObj = drilldown.series[j];
                           }
                       }
                       if (seriesObj) {
                           seriesObjs.push(seriesObj);
                       }
                   } else {
                       seriesObjs.push(ddSeries[i]);
                   }
               }
  
               ddChartConfig.series = seriesObjs;
               ddSeries = ddChartConfig.series;
  
               // Fire the event. If seriesOptions is undefined, the implementer can check for 
               // seriesOptions, and call addSeriesAsDrilldown async if necessary.
               HighchartsAdapter.fireEvent(chart, 'drilldown', {
                   point: this,
                   seriesOptions: ddChartConfig
               });
  
               if (ddChartConfig) {
                   if (_holdRedraw) {
                       chart.addSingleSeriesAsDrilldown(this, ddChartConfig);
                   } else {
                       chart.addSeriesAsDrilldown(this, ddChartConfig);
                   }
               }
           }
  
       });
   }(Highcharts));
  
  
  
  
  
  
  
  
   // Create the chart
   $('#container').highcharts({
       chart: {
           type: 'column'
       },
       title: {
           text: 'Basic drilldown'
       },
       xAxis: {
           type: 'category'
       },
  
       plotOptions: {
           column: {
               stacking: 'normal'
           }
       },
  
       series: [{
           name: 'Yearly Orders',
           data: [{
               name: 'Location 1',
               y: 100,
               drilldown: {
                   series: ['l1-wa', 'l2-wa'],
                   subtitle: "subtitle",
                   xAxis: {
                       title: {
                           text: 'X Axis'
                       }
                   },
                   yAxis: {
                       title: {
                           text: 'Y Axis'
                       }
                   }
               }
           }, {
               name: 'Location 2',
               y: 150 //,
               // drilldown: 'l2-wa'
           }]
       }],
       drilldown: {
           series: [{
               name: 'Widget A',
               type: 'column',
               id: 'l1-wa',
               data: [{
                   name: 'Qtr 1',
                   y: 5,
                   drilldown: {series: ['l2-wb'],            xAxis: {
                   },
                   yAxis: {
  
                   }}
               }, {
                   name: 'Qtr 2',
                   y: 25
               }, {
                   name: 'Qtr 3',
                   y: 25
               }, {
                   name: 'Qtr 4',
                   y: 20
               }]
           }, {
               name: 'Widget B',
               type: 'line',
               id: 'l1-wb',
               data: [{
                   name: 'Qtr 1',
                   y: 10
               }, {
                   name: 'Qtr 2',
                   y: 5
               }, {
                   name: 'Qtr 3',
                   y: 5
               }, {
                   name: 'Qtr 4',
                   y: 5
               }]
           }, {
               name: 'Widget A',
               type: 'column',
               id: 'l2-wa',
               data: [{
                   name: 'Qtr 1',
                   y: 25
               }, {
                   name: 'Qtr 2',
                   y: 5
               }, {
                   name: 'Qtr 3',
                   y: 5
               }, {
                   name: 'Qtr 4',
                   y: 15
               }]
           }, {
               name: 'Widget B',
               type: 'pie',
               id: 'l2-wb',
               data: [{
                   name: 'Qtr 1',
                   y: 30
               }, {
                   name: 'Qtr 2',
                   y: 30
               }, {
                   name: 'Qtr 3',
                   y: 15
               }, {
                   name: 'Qtr 4',
                   y: 25
               }]
           }
  
           ]
       }
   })
   });
  </code></pre>
  
  <p>Here is a <strong>JSFIDDLE</strong> <a href="http://jsfiddle.net/skTHx/10/" rel="nofollow noreferrer">http://jsfiddle.net/skTHx/10/</a></p>