unit
Configuration Structure
unit: {}plotOptions
Settings for the unit chart (chart.type: 'unit') and its waffle preset (chart.type: 'waffle'). A unit chart draws one discrete mark per unit of value, so a count reads as a countable quantity rather than a single bar or slice.
layout
'grouped'How the marks are placed.
Available Options:
- 'grouped' (default): each category is its own cluster (a phyllotaxis blob), laid out in a row.
- 'packed': one shared blob, coloured by group and (with
sortByGroup) ordered so the minority nests in the centre. - 'columns': each category is a vertical bar built from stacked dots (a unit / waffle column) whose height encodes the count.
- 'grid': one lattice of cells filled in category order, a part-to-whole square "pie".
chart.type: 'waffle'presets this layout. - 'scatter': a beeswarm (or 2D value-value plot) that places marks on real numeric value axes.
- 'arc' (added 6.7): a parliament / hemicycle, seats in concentric arced rows across an annulus, filled in category order so each category is a contiguous wedge. See
arc. - 'custom' (added 6.9): the arrangement comes from your own provider. See
positions.
positions
undefinedlayout: 'custom' only. The layout provider: either a function returning plot-pixel positions, or the name of one registered with ApexCharts.registerUnitLayout.
plotOptions: {
unit: {
layout: 'custom',
positions: (objects, rect) => objects.map((o, i) => ({
id: o.id,
x: rect.x + (i % 20) * 14,
y: rect.y + Math.floor(i / 20) * 14
}))
}
}
It is called with (objects, rect) and returns [{ id, x, y, r? }]. objects carries identity and data per mark rather than just an index, so a provider can address a specific unit rather than a positional slot, and rect is the plot area in pixels.
A layout is objects in, positions out, and nothing else. It knows nothing about animation, because the engine already tweens position, radius and colour and already keeps each mark's identity across a relayout, so an arrangement the built-in layouts cannot express needs no new transition code.
A mark whose id the provider omits animates out through the existing exit path. Ids matching no mark are ignored.
transition
'group'How marks are matched between renders on an update, which decides which previous mark each new mark tweens from.
Available Options:
- 'group' (default): keyed per category, so a mark stays in its group and category-level enters/exits fade in and out.
- 'flow': keyed by global draw order, so the anonymous crowd migrates and recolours across a regroup (the circles-to-bars transition).
- 'identity': keyed by each datum's
id/name, so a specific mark migrates across any regroup or relayout keeping its colour and size. Requires the per-unit object form with unique ids/names.
shape
'circle'Mark shape for each unit.
Available Options:
- 'circle' (default)
- 'square' (see
borderRadius) - 'image': render an icon (an isotype pictogram); configure it with
image.
image
The icon used when shape: 'image'.
src
Icon URL or data URI.
width
Icon width in pixels.
height
Icon height in pixels.
tint
falseRecolour a monochrome icon to the category colour (or a per-unit fillColor) so the pictogram matches the legend. Leave off (default) for multi-colour icons that should keep their own colours.
size
'auto'Mark radius in pixels, or 'auto' (default) to size marks so the largest cluster fits.
columns
Options for the columns layout.
size
'inherit'The columns layout can size its dots independently of size.
Available Options:
- 'inherit' (default): use
size. - 'auto': size dots to fill the plot height.
- a number: pin a columns-only size. Circle / square only (image icons keep their intrinsic size).
grid
The grid (waffle) layout: one lattice of cells filled in category order.
columns
10Cells per row. Defaults to 10.
total
Fixed cell budget (e.g. 100 for a percentage waffle); a largest-remainder rule allocates the cells to categories so they sum exactly to the budget. Leave undefined for one cell per unit (respects unitValue / maxUnits).
fillFrom
'bottom'First row of the fill.
Available Options:
- 'bottom' (default)
- 'top'
split
falseSmall multiples: render one mini-waffle per category in a trellis instead of a single shared lattice. Each tile has total cells (default 100) and fills value/max of them; the rest show as a faint trackColor backdrop, and each tile carries its own label.
tileColumns
Small-multiple tiles per row. Undefined = auto (near-square).
max
Small-multiple value → filled-cell denominator. Undefined = the largest count (the leader fills its tile). Set to 100 for true "of 100" percentage tiles.
trackColor
Small-multiple empty ("track") cell colour. Undefined = neutral grey.
arc
Options for layout: 'arc' (parliament / hemicycle). Angles use the radialBar convention (0 at the top, clockwise). The default sweep is a top semicircle; a full circle is startAngle: 0, endAngle: 360. Added in 6.7.
startAngle
-90Sweep start angle in degrees (0 at the top, clockwise).
endAngle
90Sweep end angle in degrees. 90 gives a top semicircle.
innerRadiusRatio
0.4Donut hole, as the inner radius divided by the outer radius (0 fills the centre, closer to 1 is a thin band).
rows
'auto'Number of concentric seat rows, or 'auto' to size the dots as large as fit.
gather
The gather tween that moves marks between layouts on an update, and where entering marks come from. Added in 6.7.
easing
'outCubic'Travel curve for the gather tween. 'outCubic' (default) decelerates to a stop; 'inOutCubic' accelerates gently out of rest; 'outBack' overshoots each mark past its slot and springs back.
overshoot
1.70158Spring strength for easing: 'outBack' (how far each mark overshoots before settling).
enter
'burst'Where a fresh or appearing mark animates from. 'burst' (default) flies out from the cluster centre; 'fade' materialises in place; 'rise' fades in while drifting up into the slot.
scatter
The scatter layout places units on real value axes (needs the object-form data).
y
'lanes'Axis mode.
Available Options:
- 'lanes' (default): a beeswarm, a value axis with one category lane per series (see
orientationfor which axis carries the value). - 'value': a 2D value-value scatter — each datum's
x/yon two numeric axes, category = colour.
spread
'swarm'How equal values are separated within a lane.
Available Options:
- 'swarm' (default): anti-overlap packing off the lane centre.
- 'jitter': random lane spread.
orientation
'horizontal'Beeswarm orientation (y: 'lanes' mode only; ignored by the 2D value-value scatter). The value-axis keys (xMin / xMax / xTitle / xFormatter / tickAmount) describe the value axis in both orientations.
Available Options:
- 'horizontal' (default): value on the X axis, category lanes stacked on Y.
- 'vertical': value on the Y axis, category lanes as columns across X.
tickAmount
5Approximate number of value-axis ticks. Defaults to 5.
xMin
Fixed value-axis minimum. Undefined = a nice-numbered value derived from the data. An explicit bound is extended by whole tick steps when data would fall outside it, so every datum stays inside the axis.
xMax
Fixed value-axis maximum. Undefined = a nice-numbered value derived from the data. An explicit bound is extended by whole tick steps when data would fall outside it, so every datum stays inside the axis.
xTitle
Value-axis title, drawn along the value axis in either orientation.
xFormatter
Value-axis tick-label formatter, (value) => string.
yTickAmount
5Approximate number of Y-axis ticks (2D mode). Defaults to 5.
yMin
Fixed Y-axis minimum (2D mode). Undefined = nice-numbered from the data.
yMax
Fixed Y-axis maximum (2D mode). Undefined = nice-numbered from the data.
yTitle
Y-axis title (2D mode), drawn rotated at the left.
yFormatter
Y tick-label formatter, (value) => string.
sizeField
'z'Datum key holding the bubble size value. Defaults to 'z'.
sizeRange
[minRadius, maxRadius] in pixels: turns dots into area-scaled bubbles.
laneLabelWidth
Left-gutter width reserved for lane (category) labels in lanes mode.
gridlines
trueDraw the faint gridlines. Defaults to true.
sizeByValue
Opt-in bubble sizing: scale each dot's radius by its per-unit value (requires the object-form data, series: [{ data: [{ value }] }]). Circle shape only; the lattice is spaced for the largest bubble so dots never overlap. Ignored when there are no per-unit values.
enabled
falseTurn per-unit bubble sizing on.
maxRadius
'auto'Radius (px) for the largest value, or 'auto' to fit it to the plot.
minRadius
Radius (px) for the smallest value. Defaults to ~35% of maxRadius.
scale
'area'How the value maps to size.
Available Options:
- 'area' (default): bubble area proportional to value.
- 'linear': radius proportional to value.
spacing
1.05Packing gap factor between spiral shells (1 = dots touch).
borderRadius
Corner radius for shape: 'square'.
unitValue
1One mark represents this many units of value (waffle scaling).
maxUnits
5000Safety cap on the total number of marks; counts scale down proportionally above it.
sortByGroup
truepacked layout: order categories smallest-first so the minority group is centred.
clusterLabels
A per-cluster label: a curved arc above a blob, or a straight label above / below a bar.
show
Render the per-cluster label.
position
'top'Label placement relative to the cluster / bar. Defaults to 'top'. A 'bottom' label is always straight (the curved arc rides the top crown only).
curved
Bend the label into an arc that follows the top of the blob.
color
Label colour. Defaults to the cluster's own colour.
offsetY
Vertical offset of the label in pixels.
formatter
Return the label text: (name, { seriesIndex, value, percent, w }) => string.
tooltip
Per-unit (per-dot) tooltip.
formatter
Return the tooltip body for a single hovered dot. The dot's category is seriesIndex and its index within that category is dataPointIndex, so the formatter can index into per-unit data. Return a string or HTML. Defaults to "#<dataPointIndex+1> of <count>".