Skip to content

Charts

Vee draws six kinds of chart, and a plugin reaches them through three different output formats. This page is the index: what exists, how to emit it, and what each one takes. The prose that explains any given chart lives with its surface — Plugin authoring for the menu bar, Widgets for the desktop — and each row below links into it.

Every chart is drawn natively. There is no WebView anywhere in Vee, and no charting library: an inline chart is an AppKit or SwiftUI row view, a popover is Swift Charts, and a widget is WidgetKit.

The matrix

Where each chart comes from. The same chart is spelled differently depending on which output format a plugin uses; a dash means that surface cannot draw it.

ChartText protocolJSON menu outputWidget card
Sparkline — A line/area series over time.sparkline=1,2,3"sparkline": [1,2,3]node type "sparkline" with "values", or the "trend" template's "trend"
Progress bar — One capsule bar filled to a fraction.progress=0.72 or progress=23.65,100"progress": 0.72"progress" on the card, the "gauge" template's fill
Pie — A filled circle divided into sectors.pie=45,30,25"chart": {"kind": "pie", "values": […]}
Donut — A pie with the middle punched out; the hole carries the total.donut=512,256,128"chart": {"kind": "donut", "values": […]}
Stacked bar — One horizontal bar whose segments lie end to end.stackedbar=60,25,15"chart": {"kind": "stackedbar", "values": […]}
Widget gauge — A native WidgetKit gauge.node type "gauge" with "value", or the "gauge" template

What each chart takes. One pair sizes any of them: accessoryw= and accessoryh=, whichever accessory the row carries. The per-chart names (sparklinew=, chartw=, progressw= and their heights) still parse but are deprecated, and do nothing when aimed at a chart the row does not draw.

ChartOptionsDefault sizeFull widthLimitsClick
Sparklinesparklinew, sparklineh, sparklinecolor, accessory, color90×20 pointsaccessoryw=fullWidget sparkline nodes are truncated at 256 points; non-finite entries are dropped.Yes — a full Swift Charts line/area chart.
Progress barprogressw, progressh, progresstrackcolor, accessory, color120×6 pointsaccessoryw=fullClamped to 0…1; a non-finite value is dropped.No — the bar is the whole surface.
Piechartw, charth, chartlabels, chartcolors, accessory24pt diameterNot supported — refused with a diagnostic.8 segments (the tail folds into 'Other'); size clamped to 8–200 points.Yes — full size with a labelled legend.
Donutchartw, charth, chartlabels, chartcolors, accessory24pt diameterNot supported — refused with a diagnostic.8 segments (the tail folds into 'Other'); size clamped to 8–200 points.Yes — full size with a labelled legend.
Stacked barchartw, charth, chartlabels, chartcolors, accessory110×12 pointsaccessoryw=full — the only chart kind that accepts it.8 segments (the tail folds into 'Other'); size clamped to 8–200 points.Yes — full size with a labelled legend.
Widget gaugegauge_style, style.tintgauge_style: linearNot applicable — a circular gauge takes no size knob.value clamped to 0…1.No — widgets have no popover surface.

Where a chart appears

A menu-bar chart occupies the row’s accessory slot — the same slot for all of them, which is why a row draws one chart and not three. When a line carries more than one, the last one wins in the order progress=sparkline= → share chart. accessory=leading moves it to the other edge of the row.

Most of them are also clickable. A sparkline or a share chart opens a Liquid Glass popover with the same data at full size — the legend that chartlabels= feeds is only visible there, since a menu row has no room for it. A progress bar has no popover: the bar already shows everything it has.

Sizing

Each chart is sized by knobs named after itself:

ChartWidthHeightStretch to the row
Sparklineaccessoryw=accessoryh=accessoryw=full
Progress baraccessoryw=accessoryh=accessoryw=full
Pie, donutaccessoryw= or accessoryh= — either sizes bothnot supported
Stacked baraccessoryw=accessoryh=accessoryw=full
Slideraccessoryw=— its height is its control sizenot supported

full stretches a chart to the width the row actually has, rather than a fixed number of points. It exists because a menu is as wide as its widest row, so a fixed width cannot fill a menu whose width some other row decides. It applies only to charts with free width: a pie and a donut are circles, whose width is their diameter, so stretching one would make the row as tall as the menu is wide. Vee refuses it there and says so in a diagnostic rather than guessing.

Choosing one

  • A value over time — load average, request rate, temperature — is a sparkline.
  • A single value against a maximum — disk used, battery, quota — is a progress bar, or a gauge in a widget.
  • A total that divides into categories — disk by folder, spend by department — is a share chart. Pie, donut, and stacked bar read the same numbers and differ only in shape, so switching between them needs no change to the values, labels, or colors.

Share charts carry at most eight segments, because the categorical palette has eight slots and a ninth would have to reuse a hue — exactly the ambiguity a share chart must not have. A longer series is folded, not truncated: the leading segments are kept and the rest are summed into a final Other, so the shares still add up to the plugin’s own total.

Colors

A share chart’s segments take a fixed eight-slot categorical palette, assigned in order and never cycled — slot n always means “the nth segment”, so a series that shrinks does not repaint the segments that survived. Each slot is a light/dark pair chosen against its own mode’s background rather than one color flipped, and the set is validated for colorblind separation including the first-to-last pair, which a pie makes adjacent by wrapping around.

chartcolors= overrides it positionally, and a blank or unrecognised entry keeps that segment’s palette slot rather than shifting every later color left — so chartcolors=,,red recolors only the third segment.

Color is never the only channel: every chart carries an accessibility summary reading its segments and their shares aloud, so the data survives for a reader who cannot see the difference.

See also

  • Plugin authoring — the menu-bar charts in full, with worked examples.
  • Widgets — the gauge and sparkline layout nodes, and the trend and gauge templates.
  • JSON output — the structured spelling of every chart.
  • Plugin SDKs — emitting charts from TypeScript, Python, or Go.