Skip to content
KONIGI Patterns

Dashboards / Key measures / Sparkline

‹ 6 of 7 ›

Sparkline

People need a compact view of recent changes beside a value.

Updated September 9, 2026

Problem

People need a quick sense of recent change beside a value, but there is not enough room for a full chart.

Solution

Place a small, simple trend line beside the number. Keep decoration minimal and make the time period clear from the surrounding label.

Choose the scale deliberately. If people compare rows, use a shared scale or an explicitly labeled common basis. Independently scaled lines can make a small fluctuation look as dramatic as a large change.

Keep exact values or a text description available through an accessible path. Remove or replace the line when it becomes too small to read.

Use when

A displayed number needs recent history, especially in a compact tile or table row.

Don’t use when

The exact values matter, or the viewer needs to read a specific point. A sparkline answers “what shape” and refuses to answer “how much”, and adding labels to fix that turns it back into a small chart with all the costs of one.

Trade-offs

Without axes, readers can easily misjudge the size of a change. Small lines may become decorative rather than informative. Resizing can change their apparent steepness or make them unreadable.

Checklist

  • Is each sparkline scaled to itself, to the column, or to a fixed baseline? Can the viewer tell?
  • If they’re in a column, would a reader comparing two rows reach a true conclusion?
  • What time window does the line cover, and is it the same window as the number beside it?
  • Are the endpoints marked, so the viewer knows which end is now?
  • Is the current value’s position within the recent range visible, or just the shape?
  • Does the aspect ratio put the interesting slopes near 45 degrees, or has it flattened them?
  • What happens to gaps in the data?
  • Does the sparkline survive the smallest size this container gets, and what shows if it doesn’t?
  • Is the same information reachable as text for a screen reader?
  • Is this sparkline doing work, or is it a texture the tile grew?

Compare

Grafana renders the sparkline as a background wash behind the stat value rather than beside it, and hides it when the panel shrinks, so it reads as atmosphere for the number instead of a chart in its own right. Sentry puts one on every issue row in the list, which is the pattern at its most useful: the shape tells you whether an error is new, constant, or spiking, without opening anything. Netdata effectively inverts the pattern by making the full charts small and numerous enough that it never needs a miniature. Honeycomb mostly declines it, on the same argument it makes about percentiles, that a single line hides the distribution underneath it.

KPI tile commonly holds a sparkline. Delta indicator provides a simpler endpoint comparison. Time series adds room and axes.

Data table can include a trend column. Small multiples is better when comparisons need labeled charts.

Sparkline anatomy A word-sized line drawn inside a line of text, with a grey band for the normal range and the last value marked and printed beside it. Below, the same three series scaled each to its own minimum and maximum, then on one common scale. Anatomy, drawn at the size it's meant to be 1 2 Checkout p95 312ms 90 days 3 4 1 WORD-SIZED Small, intense, simple and sized to the line of text it sits in. That's Tufte's whole spec. 2 NO FRAME, NO AXIS Data-ink ratio 1.0. Everything that isn't data comes out, ticks and gridlines first. 3 NORMAL BAND The only scale it gets. A grey stripe saying what the last ninety days counted as normal. 4 LAST VALUE Marked on the line and printed beside it, because a line with no axis has no number. Three series, two scalings Sparklines are most useful in a column, which is where they mislead hardest. 99.1–99.2% 78–74% 90–10% Each to its own min and max 99.1–99.2% 78–74% 90–10% One common scale
Wireframe — the pattern's anatomy, not any one product's version of it

Implementation

A word-sized chart with no axes, no gridlines and no tooltip. Everything a normal chart adds is what makes a sparkline stop working, so the component has to actively refuse those things rather than merely omit them.

Tokens
--foreground--card--muted--muted-foreground--border--chart-1--direction-up

Checkout p95312ms90 days

Sparkline.tsxRenders a path from values. No axes, and the endpoint dot is the only emphasis.

/**
 * A sparkline is sized to sit in a line of text, so it gets no axes, no
 * gridlines, no legend and no tooltip. Those are the things that make a chart
 * readable at chart size and unreadable at word size.
 *
 * The one piece of emphasis is the final point, because the question a
 * sparkline answers is "what shape got us to the number beside it".
 */
export function Sparkline({
  values,
  width = 72,
  height = 20,
}: {
  values: number[];
  width?: number;
  height?: number;
}) {
  if (values.length < 2) return null;
  const min = Math.min(...values);
  const max = Math.max(...values);
  const span = max - min || 1;
  const x = (i: number) => (i / (values.length - 1)) * (width - 2) + 1;
  const y = (v: number) => height - 1 - ((v - min) / span) * (height - 2);
  const d = values.map((v, i) => `${i ? "L" : "M"}${x(i).toFixed(1)} ${y(v).toFixed(1)}`).join(" ");

  return (
    <svg
      width={width}
      height={height}
      viewBox={`0 0 ${width} ${height}`}
      // Decorative: the number beside it carries the meaning, and a screen
      // reader reading out a path description helps nobody.
      aria-hidden="true"
      className="inline-block align-middle overflow-visible"
    >
      <path d={d} fill="none" stroke="currentColor" strokeWidth="1.25" strokeLinejoin="round" strokeLinecap="round" />
      <circle cx={x(values.length - 1)} cy={y(values[values.length - 1])} r="1.9" fill="currentColor" />
    </svg>
  );
}

demo.tsxHow it is called: the values, inline beside the number and its window.

import { Sparkline } from "./Sparkline";

/** Inline beside the number it belongs to, at text size, with the window named. */
export default function Demo() {
  return (
    <p className="flex items-baseline gap-3 text-sm text-foreground">
      Checkout p95
      <span className="self-center text-chart-1">
        <Sparkline values={[296, 310, 288, 322, 305, 330, 298, 315, 312]} width={180} height={24} />
      </span>
      <span className="tabular-nums text-direction-up">312ms</span>
      <span className="text-xs text-muted-foreground">90 days</span>
    </p>
  );
}
What it renders. Identical markup in both panes, with only the token values changing.

Examples

Screenshots are grouped by product and include the capture date. Dashed boxes highlight this pattern. Notes appear below each screenshot and when you hover over a box.

Grafana

Examples of panel grids, shared selectors, stat tiles, and chart configuration.

Examples / Gauge September 10, 2026 Grafana Play (signed out; no version string exposed) medium · dark · desktop-web
The showcase includes several gauges with similar disk values. Comparing them requires reading the numbers, while each arc uses substantial space. A compact set of bars would make those values easier to compare. Elsewhere, different values share the same red treatment, making the threshold definition important to understanding the result. The examples also mix color ramps, sparklines, and threshold bands.
Show 3 more examples Hide the rest

Grafana

Examples of panel grids, shared selectors, stat tiles, and chart configuration.

Examples / Stats, light theme September 10, 2026 Grafana Play (signed out; ?theme=light) dense · light · desktop-web
This light-theme capture shows the same stat-panel options as the dark version. Several value colors become pale against white, especially pink and orange. Whole-tile fills retain a different relationship between text and background, while the faint sparkline areas are harder to see. The pair is useful for checking each treatment on both backgrounds rather than assuming a theme switch preserves readability.
Examples / Stats September 10, 2026 Grafana Play (signed out; no version string exposed) dense · dark · desktop-web
Grafana’s stat showcase compares value colors, background fills, layouts, and text options. Most examples emphasize presentation without adding a comparison value or clear reference point. The No text panel uses color alone, leaving cells without labels or numbers. These are useful demonstrations of settings, but a working dashboard needs enough context to explain each value and state.
  • KPI tile A label, value, unit, and sparkline appear without an explicit comparison.
  • Dark-first data palette The dark theme makes these value colors more prominent than in the light capture.
  • Sparkline Sparklines use individual scales, so row-to-row comparison needs care.
  • Semantic status color Whole-tile color strongly emphasizes every value in this group.
  • Grayscale with alerts Multiple strong colors compete for attention.
  • KPI tile Values appear without labels explaining what they measure.
  • Semantic status color The cells have no text, leaving color as the only visible cue.
  • Header KPI strip Consistent label and value positions make the tile row easier to scan.

Home Assistant

Room-based card layouts combine household device states with controls.

Demo dashboard September 10, 2026 Home Assistant public demo (signed out) medium · light · desktop-web
Cards are grouped by rooms such as Living room, Kitchen, and Study. States are written in words, with icon color providing a second cue. Section headers add useful room summaries, such as temperature or meeting status. The page also contains controls, including lighting sliders and thermostat buttons, so people can act in the same place they check the state.