---
id: "packages/active-charts/percentage-stacks"
title: "Percentage stacks"
description: "Stacked bars and areas as shares of the visible series."
url: "/packages/active-charts/percentage-stacks"
locale: "en"
revision: "d567553c024f27c1"
---

# Percentage stacks

> [!NOTE]
> **The package's own guide**
>
> This page is the package's `docs/recipes/PERCENTAGE-STACKS.md`, included
> unchanged from the package as it is in Foundation. Links to the package's
> internal design documents keep their text.

How to show composition as shares of a whole: each column (or each x of an
area) fills 0 to 100 %. The contract is `../API.md` and
ADR-040 (W9).

## Pass raw values

The chart takes the shares. Give it the amounts as they are; rows do not
have to add up to anything.

```tsx
const allocation = [
  {fund: 'A', equity: 225, bonds: 175, cash: 100},
  {fund: 'B', equity: 30, bonds: 60, cash: 10},
];

<BarChart
  data={allocation}
  xKey="fund"
  xAxis="category"
  series={[
    {yKey: 'equity', name: t('funds.equity')},
    {yKey: 'bonds', name: t('funds.bonds')},
    {yKey: 'cash', name: t('funds.cash')},
  ]}
  stackedPercentage
  legend
  height={300}
/>;
```

Fund A shows 45 %, 35 % and 20 %; fund B 30 %, 60 % and 10 %. The value axis,
the tooltip, the screen-reader table, the keyboard announcement and the
segment labels read percentage points. CSV export and copy-as-table carry
the raw amounts.

## Areas

`AreaChart` has the same switch: the top edge is the 100 % line at every x.

```tsx
<AreaChart
  data={rows}
  xKey="year"
  xAxis={{type: 'number'}}
  series={[
    {yKey: 'growth', name: t('mix.growth')},
    {yKey: 'defensive', name: t('mix.defensive')},
  ]}
  stackedPercentage
  height={260}
/>
```

## Hiding a series

The shares are taken over the visible series. Hide one in the legend and the
others fill the column again; the hidden series has no share while it is
hidden (its table cells are empty) and gets it back when shown.

## Mixed signs

A negative value keeps its direction: its share is its magnitude over the
sum of the magnitudes, drawn below zero. Gains stack upwards, losses
downwards, and the two sides together span 100 points (ADR-020). A column
with 50 gains, 20 gains and 30 losses reads 50 %, 20 % and −30 %.

## When not to use it

A stack of absolute percentages that should NOT be forced to a whole (an
allocation that may be incomplete, where the gap matters) is a plain stack
with percentage semantics on the axis:

```tsx
<AreaChart
  data={rows}
  xKey="age"
  xAxis={{type: 'number'}}
  series={[{yKey: 'equity', name: t('mix.equity')}]}
  stacked
  yAxis={{
    valueSemantics: {kind: 'percent', source: 'percentage-points'},
    min: 0,
    max: 100,
  }}
  height={256}
/>
```
