# Unit (/docs/charts/unit)

> Countable items as individually matched circles, in grid, force, unit-bar and beeswarm layouts.

```ts
import { unit } from 'visdelta/unit';
```

`unit()` turns rows, or counts, into individually matched circles.

<LiveExample id="unit-layout" />

## Methods [#methods]

| Method                                            | Meaning                                              |
| ------------------------------------------------- | ---------------------------------------------------- |
| `.value(field, { unitValue?, maxUnits? })`        | Expand a count field into units                      |
| `.group(field)`                                   | Declare categorical membership, without choosing colour |
| `.layout('grid' \| 'force' \| 'bar' \| 'beeswarm', options?)` | Arrange the same units                   |
| `.columns(number)`                                | Set grid or unit-bar columns                         |
| `.size(number)`                                   | Set constant mark size (requested circle radius in pixels) |
| `.radius(number)`                                 | Compatibility alias for `.size(number)`               |
| `.x(field, options?)`, `.y(field, options?)`      | Declare force targets; x also positions a beeswarm   |

The available layout names are exported as `UNIT_LAYOUTS`.

```js
unit(rows)
  .key("flowerId")
  .size(6)
  .layout("beeswarm", { x: "petalLength" })
  .color("species");
```

Layout options accept `x` and `y` as field names or full channel configurations,
and `columns`. Layout type, columns and x/y bindings form one complete planner
operation. The existing horizontal-move-then-fall animation remains inside it,
with the usual per-mark stagger. Size is an independent Appearance channel.

Compact layout options and chained `.x()` / `.y()` calls are equally supported
forms of the same declaration, not compatibility syntax:

```js
unit(rows).layout("beeswarm", { x: "petalLength" });
unit(rows).layout("beeswarm").x("petalLength");
```

Both write one position binding. The last explicit assignment wins, including
across the two forms, and replaces the complete channel and its options:

```js
unit(rows)
  .key("flowerId")
  .size(6)
  .layout("beeswarm", { x: "petalLength" })
  .x("petalWidth") // replaces the earlier x binding and its options
  .color("species");
```

Reversing those x assignments makes `petalLength` win. Omitted layout options
retain earlier settings: `.x("petalWidth").layout("beeswarm")` keeps
`petalWidth`. Equivalent final states produce the same difference and transition
route; normal overwrites do not issue warnings. `.radius(6)` and layout `{ radius: 6 }` remain aliases
for `.size(6)` and obey the same last-assignment rule.

Currently Unit renders circles: size is their requested radius in pixels,
which layout fitting can reduce when space is limited. Field-driven size,
rectangle marks and glyph marks are not yet supported.
Data, quantity, grouping, size, color and attention remain independent operations.
One operation can still produce several semantic categories in `delta()`.

## Layouts [#layouts]

- **`grid`** arranges units in rows of `columns`.
- **`bar`** centres one stack of units on each category tick. It requires a
  `.group()` field.
- **`beeswarm`** places units without overlap along x. It requires an x field.
- **`force`** records a D3 simulation's ticks as a reversible physical path and
  maps progress to its cumulative movement. With no positional channel, units
  are attracted to the plot centre. An explicit x or y channel supplies a
  per-unit `forceX` or `forceY` target, so a categorical field forms labelled
  attractor bands.

Layout changes preserve matching keys. Remaining unmatched units use a global
minimum-travel assignment, and layout changes use a short, bounded per-unit
stagger unless you override it.

## Quantity per circle [#quantity-per-circle]

`unitValue` sets how much each circle represents and defaults to `1`. A positive
remainder gets one more circle, so 51 sites at `unitValue: 10` render 6 circles.
Label the chart or legend with the unit value you choose. `maxUnits` is a
whole-chart safety cap.

Changing `unitValue` is a **Grain** change: a coarse circle is the parent of the
finer circles from the same row, and the transition splits or merges them around
the parent's centroid.

<LiveExample id="unit-value" />

## Try it [#try-it]

Edit 150 Iris flowers as they leave a grid for a beeswarm in the
[playground](/playground#swarm).
