Appearance
Level lines
A level line is a reference line at a fixed value on a range axis. Config lives at annotations.levelLines.<id>.
Unlike arrows, simple level lines are reasonable to hand-author. For label snap / custom number formats, authoring in the editor then exporting is still easiest.
Minimal example
js
annotations: {
levelLines: {
target: {
id: 'target',
value: 70,
color: '#1A1A1A',
width: 1.5,
dashArray: '6,4',
rangeAxis: 'primaryRange',
labelFontFamily: 'Arial',
labelFontSize: 10,
labelFontColor: '#000000',
},
},
}Solid stroke: prefer dashArray: '' (same convention as gridlines).
Fields
| Field | Type | Notes |
|---|---|---|
id | string | Should match the map key |
value | number | Position on the range axis |
color | string | Line color |
width | number | Stroke width (px) |
dashArray | string | Dash pattern; '' = solid |
rangeAxis | 'primaryRange' | 'secondaryRange' | Which scale measures value (default primary) |
labelPositionIndex | number | null | Horizontal snap for the value label; omit/null for auto edge placement |
labelFontFamily / labelFontSize / labelFontColor | string / number / string | Per-line label chrome |
labelNumberFormatSpec | object | { mode: 'custom'|'linked', source?, customFormat } — see Number formats |
Shared bag option: annotations.levelLines.fontFamily can set a default label font for all lines.
Chart types
Common on stacked / clustered / 100% bar, waterfall, line, stacked area, scatter, combo, and bar mekko. Orientation-aware: the line follows the range axis (horizontal line on a vertical chart, and the remapped equivalent when orientation flips).
Live patches
annotations deep-merges for nested story maps in many host paths, but the safest pattern for one-off adds is still: read getChartData(), merge the new id into levelLines, then setChartData with the updated map (or replace the whole annotations.levelLines object you want).
See also Arrows.