Dashboard

Filament allows you to build dynamic custom dashboard widgets very easily.

Getting started

To get started building a BlogPostsOverview widget:

php artisan make:filament-widget BlogPostsOverview

This command will create two files - a widget class in the /Widgets directory of the Filament directory, and a view in the /widgets directory of the Filament views directory.

Widgets are pure Livewire components, so may use any features of that package.

Widgets may also used on resource pages or other custom pages.

Sorting widgets

Each widget class contains a $sort property that may be used to change its order on the page, relative to other widgets:

protected static ?int $sort = 2;

Conditionally hiding widgets

You may override the static canView() method on widgets to conditionally hide them:

public static function canView(): bool
{
return auth()->user()->isAdmin();
}

Stats overview widgets

Filament comes with a "stats overview" widget template, which you can use to display a number of different stats in a single widget, without needing to write a custom view.

Start by creating a widget with the command:

php artisan make:filament-widget StatsOverview

You can delete the generated view file, as we're using a template.

Change the class so that it extends StatsOverviewWidget instead of Widget, then return Card instances from the getCards() method:

<?php
 
namespace App\Filament\Widgets;
 
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Card;
 
class StatsOverviewWidget extends BaseWidget
{
protected function getCards(): array
{
return [
Card::make('Unique views', '192.1k'),
Card::make('Bounce rate', '21%'),
Card::make('Average time on page', '3:12'),
];
}
}

Now, check out your widget in the dashboard.

You may add a description() to provide additional information, along with a descriptionIcon():

protected function getCards(): array
{
return [
Card::make('Unique views', '192.1k')
->description('32k increase')
->descriptionIcon('heroicon-s-trending-up'),
Card::make('Bounce rate', '21%')
->description('7% increase')
->descriptionIcon('heroicon-s-trending-down'),
Card::make('Average time on page', '3:12')
->description('3% increase')
->descriptionIcon('heroicon-s-trending-up'),
];
}

You may also give cards a color() (primary, success, warning or danger):

protected function getCards(): array
{
return [
Card::make('Unique views', '192.1k')
->description('32k increase')
->descriptionIcon('heroicon-s-trending-up')
->color('success'),
Card::make('Bounce rate', '21%')
->description('7% increase')
->descriptionIcon('heroicon-s-trending-down')
->color('danger'),
Card::make('Average time on page', '3:12')
->description('3% increase')
->descriptionIcon('heroicon-s-trending-up')
->color('success'),
];
}

You may also add or chain a chart() to each card to provide historical data. The chart() method accepts an array of data points to plot:

protected function getCards(): array
{
return [
Card::make('Unique views', '192.1k')
->description('32k increase')
->descriptionIcon('heroicon-s-trending-up')
->chart([7, 2, 10, 3, 15, 4, 17])
->color('success'),
// ...
];
}

Chart widgets

Filament comes with many "chart" widget template, which you can use to display real-time, interactive charts.

Start by creating a widget with the command:

php artisan make:filament-widget BlogPostsChart

You can delete the generated view file, as we're using a template.

Change the class so that it extends a chart widget class instead of Widget. There are several chart classes available, but we'll use the LineChartWidget class for this example.

The getHeading() method is used to return a heading that describes the chart.

The getData() method is used to return an array of datasets and labels. Each dataset is a labelled array of points to plot on the chart, and each label is a string. This structure is identical with the Chart.js library, which Filament uses to render charts. You may use the Chart.js documentation to fully understand the possibilities to return from getData(), based on the chart type.

<?php
 
namespace App\Filament\Widgets;
 
use Filament\Widgets\LineChartWidget;
 
class BlogPostsChart extends LineChartWidget
{
protected function getHeading(): string
{
return 'Blog posts';
}
 
protected function getData(): array
{
return [
'datasets' => [
[
'label' => 'Blog posts created',
'data' => [0, 10, 5, 2, 21, 32, 45, 74, 65, 45, 77, 89],
],
],
'labels' => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
];
}
}

Now, check out your widget in the dashboard.

Available chart types

Below is a list of available chart widget classes which you may extend, and their corresponding Chart.js documentation page, for inspiration what to return from getData():

Generating chart data from an Eloquent model

To generate chart data from an Eloquent model, Filament recommends that you install the flowframe/laravel-trend package. You can view the documentation on the Flowframe website.

Here is an example of generating chart data from a model using the laravel-trend package:

use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
 
protected function getData(): array
{
$data = Trend::model(BlogPost::class)
->between(
start: now()->startOfYear(),
end: now()->endOfYear(),
)
->perMonth()
->count();
 
return [
'datasets' => [
[
'label' => 'Blog posts',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}

Filtering chart data

You can set up chart filters to change the data shown on chart. Commonly, this is used to change the time period that chart data is rendered for.

To set a default filter value, set the $filter property:

public ?string $filter = 'today';

Then, define the getFilters() method to return an array of values and labels for your filter:

protected function getFilters(): ?array
{
return [
'today' => 'Today',
'week' => 'Last week',
'month' => 'Last month',
'year' => 'This year',
];
}

You can use the active filter value within your getData() method:

protected function getData(): array
{
$activeFilter = $this->filter;
 
// ...
}

Live updating (polling)

By default, chart widgets refresh their data every 5 seconds.

To customize this, you may override the $pollingInterval property on the class to a new interval:

protected static string $pollingInterval = '10s';

Alternatively, you may disable polling altogether:

protected static ?string $pollingInterval = null;

Disabling the default widgets

By default, two widgets are displayed on the dashboard. These widgets can be disabled by updating the widgets.register property of the configuration file:

'widgets' => [
// ...
'register' => [],
],

Customizing widget width

You may customize the width of a widget using the $columnSpan property. You may use a number between 1 and 12 to indicate how many columns the widget should span, or full for all of them:

protected int | string | array $columnSpan = 'full';

Still need help? Join our Discord community or open a GitHub discussion

Enjoying Filament?

We are open source at heart. To allow us to build new features, fix bugs, and run the community, we require your financial support.

Sponsor Filament on GitHub