Home

Figure Overlay Components

Stencila's figure overlays let you annotate images and charts with standard SVG. That works, but raw SVG is verbose — a simple callout with a curved arrow and arrowhead definition takes 8–15 lines, and small coordinate mistakes produce arrows pointing nowhere or invisible markers.

Overlay components solve this. You write high-level elements like <s:callout>, <s:scale-bar>, and <s:arrow> inside your svg overlay block, and Stencila expands them to standard SVG during compilation. The source you write is preserved in the document; the compiled SVG is stored separately and used for rendering.

Components reduce a typical annotation from 15+ lines of raw SVG to 1–3 elements. They handle the geometry, arrowhead definitions, label positioning, and coordinate math automatically — making overlays more readable for authors and more reliable for LLM agents generating annotations.

Note

Overlay components are fully backward-compatible. You can mix s: components and standard SVG freely in the same overlay. Any existing overlay without s: elements works exactly as before.

Namespace

All components use the s: namespace prefix. Declare the namespace on your <svg> element:


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:callout x="300" y="150" label="Hello, components!" shape="pill"/>
</svg>
```

A figure annotated with a single overlay component.

:::
Hello, components!

Figure 1: A figure annotated with a single overlay component.

How it works

When your document is compiled, Stencila processes each svg overlay block:

  1. Scans for <s:anchor> definitions and generates auto-anchors from the viewBox

  2. Expands every <s:*> element into standard SVG (text, paths, shapes)

  3. Detects references to built-in definitions (arrowheads, marker symbols) and injects only the ones actually used

  4. Stores the compiled SVG separately — your source is preserved unchanged

Standard SVG elements are passed through untouched. If an overlay contains no s: elements and no references to built-in defs, it is used as-is with no compilation step.

Component reference

Overview

The component library provides 16 elements plus a positioning primitive, organized into eight categories:

CategoryComponentsPurpose
Arrows & connectors<s:arrow>Directional lines and curves between two points
Labels & callouts<s:callout>, <s:badge>Text labels with optional backgrounds and leader lines
Measurement & scale<s:scale-bar>, <s:dimension>, <s:angle>Scale bars, dimension lines, and angle arcs
Brackets & braces<s:brace>, <s:bracket>Curly braces and square/round brackets for grouping
Region of interest<s:roi-rect>, <s:roi-ellipse>, <s:roi-polygon>, <s:spotlight>Highlighted regions and inverse-highlight masks
Point markers<s:marker>, <s:crosshair>Symbol glyphs and reticles at specific locations
Emphasis & focus<s:halo>Glowing rings to draw attention to features
Orientation & reference<s:compass>Compass roses and orientation indicators
Positioning<s:anchor>Named anchor points for relative positioning

Common attributes

Most components share a consistent set of attributes for positioning, labeling, and styling.

Positioning

Components are positioned using direct coordinates, anchor references, or a combination:

AttributeDescription
x, yDirect coordinates in viewBox units
atAnchor reference for single-point components (e.g., at="#peak" or at="#s:bottom-left")
fromStart anchor reference for two-point components (e.g., from="#peak")
dx, dyOffset from the anchor or direct position
toTarget anchor reference for leader lines or endpoints
to-x, to-yDirect target coordinates

Single-point components like <s:marker>, <s:compass>, and <s:halo> use at — meaning "place this here". Two-point components like <s:arrow> and <s:brace> use from/to — meaning "draw from here to there".

Colors

All components support stroke, fill, and text attributes. If omitted, the color attribute is used as a shorthand for all three; if none are set, a component-appropriate default is used (currentColor for strokes, white for label backgrounds, currentColor for marker fills, currentColor for text). Arrow markers automatically match the stroke color of the line they are attached to.

AttributeFallbackDefaultDescription
strokecolorcurrentColorStroke color applied to all parts of the component
fillcolorvaries by componentFill color (e.g. background of badges, callouts, marker symbols)
textcolorcurrentColorLabel text color
colorcurrentColorShorthand that sets stroke, fill, and text
<s:arrow x="100" y="100" to-x="300" to-y="200" stroke="crimson"/>
<s:callout x="300" y="160" label="n = 1,024" shape="pill" fill="#e8f4fd" stroke="#4a90d9" text="#1a5276"/>
<s:marker at="#peak" symbol="circle" color="#2563eb"/>
<s:dimension x="50" y="200" to-x="250" to-y="200" label="4.2 cm" stroke="gray" text="navy"/>

Labels

AttributeValuesDescription
labelAny textShort text content displayed by the component
label-positionabove, below, left, right, centerWhere the label is placed relative to the component (available values vary by component)

Connectors

Components that draw lines between two points share these:

AttributeValuesDefaultDescription
curvestraight, quad, cubic, elbowstraightPath shape between start and end
cornerhorizontal-first, vertical-firsthorizontal-firstBend direction for curve="elbow"
tipend, start, both, noneendWhich end(s) get arrowheads
tip-styleAny #s:arrow-* ids:arrow-closedArrowhead style from the built-in defs library

SVG pass-through

Standard SVG presentation attributes like stroke-width, opacity, font-size, and stroke-dasharray are passed through to the generated SVG unchanged. Use these when you need a specific style that differs from theme defaults:

<s:arrow x="100" y="100" to-x="300" to-y="200" stroke="crimson" stroke-width="3"/>

Built-in definitions

The component library includes a set of reusable SVG marker and symbol definitions. These are automatically injected when referenced — only the definitions you actually use are included in the compiled output (tree-shaking).

Arrow markers

Use with tip-style on <s:arrow> and <s:callout>, or with marker-end/marker-start on raw SVG elements:

IdDescription
s:arrow-closedFilled triangle (default arrowhead)
s:arrow-openOpen chevron
s:arrow-dotFilled circle end
s:cap-linePerpendicular cap line (used by <s:dimension>)

Marker symbols

Use with symbol on <s:marker>, or reference directly with <use href="#s:marker-*">:

IdDescription
s:marker-circleCircle
s:marker-cross× cross (rotated plus)
s:marker-diamondDiamond (rotated square)
s:marker-pinMap-style pin
s:marker-plus+ plus (axis-aligned cross)
s:marker-squareSquare
s:marker-starStar
s:marker-triangleTriangle (pointing up)
s:marker-triangle-downTriangle (pointing down)

You can also reference any built-in definition from standard SVG elements using url(#id) or href="#id" syntax:


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns="http://www.w3.org/2000/svg">
  <line x1="100" y1="250" x2="300" y2="50" marker-end="url(#s:arrow-closed)"/>
  <text x="310" y="45">Using a built-in arrowhead</text>
</svg>
```

A standard SVG line using a built-in arrowhead definition — no component needed, just the `url(#s:arrow-closed)` reference.

:::
Using a built-in arrowhead

Figure 2: A standard SVG line using a built-in arrowhead definition — no component needed, just the url(#s:arrow-closed) reference.

Anchors and positioning

Named anchors

Define reusable named points with <s:anchor>. Other components can reference them with from and to attributes, using offsets (dx, dy) for relative positioning. Anchors are stripped from the compiled output — they exist only for coordinate resolution.


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:anchor id="feature" x="200" y="120"/>
  <s:callout from="#feature" dx="150" dy="-60" label="Important" to="#feature"/>
  <s:roi-rect from="#feature" dx="-40" dy="-30" to-x="260" to-y="170" stroke-style="dashed"/>
</svg>
```

An anchor at (200, 120) referenced by a callout and a dashed ROI rectangle. The callout label is offset 150px right and 60px up from the anchor; its leader line points back to the anchor.

:::
Important

Figure 3: An anchor at (200, 120) referenced by a callout and a dashed ROI rectangle. The callout label is offset 150px right and 60px up from the anchor; its leader line points back to the anchor.

Auto-anchors

Stencila automatically generates anchor points from the viewBox dimensions. These are available without any <s:anchor> declaration:

AnchorPosition
#s:centerCenter of the viewBox
#s:origin, #s:top-leftTop-left corner (viewBox origin)
#s:top-rightTop-right corner
#s:bottom-leftBottom-left corner
#s:bottom-rightBottom-right corner
#s:top-centerTop edge midpoint
#s:bottom-centerBottom edge midpoint
#s:mid-leftLeft edge midpoint
#s:mid-rightRight edge midpoint

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:callout from="#s:center" label="Center" shape="pill"/>
  <s:badge from="#s:top-left" dx="40" dy="30" label="A"/>
  <s:badge from="#s:top-right" dx="-40" dy="30" label="B"/>
</svg>
```

Auto-anchors in action: a callout at the center and badges near the top corners, all positioned relative to viewBox-derived anchors.

:::
Center A B

Figure 4: Auto-anchors in action: a callout at the center and badges near the top corners, all positioned relative to viewBox-derived anchors.

Arrows & connectors

The <s:arrow> component draws directional lines and curves between two points. It is a path-first component — the line is the primary visual, with an optional label along the path.

Required: start position (x/y or from) and end position (to-x/to-y or to).

AttributeValuesDefaultDescription
x, ycoordinatesStart position
fromanchor refStart position from anchor
to-x, to-ycoordinatesEnd position
toanchor refEnd position from anchor
dx, dyoffset0Offset from start anchor
curvestraight, quad, cubic, elbowstraightPath shape
cornerhorizontal-first, vertical-firsthorizontal-firstBend direction for elbow curves
tipend, start, both, noneendArrowhead placement
tip-stylemarker ids:arrow-closedArrowhead style
labeltextOptional label at midpoint
label-positionabove, belowaboveLabel offset direction relative to the line
label-anglealong, horizontal, vertical, or degreesalongLabel rotation: along follows the line angle, horizontal keeps text level, vertical rotates 90°

Straight arrows


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:arrow x="80" y="60" to-x="250" to-y="180" label="Default"/>
  <s:arrow x="280" y="240" to-x="450" to-y="80" tip="both" label="Both tips"/>
  <s:arrow x="460" y="240" to-x="560" to-y="60" tip-style="s:arrow-open" label="Open"/>
</svg>
```

Three straight arrows: default single arrowhead, double-ended, and open chevron style.

:::
Default Both tips Open

Figure 5: Three straight arrows: default single arrowhead, double-ended, and open chevron style.

Curved arrows


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:arrow x="50" y="250" to-x="200" to-y="50" curve="quad" label="Quadratic"/>
  <s:arrow x="230" y="250" to-x="380" to-y="50" curve="cubic" label="Cubic"/>
  <s:arrow x="420" y="80" to-x="560" to-y="240" curve="elbow" label="Elbow"/>
</svg>
```

Three curve types: quadratic Bézier, cubic Bézier, and right-angle elbow connector.

:::
Quadratic Cubic Elbow

Figure 6: Three curve types: quadratic Bézier, cubic Bézier, and right-angle elbow connector.

Elbow corners


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:arrow x="80" y="60" to-x="280" to-y="240" curve="elbow" corner="horizontal-first" label="H-first"/>
  <s:arrow x="350" y="60" to-x="550" to-y="240" curve="elbow" corner="vertical-first" label="V-first"/>
</svg>
```

Elbow connectors: `horizontal-first` bends horizontal then vertical; `vertical-first` bends vertical then horizontal.

:::
H-first V-first

Figure 7: Elbow connectors: horizontal-first bends horizontal then vertical; vertical-first bends vertical then horizontal.

Labels & callouts

Callout

The <s:callout> component places text at a position, optionally with a background shape and a leader line pointing to a target. It is the workhorse annotation element — text-first with an optional pointer.

Required: position (x/y or from), label.

AttributeValuesDefaultDescription
x, ycoordinatesLabel position
fromanchor refLabel position from anchor
dx, dyoffset0Offset from anchor
labeltextText content
shapenone, rect, pill, circlenoneBackground shape around the text
to, to-x/to-ytargetLeader line target (omit for standalone label)
tip-stylemarker ids:arrow-closedArrowhead on leader line
curvestraight, quad, cubic, elbowstraightLeader line path shape

Standalone labels and shapes


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:callout x="100" y="60" label="Plain text"/>
  <s:callout x="300" y="60" label="Rectangle" shape="rect"/>
  <s:callout x="500" y="60" label="Pill shape" shape="pill"/>
  <s:callout x="300" y="160" label="n = 1,024" shape="pill" fill="#e8f4fd" stroke="#4a90d9" text="#1a5276"/>
</svg>
```

Callouts without leader lines: plain text, rectangle background, pill background, and a styled pill with custom fill, stroke, and text colors.

:::
Plain text Rectangle Pill shape n = 1,024

Figure 8: Callouts without leader lines: plain text, rectangle background, pill background, and a styled pill with custom fill, stroke, and text colors.

Callouts with leader lines


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:anchor id="spot" x="150" y="200"/>
  <s:callout from="#spot" dx="120" dy="-120" label="Feature A" to="#spot"/>
  <s:callout x="450" y="50" label="Peak" to-x="350" to-y="180" shape="rect" curve="quad"/>
</svg>
```

Two callouts with leader lines: one using an anchor reference, another with direct coordinates and a quadratic curve.

:::
Feature A Peak

Figure 9: Two callouts with leader lines: one using an anchor reference, another with direct coordinates and a quadratic curve.

Badge

The <s:badge> component is a compact annotation token — always displayed with a pill-shaped background, smaller font, and no leader line. Use badges for short identifiers like panel labels, numbered markers, or channel names.

Required: position (x/y or from), label.

AttributeValuesDefaultDescription
x, ycoordinatesPosition
fromanchor refPosition from anchor
dx, dyoffset0Offset from anchor
labeltextShort text (1–4 characters ideal)

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:badge from="#s:top-left" dx="30" dy="25" label="GFP"/>
  <s:badge x="300" y="150" label="Ch2"/>
  <s:badge from="#s:bottom-right" dx="-60" dy="-35" label="DAPI"/>
</svg>
```

Three badges using a mix of auto-anchor and direct coordinate positioning: a fluorescence channel name, a short identifier, and a stain label.

:::
GFP Ch2 DAPI

Figure 10: Three badges using a mix of auto-anchor and direct coordinate positioning: a fluorescence channel name, a short identifier, and a stain label.

Tip

Use <s:badge> for short identifiers (A, B, ①, DAPI). Use <s:callout> for explanatory text, longer labels, or anything that needs a leader line.

Measurement & scale

Scale bar

The <s:scale-bar> component renders a calibrated bar with end caps and a label — standard in microscopy, maps, and technical imaging.

Required: position (x/y or at), length.

AttributeValuesDefaultDescription
x, ycoordinatesPosition (left/top of bar)
atanchor refPosition from anchor
dx, dyoffset0Offset from anchor
lengthnumberBar length in viewBox units
labeltextScale text (e.g., "20 μm")
label-positionabove, belowbelowLabel placement
sidebottom, top, left, rightbottomOrientation: left/right produce vertical bars

Horizontal scale bar


::: figure {pad="0 0 56 0"}

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 356" xmlns:s="https://stencila.io/svg">
  <s:scale-bar at="#s:bottom-left" dx="40" dy="-30" length="130" label="20 μm"/>
</svg>
```

A microscopy-style scale bar positioned relative to the bottom-left auto-anchor using bottom padding.

:::
20 μm

Figure 11: A microscopy-style scale bar positioned relative to the bottom-left auto-anchor using bottom padding.

Scale bar variations


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:scale-bar x="40" y="270" length="150" label="50 μm"/>
  <s:scale-bar x="300" y="270" length="150" label="100 nm" label-position="above"/>
  <s:scale-bar x="560" y="40" length="200" label="1 mm" side="right"/>
</svg>
```

Three scale bars: default (label below), label above, and a vertical bar on the right.

:::
50 μm 100 nm 1 mm

Figure 12: Three scale bars: default (label below), label above, and a vertical bar on the right.

Dimension line

The <s:dimension> component draws a measurement line between two points with perpendicular end bars, extension lines, and a label. Use it for engineering-style dimensional annotations.

The side attribute controls which direction the dimension line is offset, relative to the directional vector from from to to. For a rightward vector, above projects upward; for a downward vector, above projects to the viewer's right. This follows the same perpendicular-normal convention as <s:bracket> and <s:brace>.

Required: start position (x/y or from) and end position (to-x/to-y or to).

AttributeValuesDefaultDescription
x, ycoordinatesStart point
fromanchor refStart point from anchor
to-x, to-ycoordinatesEnd point
toanchor refEnd point from anchor
labeltextMeasurement text (e.g., "4.2 cm")
label-positionabove, belowaboveLabel placement on the dimension line
label-anglealong, horizontal, vertical, or degreesalongLabel rotation: along follows the line angle, horizontal keeps text level, vertical rotates 90°
sideabove, below, left, rightaboveWhich side the offset dimension line appears
backgroundcolor or nonenoneSemi-transparent pill behind the label for legibility on busy backgrounds

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:dimension x="100" y="100" to-x="400" to-y="100" label="30 cm" side="above"/>
  <s:dimension x="450" y="60" to-x="450" to-y="240" label="18 cm" side="below"/>
</svg>
```

Horizontal and vertical dimension lines showing measured extents with perpendicular end bars.

:::
30 cm 18 cm

Figure 13: Horizontal and vertical dimension lines showing measured extents with perpendicular end bars.

Angle arc

The <s:angle> component draws an arc showing the angle between two lines meeting at a vertex. Use it for geometric annotations showing angles between features.

Required: vertex position (x/y or at), from, and to.

AttributeValuesDefaultDescription
x, ycoordinatesVertex position
atanchor refVertex position from anchor
fromanchor refFirst ray endpoint
from-x, from-ycoordinatesFirst ray endpoint (direct)
to, to-x/to-ytargetSecond ray endpoint
rnumber30Arc radius in viewBox units
labeltextLabel at arc midpoint (e.g., "45°", "θ")

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:anchor id="vertex" x="200" y="240"/>
  <s:anchor id="ray1" x="450" y="240"/>
  <s:anchor id="ray2" x="350" y="60"/>

  <!-- Draw the ray lines for context -->
  <line x1="200" y1="240" x2="450" y2="240" stroke="currentColor" stroke-dasharray="4 3"/>
  <line x1="200" y1="240" x2="350" y2="60" stroke="currentColor" stroke-dasharray="4 3"/>

  <!-- Angle arc with label -->
  <s:angle from="#ray1" to="#ray2" x="200" y="240" r="50" label="θ"/>
</svg>
```

An angle arc showing the angle between two rays from a vertex, with dashed reference lines drawn in raw SVG.

:::
θ

Figure 14: An angle arc showing the angle between two rays from a vertex, with dashed reference lines drawn in raw SVG.

Brackets & braces

Brackets

The <s:bracket> component draws a square or round bracket between two points. Use it for grouping annotations, significance brackets (e.g., p < 0.05), or spanning labels.

Required: start position (x/y or from) and end position (to-x/to-y or to).

AttributeValuesDefaultDescription
x, ycoordinatesStart point
fromanchor refStart point from anchor
to-x, to-ycoordinatesEnd point
toanchor refEnd point from anchor
sideabove, below, left, rightaboveWhich side the bracket opens toward
depthnumber8% of lengthBracket depth perpendicular to the endpoint line
variantsquare, roundsquareBracket shape
labeltextText at the bracket midpoint

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:bracket x="80" y="120" to-x="260" to-y="120" side="above" label="Group A"/>
  <s:bracket x="300" y="120" to-x="520" to-y="120" side="above" variant="round" label="Group B"/>
  <s:bracket x="180" y="200" to-x="420" to-y="200" side="below" label="p &lt; 0.05"/>
</svg>
```

Three bracket variants: a square bracket above, a round bracket above, and a square bracket below with a significance label.

:::
Group A Group B p < 0.05

Figure 15: Three bracket variants: a square bracket above, a round bracket above, and a square bracket below with a significance label.

Braces

The <s:brace> component draws a curly brace between two points, with an optional label at the apex. Use it for grouping or spanning annotations.

Required: start position (x/y or from) and end position (to-x/to-y or to).

AttributeValuesDefaultDescription
x, ycoordinatesStart point
fromanchor refStart point from anchor
to-x, to-ycoordinatesEnd point
toanchor refEnd point from anchor
sideabove, below, left, rightaboveWhich side the brace bulges toward
bulgenumber10% of lengthDepth of the brace perpendicular to the endpoint line
labeltextText at the apex of the brace

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:brace x="100" y="60" to-x="100" to-y="260" side="left" label="Range A"/>
  <s:brace x="200" y="100" to-x="400" to-y="100" side="above" label="Group A"/>
  <s:brace x="200" y="200" to-x="400" to-y="200" side="below" label="Group B"/>
  <s:brace x="500" y="60" to-x="500" to-y="260" side="right" label="Range B"/>
</svg>
```

Curly braces: above (Group A), below (Group B), on the left (Range A), and on the right (Range B).

:::
Range A Group A Group B Range B

Figure 16: Curly braces: above (Group A), below (Group B), on the left (Range A), and on the right (Range B).

Region of interest

ROI rectangle

The <s:roi-rect> component outlines a rectangular region of interest with an optional label.

Required: position and size via x/y + width/height, or bounds via from/to.

AttributeValuesDefaultDescription
x, ycoordinatesTop-left corner
width, heightdimensions50Rectangle dimensions
from, toanchor refsBounds from two anchor points
labeltextOptional label
label-positionabove, below, center, left, rightaboveLabel placement
stroke-stylesolid, dashed, dottedsolidStroke pattern

ROI ellipse

The <s:roi-ellipse> component outlines an elliptical or circular region.

Required: position (cx/cy or at), rx, ry.

AttributeValuesDefaultDescription
cx, cycoordinatesCenter position
atanchor refCenter position from anchor
dx, dyoffset0Offset from anchor
rx, ryradiiHorizontal and vertical radii
labeltextOptional label
label-positionabove, below, center, left, rightaboveLabel placement
stroke-stylesolid, dashed, dottedsolidStroke pattern

Highlighting regions


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:roi-rect x="50" y="40" width="160" height="100" label="Region A" stroke-style="dashed" color="green"/>
  <s:roi-rect x="350" y="160" width="120" height="90" label="Region B" label-position="below" stroke-style="dotted"/>
  <s:roi-ellipse at="#s:center" rx="80" ry="50" label="Zone C"/>
</svg>
```

Two ROI rectangles with different stroke styles and label positions, and an elliptical region centered with the `#s:center` auto-anchor.

:::
Region A Region B Zone C

Figure 17: Two ROI rectangles with different stroke styles and label positions, and an elliptical region centered with the #s:center auto-anchor.

Using anchors for ROI bounds


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:anchor id="tl" x="180" y="70"/>
  <s:anchor id="br" x="420" y="230"/>
  <s:roi-rect from="#tl" to="#br" label="Selection" stroke-style="dashed"/>
  <s:marker at="#tl" symbol="cross" size="14"/>
  <s:marker at="#br" symbol="cross" size="14"/>
</svg>
```

An ROI rectangle defined by two anchor points with `from`/`to`, and cross markers at each corner using `at` — no coordinate duplication.

:::
Selection

Figure 18: An ROI rectangle defined by two anchor points with from/to, and cross markers at each corner using at — no coordinate duplication.

ROI polygon

The <s:roi-polygon> component outlines a polygonal region of interest using a list of coordinate points.

Required: points.

AttributeValuesDefaultDescription
pointscoordinate pairsSpace-separated x,y pairs (e.g., "100,50 200,80 150,180")
labeltextOptional label
label-positionabove, below, center, left, rightaboveLabel placement
stroke-stylesolid, dashed, dottedsolidStroke pattern

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:roi-polygon points="100,60 250,40 300,120 220,200 80,160" label="Tissue boundary" stroke-style="dashed"/>
  <s:roi-polygon points="350,80 480,60 520,180 430,240 330,200" label="Region B" stroke="crimson"/>
</svg>
```

Two polygon ROIs: a dashed tissue boundary and a solid region in crimson, each defined by a list of vertex coordinates.

:::
Tissue boundary Region B

Figure 19: Two polygon ROIs: a dashed tissue boundary and a solid region in crimson, each defined by a list of vertex coordinates.

Spotlight

The <s:spotlight> component creates an inverse highlight — it dims everything outside a specified region, drawing attention to the spotlighted area. It uses an SVG <mask> element internally.

Required: position (cx/cy or at).

AttributeValuesDefaultDescription
cx, cycoordinatesCenter of the spotlight region
atanchor refCenter position from anchor
dx, dyoffset0Offset from anchor
rnumber50Radius for circular spotlight
rx, rynumbersRadii for elliptical spotlight (overrides r)
shapecircle, rectcircleSpotlight shape
width, heightdimensions100Dimensions for rectangular spotlight
opacity0.01.00.6Opacity of the dimmed area (higher = darker)

::: figure

![](images/600x300-blue.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:anchor id="feature" x="200" y="150"/>
  <s:spotlight at="#feature" r="70"/>
  <s:callout x="400" y="60" label="Feature of interest" to="#feature" shape="rect"/>
</svg>
```

A circular spotlight positioned with an anchor dims the surrounding area, with a callout pointing to the same anchor.

:::
Feature of interest

Figure 20: A circular spotlight positioned with an anchor dims the surrounding area, with a callout pointing to the same anchor.

Point markers

Marker

The <s:marker> component stamps a symbol at a location, drawn from a built-in library of glyphs. Use it for marking sampling sites, points of interest, or any location that needs a distinct symbol.

Required: position (x/y or at).

AttributeValuesDefaultDescription
x, ycoordinatesPosition
atanchor refPosition from anchor
dx, dyoffset0Offset from anchor
symbolcircle, cross, diamond, pin, plus, square, star, triangle, triangle-downcircleSymbol glyph
sizenumber20Symbol size in viewBox units
colorcolorcurrentColorSets both fill and stroke
fillcolorcurrentColorFill color (overrides color)
strokecolorcurrentColorStroke color (overrides color)
backgroundcolor or nonewhiteBackground behind symbol and label (50% opacity)
labeltextOptional label
label-positionright, above, below, leftrightLabel placement
Tip

Use fill="none" for outline-only markers (e.g., an open circle or outlined star).


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <!-- Filled markers using auto-anchors -->
  <s:marker at="#s:top-left" dx="60" dy="60" symbol="circle" label="circle" label-position="above" color="#2563eb"/>
  <s:marker at="#s:top-center" dx="-60" dy="60" symbol="square" label="square" label-position="above" color="#2563eb"/>
  <s:marker at="#s:top-center" dx="60" dy="60" symbol="diamond" label="diamond" label-position="above" color="#2563eb"/>
  <s:marker at="#s:top-right" dx="-60" dy="60" symbol="triangle" label="triangle" label-position="above" color="#2563eb"/>

  <!-- Open (outline) variants using auto-anchors -->
  <s:marker at="#s:mid-left" dx="60" dy="40" symbol="star" label="star (open)" label-position="below" fill="none" color="#dc2626"/>
  <s:marker at="#s:center" dx="-60" dy="40" symbol="triangle-down" label="triangle-down (open)" label-position="below" fill="none" color="#dc2626"/>

  <!-- Stroke-only symbols and pin using x/y -->
  <s:marker x="420" y="190" symbol="cross" label="cross" color="#16a34a"/>
  <s:marker x="520" y="190" symbol="plus" label="plus" color="#16a34a"/>
  <s:marker at="#s:bottom-center" dy="-30" symbol="pin" label="pin" label-position="left" color="#9333ea" size="24"/>
</svg>
```

All nine marker symbols. Top row: filled markers in blue. Middle row: open (outline) variants using `fill="none"`. Bottom: stroke-only symbols (cross, plus) and a pin.

:::
circle square diamond triangle star (open) triangle-down (open) cross plus pin

Figure 21: All nine marker symbols. Top row: filled markers in blue. Middle row: open (outline) variants using fill="none". Bottom: stroke-only symbols (cross, plus) and a pin.

Crosshair

The <s:crosshair> component renders a crosshair/reticle centered on a point, with an optional central gap and enclosing ring. Use it for precise location marking in microscopy, targeting, or alignment contexts.

Required: position (cx/cy or at).

AttributeValuesDefaultDescription
cx, cycoordinatesCenter position
atanchor refCenter position from anchor
dx, dyoffset0Offset from anchor
sizenumber20Arm length from center
gapnumber4Gap radius around center (keeps center visible)
ringtrue, falsefalseDraw an enclosing circle at arm endpoints
labeltextOptional label
label-positionright, above, below, leftrightLabel placement

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:crosshair cx="150" cy="150" size="25" gap="5" label="Point A"/>
  <s:crosshair at="#s:center" size="30" gap="6" ring="true" label="Center target" stroke="crimson" text="darkred"/>
</svg>
```

Two crosshairs: a basic reticle with direct coordinates, and a ringed crosshair positioned at the center auto-anchor.

:::
Point A Center target

Figure 22: Two crosshairs: a basic reticle with direct coordinates, and a ringed crosshair positioned at the center auto-anchor.

Emphasis & focus

Halo

The <s:halo> component renders a semi-transparent glowing ring around a point, drawing attention without obscuring the underlying content. Use it for highlighting points of interest, active selections, or emphasis.

Required: position (cx/cy or at).

AttributeValuesDefaultDescription
cx, cycoordinatesCenter position
atanchor refCenter position from anchor
dx, dyoffset0Offset from anchor
rnumber15Inner radius of the halo ring
widthnumber8Ring thickness
colorcolorcurrentColorRing color
opacity0.01.00.4Ring opacity

::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:anchor id="site-a" x="150" y="150"/>
  <s:anchor id="site-b" x="420" y="180"/>

  <s:halo at="#site-a" r="20" width="10" color="gold" opacity="0.5"/>
  <s:marker at="#site-a" symbol="circle" size="12"/>
  <s:callout x="250" y="100" label="Active site" to="#site-a"/>

  <s:halo at="#site-b" r="25" width="12" color="crimson" opacity="0.3"/>
  <s:marker at="#site-b" symbol="star" size="16"/>
</svg>
```

Anchors eliminate coordinate duplication: each halo and marker pair references the same anchor, so moving a point means changing one `<s:anchor>` instead of two components.

:::
Active site

Figure 23: Anchors eliminate coordinate duplication: each halo and marker pair references the same anchor, so moving a point means changing one <s:anchor> instead of two components.

Orientation & reference

The <s:compass> component renders an orientation indicator. In its default arrow variant it draws a single directional arrow — commonly a north arrow for maps or an anatomical axis for medical imaging. The full variant shows a four-point cross with all axis labels.

Required: position (x/y or at).

AttributeValuesDefaultDescription
x, ycoordinatesCenter position
atanchor refCenter position from anchor
dx, dyoffset0Offset from anchor
sizenumber50Overall size in viewBox units
variantarrow, fullarrowSingle-axis arrow or four-point cross
axesaxis pairsN/S E/WLabels as slash-separated pairs (e.g., "A/P D/V")

The axes attribute uses the format "primary-pos/primary-neg secondary-pos/secondary-neg". Each axis is a pair of opposed labels separated by /, and two axes are separated by a space:

axes valueDomainLabels shown
N/S E/WGeographicN, S, E, W
A/P D/VAnatomical (sagittal)Anterior, Posterior, Dorsal, Ventral
L/R S/IAnatomical (coronal)Left, Right, Superior, Inferior

Arrow variant (default)

The default arrow variant shows a single directional arrow with the positive label of the primary axis:


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:compass at="#s:bottom-left" dx="60" dy="-50" size="50"/>
  <s:callout x="100" y="270" label="Geographic north arrow" shape="none"/>
</svg>
```

A compass positioned with the `#s:bottom-left` auto-anchor, showing a north indicator.

:::
N Geographic north arrow

Figure 24: A compass positioned with the #s:bottom-left auto-anchor, showing a north indicator.

Full variant with custom axes

The full variant renders both axes as a four-point cross, useful for anatomical imaging orientations:


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:compass at="#s:bottom-left" dx="80" dy="-60" size="50" variant="full" axes="A/P D/V"/>
  <s:callout x="160" y="270" label="Anatomical axes" shape="none"/>
  <s:compass at="#s:bottom-right" dx="-100" dy="-60" size="50" variant="full"/>
  <s:callout x="500" y="195" label="Cardinal" shape="none"/>
</svg>
```

Full compass variants: anatomical axes (A/P, D/V) on the left and default cardinal directions (N/S, E/W) on the right.

:::
APDV Anatomical axes NSEW Cardinal

Figure 25: Full compass variants: anatomical axes (A/P, D/V) on the left and default cardinal directions (N/S, E/W) on the right.

Mixing components with raw SVG

Components and standard SVG work seamlessly together. Use components for the high-level annotations and raw SVG when you need precise control:


::: figure

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 300" xmlns:s="https://stencila.io/svg">
  <s:anchor id="target" x="300" y="150"/>

  <!-- Raw SVG for a custom shape -->
  <rect x="240" y="100" width="120" height="100" rx="12" fill="none" stroke="currentColor" stroke-dasharray="6 3"/>

  <!-- Component callout pointing at the custom shape -->
  <s:callout x="480" y="50" label="Custom region" to="#target" shape="rect" curve="quad"/>

  <!-- Component scale bar using auto-anchor -->
  <s:scale-bar at="#s:bottom-left" dx="30" dy="-30" length="100" label="10 mm"/>

  <!-- Component badge -->
  <s:badge x="300" y="30" label="①"/>
</svg>
```

Raw SVG (dashed rounded rectangle) combined with overlay components (callout, scale bar, badge) in the same overlay.

:::
Custom region 10 mm

Figure 26: Raw SVG (dashed rounded rectangle) combined with overlay components (callout, scale bar, badge) in the same overlay.

Comprehensive example

This example brings together multiple component types to annotate a figure in a realistic scientific context:


::: figure {pad="0 0 46 0"}

![](images/600x300-transparent.png)

```svg overlay
<svg viewBox="0 0 600 346" xmlns:s="https://stencila.io/svg">
  <!-- Named anchors for key features -->
  <s:anchor id="peak" x="250" y="80"/>
  <s:anchor id="valley" x="420" y="200"/>

  <!-- Region of interest -->
  <s:roi-rect x="180" y="50" width="160" height="80" label="Primary ROI" stroke-style="dashed"/>

  <!-- Callout with leader line -->
  <s:callout from="#valley" dx="100" dy="-100" label="Local minimum" to="#valley" shape="rect"/>

  <!-- Arrow connecting features -->
  <s:arrow from="#peak" to="#valley" curve="quad" label="Transition" tip="both" stroke-width="1.5"/>

  <!-- Halo and marker at anchors — no coordinate duplication -->
  <s:halo at="#peak" r="10" width="6" color="gold" opacity="0.5"/>
  <s:halo at="#valley" r="10" width="6" color="red" opacity="0.5"/>
  <s:marker at="#peak" symbol="circle" size="12"/>
  <s:marker at="#valley" symbol="circle" size="12"/>

  <!-- Brace -->
  <s:brace x="180" y="230" to-x="340" to-y="230" side="below" label="Observed range"/>

  <!-- Scale bar and compass positioned via auto-anchors -->
  <s:scale-bar at="#s:bottom-left" dx="40" dy="-26" length="130" label="20 μm"/>
  <s:compass at="#s:bottom-right" dx="-40" dy="-26" size="36"/>
</svg>
```

A comprehensive annotation using `at` anchors: halos and markers reference named anchors (no coordinate duplication), while the scale bar and compass use auto-anchors for consistent bottom-edge placement.

:::
Primary ROI Local minimum Transition Observed range 20 μm N

Figure 27: A comprehensive annotation using at anchors: halos and markers reference named anchors (no coordinate duplication), while the scale bar and compass use auto-anchors for consistent bottom-edge placement.

© 2026 Stencila