Slope
Slope connects each category's before and after value on one shared scale, so rises, falls, and crossings read directly.
- encodes
- line slope between two aligned columns
- precision
- medium-high
- nodes
- ≤ 3 per category (≤ 7)
Slope draws one line per category between two moments: East 40 to 47, West 55 to 41, and any crossing between them. Both
columns share one y-domain, since per-column normalization would fake convergence. Lines stay neutral until you declare
positive, because a rank change is not automatically good or bad.
Install
import { Slope } from "@microcharts/react/slope";// cohorts — real values under “Sample data” below<Slope data={cohorts} title="Before vs after" />Sample data
const cohorts = [ { label: "East", from: 40, to: 47 }, { label: "West", from: 55, to: 41 }, { label: "South", from: 30, to: 33 }, { label: "North", from: 50, to: 44 }, { label: "Mid", from: 20, to: 35 },];Try it
When to use it
Use it for before/after experiments, rank shuffles, and two-moment comparisons, up to about 7 categories. A two-point line says nothing about the path between the moments, so use Sparkline when that path is the point.
Sizing
Variants
End labels drop deterministically rather than by measurement: when the rows are denser than the label font (height ÷ count), and when the reserved label gutters would squeeze the two columns under ~35% of the width. The reclaimed room goes back to the lines. Endpoints that would collide inside a column are nudged apart to a full glyph pitch instead of overlapping.
Edge cases
A row missing one side (from or to as NaN) draws a short dashed stub toward the end it does have rather than a
full line. There is no second point to connect to, so nothing is interpolated, and the row is announced as "incomplete".
With a locale, both column labels and the announced values follow that locale's own grouping.
Four homes
Accessibility
The accessible name counts directions and leads with the biggest mover: "3 categories: 2 up, 1 down. Largest change Mid, up 75%." The interactive entry finds the nearest line under the pointer and roves categories ordered by their after-value, announcing each slope ("East: 40 to 47, up 18%.").
The interactive entry follows the shared interaction contract:
arrow keys rove between units on both axes, Home and End jump to the ends, and a click, tap, Enter or
Space selects a unit — pinning its readout so it survives blur, until you select it again or press Escape.
On touch, a tap pins and a drag scrubs.
Props
| Prop | Type | Notes |
|---|---|---|
| data* | { label; from; to }[] | Two aligned moments per category. |
| label | "none" | "value" | "label" | "both" | End labels; dropped deterministically when rows collide. |
| highlight | number | string | The one-vs-field editorial read. |
| positive | "up" | "down" | Direction valence; unset = neutral ink. |
| animate | boolean | interactiveOpt-in entrance motion when the chart mounts client-side — add import "@microcharts/react/motion" once. Inert on the server, on hydrated server HTML, and under prefers-reduced-motion. |
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.