Polar Area Chart

A polar area chart in ApexCharts displays categorical data as a set of sectors arranged in a full circle, where every sector spans the same angle but the radius of each sector varies to represent its value. This is the key difference from a pie chart: in a pie chart the angle changes while all radii are equal; in a polar area chart the angle is fixed and the radius changes. Use polar area charts when you want a wheel-shaped layout but need readers to compare magnitudes visually rather than angular proportions.

Data Format

The series for a polar area chart is a flat array of numbers, one per sector. Category names are supplied in a parallel labels array.

options = {
  series: [14, 23, 21, 17, 15, 10, 12, 17, 21],
  labels: ['Comedy', 'Action', 'SciFi', 'Drama', 'Horror', 'Musical', 'Sport', 'Thriller', 'Romance'],
  chart: {
    type: 'polarArea'
  }
}

The order of labels must match the order of series values. The first label names the first sector, the second label names the second sector, and so on.

Basic Example

The following is a complete, self-contained polar area chart. Every option shown here is sufficient to render the chart with sensible defaults for tooltips, legends, and colors.

const options = {
  series: [14, 23, 21, 17, 15, 10, 12, 17, 21],
  labels: ['Comedy', 'Action', 'SciFi', 'Drama', 'Horror', 'Musical', 'Sport', 'Thriller', 'Romance'],
  chart: {
    type: 'polarArea',
    height: 420
  },
  stroke: {
    colors: ['#fff']
  },
  fill: {
    opacity: 0.8
  },
  legend: {
    position: 'bottom'
  },
  responsive: [
    {
      breakpoint: 480,
      options: {
        chart: {
          height: 300
        },
        legend: {
          position: 'bottom'
        }
      }
    }
  ]
}

const chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()

The stroke.colors array sets the border color between sectors. A white border ('#fff') visually separates sectors and makes the chart easier to read when adjacent sectors have similar colors. The fill.opacity of 0.8 applies a slight transparency that softens the palette without losing readability.

How Polar Area Differs From Pie and Donut

In a pie or donut chart every slice has the same outer radius and the angle of each slice is proportional to its value. A small value gets a narrow slice; a large value gets a wide arc. Readers compare the angular sweep of each slice.

In a polar area chart every sector occupies exactly 360 / n degrees, where n is the number of categories. Instead of adjusting the angle, the chart adjusts how far each sector extends from the center. A large value reaches closer to the outer edge; a small value stays near the center. Readers compare the area filled by each sector.

This means polar area works better when you have categories of similar importance but different magnitudes and you want to preserve a symmetrical, clock-face layout. Pie and donut work better when the primary message is the percentage share of a whole.

How Polar Area Differs From Radar

A radar (spider) chart also uses a circular layout with category axes, but the visual encoding is a connected polygon. You plot a point on each axis for each data series, then connect the points with lines and optionally fill the enclosed area. Radar charts are suited for comparing multiple series across the same set of categories, for example comparing the skill profiles of two job candidates.

A polar area chart does not connect points. Each category gets its own distinct filled sector. There is no concept of a polygon or series profile. Polar area is better when each category is independent and you want each value to stand alone visually rather than be part of a connected shape.

Rings and Spokes

The concentric ring lines and the spoke lines radiating from the center are controlled under plotOptions.polarArea.

plotOptions: {
  polarArea: {
    rings: {
      strokeWidth: 1,
      strokeColor: '#e8e8e8'
    },
    spokes: {
      strokeWidth: 1,
      connectorColors: '#e8e8e8'
    }
  }
}

rings.strokeWidth sets the pixel width of each concentric circle. Set it to 0 to hide the rings entirely. rings.strokeColor accepts a hex color string.

spokes.strokeWidth sets the width of each line that radiates from the center to the outer edge. spokes.connectorColors accepts either a single color string (all spokes share the color) or an array of color strings (each spoke gets its own color, matched by index to the sector order).

To remove the grid lines and leave only the filled sectors, set both strokeWidth values to 0:

plotOptions: {
  polarArea: {
    rings: {
      strokeWidth: 0
    },
    spokes: {
      strokeWidth: 0
    }
  }
}

Monochrome Variant

When the default multi-color palette does not fit a brand or a subdued presentation, use the theme.monochrome option to shade all sectors from a single base color. ApexCharts automatically generates tints and shades from the color you supply.

const options = {
  series: [14, 23, 21, 17, 15, 10, 12, 17, 21],
  labels: ['Comedy', 'Action', 'SciFi', 'Drama', 'Horror', 'Musical', 'Sport', 'Thriller', 'Romance'],
  chart: {
    type: 'polarArea',
    height: 420
  },
  stroke: {
    colors: ['#fff']
  },
  fill: {
    opacity: 0.8
  },
  theme: {
    monochrome: {
      enabled: true,
      color: '#008FFB',
      shadeTo: 'light',
      shadeIntensity: 0.65
    }
  },
  legend: {
    position: 'bottom'
  }
}

shadeTo: 'light' shades from the base color toward white. Use 'dark' to shade toward black. shadeIntensity controls how far the shading goes: 0 produces nearly identical sectors while 1 produces a full range from the base color to white or black.

Responsive Configuration

The chart resizes automatically when the browser window changes, but you can override specific options at defined breakpoints using the responsive array. Each entry in the array specifies a breakpoint in pixels and an options object that is merged into the chart configuration when the viewport width is below that breakpoint.

const options = {
  series: [14, 23, 21, 17, 15, 10, 12, 17, 21],
  labels: ['Comedy', 'Action', 'SciFi', 'Drama', 'Horror', 'Musical', 'Sport', 'Thriller', 'Romance'],
  chart: {
    type: 'polarArea',
    height: 420
  },
  stroke: {
    colors: ['#fff']
  },
  fill: {
    opacity: 0.8
  },
  legend: {
    position: 'right'
  },
  responsive: [
    {
      breakpoint: 768,
      options: {
        chart: {
          height: 340
        },
        legend: {
          position: 'bottom'
        }
      }
    },
    {
      breakpoint: 480,
      options: {
        chart: {
          height: 260
        },
        legend: {
          show: false
        }
      }
    }
  ]
}

At viewport widths above 768 px the legend sits to the right of the chart. Below 768 px the chart height reduces and the legend moves to the bottom. Below 480 px the chart shrinks further and the legend is hidden entirely to reclaim space on small phone screens.

Customizing Data Labels

The percentage or raw values displayed inside each sector are controlled by dataLabels. By default a formatter receives the percentage value as the first argument.

dataLabels: {
  enabled: true,
  formatter: function (val) {
    return val.toFixed(1) + '%'
  }
}

To show the raw numeric value from series instead of the percentage, use the third argument of the formatter which carries the full data context:

dataLabels: {
  enabled: true,
  formatter: function (val, opts) {
    return opts.w.globals.series[opts.seriesIndex]
  }
}

Full documentation for dataLabels is at options.dataLabels.

Further Reading