> ## Documentation Index
> Fetch the complete documentation index at: https://react-native-livechart.brandtnewlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Reference lines & bands

> Draw horizontal lines, value/time bands, pill badges, and draggable working orders.

<Note>
  **Live examples:**
  [`app/demo/reference-lines-and-bands.tsx`](https://github.com/brandtnewlabs/react-native-livechart/blob/main/app/demo/reference-lines-and-bands.tsx)
  (lines, bands, badges) and
  [`app/demo/working-orders.tsx`](https://github.com/brandtnewlabs/react-native-livechart/blob/main/app/demo/working-orders.tsx)
  (draggable orders, custom tags, grouping) in the example app.
</Note>

<Frame caption="Reference lines, bands, and off-axis badges">
  <video autoPlay loop muted playsInline controls poster="/media/reference-lines-and-bands.jpg" src="https://mintcdn.com/brandtnewlabs/3aK_iydbC8Ff9g3s/media/reference-lines-and-bands.mp4?fit=max&auto=format&n=3aK_iydbC8Ff9g3s&q=85&s=396b411f768b849a0c889ea6974880eb" data-path="media/reference-lines-and-bands.mp4" />
</Frame>

`referenceLines` accepts an array of `ReferenceLine`s in three mutually-exclusive forms:

* **Horizontal line** at a `value`
* **Horizontal band** between `valueFrom` and `valueTo`
* **Vertical time band** between `from` and `to` (unix seconds)

```tsx theme={null}
<LiveChart
  data={data}
  value={value}
  referenceLines={[
    { value: 100, label: "Entry", showValue: true },
    { valueFrom: 95, valueTo: 105, fillOpacity: 0.12, label: "Range" },
  ]}
/>
```

Lines support labels, dashes (`intervals`), and excluding their value from the axis range
(`excludeFromRange`). See the [types reference](/api-reference/types) for every field.
When the array can reorder (for example, a dynamic order book), give each line a unique `id`
so its rendered identity follows that line instead of its array position.

## Full-width lines (`fullWidth`)

By default a line/band stops at the plot's right edge. Set `fullWidth: true` to span it
**edge to edge through the Y-axis gutter**, so it connects visually to its value on the axis
(like a price tag). Only the line/band extends — any `label` or `badge` stays anchored inside
the plot. For a Form-A line with a `badge`, the full-width line replaces the dashed connector.

When `yAxis.labelRightMargin` is set, a plain non-`fullWidth` line stops at the same X as the grid,
honoring `yAxis.gridEndGap`. Badge/label anchors, `fullWidth` lines, and value/time bands are
unchanged.

```tsx theme={null}
referenceLines={[
  { value: 142.5, label: "Avg entry", fullWidth: true }, // runs through the gutter
  { value: 150.0 },                                      // stops at the plot edge (default)
]}
```

## Pill badges (working orders, alerts, targets)

For a Form-A line, `badge` renders the value as a **pill** pinned to a plot edge with a dashed
connector to the opposite side — instead of a plain gutter label that collides with the Y-axis
ticks. When the value scrolls off-screen it auto-pins to the nearest edge with a directional
chevron, so a working order or alert never disappears. It pairs naturally with the
[order-ticket flow](/guides/order-ticket).

```tsx theme={null}
referenceLines={[
  // left-pinned tag with the value and a leading glyph
  { value: 142.5, color: "#16a34a", showValue: true, badge: { icon: "▲" } },
  // icon-only badge (text: false), pinned to the right edge
  { value: 128.0, color: "#dc2626", badge: { position: "right", text: false, icon: "▼" } },
]}
```

`badge: true` uses the defaults (left-pinned, the line's label/value); pass a
[`ReferenceLineBadgeConfig`](/api-reference/types#annotations) for `position` (`"left"` /
`"center"` / `"right"` — `"center"` floats the pill at the value with no connector), an `icon`,
`text: false` (icon-only), and the full style/shape config — `background`, `borderColor` /
`borderWidth`, `radius`, `textColor`, `fontSize` / `fontFamily` / `fontWeight`, and
`offsetX` / `offsetY` (the same knobs as the value [`badge`](/api-reference/types#annotations)).
It supersedes the legacy `offAxisBadge` (still supported), which only appears once the value is
off-screen and takes no icon.

## Draggable lines (`draggable`)

Make a Form-A line draggable along the Y-axis — grab it near its value and drag to set a new price
(a working order, alert level, or target). The line tracks the finger on the UI thread; per-line
callbacks report the value to JS:

```tsx theme={null}
referenceLines={[
  {
    value: limitPrice,            // controlled: write `onCommit` back into this
    label: "Limit buy",
    draggable: true,
    snap: 0.05,                   // round drops to a tick size
    bounds: [0, lastPrice],       // hard-clamp the drag range
    onChange: (v) => {},          // during drag (de-duped to value changes)
    onCommit: setLimitPrice,      // on release — persist the move
    onDragIn: (v) => {},          // value (re-)entered the visible range / bounds
    onDragOut: (v) => {},         // value left the visible range / hit a bound
  },
]}
```

The line is **uncontrolled** by default (it stays where you drop it); pair `onCommit` with writing
the value back into `value` to make it controlled. `onDragIn` / `onDragOut` are edge-triggered and
also fire when the axis rescales under a fixed value (e.g. an order scrolling off the top), so
they're a clean "is my order still on screen" signal even without dragging.

Dragging coexists with [scrubbing](/guides/scrubbing): a press that lands within reach of a
draggable line grabs the line and any drag moves it (in any direction), while a press anywhere else
scrubs as usual. So you can keep `scrub` enabled alongside draggable orders — only the thin grab
band around each draggable line is reserved for the drag.

## Custom tags (`renderReferenceLine`)

On both `LiveChart` and `LiveChartSeries`, replace a line's built-in pill / gutter label with any
**React Native** view — the same model as `renderMarker` / `renderTooltip`. The chart floats your
element over the canvas and pins it to the
line's value (vertically centered, horizontally at the badge / label position), tracking the
rescaling axis and any drag without JS re-renders. Called per Form-A line; return `null` to keep
that line's built-in tag (works with `badge: false` too). Bind the `ctx.value` / `ctx.valueStr`
SharedValues to animated text for a live readout:

```tsx theme={null}
renderReferenceLine={(ctx) =>
  ctx.line.draggable ? (
    <View style={styles.tag}>
      <Text>{ctx.line.label}</Text>
      {/* live price, updated on the UI thread while dragging */}
      <AnimatedTrendTextInput sharedValue={ctx.value} maximumFractionDigits={2} />
    </View>
  ) : null
}
```

`ctx` ([`ReferenceLineRenderProps`](/api-reference/types#annotations)) also carries `y`, `inRange`,
`edge` (`"above"` / `"in"` / `"below"`, for a directional chevron), and `dragging` as SharedValues.
For a left- or right-pinned `badge`, the built-in dashed connector stays in place
behind the native tag and starts after the tag's measured edge; a center badge has
no connector by design.

For example, a multi-series market chart can use the app's native icon and localized target copy
while leaving any other line on the built-in renderer:

```tsx theme={null}
<LiveChartSeries
  series={series}
  referenceLines={[
    { value: 0.66, label: "Target", badge: { position: "right" } },
    { value: 0.5, label: "Midpoint", badge: { position: "center" } },
  ]}
  renderReferenceLine={({ line }) =>
    line.label === "Target" ? (
      <View style={styles.targetTag}>
        <SolidUpIcon />
        <Text>{t("market.target", { value: line.value })}</Text>
      </View>
    ) : null
  }
/>
```

The custom target owns only its tag: its dashed connector still draws from the
native tag's measured edge to the plot boundary, while the midpoint keeps its
built-in badge. The React Native tag is layered above the left-edge fade and scrub overlay.

## Off-axis-only custom tags (`renderOffAxisReferenceLine`)

Use `renderOffAxisReferenceLine` when the regular label should remain in range but an
edge-pinned target needs custom chrome. The chart switches the two tags on the UI thread:
the built-in tag remains in range, and the custom element appears only above or below the
plot. Give the line a left- or right-pinned `badge` (or legacy `offAxisBadge`) to retain
the native dashed connector; it begins after the custom tag's measured edge.

```tsx theme={null}
<LiveChart
  data={data}
  value={value}
  referenceLines={[
    {
      id: "take-profit",
      value: 142.5,
      label: "Target",
      excludeFromRange: true,
      badge: { position: "left" },
    },
  ]}
  renderOffAxisReferenceLine={({ line, edge }) => (
    <OffAxisTargetTag label={line.label} edge={edge} />
  )}
/>
```

`OffAxisTargetTag` stays mounted so it can read the live `edge` SharedValue in an animated
style and flip its caret between `"above"` and `"below"`. Return `null` from the callback
only to opt a static `line` / `index` out; do not branch on `edge.get()` while rendering the
callback itself. `renderReferenceLine` takes precedence if both callbacks handle one line.

## Grouping near-value lines (`referenceLineGrouping`)

When a stack of orders or alerts sits near the same price, their tags pile up illegibly. Pass
`referenceLineGrouping` to collapse Form-A lines whose handles fall within `radius` px of each other
into a single count handle:

```tsx theme={null}
referenceLineGrouping={{
  radius: 18,                       // proximity that collapses into one pill
  // `format` runs on the UI thread — it MUST be a worklet (like `formatValue`).
  format: (n) => { "worklet"; return `×${n}`; }, // label the count (default: the bare number)
  badge: { position: "left", textColor: "#a855f7" }, // same style/shape config as a line badge
}}
// or `true` for the defaults
```

The clustered lines' individual tags are suppressed and replaced by one "count" pill at the
cluster's center; the lines themselves still draw. Lines you render with `renderReferenceLine`
or `renderOffAxisReferenceLine` are excluded from grouping (their custom tag draws itself), so
the count reflects only collapsed built-in tags. The count pill takes the same style/shape config as a per-line badge
([`ReferenceLineBadgeConfig`](/api-reference/types#annotations)) via `badge`, plus a `format` fn
for the count label.

<Note>
  Need an overlay the built-in lines and badges can't express — your own draggable order book or
  liquidation chrome? See [Overlay bridge](/guides/overlay-bridge).
</Note>
