Skip to content
microcharts
ReferenceExpressiveTallyMarks

TallyMarks

React tally marks chart — counts as five-and-strike tally clusters humans already read. Tiny accessible SVG microchart; RSC-safe static or /interactive.

TallyMarks answers "how many?" the way a human actually counts — in four-and-strike clusters of five. The count reads back exactly: no scale to calibrate, no color to decode. Past total the marks stop growing and a +N numeral tells the truth, so a cell never blows out its width. Marks are never resized to fit — width grows with the count until the cap, then the numeral takes over.

TallyMarks
interactive · 2.98 kB · static · 1.6 kB

Install

Import & usereact/tally-marks
import { TallyMarks } from "@microcharts/react/tally-marks";<TallyMarks value={23} title="Signatures" />
Needs package + stylesheetSet up with AI

Try it

When to use it

  • Good for — a small running count in a sentence or cell, a live event or score counter, or an editorial hand-tallied context.
  • Avoid for — large magnitudes (MiniBar), trends over time (Sparkline), or proportions (Progress).

Sizing

Variants

hand-drawn pen + capped width

Edge cases

zero — no marks, a real '0 counted.'
negative clamps to 0 — the summary reads '0 counted.', never a negative count
a non-physical value saturates at the 200-mark ceiling

Four homes

Why this default

The ruled pen is the default because product tables want precision first — evenly ruled strokes count back fastest. The drawn pen adds a seeded, deterministic jitter (same count always renders identically, on the server and after hydration) for the editorial voice, and it only perturbs how each stroke is drawn — the count is never touched. Past total, the default overflow="numeral" appends a +N so the true total survives even when the marks can't; overflow="clamp" suppresses the numeral for dense columns, and the accessible name still carries the exact count.

Accessibility

The accessible name is the exact count — "17 counted." — always the true value, even when the marks overflow to a +N numeral or clamp. The interactive entry announces the new total through a polite live region on change and draws newly added marks in with a brief, reduced-motion-gated sweep. A count has no sub-parts, so focus reads the summary and there is no cursor to move.

This chart is a single unit, so there is nothing to rove between: a click, tap, Enter or Space selects it and fires onSelect, and no selection stays pinned. That is the scalar half of the shared interaction contract.

Props

PropTypeNotes
value*numberThe count. Floored; negatives clamp to 0.
totalnumberMarks drawn before overflow (default 25).
overflow"numeral" | "clamp"numeral appends +N; clamp stops drawing. The summary always keeps the true count.
pen"ruled" | "drawn"Hand-drawn jitter for editorial contexts.

Plus the shared grammar — data, domain, color, title, summary, format — and the layout props (width, height, className, style) that every chart accepts. Interactive entries also share animate and live, and — wherever a chart has more than one navigable unit — onActive, onSelect, selectedIndex and defaultSelectedIndex; and — wherever the chart shows a hover value — readout. See the shared grammar.

Related charts