Annotations

A line chart shows the trend. Annotations explain why the trend bent — and what it should be measured against. They are reference markers placed on the chart’s axes: a halving date, a product release, a break-even level, a target band. Without them, the reader is left to guess which kink in the line corresponds to which event, or whether the current value is good or bad.

RareCharts supports four kinds of annotations within a single annotations array:

  • Point — a single date with a label. Drawn as a vertical line spanning the full plot height, with the label in the reserved area above the chart.
  • Range — a date range with optional fill. Drawn as a translucent band between two boundary lines. Useful for periods (a bear market, a freeze window, an A/B test).
  • Horizontal line — a reference level at a Y value. Drawn as a horizontal line spanning the full plot width, with an inline label. Useful for break-even, targets, KPI thresholds.
  • Horizontal band — a Y-value range with optional fill. Useful for tolerance windows or “acceptable range” bands.

Annotations are supported on Line, DualAxes, and TimeSeries charts. The kind is inferred from which fields are present — date, from/to, value, or yFrom/yTo.

The chart above combines all three common cases: a point annotation on the 4th BTC halving (2024-04-19), a range annotation for the post-election rally window, and a horizontal line at the $100k psychological level. All three are out-of-the-box visuals — no custom SVG, no overlays. The chart automatically reserves vertical space above the plot for the date labels.

Configuration

Pass an annotations array on the chart options. Each entry is one of four kinds, inferred from its fields:

new RareCharts.Line('#chart', {
    height: 360,
    annotations: [
        // Point — vertical line at a date
        {
            date:  '2024-04-19',
            label: '4th Halving',
            color: '#888',
        },
        // Range — vertical band between two dates
        {
            from:        '2024-11-05',
            to:          '2025-01-20',
            label:       'Post-election rally',
            color:       '#00c97a',
            fillOpacity: 0.06,
        },
        // Horizontal line — reference level at a Y value
        {
            value:         100_000,
            label:         '$100k',
            color:         '#fa8c16',
            labelPosition: 'left',
        },
        // Horizontal band — between two Y values
        {
            yFrom:       80_000,
            yTo:         100_000,
            label:       'Support zone',
            fillOpacity: 0.05,
        },
    ],
}).setData(values);

Dates accept any format understood by the chart’s date parser: ISO strings, timestamps, or Date objects. Y values are plain numbers in the same units as the data series.

Horizontal annotations vs. constant series

The classic way to draw a reference level is to add a series with a constant value. That works, but it has costs: the constant series stretches the Y domain (a far-out break-even pulls the axis), shows up in the crosshair tooltip on every point, and clutters the legend.

Horizontal annotations sidestep all of that. They’re purely visual — they don’t participate in domain calculation, they don’t appear in the tooltip, and they don’t belong to the legend. Use them for break-even lines, KPI targets, support/resistance levels, tolerance bands.

DualAxes — choosing an axis

For a DualAxes chart, horizontal annotations need to specify which Y axis they reference:

new RareCharts.DualAxes('#chart', {
    annotations: [
        { value: 14.50, axis: 'y2', label: 'Break-even, USD' },
        { value: 100_000, axis: 'y1', label: 'BTC $100k' },
    ],
});

axis defaults to 'y1'. Vertical (date-based) annotations don’t need this — they span both axes by definition.

Layout

Labels are rendered above the plot area. The chart automatically pushes its top margin down by annotationLabelHeight + 4 pixels when at least one annotation is configured, so labels never collide with the line. The default height is 22. Override it when you need taller labels (multi-line, larger font) or want to compact the layout:

new RareCharts.Line('#chart', {
    annotations: [{ date: '2024-04-19', label: '4th Halving' }],
    annotationLabelHeight: 28,
});

If you provide an explicit margin.top it will be respected — but you must reserve enough room yourself.

View clipping

Annotations whose date(s) fall outside the visible X extent are skipped automatically. This is the expected behavior when used together with timeframes, navigator, or setView(): as the user zooms or pans, in-range annotations appear and out-of-range ones disappear. For range annotations partially visible, the fill is clamped to the visible portion and only the boundary line(s) inside the extent are drawn.

Styling

Annotations inherit the muted theme color by default so they don’t compete with the data. Per-annotation overrides:

Field Type Default Description
Point annotation
date Date | string | number Required. The X position of the marker.
label string '' Text rendered above the chart. Empty string suppresses the label, line stays visible.
color CSS color theme.muted Stroke color of the vertical line and default label color.
strokeDash string 'dashed' Line pattern: 'solid', 'dashed', 'dotted', 'dashDot', 'longDash'.
labelColor CSS color same as color Label text color, when you want it different from the line.
Range annotation
from Date | string | number Required. Range start.
to Date | string | number Required. Range end. If to < from, they are swapped.
label string '' Text rendered above the chart, centered over the visible portion of the range.
color CSS color theme.muted Boundary line color and default fill color.
fill CSS color same as color Background fill of the band when you want it independent from the boundary color.
fillOpacity number 0.08 Opacity of the fill band, 01.
strokeDash string 'dashed' Boundary line pattern.
labelColor CSS color same as color Label text color override.
Horizontal line
value number Required. The Y position of the reference line.
axis 'y1' | 'y2' 'y1' Which Y axis the value belongs to. Only relevant for DualAxes.
label string '' Text rendered inline next to the line.
labelPosition 'left' | 'right' 'left' Which end of the line the label is anchored to. Pick 'right' if your Y axis is on the left and the right edge is free.
color CSS color theme.muted Stroke color and default label color.
strokeDash string 'dashed' Line pattern.
labelColor CSS color same as color Label text color override.
Horizontal band
yFrom number Required. Lower Y value of the band.
yTo number Required. Upper Y value. Order is normalized.
axis 'y1' | 'y2' 'y1' Which Y axis the values belong to.
label string '' Text rendered inline at the top edge of the band.
labelPosition 'left' | 'right' 'left' Which end of the band the label is anchored to.
color CSS color theme.muted Boundary line color and default fill color.
fill CSS color same as color Background fill of the band when independent from the boundary color.
fillOpacity number 0.08 Opacity of the fill band, 01.
strokeDash string 'dashed' Boundary line pattern.
labelColor CSS color same as color Label text color override.

Chart-level options

Option Type Default Description
annotations array Array of point and/or range annotations. Mixed entries are allowed.
annotationLabelHeight number 22 Pixels reserved above the chart for annotation labels. Increase if labels are clipped, decrease for a tighter layout.

When to use them

Annotations are content, not decoration. A good annotation answers a question the chart raises:

  • “Why did hashrate drop in April 2024?” → halving annotation.
  • “Why did revenue plateau in Q3?” → range covering the marketing freeze.
  • “When did the new pricing roll out?” → point on launch day.

Avoid annotating every minor event. The chart starts to look like a footnote index, and the reader stops reading them. Three or four well-chosen markers are usually enough — the rest belongs in the article body.