# How to Make a Circle Packing Chart in Figma (Nesting You Can See)
_August 27, 2026 · 11 min read · by Systergon_
> Circle packing shows a hierarchy as circles inside circles — the clearest nesting of any chart here, because containment is literal and needs no convention. It pays for that by deliberately wasting space, since circles cannot tile. When the structure is worth the pixels, the value ratio to check before building, and the near-identical charts hiding under the Scatter chip.
Tags: Figma, Charts, Circle Packing, Hierarchy, Plugin
URL: https://systergon.com/blog/figma-charts-circle-packing
---
[Install Figma Charts — it’s free to try →](https://www.figma.com/community/plugin/1345221583582136577/figma-charts) [See the circle packing gallery →](https://systergon.com/figma-charts/chart-types/circlepacking)

Circle packing shows a hierarchy as circles inside circles: each parent contains its children, each circle’s area is its value. It is the clearest nesting of any chart in this series — containment is literal, so nobody has to learn a convention — and it pays for that clarity by **deliberately wasting space**, because circles cannot tile a plane.

![A circle packing chart drawn by Nivo inside the Figma Charts plugin](https://systergon.com/blog/figma-charts-circle-packing/images/packing-nivo.svg)

_Real plugin output: a Nivo circle packing chart captured from the editor. Every chart on this page is the library’s own drawing._

That trade is the whole decision. A [treemap](https://systergon.com/blog/figma-charts-treemap) uses every pixel and makes you work out which rectangle belongs to which parent; circle packing throws away the gaps and makes the structure obvious. This page is about when the structure is worth the pixels — and about the near-identical chart hiding under a completely different category chip.

## First — get the plugin

Everything below happens inside **Figma Charts**, a Figma plugin. It runs the real JavaScript charting libraries — Google Charts, Highcharts, D3-based Nivo, ApexCharts and Apache ECharts — inside the plugin window, so the packing on your canvas is the library’s own layout algorithm.

[Install Figma Charts from the Figma Community →](https://www.figma.com/community/plugin/1345221583582136577/figma-charts)

Press **⌘/** (**Ctrl /** on Windows), type _Figma Charts_, hit Enter, and pick **Circle Packing** from the category filter. One example, from Nivo — and two close relatives elsewhere, which the [library section](#libraries) covers.

## What the circles encode

Three rules, and the third is the one people get wrong:

- **Containment is parentage.** A circle inside another circle is a child of it. No colour, padding or header is needed to say so — the geometry does it, which is why this chart is so easy to read at a glance.
- **Area is value.** A leaf twice the value has twice the area, so its radius is about 1.4 times larger. Every library here gets that right by default.
- **Position is packing.** Where a circle sits inside its parent is the algorithm finding a fit, not a statement about the data. Adjacent circles have nothing in common except that they fitted.

A fourth property is worth stating because it separates this chart from a [treemap](https://systergon.com/blog/figma-charts-treemap): **the outermost circle sets the scale for everything**. Add one very large leaf and every other circle shrinks to accommodate it, where a treemap would simply re-tile. That makes circle packing more sensitive to outliers than any other hierarchy chart here.

The empty space between circles is not waste in the pejorative sense — it is the price of the containment being legible. But it does mean the chart shows fewer items per square inch than a treemap, and that difference grows with depth.

## Three packings, and the two filed elsewhere

![A packed bubble chart drawn by Highcharts](https://systergon.com/blog/figma-charts-circle-packing/images/packing-packed-bubble.svg)

_**The packed bubble** — the same technique with a single level: circles sized by value and packed together, no hierarchy. Highcharts files these under Scatter_, not Circle Packing, which is why the category looks emptier than the plugin actually is.

![A split packed bubble chart drawn by Highcharts](https://systergon.com/blog/figma-charts-circle-packing/images/packing-split-packed.svg)

_**Split packed bubbles** — and now it is a hierarchy again: the bubbles are grouped into clusters, one per category, which is circle packing with two levels under another name. Same reading, same strengths, different chip._

## When circle packing is the right shape

**Use it when** the hierarchy itself is the finding, the tree is shallow (two or three levels), the item count is modest, and the audience will not be asked to compare sizes precisely.

Three cases where something else is better:

**1. Space is tight.** A treemap fits perhaps twice as much data into the same frame. On a dashboard tile or a slide with a lot else on it, that difference decides the chart.

**2. Comparison matters.** Judging area is imprecise, and judging the area of circles is worse than judging rectangles because there is no shared edge to align against. If the reader will rank items, use a [bar chart](https://systergon.com/blog/figma-charts-bar-chart).

**3. The hierarchy is deep.** Every level nests inside the last, so a fourth level is a dot. Circle packing tolerates depth even less well than a [sunburst](https://systergon.com/blog/figma-charts-sunburst-chart); use an icicle or a tree.

A fourth, worth naming: **when there are no groups at all.** A flat set of packed bubbles is a bubble chart without axes — visually appealing, and it has thrown away the positional encoding that would have made the values readable. If the data is flat, a bar chart says it plainly.

## Packed bubbles, bubble charts and circle packing

Three charts made of circles get confused with each other constantly, and the differences matter because they encode different things.

**A [bubble chart](https://systergon.com/blog/figma-charts-scatter-plot)** positions circles on two axes and uses area for a third variable. Position is data — that is the whole point — and there is no hierarchy at all.

**A packed bubble chart** throws the axes away. Circles are sized by value and packed to fill a space, so position carries nothing. It looks like a bubble chart and encodes one variable instead of three, which is why it is so often the wrong choice: someone wanted a bubble chart and got a decorative arrangement of one number.

**Circle packing** is a packed bubble chart with nesting: circles inside circles, so containment carries the hierarchy. Position still means nothing; the enclosure means everything.

The practical test: if your data has two measures per item, you want a bubble chart with axes. If it has one measure and a grouping, you want circle packing. If it has one measure and no grouping, you probably want a bar chart, and the packed bubble is a styling decision.

## The interaction that makes it work at scale

Circle packing has one interaction so standard that the chart is designed around it: **click a circle to zoom into it**, making that node the new outermost container. Its children fill the frame, their labels become readable, and a breadcrumb records the path.

That is the answer to both of this chart’s limits at once — depth and small leaves — because you are never rendering more than two levels at a time. Nivo supports it, and file-system explorers and code-base visualisations have used the pattern for years.

The catch for design work is the familiar one: **an inserted SVG has no interaction**. A static circle packing has to earn its place on one frame, which in practice means fewer levels, bigger leaves and labels that fit. If the design depends on zooming, the deliverable is a prototype with a frame per level rather than a chart.

## Building one, step by step

Six screens, start to finish, captured from the plugin.

![The Figma Charts gallery filtered to the Circle Packing category](https://systergon.com/blog/figma-charts-circle-packing/images/step-gallery.webp)

_**1. Filter to Circle Packing.** Nivo has the category with one example. For the packed-bubble variants, look under Scatter in Highcharts._

![The Figma Charts editor with a circle packing chart in the preview](https://systergon.com/blog/figma-charts-circle-packing/images/step-editor.webp)

_**2. The editor.** Live preview above, tabs below. This chart wants a square frame — a wide one leaves large empty margins at the sides, because the outermost circle sets the scale._

![The Data tab showing hierarchical data for a circle packing chart](https://systergon.com/blog/figma-charts-circle-packing/images/step-data.webp)

_**3. A hierarchy, as JSON.** Nested `name / value / children` — the same shape a treemap and a sunburst take. In Nivo it is edited as JSON rather than a table, because a flat grid cannot express nesting._

![The Configuration tab showing circle packing option groups](https://systergon.com/blog/figma-charts-circle-packing/images/step-config.webp)

_**4. Configure.** Padding between circles, leaf-level labelling, colour inheritance and border styling. Padding is the important one: it is what makes the levels visible._

![The Export tab showing code export formats](https://systergon.com/blog/figma-charts-circle-packing/images/step-export.webp)

_**5. Export.** Nivo exports to React, so for this chart the library choice constrains the handoff before the design does._

![The + SVG and + PNG insert buttons](https://systergon.com/blog/figma-charts-circle-packing/images/step-insert.webp)

_**6. Insert.** SVG gives you every circle as its own vector shape — and because circles are the friendliest primitive in Figma, an inserted packing is unusually pleasant to restyle by hand._

## The data shape it needs

Hierarchical: `{ name, value, children }`, exactly as for a treemap or sunburst, with values on the leaves so parents can sum them. In the plugin it is a **JSON** edit rather than a table, and — as with every hierarchy chart here — **it cannot bind a live data source**: the plugin refuses the connection rather than corrupting the structure, because a connector cannot build a tree from a flat range.

Two data conditions to check. **Values must be non-negative**, since there is no negative area. And **the leaves carry the numbers**: supplying a parent value that disagrees with the sum of its children leaves the library to choose which to believe, and it will not tell you which it chose.

## Library by library — and the chip that hides two of them

The **Circle Packing** category holds **one example, in Nivo**. That number is accurate and misleading in the usual way.

- **Nivo — 1 example**, and the only true hierarchical circle packing here: arbitrary depth, colour inheritance, leaf labelling and zoom-on-click in its own API. React-only export.
- **Highcharts — two packed-bubble charts, filed under _Scatter_.** A packed bubble is single-level circle packing; the _split_ packed bubble adds grouping, which makes it two-level circle packing. If you are on Highcharts and want this look, that is where it lives — and it is worth knowing, because looking at the Circle Packing chip alone would tell you Highcharts cannot do this.
- **ECharts, Google Charts and ApexCharts — nothing directly.** ECharts’ graph type can be coaxed into a bubble pack with a force layout, which is a workaround rather than a chart type.

As always: **design in whichever library your engineers already use**, because the export then matches production exactly. [Choosing the right chart library](https://systergon.com/blog/figma-charts-choosing-the-right-chart-library) covers the trade-offs.

## Sizing, and the one number to check

Because area encodes the value, the ratio between your largest and smallest leaf decides whether the chart is readable before any styling happens.

**Compute the ratio first.** If the biggest leaf is 50 times the smallest, the smallest is drawn at about a seventh of the diameter — often a handful of pixels. A ratio under about 20:1 packs comfortably; beyond 100:1 the tail is invisible whatever you do.

**The fixes are the usual three.** Aggregate the small leaves into an explicit “other” sibling; split the chart into one per top-level group so each has its own scale; or accept the chart is about the big items and label only those.

**What not to do is compress the scale.** Drawing area on a square-root or log scale makes the small circles visible and breaks the one honest property this chart has — that area is proportional to value. A reader cannot tell the scale was changed, so the chart is quietly lying about every comparison.

## Styling it well

**Padding is the level indicator.** More space between a parent’s edge and its children than between siblings is what makes the nesting legible. Equal padding everywhere flattens the whole chart into one soup of circles.

**Inherit colour down the tree.** Give each top-level group a hue and let its descendants take tints of it. Same rule as a sunburst, and it does the same job: colour says which branch, containment says where in it.

**Label the leaves that fit, and the parents always.** Parent labels can sit on the circle’s edge or above it; leaf labels only work inside circles above a size threshold. Setting that threshold deliberately beats letting the library truncate.

**Give parents a fill, not just a border.** A very pale fill for containers makes them read as objects rather than as outlines, which helps when a parent has only one child and the two circles nearly coincide.

**Do not add a drop shadow to every circle.** It is the most tempting decoration for this chart and it turns forty circles into forty objects competing for depth. One subtle shadow on the outermost container, if any.

For type and colour, bind them to your design system rather than picking by hand — covered in [Your chart, your design system](https://systergon.com/blog/figma-charts-design-system-colors-typography-tokens).

## Reading it well — and the ways it misleads

**Circle area is hard to judge.** Readers underestimate large circles relative to small ones — a well-documented perceptual bias — so a leaf four times the value looks perhaps two and a half times bigger. That makes this a chart for “this branch dominates”, never for “this is 40% larger”.

**Empty space is not data.** The gaps between circles are packing artefacts. A cluster that looks loose is not more dispersed in any meaningful sense.

**Position carries nothing.** Neighbouring circles are neighbours because they fitted. Readers infer adjacency as similarity; there is none.

**A single child looks like a duplicate.** A parent with exactly one child draws as two nearly-concentric circles, which reads as an error rather than as a structure. Either flatten those branches or label them clearly.

**Small leaves vanish.** Below a few pixels a circle is a dot with no label, so the long tail is present but unreadable — aggregate it into an explicit “other” child if it matters.

## Where it is genuinely the best chart

Circle packing has a narrow but real niche, and three cases sit squarely in it.

**Codebases and file systems.** Folders containing folders containing files, sized by lines or bytes. The containment maps exactly onto the mental model people already have, and the wasted space costs nothing because the finding is “this directory is enormous” rather than a precise ratio.

**Organisational composition.** Departments containing teams containing headcount. It reads as groups-within-groups without anyone learning a convention, which matters when the audience is the organisation itself.

**Editorial and explanatory graphics.** When a chart has to be understood in two seconds by a general reader with no legend, nested circles are about as low-friction as data visualisation gets. It is why newspapers reach for them and why dashboards mostly should not.

The common thread: shallow hierarchies, an audience that has not been trained on charts, and a finding about structure rather than about magnitude. Move away from any of those three and a treemap or a bar chart does the job better.

## Accessibility

**Do not rely on colour tints alone.** Inherited palettes produce subtle lightness differences between levels; make sure the containment is legible from the geometry, which it will be if the padding is right.

**Label enough to navigate.** A packing with no text is an abstract picture. Parent labels at minimum, plus the leaves above a size threshold.

**Do not put values only in tooltips.** An inserted SVG has no hover; anything essential belongs on the canvas or in an accompanying table.

**Give it a text equivalent.** The Export tab’s **Copy Alt Text**, **Copy Data Table** and **Set Node Desc** produce a description, a table of the numbers and a description written onto the Figma node. For a hierarchy chart the table is the accessible version of the structure, and it carries the small leaves the picture cannot.

## Common questions

### How big can the range of values be?

Check the ratio between your largest and smallest leaf before building. Under about 20:1 packs comfortably; past 100:1 the smallest circles are a few pixels with no room for a label. Aggregate the tail or split the chart — but never compress the area scale, because proportional area is the only honest property this chart has.

### Circle packing or treemap?

Treemap when space is tight or sizes need comparing — it fills the frame and rectangles are easier to judge. Circle packing when the nesting itself is the message, because containment is literal and needs no explanation. Roughly: treemap for quantities, packing for structure.

### Which libraries can draw one?

**Nivo** has the only Circle Packing category — one example, arbitrary depth. **Highcharts’ packed bubble and split packed bubble**, filed under Scatter, are single-level and two-level circle packing respectively. ECharts, Google Charts and ApexCharts have no equivalent chart type.

### How deep can the hierarchy go?

Two or three levels. Each level nests inside the last, so circles shrink fast — a fourth level is usually a dot. For deeper trees use an icicle chart or a tree diagram, both of which handle depth without shrinking everything.

### Why is there so much empty space?

Because circles cannot tile a plane. The gaps are the cost of the containment being obvious, and they are the reason a treemap fits more data in the same frame. If the empty space bothers you, the treemap is the chart you wanted.

### Can it show negative values?

No — there is no negative area. Split gains and losses into separate charts, or use a bar chart which handles signs naturally.

### How should I colour it?

By top-level branch, with children taking tints of their parent’s hue. That makes lineage readable without a legend, and it is the same strategy that works for sunbursts.

### Can it use live data?

No. Like every hierarchy chart in the plugin, circle packing cannot bind a linked source — a connector cannot build a nested structure from a flat range, so the connection is refused rather than producing a broken chart.

### What is the difference between a packed bubble chart and circle packing?

Nesting. A packed bubble chart sizes circles by value and packs them into a space with no hierarchy; circle packing puts circles inside circles so containment carries the structure. Highcharts’ split packed bubble sits between the two — grouped clusters, which is circle packing with exactly two levels.

### Does the chart stay editable in Figma?

Insert as **SVG** and every circle is a real vector shape — the friendliest primitive there is to restyle on the canvas, which makes this one of the more pleasant charts to finish by hand. Insert as **PNG** for a flat image at twice the pixel density.

## Where to start

Open the plugin, filter to Circle Packing, and put your hierarchy in — then draw the same data as a treemap and put them side by side. If the treemap leaves you hunting for which rectangle belongs to which group, the packing is worth its wasted space. If the packing leaves you unable to compare the things you came to compare, the treemap was right.

[Install Figma Charts — it’s free to try →](https://www.figma.com/community/plugin/1345221583582136577/figma-charts) [Browse all 45 chart types →](https://systergon.com/figma-charts/chart-types)