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

# Multi-series

> Render several live series with a toggleable legend and per-series dots.

`LiveChartSeries` draws multiple line series that share an axis, time window, and crosshair.
Pass a `SharedValue<SeriesConfig[]>`.

<Note>
  **Live example:**
  [`app/demo/multi-series.tsx`](https://github.com/brandtnewlabs/react-native-livechart/blob/main/app/demo/multi-series.tsx)
  in the example app.
</Note>

<Frame caption="Multiple live series with a toggleable legend">
  <video autoPlay loop muted playsInline controls poster="/media/multi-series.jpg" src="https://mintcdn.com/brandtnewlabs/3aK_iydbC8Ff9g3s/media/multi-series.mp4?fit=max&auto=format&n=3aK_iydbC8Ff9g3s&q=85&s=769a8d0275db83c160c8aee5bb5a5169" data-path="media/multi-series.mp4" />
</Frame>

```tsx theme={null}
import { useSharedValue } from "react-native-reanimated";
import { LiveChartSeries, type SeriesConfig } from "react-native-livechart";

const series = useSharedValue<SeriesConfig[]>([
  { id: "btc", label: "BTC", color: "#f7931a", data: [], value: 0 },
  { id: "eth", label: "ETH", color: "#627eea", data: [], value: 0 },
]);

<LiveChartSeries series={series} legend dot />;
```

Update the series the same way you feed a single chart — append points in place with
`series.modify(...)` (mutating each entry's `data` array and `value`), or replace the whole array
with `series.set(...)`. Avoid `series.value = ...`.

## Series options

Each `SeriesConfig` supports:

| Field         | Purpose                                                              |
| ------------- | -------------------------------------------------------------------- |
| `id`          | Stable identifier (required)                                         |
| `data`        | `LiveChartPoint[]` history (required)                                |
| `value`       | Latest live value for interpolation (required)                       |
| `color`       | Line color (falls back to the built-in series palette)               |
| `label`       | Legend chip text                                                     |
| `visible`     | Show/hide the series (default `true`)                                |
| `style`       | `"solid"` or `"dashed"` (with `intervals`)                           |
| `curve`       | `"monotone"` (default) smooth spline or `"linear"` straight segments |
| `strokeWidth` | Per-series width override                                            |
| `glow`        | Soft glow behind the line                                            |
| `kind`        | `"outcome"` (default) or `"derived"` (subdued/dashed chip)           |

## Legend

The legend renders toggle chips by default. Configure it with the `legend` prop, and listen for
taps with `onSeriesToggle`:

```tsx theme={null}
<LiveChartSeries
  series={series}
  legend={{ position: "top", compact: false }}
  onSeriesToggle={(id, visible) => {
    // Persist the toggle back onto the series shared value.
    series.set(series.get().map((s) => (s.id === id ? { ...s, visible } : s)));
  }}
/>
```

## Per-series dots

The `dot` prop controls the live dots, their pulse, value lines, and inline labels.
Each dot is **haloed** by default — a contrasting outer ring (in the chart
background color) behind the colored dot, matching the single-series live dot so
overlapping series stay legible:

```tsx theme={null}
<LiveChartSeries
  series={series}
  dot={{ radius: 3.5, ring: true, pulse: true, valueLine: true, valueLabel: true }}
/>
```

Tune or turn off the halo, hide the dots, or override the fill color:

```tsx theme={null}
<LiveChartSeries
  series={series}
  // thicker, tinted halo
  dot={{ ring: { color: "#0b0b0f", width: 3 } }}
  // ...or a flat circle (no halo)
  // dot={{ ring: false }}
  // ...or hide the dots entirely (lines + labels still render)
  // dot={{ show: false }}
/>
```

See the full prop list in the [`LiveChartSeries` reference](/api-reference/livechart-series).

## Per-series scrub tooltip

`LiveChartSeries` keeps its historical guide-only scrub by default. Opt into the
Morfi market-detail readout with `scrub.seriesTooltip`: a dashed vertical guide,
a top-centred bucket range, and one pill plus intersection dot for every visible
series. Close values stack instead of overlapping, wide pills flip to the
guide's left near the right edge, and hidden legend series are omitted.

<Note>
  This feature is opt-in and backward compatible. `scrub={true}`,
  `scrub={{}}`, and `scrub={{ seriesTooltip: false }}` all keep the existing
  guide-only multi-series behavior. The existing `scrub.tooltip` property is
  still the master switch; setting it to `false` also suppresses the per-series
  pills.
</Note>

Enable the default tooltip treatment with:

```tsx theme={null}
<LiveChartSeries
  series={series}
  scrub={{ seriesTooltip: true }}
/>
```

Pass an object instead of `true` to customize formatting and appearance:

```tsx theme={null}
<LiveChartSeries
  series={series}
  scrub={{
    seriesTooltip: {
      formatSeriesValue: (value, seriesId) => {
        "worklet";
        return seriesId.startsWith("probability")
          ? `${(value * 100).toFixed(1)}%`
          : `$${value.toFixed(2)}`;
      },
      formatTimeRange: (from, to) => {
        "worklet";
        return `${formatTime(from)} – ${formatTime(to)}`;
      },
      maxLabelChars: 14,
    },
  }}
/>
```

`formatSeriesValue` and `formatTimeRange` run on the UI thread; keep them
worklet-safe, just like the chart's `formatValue` and `formatTime`. Omit
`bucketSeconds` to infer the range width from the first visible series. The
range end is always clamped to the chart's current-time anchor, so an
in-progress live bucket never displays a future end time.

Set `alwaysShow` to keep the value pills at the visible endpoints while the
user is not touching the chart. Idle mode deliberately hides the guide and
time pill; scrubbing restores the full readout.

```tsx theme={null}
<LiveChartSeries
  series={series}
  scrub={{
    seriesTooltip: {
      alwaysShow: true,
      guideColor: "#f59e0b",
      guideDashPattern: [3, 3],
      timePillBackground: "#1e293b",
      seriesPillBackground: "#1e293b",
      seriesPillLabelColor: "#94a3b8",
      seriesPillValueColor: "#f8fafc",
      seriesPillRadius: 10,
      intersectionDotSize: 8,
    },
  }}
/>
```

The [multi-series demo](https://github.com/brandtnewlabs/react-native-livechart/blob/main/app/demo/multi-series.tsx)
has live toggles for the pills, pinned mode, and styling.
