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.
The X-axis labels are hidden on every streaming preview (xaxis.labels.show: false). Reason: every preview above bounds its visible window with xaxis.range: 40, so the window slides right as points arrive and 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 (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:
public function pushSample(float $value): void
{
$this->dispatch('cpu.sample', point: $value);
}
<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 and calls chart.appendData([{ data: [point] }]) — the new point animates in from the right edge while the points already on the chart keep their values and shift left.
Three configuration props
| Prop | Default | Purpose |
|---|---|---|
wireStream |
null |
Event name. When set, the chart subscribes; when null, no streaming behavior. |
wireStreamMode |
'strict' |
Advisory on this adapter — see below. Both values append; neither drops a point. |
wireStreamCap |
100 |
Advisory on this adapter — the point count your app treats as the ceiling. |
The cap is advisory here — bounding the series is your app's job
The ApexCharts adapter does not trim
On ApexCharts these two props do not drop points, whatever wireStreamMode is set to. Every
dispatch goes through chart.appendData(), so a series streamed into a long-running dashboard
keeps growing for as long as the page is open — do not rely on the cap for memory.
The Chart.js adapter is the one that
drops the oldest point for you.
The divergence is deliberate: an updateSeries()-based trim re-interpolates every existing
position's Y-value on each tick, which reads on screen as the whole line reversing direction once
per point. Appending keeps the motion honest, and costs the automatic bound.
Two things to do about it in an app that streams for hours:
- Bound the VISIBLE window with
xaxis.range(:options="['xaxis' => ['range' => 60]]"), as every preview on this page does. This is a viewport, not a cap — the series behind it still grows. - Bound the SERIES yourself: count the points you have dispatched and, once you pass
wireStreamCap, re-mount the chart with a truncated dataset — or reach for ApexCharts'chart.resetSeries(). Read the ceiling back off the element'sdata-wire-stream-capattribute so the Blade prop stays the single place it is configured.
Multi-series streaming
When the payload includes datasetIndex, the point is appended to the matching series instead of dataset 0:
<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"
/>
// 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
<div wire:poll.5s="emitLatencySamples">
<x-wirekit-chart
type="line"
:labels="$buckets"
:datasets="$datasets"
wireStream="latency.sample"
wireStreamMode="strict"
:wireStreamCap="120"
height="280px"
/>
</div>
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 and apexcharts.com/license for the full terms.
See Also
- Chart.js advanced patterns for the same props on the alternative adapter — the one that enforces
wireStreamCapfor you - Annotations for marking specific events on the streaming timeline
Design Tokens
See ApexCharts adapter — Design Tokens for the color, typography, and grid tokens shared across every ApexCharts demo.