Skip to content

Livewire & Volt Examples

Every LiveCharts chart runs inside a <livewire:livecharts /> child component. The examples below show how to wire it up from a Livewire class component (v3/v4) and from a Volt functional component side-by-side.


app/Livewire/SalesDashboard.php
namespace App\Livewire;
use Livewire\Component;
use Matheusmarnt\LiveCharts\Facades\LiveCharts;
use Matheusmarnt\LiveCharts\Enums\{TwColor, TwPalette};
class SalesDashboard extends Component
{
public function render()
{
$chart = LiveCharts::bar()
->title('Monthly Sales')
->labels(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'])
->dataset('2026', [1200, 1900, 1500, 2200, 1800, 2600])
->palette(TwPalette::Vibrant)
->titleColor(dark: TwColor::Slate100, light: TwColor::Slate900)
->gridColor(dark: TwColor::Slate800, light: TwColor::Slate200);
return view('livewire.sales-dashboard', compact('chart'));
}
}
{{-- resources/views/livewire/sales-dashboard.blade.php --}}
<div>
<livewire:livecharts :chart="$chart" />
</div>

The chart re-renders when a Livewire property changes. Use :key to force a clean re-mount.

namespace App\Livewire;
use Livewire\Component;
use Matheusmarnt\LiveCharts\Facades\LiveCharts;
use Matheusmarnt\LiveCharts\Enums\TwColor;
class RevenueChart extends Component
{
public string $period = '30d';
public string $engine = 'apexcharts';
public function render()
{
$chart = LiveCharts::line()
->engine($this->engine)
->title('Revenue — '.$this->period)
->labels($this->labels())
->dataset('Revenue', $this->data())
->titleColor(dark: TwColor::Amber300, light: TwColor::Amber700)
->gridColor(dark: TwColor::Slate800, light: TwColor::Slate200)
->tooltipColor(dark: TwColor::White, light: TwColor::Slate900);
return view('livewire.revenue-chart', compact('chart'));
}
private function labels(): array
{
return match ($this->period) {
'7d' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
'30d' => range(1, 30),
default => range(1, 90),
};
}
private function data(): array
{
return array_map(fn () => rand(800, 3000), $this->labels());
}
}
<div>
<div class="flex gap-4 mb-4">
<select wire:model.live="period">
<option value="7d">Last 7 days</option>
<option value="30d">Last 30 days</option>
<option value="90d">Last 90 days</option>
</select>
<select wire:model.live="engine">
<option value="apexcharts">ApexCharts</option>
<option value="chartjs">Chart.js</option>
</select>
</div>
<livewire:livecharts :chart="$chart" :key="$period.'-'.$engine" />
</div>

pollEvery() adds wire:poll to the chart component. The livecharts:refreshed event fires each cycle — listen on the parent to hydrate sibling state.

namespace App\Livewire;
use Livewire\Attributes\On;
use Livewire\Component;
use Matheusmarnt\LiveCharts\Facades\LiveCharts;
use Matheusmarnt\LiveCharts\Enums\TwColor;
class ActiveSessions extends Component
{
public int $total = 0;
public function mount(): void
{
$this->total = $this->fetchSessions();
}
#[On('livecharts:refreshed')]
public function refresh(): void
{
$this->total = $this->fetchSessions();
}
public function render()
{
$chart = LiveCharts::line()
->title('Active Sessions')
->labels(array_map(fn ($i) => now()->subMinutes(9 - $i)->format('H:i'), range(0, 9)))
->dataset('Sessions', $this->fetchHistory())
->pollEvery(30)
->gridColor(dark: TwColor::Slate800, light: TwColor::Slate200)
->labelsColor(dark: TwColor::Slate400, light: TwColor::Slate600);
return view('livewire.active-sessions', compact('chart'));
}
private function fetchSessions(): int
{
return rand(100, 500); // replace with real query
}
private function fetchHistory(): array
{
return array_map(fn () => rand(100, 500), range(0, 9));
}
}
<div>
<p class="text-2xl font-bold">{{ $total }} active now</p>
<livewire:livecharts :chart="$chart" />
</div>

namespace App\Livewire;
use Livewire\Attributes\On;
use Livewire\Component;
use Matheusmarnt\LiveCharts\Facades\LiveCharts;
use Matheusmarnt\LiveCharts\Enums\TwColor;
class SalesDrillDown extends Component
{
public ?string $selected = null;
public array $detail = [];
public function render()
{
$overview = LiveCharts::bar()
->title('Sales by Region')
->labels(['North', 'South', 'East', 'West'])
->dataset('Q1', [4200, 3100, 5600, 2900])
->onDataPointClick('region-selected')
->titleColor(dark: TwColor::Slate100, light: TwColor::Slate900);
return view('livewire.sales-drill-down', compact('overview'));
}
#[On('region-selected')]
public function drillDown(array $data): void
{
$this->selected = $data['label'];
$this->detail = $this->detailFor($data['label']);
}
private function detailFor(string $region): array
{
return array_map(fn () => rand(200, 1800), range(1, 3));
}
}
<div>
<livewire:livecharts :chart="$overview" />
@if ($selected)
<p class="mt-4 font-semibold">{{ $selected }} breakdown</p>
<livewire:livecharts
:chart="LiveCharts::bar()
->title($selected)
->labels(['Product A', 'Product B', 'Product C'])
->dataset('Sales', $detail)"
:key="$selected"
/>
@endif
</div>

Class-based chart with dependency injection

Section titled “Class-based chart with dependency injection”

Class-based charts support Laravel’s container — inject repositories, services, or configs directly.

app/Charts/RevenueChart.php
namespace App\Charts;
use App\Repositories\OrderRepository;
use Matheusmarnt\LiveCharts\Charts\Chart;
use Matheusmarnt\LiveCharts\Charts\Dataset;
use Matheusmarnt\LiveCharts\Enums\{TwColor, TwPalette};
class RevenueChart extends Chart
{
protected string $type = 'line';
public function __construct(private OrderRepository $orders) {}
public function labels(): array
{
return $this->orders->months(6);
}
public function datasets(): array
{
return [
Dataset::make('Direct')
->data($this->orders->directRevenue(6))
->backgroundColor(dark: TwColor::Emerald400, light: TwColor::Emerald600)
->borderColor(dark: TwColor::Emerald300, light: TwColor::Emerald700),
Dataset::make('Affiliate')
->data($this->orders->affiliateRevenue(6))
->backgroundColor(dark: TwColor::Sky400, light: TwColor::Sky600)
->borderColor(dark: TwColor::Sky300, light: TwColor::Sky700),
];
}
}
app/Livewire/RevenuePage.php
namespace App\Livewire;
use Livewire\Component;
class RevenuePage extends Component
{
public function render()
{
return view('livewire.revenue-page');
}
}
{{-- resolve from container — DI applied automatically --}}
<livewire:livecharts :chart="App\Charts\RevenueChart::class" />

namespace App\Livewire;
use Livewire\Component;
use Matheusmarnt\LiveCharts\Facades\LiveCharts;
use Matheusmarnt\LiveCharts\Enums\{TwColor, TwPalette};
class Dashboard extends Component
{
public string $period = '30d';
public function render()
{
$sharedColors = [
'title' => [dark: TwColor::Slate100, light: TwColor::Slate900],
'legend' => [dark: TwColor::Slate300, light: TwColor::Slate700],
'grid' => [dark: TwColor::Slate800, light: TwColor::Slate200],
];
$revenue = LiveCharts::area()
->title('Revenue')
->labels($this->months())
->dataset('MRR', [4200, 5100, 4800, 6200, 5900, 7100])
->palette(TwPalette::Vibrant)
->titleColor(...$sharedColors['title'])
->gridColor(...$sharedColors['grid']);
$users = LiveCharts::bar()
->title('New Users')
->labels($this->months())
->dataset('Signups', [120, 180, 140, 220, 195, 260])
->palette(TwPalette::Muted)
->titleColor(...$sharedColors['title'])
->gridColor(...$sharedColors['grid']);
$churn = LiveCharts::donut()
->title('Churn Reasons')
->labels(['Price', 'Support', 'Features', 'Other'])
->dataset('Churn', [42, 18, 25, 15])
->palette(TwPalette::Pastel);
return view('livewire.dashboard', compact('revenue', 'users', 'churn'));
}
private function months(): array
{
return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
}
}
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="lg:col-span-2">
<livewire:livecharts :chart="$revenue" />
</div>
<livewire:livecharts :chart="$users" />
<livewire:livecharts :chart="$churn" />
</div>

$chart = LiveCharts::line()
->title('Live Orders')
->labels(['12:00', '12:05', '12:10', '12:15', '12:20'])
->dataset('Orders', [12, 18, 14, 22, 19])
->broadcastOn('private-dashboard.'.$team->id)
->broadcastAs('orders.updated');

When the server dispatches orders.updated on the channel, the chart re-renders automatically via Laravel Echo.


PatternLivewire classVolt
Reactive statepublic $prop;wire:modelstate(['prop' => ...])wire:model
Computed chartBuild in render()computed(fn () => ...)
Init logicmount() methodmount(fn () => ...)
Event listener#[On('event')] on methodon(['event' => fn () => ...])
Access chart in template$chart$this->chart
Force re-mount:key="$prop":key="$prop" (same)
DI chart classPass class stringPass class string