A lightweight animated dot-matrix chart with a dependency-free calculation core and an optional React adapter.
dot-matrix-chart is available as a public npm package with a dependency-free core and an optional React adapter.
1count renders as one dot when the data fits within the configured row capacity.- Zero values render no dots.
- Larger count and currency ranges choose an explicit readable unit such as
1 dot = 3 usersor1 dot = $3k. - Any source length is resampled into a stable visual field.
- The reveal begins exactly at the zero line and moves upward, column by column.
- Motion honors
prefers-reduced-motion. - The core has no runtime dependencies. React is a peer dependency of the adapter.
npm install dot-matrix-chartimport { DotMatrixChart } from "dot-matrix-chart/react";
const values = [0, 1, 0, 2, 1, 0, 1, 3, 1, 2, 1, 4, 2, 3];
export function NewUsersChart() {
return (
<DotMatrixChart
data={values}
valueKind="count"
singularLabel="user"
pluralLabel="users"
historicalColor="#d0d5dd"
accentColor="#c9a96e"
recentFraction={0.5}
xLabels={["Jul 28", "Aug 3", "Aug 10"]}
ariaLabel="New users over the last 14 days"
/>
);
}The approved visual defaults are 60 columns, 18 rows, 6.5px tiles, a 14ms column stagger, and a 520ms rise. The included Vite playground exposes the complete visual API and accepts pasted comma- or space-separated data.
import { createDotMatrix, formatDotUnit } from "dot-matrix-chart";
const model = createDotMatrix({
values: [0, 1, 2, 3, 4],
columns: 60,
rows: 18,
valueKind: "count",
});
console.log(model.dotUnit); // 1
console.log(formatDotUnit(model.dotUnit, "count", "user", "users"));Every visual decision is adjustable:
| Group | Props | Defaults |
|---|---|---|
| Data | data, valueKind, dotUnit, singularLabel, pluralLabel, formatValue |
count data with automatic dot units |
| Matrix | columns, rows, tileSize, tileRadius |
60, 18, 6.5, 1.3 px |
| Color | historicalColor, accentColor, guideColor, labelColor, recentFraction |
gray history, gold recent range, final third accented |
| Motion | staggerMs, animationDurationMs, animationEasing, overshoot, animate |
14ms, 520ms, smooth rise, 5, enabled |
| Layout | width, fallbackWidth, height, compactHeight, compactBreakpoint |
responsive, 720, 258, 224, 520 px |
| Annotation | xLabels, showGuides, showUnitKey |
optional dates, guides and unit key shown |
| Accessibility | ariaLabel, description |
generated accessible chart summary |
| Container | className, style, and standard div props |
none |
tileRadius is clamped to half the rendered tile size. Fractions, timing, dimensions, and other numeric visual inputs are also safely clamped or given sensible fallbacks.
The range picker intentionally lives outside the library. Consumers decide whether Daily, Weekly, or Monthly is selected and pass the corresponding values and labels into the chart.
npm install
npm run dev
npm run check
npm run demo:buildThe API may evolve during the 0.x releases as usage feedback is incorporated before 1.0.
