geom.rule(), layered into the spec with its own value and style.
A horizontal goal line
Bind the rule to a constanty with aes: { y: { value } }. The { value } form is a constant mapping — it pins the aesthetic to a literal instead of a column:
The label
A rule’sparams carry its label and nothing else:
string
Optional inline text drawn alongside the line. Omit to draw a bare line.
'start' | 'end'
default:"start"
Anchors the label at the start or end of the line.
coord.flip() a rule runs vertically, where 'end'
puts the label at the top of the line rather than at its foot. ToggleGoalLineCommand and
SetStatLineCommand pick that way round for you when they build a line under a flipped coord.
Painting the line
Stroke and label typography come from the stylesheet, the same as every other mark.style.geom.rule() takes color, strokeWidth and lineType; style.geom.rule.label()
takes fontFamily, fontSize, fontWeight and lineHeight. Both take a { layer } option, so a
single rule can be painted without touching the others:
ruleColor token, so a bare
geom.rule() draws a dashed line. Redefine ruleColor through styles({ tokens: { ruleColor } })
to recolour every rule, goal line and average line at once.
Vertical lines
Mark a constant along the x-axis withaes: { x: { value } } instead:
A vertical rule requires a numeric x-axis — it marks a constant x-value,
which only has meaning when x is continuous. Categorical and date x-axes
support horizontal rules only. A rule reads a scalar from exactly one axis, so
supplying both
x and y is an INVALID_RULE_MAPPING error, as is supplying
neither.Multiple rules
Rules compose like any other layer, and paint in spec order — a rule added aftergeom.bar() draws in front of the bars. Stack as many as you need:
id on the layer is what a { layer }-scoped entry
addresses.
Flipped and secondary axes
A rule tracks the data space, not the screen. Undercoord.flip() a { y: { value } } rule still marks a constant y — the renderer paints it as a vertical line because the y-axis now runs horizontally. To pin a rule to a secondary axis, add yScaleType: 'secondary':
An average line
A rule’s value can also be computed. Give itstat.mean() instead
of a constant and the line lands at the layer’s average:
Editing a rule at runtime
Four commands cover reference lines in an editing UI:Related
- Styling — the stylesheet entries that paint a rule and its label
- Statistics —
stat.mean()and the fitted trends a rule can carry - Mappings & aesthetics — the
{ value }constant form - Scales — how the rule value extends the auto-domain
- Coordinate systems — rules under
coord.flip()

