Skip to content
microcharts
ReferenceExpressiveTallyMarks

TallyMarks

TallyMarks counts in four-and-strike clusters of five, and prints a +N numeral once the count passes the cap.

encodes
mark count in four-and-strike clusters of five
precision
high
nodes
2 (strokes + overflow numeral)
collection
Expressive
Source

The chart below prints 23 as four clusters of five plus three loose strokes, the way a person counts. The count reads back exactly: there is no scale to calibrate and no color to decode. Past total the marks stop growing and a +N numeral carries the rest, 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 · 3.22 kB · static · 1.67 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

Live playground
onSelect
idle
  1. hover · click · Enter…

Tap to count — each new mark draws in and the total is announced through a polite live region. A count has no sub-parts, so focus reads the summary and there is no cursor to move.

value · 23
total · 25
pen
overflow
import { TallyMarks } from "@microcharts/react/tally-marks/interactive";<TallyMarks  value={23}/>

When to use it

Use it for a small running count in a sentence or cell, a live event or score counter, or an editorial hand-tallied context. Large magnitudes belong in MiniBar, trends over time in Sparkline, and proportions in Progress.

Sizing

hand-drawn pen for an editorial count
cap the width — the numeral tells the truth past total

Variants

The ruled pen is the default, because evenly ruled strokes count back fastest in a product table. The drawn pen adds a seeded, deterministic jitter for an editorial voice: the same count always renders identically, on the server and after hydration, and the jitter only changes how each stroke is drawn, never the count.

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

A negative value clamps to 0 and a non-physical value saturates at the 200-mark ceiling. 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.

Four homes

In a sentence

Petition signatures — 23 collected, 27 to goal.

In a table cell
District 123
District 218
District 331
In a KPI card
Signatures
23of 50 goal
In a tab header
District 1District 2District 3

Preview uses the public chart API only. When an interactive twin exists, it swaps in with the same props and no entrance motion - code samples stay on the static import. Placement recipes: Composition, Sizing.

Accessibility

The accessible name is the exact count, "17 counted.", and stays 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