Text Version of the Lesson
Filament has a concept of "Widget", which may be used in different contexts on different pages. But the most typical use case is the Dashboard: you can replace the default "Information" blocks with your own widgets.
This is what the default Dashboard looks like:

Not very useful, is it? A typical user shouldn't even know what version of Filament is running under the hood.
So let's add a few widget blocks here. Filament offers three typical widget types:
- Stats Overview
- Chart
- Table
I will show you all three, in this lesson.
Stats Overview: Total Revenue Widget
We will calculate the total revenue from orders in three slices: the sum of orders.price today, over the last 7 days and 30 days.
For that, we generate a Widget with the type stats-overview:
php artisan make:filament-widget RevenueToday --stats-overview
Important: this Artisan command requires choosing the panel. Since widgets can be used outside of the dashboard as separate Livewire components, you need to choose specifically "admin" if you want to use it on the dashboard.

Then it generates the file in app/Filament/Widgets where we need to fill in the getStats() method. The syntax is this:
app/Filament/Widgets/RevenueToday.php:
use App\Models\Order;use Filament\Widgets\StatsOverviewWidget\Stat; class RevenueToday extends BaseWidget{ protected function getStats(): array { $totalRevenue = Order::whereDate('created_at', date('Y-m-d'))->sum('price') / 100; return [ Stat::make('Revenue Today (USD)', number_format($totalRevenue, 2)) ]; }}
As you can see, we have two parameters to Stat::make(): the title and the number/text we want to show.
And that's it. We have a new widget on the dashboard. No need to configure anything else!

But of course, this is just the beginning of our dashboard. Let's generate...
How do you add a link to a table widget to view the item?
Found it in your tables guide, for others looking to do the same:
Tables\Columns\TextColumn::make('title')->url(fn (Application $application): string => ApplicationResource::getUrl('edit', 'record' => $application->id])),
I have 3 stats widgets. One for Income, another for expenses. Is there a way to calculate the difference between the to for a third widget called Net Income? Trying to learn how to do basic math within a widget. Thank you!
Load everything into variables before the
return [and simply do the math with variables there :)It looks like a basic operation to me, so I'm not sure what issue you are having. Maybe add some code where I could guide you to the final result
Thank you for your help. I'm still fairly new and learning just how much I still don't know :) This site is amazing and a very good tool for someone just starting out like myself.
We all had to start somewhere! But don't worry, the road ahead will be fun once you get over a few bumps :)
You helped me! I took what you said and applied it to an online example that wasn't working before. It works perfectly. Thank you again.
Can anyone suggest how to use trends and filter by say, company_id? This probably is easy to do, and I did a lot of searching, but couldnt find anything. This site is amazing and is helping learn Filament, but I'm learning that I have a long ways to go to getting good. Thank you.
This might help you: https://laraveldaily.com/post/filament-dashboard-widgets-date-filters
It's not for the company_id, but you can change the date filter to the company filter as the logic is the same.
I'm getting somewhere with this. I just solved the problem and wanted to share my solution. This allows Trends to query just about anything (including company_id for multi-tenancy applications).
$data = Trend::query( Accounting::query() ->where('company_id', $tenant->id) ) ->dateColumn('date') ->between( start: now()->startOfYear(), end: now()->endOfYear(), ) ->perMonth() ->sum('amount');
Has anyone ran into a situation where the trend data is not relyable? I have a table with many rows. If I use trend to get a count of records by month, for example, and show the number in a chart based on 12 months, the data will change each time I hit refresh. This is hapening on my local enviroment, as well as VPS (server is maxed with ram & cores). I've tried the tricks of slowing down the chart to give the system time to preform the query with no effect on the outcome. If I'm expecting a count of 88, I probably get the correct(88) 1 out of 20 times that I hit refresh. Any help would be greatly appreciated. I created a workaround but struggle to understand why my code works and Trend is having issues.
Thank you :)
It should be reliable as long as your query is reliably made.
In your case, I would check what kind of query it makes to the database and debug from there
This is really odd. I have two charts, one income, and the other expense. The income gets read first and it is always good(it is on the same page and next to the chart with the issue). The expense is the exact same query except for the table being read. If I do nothing but watch the chart, the bar jumps to values that are equal a partial query. I know that the auto-updating is a function of the chart, but it seems to only read part of the table and almost all times, it does not query 100% of the date. Even if I hault the auto-updating, or add a delay, the chart is almost always the wrong value. I can share a private link, this is must unusable. Most of my laravel journey has been learning what I dont know, this seems like it isn't caused by an error with my code. This is my query..
$tenant = Filament::getTenant();
Hmm, this seems to be okay, but... what is the type of your
amount? Is it float by any chance? :)I would honestly install
telescopehttps://laravel.com/docs/10.x/telescope - find the query and try to run it in the database client. This could give you an idea if the results are correct (and I suspect that there is something funky going on with that)I struggled to find information on how to add a link to the "Stat" It's not in the documentation either.