annotation builder pipes them into the spec like any other feature.
Because they’re a spec feature, annotations re-resolve on every compile: panel-anchored ones re-flow when the chart resizes, and data-anchored ones move with the observation they’re pinned to.
Anchoring
Every annotation is positioned by an anchor that describes a relationship to the graph, not a fixed pixel. There are two frames:- Panel — a fraction of the plot rectangle,
[0, 1]from the top-left.{ anchorType: 'panel', x: 0.5, y: 0 }is the top-centre. Panel anchors don’t snap to data, so they hold their place as the data changes. - Observation — pinned to a single data point by its
anchorValue(the x-value) and optionalgroupValue(the series). The annotation follows that observation wherever it lands.
{ anchorType: 'panel', x, y, width, height } — and point/observation annotations take a single anchor. An observation anchor also accepts an align (which edge or corner of the observation to attach to) and an offset (a nudge in panel fractions or pixels).
On a combo chart, more than one layer can hold the same (anchorValue, groupValue) pair — bars and a trend line both have a value at 'Jun'. Name the layer you mean and pass its id as layerId:
layerId and the anchor resolves against the first layer that matches. An id no layer carries drops that annotation with a warning rather than silently moving it.
The annotation kinds
Each method onannotation appends one callout. Multiple calls of the same kind accumulate.
Difference arrow
A difference arrow spans two observations and labels the change between them — you choose what the label measures:annotation.arrow(), which is a plain arrow between two positions you specify — it doesn’t read any data.
Shaded region
zOrder decides whether a shape or image sits behind the data ('background', the usual choice for a wash of color) or in front of it ('foreground').
Text
A text annotation takes a rich-text node and a top-left point anchor.width is a fraction of the plot width; height follows the content:
Image
Place an image in a panel region.fit decides how it scales inside the box — 'fill' stretches, 'contain' letterboxes, 'cover' crops to fill:
zOrder ('background' or 'foreground') and an opacity in [0, 1].
Sticker
A sticker pins a built-in emoji-like image to a single observation. Give it asticker id from the catalogue and an observation anchor — it then travels with its data point through re-sorts and filters:
Related
- Reference lines — for marking a constant value rather than a region
- Content — the rich-text node shape used by text and comment annotations
- Mappings & aesthetics — the series and x-values an observation anchor names

