Make goal charts from text

Doubloons Plundered ($)64%6.4k10k
Doubloons Plundered ($)64%6.4k10k
goal Doubloons Plundered ($)
now 6400
target 10000

Overview

A goal chart is a single progress-toward-a-target reading: one now value against one target, answering “how close am I?” at a glance. Reach for it for a KPI tile, a fundraising thermometer, a quarterly quota, or a completion percentage — anywhere one number racing toward one goal is the whole story. It has no time axis, no series, and no milestones.

When to use

  • goal — one number racing toward one target, and “how close am I?” is the whole question.
  • countdown — the thing running out is time, not a quantity. A deadline drawn as a goal bar implies you’re 60% done when you’re really 60% out of timegoal has no time dimension at all.
  • bar — you’re comparing several numbers against each other rather than one number against its target.
  • funnel — you have several sequential stages each losing volume, not one aggregate reading.
  • gantt — you want the task list and dates behind the percentage, not the single ”% there” reading.
  • kanban — you’re tracking many individual items sitting in various stages rather than one rolled-up number.
  • line — the point is the value’s trend over time.

The three faces

The face is the heart of a goal chart. The same now/target pair can be drawn three ways — progress bar, thermometer, or gauge — and the one you pick sets the whole mood of the reading. Choose the face first, then fill in the numbers. Select it with a bare flag on its own line (no colon, no value); omit the flag for the default bar.

Progress bar (default)

The workhorse. A horizontal rounded fill — compact, honest, unmistakable. Reach for it for a plain KPI tile, a dashboard cell, or anywhere the number just needs to read at a glance. No flag needed.

Doubloons Plundered ($)64%6.4k10k
Doubloons Plundered ($)64%6.4k10k
goal Doubloons Plundered ($)
now 6400
target 10000

Thermometer

A vertical tube with a bulb; the column climbs as you fill it. This is the “fill it up” face — fundraising drives, tank/barrel levels, a stretch goal you’re pouring into. It reads as a physical thing filling, which is why the classic charity fundraiser thermometer works.

025TARGET5034Grog Barrel Fill (L)68%
025TARGET5034Grog Barrel Fill (L)68%
goal Grog Barrel Fill (L)
thermometer
now 34
target 50

Gauge

A semicircular dial with a needle sweeping an arc. This is the “how’s it running” face — speedometers, utilization, capacity, quota attainment. The needle position gives an instant instrument-panel read, and it pins at the max when you blow past the target.

640255075TARGET100Voyage Quota (chests)
640255075TARGET100Voyage Quota (chests)
goal Voyage Quota (chests)
gauge
now 64
target 100

All three faces read the same now/target pair — the flag only changes the drawing, never the meaning. The percent, the traffic-light color, the labels, and the note all behave identically across faces.

FlagFaceReach for it when…
(none)Progress bara plain KPI / dashboard number.
thermometerThermometerfundraising or a “fill it up” framing.
gaugeGaugea speedometer / utilization / quota feel.

Values (now / target)

goal Title with unit, e.g. "Marathon Fund ($)"
// now — the current value; space-separated, no colon
now 6400
// target — the goal value; must be > 0
target 10000

The first line declares the chart type and a title. Put the unit in the title — there’s no format or currency directive. now and target are space-separated key value directives (like gantt’s start-date): no colon. Values accept _ separators (10_000) but not thousands commas.

The percent is simply now / target. Values auto-compact for display (6.4k, 1.2M).

Color

By default the fill is auto traffic-light by completion: < 50% red, 50–80% orange, ≥ 80% green (over-target stays green) — so the color already reads the health of the number. Precedence:

  1. A trailing color word on the title line (goal Marathon Fund ($) green) always wins.
  2. Otherwise the auto band color (needs a target).
  3. no-auto-color disables the bands and falls back to the flat palette series color.

The fill is a light 25% tint of the resolved color; add fill-solid for full saturation.

Note

Add an optional note to caption the number with context — who’s still owed, what’s left, a rallying cry. Two forms: inline (note Still waiting on three crews) or a block header on its own line followed by an indented body:

025TARGET5034Grog Barrel Fill (L)68%Great job, crew! Grog's flowing. Still waiting on tallies from:Seattle — first mate says "soon"Columbus — you're almost there!Top us off to 50L and the shanties start.
025TARGET5034Grog Barrel Fill (L)68%Great job, crew! Grog's flowing. Still waiting on tallies from:Seattle — first mate says "soon"Columbus — you're almost there!Top us off to 50L and the shanties start.
goal Grog Barrel Fill (L)
thermometer
now 34
target 50
note
  **Great job, crew!** Grog's flowing. Still waiting on tallies from:
  - *Seattle*  first mate says "soon"
  - **Columbus**  you're almost there!
  Top us off to `50L` and the shanties start.

The body supports simple inline markdown (**bold**, *italic*, `code`), - /* bullets, and blank-line gaps. It renders in the left column for thermometer/gauge and under the bar for the default face. no-notes hides it even when authored — that plural spelling is canonical; the singular no-note is accepted as a legacy alias and does the same thing.

Over-target & edge cases

  • Over target (now > target): the fill clamps at 100% but the % label stays truthful (120%); the gauge needle pins at the max.
  • Negative now: the fill clamps to 0%, the label stays honest.
  • Missing / non-positive target: flagged as an error, but the chart still renders a 0% shell.
  • Missing now: treated as 0 with a warning.

Directives

DirectiveEffect
thermometer / gaugeSelect the render face (bare flag).
now <n>Current value (required, ≥ 0).
target <n>Goal value (required, > 0).
note <text> / note + bodyFree-text caption (inline or indented block).
no-percentHide the % label.
no-valueHide the raw now / target label.
fill-solidFull-saturation fill instead of the 25% tint.
no-titleHide the banner title.
no-notesSuppress the note block even if authored.
no-auto-colorDisable the traffic-light bands; use palette color.

Tips

  • Pick the face first — it carries more meaning than any directive. Bar for a KPI, thermometer for “fill it up”, gauge for “how’s it running”.
  • Keep the unit in the title (($), (L), (chests)) — a goal has no unit directive.
  • One value only: a goal has no children. Indented lines are ignored with a warning — except an indented note block body.
  • Let the traffic-light color do the work: red/orange/green already signals whether the number is healthy. Only pin a trailing color or add no-auto-color when the band coding fights your dashboard.
  • Reach for goal when one number chases one target; use line for a trend and countdown for a deadline.

Appearance

Every chart accepts the universal appearance directives:

DirectiveEffect
fill-tintSoft tinted fills (default).
fill-solidSaturated solid fills.
fill-outlineOutline only, no fill.
no-titleHide the title line.
no-legendHide the legend.

Colors come from the active palette — see Colors. Set the palette and light/dark theme at render time with --palette <name> and --theme light|dark|transparent.

Next