> ## 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.

# LiveChartSeries

> Props for the multi-series line component.

```tsx theme={null}
import { LiveChartSeries } from "react-native-livechart";
```

`LiveChartSeries` draws several line series sharing an axis, time window, and crosshair. It
accepts all the shared theming, axis, range, layout, and text props from
[`LiveChart`](/api-reference/livechart) (`theme`, `accentColor`, `palette`, `metrics`, `font`,
`canvasMode`, `timeWindow`, `smoothing`, [`snapKey`](/api-reference/livechart#param-snap-key), `yAxis`,
`referenceLines`, `formatValue`, …), plus the multi-series props below.

On Android, the shared experimental `canvasMode="opaque"` option selects an opaque SurfaceView and
paints the palette background inside the canvas. See
[Android surface rendering](/guides/android-surface-rendering) for constraints and profiling guidance.

## Custom overlays

<ParamField body="renderOverlay" type="(ctx: ChartOverlayContext) => ReactElement | null">
  Render a full-bleed custom React Native overlay with the live price↔pixel /
  time↔pixel bridge. [`ChartOverlayContext`](/api-reference/types#chartoverlaycontext)
  includes the resolved plot rectangle, so custom off-axis tags and connectors can
  stop at the same axis inset as the chart. Return `null` or `undefined` for no
  overlay. See [Overlay bridge](/guides/overlay-bridge).
</ParamField>

## Reference-line tags

<ParamField body="renderReferenceLine" type="(ctx: ReferenceLineRenderProps) => ReactElement | null">
  Replace a Form-A reference line's built-in Skia badge or gutter label with any
  React Native element. Return `null` or `undefined` for per-line fallback to the
  built-in tag. The custom view tracks the line's live Y position, pins to the
  nearest plot edge when off-axis, and respects left, center, and right badge
  positions. A left- or right-pinned badge keeps its dashed connector, beginning
  after the measured custom view. The reference-line stroke remains visible. See
  [Reference lines and bands](/guides/reference-lines-and-bands#custom-tags-renderreferenceline).
</ParamField>

<ParamField body="renderOffAxisReferenceLine" type="(ctx: ReferenceLineRenderProps) => ReactElement | null">
  Replace only an off-axis Form-A tag. The standard Skia tag or gutter label stays
  in range, while the custom React Native view takes over when the line is pinned
  above or below the plot. A left- or right-pinned `badge` (or legacy
  `offAxisBadge`) retains its dashed connector from the custom view's measured
  edge. Return `null` for lines that opt out, and use `ctx.edge` inside the
  returned component for a directional caret. See
  [Reference lines and bands](/guides/reference-lines-and-bands#off-axis-only-custom-tags-renderoffaxisreferenceline).
</ParamField>

## Series data

<ParamField body="series" type="SharedValue<SeriesConfig[]>" required>
  Array of series definitions. Read on the UI thread. See [`SeriesConfig`](/api-reference/types).
</ParamField>

## Axis labels

Shared with [`LiveChart`](/api-reference/livechart#axes-grid-range). Both
default off.

<ParamField body="topLabel" type="boolean | AxisLabelConfig" default="false">
  Edge label at the plot's top. `true` shows the built-in value label — the
  chart's current top Y-axis bound, updated each frame. Pass
  [`AxisLabelConfig`](/api-reference/types#axislabelconfig) (`format` / `color` /
  `position`) or `{ render }` for a custom element.
</ParamField>

<ParamField body="bottomLabel" type="boolean | AxisLabelConfig" default="false">
  Edge label at the plot's bottom (the current bottom Y-axis bound), with the
  same options as `topLabel`.
</ParamField>

## Legend

<ParamField body="legend" type="boolean | LegendConfig" default="true">
  Toggle chips. Configure `position`, `compact`, and `style`.
</ParamField>

<ParamField body="onSeriesToggle" type="(id: string, visible: boolean) => void">
  Fires when a legend chip is tapped.
</ParamField>

## Dots

<ParamField body="dot" type="boolean | MultiSeriesDotConfig" default="true">
  Per-series live dots: `radius`, `ring`, `color`, `pulse`, `valueLine`,
  `valueLabel`. Each dot is haloed with a contrasting outer `ring` by default
  (matching the single-series live dot); pass `ring: false` for a flat circle,
  `dot={false}` to hide the dots, or `color` to override the per-series fill.
  (The deprecated `dot={{ show: false }}` still hides them.)
</ParamField>

## Scrub

<ParamField body="scrub" type="boolean | ScrubConfig" default="true">
  Crosshair scrubbing on drag. **As of v2 this defaults to `true`** (it previously
  defaulted to `false`); pass `scrub={false}` to disable. The existing default is
  a guide/dim layer. Omitting `seriesTooltip` (or setting it to `false`) preserves
  that behavior. Set `scrub.seriesTooltip` to opt into the Morfi-style
  time-range pill, one colour/value pill and intersection dot per visible series,
  collision stacking, and edge flipping. `seriesTooltip.alwaysShow` keeps value
  pills pinned to the visible endpoints while idle without showing the guide or
  time pill. The existing `scrub.tooltip={false}` switch remains the master
  tooltip control and also suppresses the per-series pills. See
  [Multi-series tooltips](/guides/multi-series#per-series-scrub-tooltip).
  `crosshairFadeDistance` and `crosshairLineCap` style the visible guide,
  selection dot, and tooltip consistently with `LiveChart`.
</ParamField>

<ParamField body="selectionDot" type="boolean | SelectionDotConfig" default="false">
  Dot drawn at the scrub intersection while scrubbing. **Hidden by default on
  `LiveChartSeries`** (unlike `LiveChart`): with multiple lines the dot can only
  track the leading series, so the crosshair and the opt-in tooltip's per-series
  intersection dots mark the scrub point instead. Pass `true` to opt in (it anchors to the leading series),
  a config to set `size` / `color` / `ring`, or `{ component }` for a fully
  custom Skia dot. See [Scrubbing](/guides/scrubbing#selection-dot).
</ParamField>

<ParamField body="onScrub" type="(point: ScrubPointMulti | null) => void">
  **Worklet** callback fired on the UI thread each frame while scrubbing; `null` when it ends.
  Includes a per-series value array. See [Scrubbing](/guides/scrubbing).
</ParamField>

<ParamField body="onGestureStart" type="() => void">
  JS-thread callback fired once when the user starts scrubbing. Respects
  `scrub.panGestureDelay` (it fires when the pan activates, not on first touch).
</ParamField>

<ParamField body="onGestureEnd" type="() => void">
  JS-thread callback fired once when the user stops scrubbing. Fires only if a
  scrub actually started — a tap that never activates emits neither callback.
</ParamField>

<ParamField body="timeScroll" type="boolean | TimeScrollConfig" default="false">
  Pan back through history (same as `LiveChart`). Drag (or fling) to scroll; the
  chart stops auto-following until you return to the live edge. Setting it back to
  `false` while scrolled back glides the window back to the live edge (eased, not
  an instant jump; never frozen at the old position). Per-series dots / value
  labels track each series' value at the visible right edge while scrolled.
  **@experimental.** See [Time-scroll](/guides/time-scroll).
</ParamField>

<ParamField body="returnToLive" type="boolean | ReturnToLiveConfig" default="true">
  Controls the glide back to live when `timeScroll` is switched off while scrolled
  back (same as `LiveChart`). `true` (default) eases over `450` ms, `false` snaps
  instantly, `{ duration }` sets a custom length. Sibling of `timeScroll` so it
  survives `timeScroll={false}`. **@experimental.** See
  [Time-scroll → Turning it back off](/guides/time-scroll#turning-it-back-off).
</ParamField>

<ParamField body="zoom" type="boolean | ZoomConfig" default="false">
  Pinch-to-zoom the visible window (same as `LiveChart`), anchored at the focal
  point. Composes with `timeScroll`. **@experimental.** See
  [Time-scroll](/guides/time-scroll#pinch-to-zoom-zoom).
</ParamField>

<ParamField body="onVisibleRangeChange" type="(range: VisibleRange) => void">
  Called as the visible window changes (\~1 Hz) with `{ startSec, endSec,
      following }`. **@experimental.**
</ParamField>

<ParamField body="onReachStart" type="() => void">
  Called once when the left edge nears the earliest retained data — the cue to
  page in older history. **@experimental.**
</ParamField>

## Degen

<ParamField body="degen" type="boolean | DegenOptions">
  Chart shake + spark burst off the leading series' dot on an upward swing.
</ParamField>

<ParamField body="onDegenShake" type="(payload: DegenShakePayload) => void">
  JS-thread callback when a degen shake starts.
</ParamField>
