# Circle Packing with d3-force

This tutorial is a variation around the general introduction to circle packing with react and d3.js. You should probably understand the concepts described there before reading here.

Instead of relying on the `pack()`

function of d3.js to compute the best node positions, this example suggests to rely on the d3-force plugin to apply **physical forces** on each node.

A code sandbox is provided for the final result, but explanations target what's different compared to a classic circular packing based on some concepts described in the network diagram section.

## Plot and code

Here is the final plot we're trying to achieve here, together with its code:🙇♂️

It is a circular packing chart where all circles represent an item of the dataset.

- The circle area is proportional to the
`value`

property of the data item. - All circles are close to each other but
**do not collide**. They are also attracted by the`y=0`

horizontal axis, what**aligns them horizontally**

To understand how this chart works, you need the concepts described in the Network diagram and Circle pack sections.

A circle packing chart made using the d3-force plugin, with bubbles being attracted by the `y=0`

baseline.

## Using `d3-force`

This example is actually a variation of a network diagram, but with no links between nodes.

Some physical forces are applied to each node to compute their position through an iterative simulation:

```
d3.forceSimulation(nodes)
.force(
'collide',
d3.forceCollide().radius((node) => sizeScale(node.value) + 1)
)
.force('charge', d3.forceManyBody().strength(80))
.force('center', d3.forceCenter(width / 2, height / 2))
.force('charge', d3.forceY(0).strength(0.05))
```

Here is a reminder:

**collide**avoids circle overlap. It uses each node radius to make sure there is no collision.**manyBody**makes sure that nodes are attracted one to each other since the`strength`

in use is positive.**forceCenter**center the whole chart on the canvas.**forceY**aligns bubble on a horizontal line.

## Bubble Size

As explained in the bubble chart section, it is very important to have the bubble **area** being proportional to the numeric`value`

of the data point.

It is a very common mistake to make the **radius** proportional to numeric value, which leads to a misleading visualization.

Fortunately, it is very straightforward to scale the bubble appropriately thanks to the `scaleSqrt()`

function.

```
const sizeScale = scaleSqrt()
.domain([min, max])
.range([BUBBLE_MIN_SIZE, BUBBLE_MAX_SIZE]);
```

## Contact

👋 Hey, I'm Yan and I'm currently working on this project!

Feedback is welcome ❤️. You can fill an issue on Github, drop me a message on Twitter, or even send me an email pasting `yan.holtz.data`

with `gmail.com`

. You can also subscribe to the newsletter to know when I publish more content!