import { UnitPileChart } from "semiotic/physics"
Example
Mechanical mode generates seeded category totals without requiring input data. Use it for capacity sketches, design reviews, or empty-state demos; switch back to sample mode when real rows should determine each pile.
Each full circle represents unitValue. A record's remainder becomes a smaller circle whose area represents its share of a unit. Labels show exact source totals; pile height and the faint stacking guides are approximate. For example, 49 + 49 with unitValue={100} produces two partial circles and a total of 98. Set showProjection={false} to hide the guides and labels.
Try live updates
Start with 49 + 49: the total is 98. Add another 49 to make 147, then add category B to create a second tube. Change the value per full circle: the circle count changes while the totals stay the same. Pause motion to inspect edits without waiting for a fall.
2 source records · Total 98
Source records| Category | Value |
|---|
| A | 49 |
| A | 49 |
| Total | 98 |
|---|
This editor uses push, update, remove, and clearon the chart ref. getData() returns each source record once, including records waiting to enter. A new data array replaces the source records; changing an accessor or unitValue re-encodes the current records. A changing React key is unnecessary. An enabled rerunMS replays the original seeded data. popBodies only removes visual bodies; use remove to change source records and totals.
Select Empty array and try adding a record: data={[]}keeps the chart empty. Select Push via ref to omit dataand enable live ingestion. Rejected pushes are not saved for a later mode change.
Props
| Prop | Type | Required | Default | Description |
|---|
data | array | — | — | Rows to unitize into category piles. Optional when mode is mechanical. |
categoryAccessor | string | function | — | "category" | Categorical field that chooses the pile. |
valueAccessor | string | function | — | — | Nonnegative numeric field converted into units. Omit to count each row as 1; mechanical mode defaults to value. |
mode | "sample" | "mechanical" | — | "sample" | Use data values or generate a deterministic no-data unit pile. |
mechanicalCount | number | — | max(48, categories * 12) | Number of generated unit bodies in mechanical mode. |
mechanicalCategories | array | — | ["Intake", "Review", "Build", "Ship"] | Category labels generated by mechanical mode. |
unitValue | number | — | 1 | Value per full circle. A record's remainder uses a partial circle scaled by area. |
ballRadius | number | — | 8 | Radius of a full unit circle. Remainder circles scale by area. |
colorBy | string | function | — | — | Categorical field used to color bodies. |
seed | number | — | 1 | Deterministic simulation seed. |
showProjection | boolean | — | true | Label exact source category totals and show approximate stacking guides. |
sediment | boolean | — | — | Reserved future sediment mode. |
size | array | — | [700, 380] | [width, height] in pixels. |
width | number | — | 700 | Width alias used when size is omitted. |
height | number | — | 380 | Height alias used when size is omitted. |
hoverRadius | number | — | 16 | Pixel hit radius for unit-body hover tooltips. |
paused | boolean | — | false | Pause the simulation. |
tooltip | boolean | function | object | — | true | Enable the default unit-body tooltip, pass a custom tooltip renderer/config, or set false to disable hover tooltips. |
frameProps | object | — | — | Advanced StreamPhysicsFrame props. |