Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/highcharts/highcharts/llms.txt

Use this file to discover all available pages before exploring further.

Drilldown Functionality

Drilldown allows users to click on data points to navigate to more detailed information, creating a hierarchical data exploration experience.

Overview

The drilldown module enables multi-level data visualization where clicking on a point reveals more detailed data about that category.

Setup

First, include the drilldown module:
import Highcharts from 'highcharts';
import Drilldown from 'highcharts/modules/drilldown';

Drilldown(Highcharts);

Basic Drilldown

Simple Column Drilldown

From the official demo (samples/highcharts/demo/column-drilldown/demo.js:4-315):
Highcharts.chart('container', {
  chart: {
    type: 'column'
  },
  title: {
    text: 'Browser market shares. January, 2022'
  },
  subtitle: {
    text: 'Click the columns to view versions. Source: statcounter.com'
  },
  accessibility: {
    announceNewData: {
      enabled: true
    }
  },
  xAxis: {
    type: 'category'
  },
  yAxis: {
    title: {
      text: 'Total percent market share'
    }
  },
  legend: {
    enabled: false
  },
  plotOptions: {
    series: {
      borderWidth: 0,
      dataLabels: {
        enabled: true,
        format: '{point.y:.1f}%'
      }
    }
  },
  tooltip: {
    headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
    pointFormat: '<span style="color:{point.color}">{point.name}</span>: ' +
      '<b>{point.y:.2f}%</b> of total<br/>'
  },
  series: [{
    name: 'Browsers',
    colorByPoint: true,
    data: [
      {
        name: 'Chrome',
        y: 63.06,
        drilldown: 'Chrome'  // Links to drilldown series
      },
      {
        name: 'Safari',
        y: 19.84,
        drilldown: 'Safari'
      },
      {
        name: 'Firefox',
        y: 4.18,
        drilldown: 'Firefox'
      },
      {
        name: 'Edge',
        y: 4.12,
        drilldown: 'Edge'
      },
      {
        name: 'Opera',
        y: 2.33,
        drilldown: 'Opera'
      }
    ]
  }],
  drilldown: {
    series: [
      {
        name: 'Chrome',
        id: 'Chrome',
        data: [
          ['v65.0', 0.1],
          ['v64.0', 1.3],
          ['v63.0', 53.02],
          ['v62.0', 1.4],
          ['v61.0', 0.88]
        ]
      },
      {
        name: 'Safari',
        id: 'Safari',
        data: [
          ['v11.0', 3.39],
          ['v10.1', 0.96],
          ['v10.0', 0.36],
          ['v9.1', 0.54]
        ]
      },
      {
        name: 'Firefox',
        id: 'Firefox',
        data: [
          ['v58.0', 1.02],
          ['v57.0', 7.36],
          ['v56.0', 0.35],
          ['v55.0', 0.11]
        ]
      }
    ]
  }
});

Drilldown Configuration

Breadcrumbs help users navigate back through drilldown levels:
{
  drilldown: {
    breadcrumbs: {
      position: {
        align: 'right',
        verticalAlign: 'top',
        x: 0,
        y: 0
      },
      showFullPath: true,
      format: '{level.name}',
      buttonTheme: {
        fill: '#f7f7f7',
        padding: 8,
        stroke: '#cccccc',
        'stroke-width': 1,
        r: 3,
        style: {
          color: '#333333',
          fontWeight: 'normal'
        },
        states: {
          hover: {
            fill: '#e6e6e6'
          }
        }
      },
      floating: false,
      relativeTo: 'plotBox'
    }
  }
}

Active Data Label Styling

Customize how drillable points are styled:
{
  drilldown: {
    activeAxisLabelStyle: {
      color: '#F0F0F3',
      textDecoration: 'none',
      cursor: 'pointer'
    },
    activeDataLabelStyle: {
      color: '#F0F0F3',
      textDecoration: 'none',
      cursor: 'pointer'
    }
  }
}

Drill Up Button

Customize the button that appears to navigate back:
{
  drilldown: {
    drillUpButton: {
      relativeTo: 'plotBox',
      position: {
        align: 'right',
        verticalAlign: 'top',
        x: -10,
        y: 10
      },
      theme: {
        fill: 'white',
        stroke: '#cccccc',
        r: 3,
        states: {
          hover: {
            fill: '#e6e6e6'
          }
        }
      }
    }
  }
}

Advanced Drilldown Features

Multi-Level Drilldown

Create multiple levels of drilling:
{
  series: [{
    name: 'Continents',
    data: [
      { name: 'Asia', y: 4641, drilldown: 'asia' },
      { name: 'Europe', y: 747, drilldown: 'europe' }
    ]
  }],
  drilldown: {
    series: [
      {
        id: 'asia',
        name: 'Asian Countries',
        data: [
          { name: 'China', y: 1444, drilldown: 'china' },
          { name: 'India', y: 1393, drilldown: 'india' }
        ]
      },
      {
        id: 'china',
        name: 'Chinese Cities',
        data: [
          ['Shanghai', 27],
          ['Beijing', 21],
          ['Guangzhou', 15]
        ]
      }
    ]
  }
}

Async Drilldown

Load drilldown data dynamically from an API (from ts/Extensions/Drilldown/Drilldown.ts:134-158):
const chart = Highcharts.chart('container', {
  chart: {
    type: 'column',
    events: {
      drilldown: function (e) {
        if (!e.seriesOptions) {
          const chart = this;
          
          // Show loading message
          chart.showLoading('Loading drilldown data...');
          
          // Fetch data from API
          fetch(`/api/drilldown/${e.point.drilldown}`)
            .then(response => response.json())
            .then(data => {
              chart.hideLoading();
              
              // Add the series
              chart.addSeriesAsDrilldown(e.point, {
                name: e.point.name,
                data: data
              });
            })
            .catch(error => {
              chart.hideLoading();
              console.error('Error loading drilldown:', error);
            });
        }
      }
    }
  },
  series: [{
    name: 'Categories',
    data: [
      { name: 'Category A', y: 100, drilldown: 'cat-a' },
      { name: 'Category B', y: 80, drilldown: 'cat-b' }
    ]
  }]
});

Programmatic Drilldown

Trigger drilldown programmatically:
1

Point Drilldown

Drill down on a specific point:
// Get the point
const point = chart.series[0].points[2];

// Trigger drilldown
point.doDrilldown();
2

Axis Drilldown

Drill down to a category on an axis:
// Drilldown on category at index 1
chart.xAxis[0].drilldownCategory(1);
3

Drill Up

Navigate back programmatically:
// Go back one level
chart.drillUp();

Drilldown Events

Handle drilldown interactions with events:
{
  chart: {
    events: {
      drilldown: function (e) {
        console.log('Drilling down to:', e.point.name);
        console.log('Drilldown level:', this.drilldownLevels?.length || 0);
        
        // Track analytics
        trackEvent('drilldown', {
          category: e.point.name,
          level: this.drilldownLevels?.length || 0
        });
      },
      drillup: function (e) {
        console.log('Drilling up from:', e.seriesOptions.name);
      },
      drillupall: function () {
        console.log('Returned to top level');
      }
    }
  }
}

Drilldown with Different Chart Types

Pie Chart Drilldown

{
  chart: {
    type: 'pie'
  },
  plotOptions: {
    pie: {
      allowPointSelect: true,
      cursor: 'pointer',
      dataLabels: {
        enabled: true,
        format: '{point.name}: {point.y:.1f}%'
      }
    }
  },
  series: [{
    name: 'Market Share',
    colorByPoint: true,
    data: [
      { name: 'Desktop', y: 55.02, drilldown: 'desktop' },
      { name: 'Mobile', y: 44.98, drilldown: 'mobile' }
    ]
  }],
  drilldown: {
    series: [
      {
        id: 'desktop',
        name: 'Desktop OS',
        data: [
          ['Windows', 47.56],
          ['Mac', 7.23],
          ['Linux', 0.23]
        ]
      },
      {
        id: 'mobile',
        name: 'Mobile OS',
        data: [
          ['Android', 25.43],
          ['iOS', 19.32],
          ['Other', 0.23]
        ]
      }
    ]
  }
}

Map Drilldown

{
  chart: {
    type: 'map'
  },
  series: [{
    data: [
      { code: 'US', value: 331, drilldown: 'us-states' },
      { code: 'CN', value: 1444, drilldown: 'china-provinces' }
    ]
  }],
  drilldown: {
    series: [
      {
        id: 'us-states',
        mapData: Highcharts.maps['countries/us/us-all'],
        data: [
          ['us-ca', 39],
          ['us-tx', 29],
          ['us-fl', 21]
        ]
      }
    ]
  }
}

Styling Drilldown

Animation

{
  drilldown: {
    animation: {
      duration: 500,
      easing: 'easeOutBounce'
    }
  }
}

Series-Specific Styling

{
  drilldown: {
    series: [
      {
        id: 'chrome-versions',
        name: 'Chrome Versions',
        // Apply different chart type
        type: 'bar',
        // Custom colors
        color: '#4CAF50',
        // Custom options
        borderRadius: 5,
        data: [/* ... */]
      }
    ]
  }
}

Accessibility

Ensure drilldown is accessible:
{
  accessibility: {
    announceNewData: {
      enabled: true,
      minAnnounceInterval: 1000,
      announcementFormatter: function (allSeries, newSeries, newPoint) {
        if (newSeries) {
          return 'Drilldown to ' + newSeries.name + '. ' + 
                 newSeries.points.length + ' data points.';
        }
        return false;
      }
    },
    point: {
      descriptionFormatter: function (point) {
        if (point.drilldown) {
          return point.name + ', ' + point.y + '. ' +
            'Click to drill down to more details.';
        }
        return point.name + ', ' + point.y + '.';
      }
    }
  }
}

Best Practices

Drilldown UX Tips
  • Always show breadcrumbs or a drill-up button
  • Provide visual feedback that points are clickable (cursor, hover states)
  • Use consistent chart types across drill levels when possible
  • Include instructions in subtitle or caption
  • Limit drill depth to 3-4 levels for usability
  • Pre-load common drilldown data to reduce latency
Common Pitfalls
  • Drilldown series IDs must match the drilldown property exactly
  • Async drilldown requires checking if (!e.seriesOptions)
  • Don’t forget to include the drilldown module
  • Memory usage can grow with many drill levels
  • Test on touch devices - ensure tap targets are large enough

Complete Example with All Features

import Highcharts from 'highcharts';
import Drilldown from 'highcharts/modules/drilldown';

Drilldown(Highcharts);

Highcharts.chart('container', {
  chart: {
    type: 'column',
    events: {
      drilldown: function (e) {
        console.log('Drilling to:', e.point.name);
      },
      drillup: function () {
        console.log('Drilling up');
      }
    }
  },
  title: {
    text: 'Sales by Category'
  },
  subtitle: {
    text: 'Click columns to drill down'
  },
  accessibility: {
    announceNewData: {
      enabled: true
    }
  },
  xAxis: {
    type: 'category'
  },
  legend: {
    enabled: false
  },
  plotOptions: {
    series: {
      borderWidth: 0,
      dataLabels: {
        enabled: true
      }
    }
  },
  series: [{
    name: 'Categories',
    colorByPoint: true,
    data: [
      { name: 'Electronics', y: 5000, drilldown: 'electronics' },
      { name: 'Clothing', y: 3000, drilldown: 'clothing' },
      { name: 'Food', y: 2000, drilldown: 'food' }
    ]
  }],
  drilldown: {
    breadcrumbs: {
      position: {
        align: 'right'
      }
    },
    series: [
      {
        id: 'electronics',
        name: 'Electronics',
        data: [
          ['Phones', 2000],
          ['Laptops', 1800],
          ['Tablets', 1200]
        ]
      },
      {
        id: 'clothing',
        name: 'Clothing',
        data: [
          ['Men', 1500],
          ['Women', 1000],
          ['Kids', 500]
        ]
      },
      {
        id: 'food',
        name: 'Food',
        data: [
          ['Produce', 800],
          ['Meat', 700],
          ['Dairy', 500]
        ]
      }
    ]
  }
});