Filament Chart Widget on View Page: Access Current Record

2024-12-17

In Filament Infolist on Edit/View page, you may want to add Stats or Chart Widgets that use the current record. Let me show you how to access that record in widgets.


Imagine you have a stats overview and a chart widget. Now, how do you access the current record in both widgets? The record is available in a $record public property on the widget class.

use Illuminate\Database\Eloquent\Model;
 
public ?Model $record = null;

Now, let's see how we can use it in a widget. First, the stats widget. In this widget, you can use a selectRaw() method on Eloquent to get the count of the data based on the needs.

use App\Models\Click;
use Illuminate\Database\Eloquent\Model;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
 
class LinkClicksOverview extends BaseWidget
{
public ?Model $record = null;
 
protected function getStats(): array
{
$clicks = Click::query()
->where('link_id', $this->record->id)
->selectRaw("COUNT(CASE WHEN created_at > ? THEN 1 END) as lastHour", [now()->subHour()])
->selectRaw("COUNT(CASE WHEN created_at > ? THEN 1 END) as last24hours", [now()->subDay()])
->selectRaw("COUNT(CASE WHEN created_at > ? THEN 1 END) as last7days", [now()->subDays(7)])
->selectRaw("COUNT(CASE WHEN created_at > ? THEN 1 END) as last30days", [now()->subDays(30)])
->first();
 
return [
Stat::make('Last Hour', $clicks->lastHour),
Stat::make('Last 24 Hours', $clicks->last24hours),
Stat::make('Last 7 Days', $clicks->last7days),
Stat::make('Last 30 Days', $clicks->last30days),
];
}
}

For the chart, Filament recommends the flowframe/laravel-trend package. In this package, you can also query only for the current record.

use App\Models\Click;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
use Filament\Widgets\ChartWidget;
use Illuminate\Database\Eloquent\Model;
 
class LinkClicksChart extends ChartWidget
{
protected static ?string $heading = 'Chart';
 
protected int | string | array $columnSpan = 'full';
 
public ?Model $record = null;
 
protected function getData(): array
{
$data = Trend::query(Click::query()->where('link_id', $this->record->id))
->between(
start: now()->startOfYear(),
end: now()->endOfYear(),
)
->perMonth()
->count();
 
return [
'datasets' => [
[
'label' => 'Clicks over time',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}
 
protected function getType(): string
{
return 'line';
}
}

You can access the current record on the Edit and View pages. The only thing you need to do is register widgets on these pages.

class ViewLink extends ViewRecord
{
// ...
 
protected function getHeaderWidgets(): array
{
return [
LinkResource\Widgets\LinkClicksOverview::class,
LinkResource\Widgets\LinkClicksChart::class,
];
}
}

A few of our Premium Examples: