Home / Part to Whole / Circle Packing Chart
Circle Packing Chart in HTML, CSS and JavaScript
A circle packing chart shows groups as big circles with smaller circles packed inside them. This free template draws one with plain SVG and vanilla JavaScript, no chart library. The example shows staff at a food company grouped by department and team.
What is a circle packing chart?
A circle packing chart shows groups as big circles with smaller circles packed inside them. The area of each circle matches its value, so bigger teams get bigger circles.
It uses space less efficiently than a treemap, but the round shapes make the groups very easy to see. It is a friendly way to show the structure of a company, a budget or a collection.
At a glance
- Best for
- Groups and the items inside them, shown softly
- Data you need
- A group, a name and a value for each item
- Skip it when
- Comparing values exactly. Circle areas are hard to judge.
- Made with
- HTML, CSS and vanilla JavaScript. No library.
When to use a circle packing chart
- Company teams by headcount
- Products grouped by category
- Topics grouped by theme
- Budgets for a public or general audience
When to pick another chart
- Treemap: you want to use space fully and compare sizes more easily
- Grouped Bar Chart: you need exact comparisons
What you get in this template
- A packing layout where each circle touches two others
- Circle area, not radius, matches headcount so sizes are honest
- Department circles with their teams packed inside
- The layout turns sideways on wide screens to use the space
- Names shorten to fit small circles
- Tooltips, keyboard support and a data table
How the code works
Here is a short version of the idea behind this circle packing chart. The full file adds the axis, labels, tooltips, sorting and resizing on top of it.
// Place circles side by side, sized by area (simple version of packing)
const teams = [['Drivers', 31], ['Prep cooks', 22], ['Cashiers', 18], ['Chefs', 14]];
let x = 20;
teams.forEach(([name, people]) => {
const r = Math.sqrt(people) * 10; // area matches the value
drawCircle(x + r, 150, r, '#c05a2e');
drawText(x + r, 154, name, 'middle');
x += r * 2 + 8;
});The example uses four tiny helpers that create SVG shapes. Put them above the code and it runs as is.
const svg = document.querySelector('svg');
function make(tag, attrs) {
const n = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (const k in attrs) n.setAttribute(k, attrs[k]);
svg.appendChild(n);
return n;
}
function drawRect(x, y, width, height, fill) { return make('rect', { x, y, width, height, fill }); }
function drawCircle(cx, cy, r, fill) { return make('circle', { cx, cy, r, fill }); }
function drawLine(x1, y1, x2, y2, stroke, width, dash) {
return make('line', { x1, y1, x2, y2, stroke, 'stroke-width': width || 1, 'stroke-dasharray': dash || 'none' });
}
function drawText(x, y, str, anchor) {
const t = make('text', { x, y, 'text-anchor': anchor || 'start' });
t.textContent = str;
return t;
}How to add it to your website
- Download the file. Click Download HTML file above. You get one file called circle-packing.html with everything inside.
- Change the data. Open the file in any code editor and find the DATA list near the bottom. Replace the names and numbers with your own.
- Change the colors and text. Colors are at the top of the style tag. The title, subtitle and main point are plain HTML near the top of the body.
- Put it online. Upload the file to any host, such as GitHub Pages, Netlify or your own server, or paste it into your site. There is no build step.
Questions people ask
What is a circle packing chart?
It is a chart that shows groups as large circles with smaller circles packed inside them. Each circle area matches a value, like the number of people in a team.
Why use the square root for circle size?
A circle area grows with the square of its radius. Using the square root of the value for the radius makes the area match the value, so a team twice as big looks twice as big.
How do you pack circles without overlap?
Place the largest circle first, then put each next circle where it touches two circles already placed without overlapping any, choosing the spot closest to the center. This template does that in plain JavaScript.
Is circle packing better than a treemap?
A treemap is more exact and uses space better. Circle packing is easier on the eye and makes the groups stand out, so it suits a general audience.
More part to whole

021. Pie Chart
Example: how customers paid at a cafe
022. Donut Chart
Example: workouts logged by members of a fitness app
023. Semi Donut Chart
Example: a fundraising appeal and the money still needed
024. Treemap
Example: bookshop sales by section and genre
025. Sunburst Chart
Example: where a city sends its household waste
026. Waffle Chart
Example: how 100 new customers found a furniture shop
027. Marimekko Chart
Example: e-bike market share by region and brand
028. Funnel Chart
Example: shoppers moving from first visit to purchase in an online shop