---
title: Streaming
description: Live data via Livewire wire:streaming with strict / stream FIFO modes.
visibility: guest
draft: false
related:
  - /components/charts-apex
  - /components/charts-chartjs/advanced
---

# Streaming

Subscribe a chart to a Livewire-emitted event and pipe each fired payload into the live ApexCharts instance via `chart.appendData()`. The same `<x-wirekit-chart wireStream="...">` API works with both adapters; the imperative-update path differs internally.

## Live demos

The previews below stream pseudo-random data through the same wire-streaming pipeline a production app uses. Watch each chart's series grow over time as the live ticker fires events into it.

:::preview{title="Single-series live ticker — 1s cadence"}
<div data-stream-config='{"event":"wirekit:demo-stream-cpu","interval":1000,"series":1,"range":[40,80]}' style="display: block; width: 100%;">
    <x-wirekit-chart
        library="apexcharts"
        type="line"
        :labels="[]"
        :options="['chart' => ['animations' => ['easing' => 'linear', 'dynamicAnimation' => ['enabled' => true, 'speed' => 950]]], 'xaxis' => ['labels' => ['show' => false], 'axisTicks' => ['show' => false], 'range' => 40], 'yaxis' => ['decimalsInFloat' => 2]]"
        :datasets="[['label' => 'CPU (%)', 'data' => [52, 56, 49, 61, 58, 64, 55, 60, 57, 62]]]"
        valueDecimals="2"
        valueSuffix=" %"
        wireStream="wirekit:demo-stream-cpu"
        wireStreamMode="strict"
        :wireStreamCap="40"
        aria-label="Live CPU utilization streaming chart"
    />
</div>
:::

:::preview{title="Multi-series streaming — 3 latency percentiles, 750ms cadence"}
<div data-stream-config='{"event":"wirekit:demo-stream-latency","interval":750,"series":3,"range":[40,200]}' style="display: block; width: 100%;">
    <x-wirekit-chart
        library="apexcharts"
        type="line"
        :labels="[]"
        :options="['chart' => ['animations' => ['easing' => 'linear', 'dynamicAnimation' => ['enabled' => true, 'speed' => 700]]], 'xaxis' => ['labels' => ['show' => false], 'axisTicks' => ['show' => false], 'range' => 40], 'yaxis' => ['decimalsInFloat' => 2]]"
        :datasets="[
            ['label' => 'p50', 'data' => [45, 48, 52, 49, 51, 47, 50, 53, 48, 49]],
            ['label' => 'p95', 'data' => [120, 132, 128, 145, 138, 142, 135, 128, 140, 144]],
            ['label' => 'p99', 'data' => [180, 195, 188, 210, 205, 198, 215, 200, 192, 208]],
        ]"
        valueDecimals="2"
        valueSuffix=" ms"
        wireStream="wirekit:demo-stream-latency"
        wireStreamMode="strict"
        :wireStreamCap="40"
        aria-label="Live three-percentile latency streaming chart"
    />
</div>
:::

:::preview{title="Slow-cadence sales ticker — 2s interval"}
<div data-stream-config='{"event":"wirekit:demo-stream-sales","interval":2000,"series":1,"range":[10,50]}' style="display: block; width: 100%;">
    <x-wirekit-chart
        library="apexcharts"
        type="line"
        :labels="[]"
        :options="['chart' => ['animations' => ['easing' => 'linear', 'dynamicAnimation' => ['enabled' => true, 'speed' => 1900]]], 'xaxis' => ['labels' => ['show' => false], 'axisTicks' => ['show' => false], 'range' => 40], 'yaxis' => ['decimalsInFloat' => 2]]"
        :datasets="[['label' => 'Sales / minute', 'data' => [22, 28, 31, 25, 33, 29, 36, 30, 27, 32]]]"
        valueDecimals="2"
        wireStream="wirekit:demo-stream-sales"
        wireStreamMode="strict"
        :wireStreamCap="40"
        aria-label="Live sales-per-minute streaming chart"
    />
</div>
:::

The X-axis labels are hidden on every streaming preview (`xaxis.labels.show: false`). Reason: with a rolling FIFO window — once `wireStreamCap` is reached, every new point bumps the oldest off the left edge — any static category label set at mount time goes stale within the first cycle. Either the labels need to update in lockstep with the data shift (real-app responsibility: pass `xaxis.categories` per-tick alongside the value), or they should be absent. The streaming previews opt for absent so the visible axis stays honest. The y-axis + legend still carry the chart's meaning; the x-axis just represents "time flowing right" without a calibrated tick label.

The pseudo-data ticker that drives these previews is documented in docs.wirekit.app's `streaming-demo.js` shim — same wire-streaming pipeline a production Livewire app would feed via `$this->dispatch(...)`. Match the chart's `wireStream="…"` to the event name in the wrapper's `data-stream-config="event"` field; everything else flows automatically.

## Setup — Server-side event source

In your Livewire component:

```php
public function pushSample(float $value): void
{
    $this->dispatch('cpu.sample', point: $value);
}
```

In your view:

```blade
<x-wirekit-chart
    type="line"
    :labels="$initialLabels"
    :datasets="[['label' => 'CPU (%)', 'data' => $initialData]]"
    wireStream="cpu.sample"
    wireStreamMode="strict"
    :wireStreamCap="60"
    height="240px"
/>
```

The Alpine factory listens for `cpu.sample` events, calls `chart.appendData([{ data: [point] }])`, and (under `strict` mode) trims the oldest point so the visible window stays at `wireStreamCap = 60` points.

## Three configuration props

| Prop | Default | Purpose |
|---|---|---|
| `wireStream` | `null` | Event name. When set, the chart subscribes; when null, no streaming behavior. |
| `wireStreamMode` | `'strict'` | `'strict'` shifts FIFO at `wireStreamCap`; `'stream'` grows unbounded — developer's responsibility to trim. |
| `wireStreamCap` | `100` | Max points per series under `'strict'`. |

## Multi-series streaming

When the payload includes `datasetIndex`, the point is appended to the matching series instead of dataset 0:

```blade
<x-wirekit-chart
    type="line"
    :labels="$labels"
    :datasets="[
        ['label' => 'p50', 'data' => $p50Initial],
        ['label' => 'p95', 'data' => $p95Initial],
        ['label' => 'p99', 'data' => $p99Initial],
    ]"
    wireStream="latency.sample"
    :wireStreamCap="120"
/>
```

```php
// Server-side dispatch:
$this->dispatch('latency.sample', datasetIndex: 0, point: 45);  // p50
$this->dispatch('latency.sample', datasetIndex: 1, point: 220); // p95
$this->dispatch('latency.sample', datasetIndex: 2, point: 580); // p99
```

## Real-world recipe — Polling for samples

```blade
<div wire:poll.5s="emitLatencySamples">
    <x-wirekit-chart
        type="line"
        :labels="$buckets"
        :datasets="$datasets"
        wireStream="latency.sample"
        wireStreamMode="strict"
        :wireStreamCap="120"
        height="280px"
    />
</div>
```

```php
public function emitLatencySamples(): void
{
    $sample = \App\Metrics\Api::currentLatencyPercentiles();
    $this->dispatch('latency.sample', datasetIndex: 0, point: $sample->p50);
    $this->dispatch('latency.sample', datasetIndex: 1, point: $sample->p95);
    $this->dispatch('latency.sample', datasetIndex: 2, point: $sample->p99);
}
```

The `wire:poll.5s` directive triggers the server-side method every 5 seconds; each dispatch fires the matching client-side listener and appends one point to each series.

## License note

ApexCharts is non-MIT — see [the License section on the Chart overview page](/components/chart#license-apexcharts-only) and [apexcharts.com/license](https://apexcharts.com/license/) for the full terms.

## See Also

- [Chart.js advanced patterns](../charts-chartjs/advanced.md#wire-streaming) for the same prop on the alternative adapter
- [Annotations](./annotations.md) for marking specific events on the streaming timeline

## Design Tokens

See [ApexCharts adapter — Design Tokens](/components/charts-apex#design-tokens) for the color, typography, and grid tokens shared across every ApexCharts demo.
