构建小部件
带日期过滤器的表单
显示订单的图表
可视化用户数据的图表
执行以下命令来搭建这些小部件:
php artisan make:filament-widget Filters
php artisan make:filament-widget OrdersChart --chart
php artisan make:filament-widget UsersChart --chart
我们选择的图表可视化工具是条形图
接下来,在过滤器小部件中,我们将使用 Filament Forms 集成日期输入元素。该小部件应跨越整个宽度,并通过$sort = 1定位在顶部。
app/Filament/Widgets/Filters.php :
use Filament\Forms\Form;
use Filament\Forms\Components\Grid;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Concerns\InteractsWithForms;
class Filters extends Widget implements HasForms
{
use InteractsWithForms;
protected static string $view = 'filament.widgets.filters';
protected $columnSpan = 'full';
protected static ?int $sort = 1;
public ?array $data = [];
public function form(Form $form): Form
{
return $form
->statePath('data')
->schema([ Grid::make() ->schema([ DatePicker::make('from'), DatePicker::make('to'), ]),
]);
}
}
resources/views/filament/widgets/filters.blade.php :
<x-filament-widgets::widget>
<x-filament::section>
{{ $this->form }}
</x-filament::section>
</x-filament-widgets::widget>
一旦这些配置到位,您将在仪表板上看到一个配备双日期输入的小部件,准备好跨多个图表过滤数据。
为了全面了解应用程序的增长,我们将创建User模型和Order模型的可视化表示。这些图表将描述每日创建的新记录,提供对应用程序性能的深入了解。
为了将数据汇集到这些图表中,我们选择了 Filament 推荐的flowframe/laravel-trend包。
composer require flowframe/laravel-trend
让我们深入研究各个图表:
1. Orders Chart 1. 订单图表
app/Filament/Widgets/OrdersChart.php:
use App\Models\Order;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
use Filament\Widgets\ChartWidget;
class OrdersChart extends ChartWidget
{
protected static ?string $heading = 'Orders Chart';
protected static ?int $sort = 2;
protected function getData(): array
{
$data = Trend::model(Order::class)
->between(start: now()->subWeek(), end: now())
->perDay()
->count();
return [ 'datasets' => [ ['label' => 'Orders', 'data' => $data->map(fn (TrendValue $value) => $value->aggregate)],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}
protected function getType(): string
{
return 'bar';
}
}
2. Users Chart 2. 用户图
app/Filament/Widgets/UsersChart.php:
use App\Models\User;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
use Filament\Widgets\ChartWidget;
class UsersChart extends ChartWidget
{
protected static ?string $heading = 'Users Chart';
protected static ?int $sort = 3;
protected function getData(): array
{
$data = Trend::model(User::class)
->between(start: now()->subWeek(), end: now())
->perDay()
->count();
return [
'datasets' => [
['label' => 'Users', 'data' => $data->map(fn (TrendValue $value) => $value->aggregate)],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}
protected function getType(): string
{
return 'bar';
}
}
实施后,您的仪表板现在将具有两个视觉上令人愉悦的图表,显示过去一周到今天的数据。
想要使用选定的过滤器刷新您的图表吗?这比你想象的要简单!使用 Livewire 事件,您可以在选择过滤器时快速更新多个图表小部件。让我们深入探讨其机制。
1. 配置过滤器小部件
在 app/Filament/Widgets/Filters.php :
class Filters extends Widget implements HasForms
{
// ...
public function form(Form $form): Form
{
return $form
->statePath('data')
->schema([
Grid::make()
->schema([
DatePicker::make('from')
->live()
->afterStateUpdated(fn (?string $state) => $this->dispatch('updateFromDate', from: $state)),
DatePicker::make('to')
->live()
->afterStateUpdated(fn (?string $state) => $this->dispatch('updateToDate', to: $state)),
]),
]);
}
}
2. 对图表小部件中的事件做出反应
现在,两个图表小部件都应该准备好响应日期选择事件。
app/Filament/Widgets/OrdersChart.php :
use Livewire\Attributes\On;
use Illuminate\Support\Carbon;
class OrdersChart extends ChartWidget
{
protected static ?string $heading = 'Orders Chart';
protected static ?int $sort = 2;
public Carbon $fromDate;
public Carbon $toDate;
// ...
#[On('updateFromDate')]
public function updateFromDate(string $from): void
{
$this->fromDate = Carbon::parse($from);
$this->updateChartData();
}
#[On('updateToDate')]
public function updateToDate(string $to): void
{
$this->toDate = Carbon::parse($to);
$this->updateChartData();
}
}
做类似的事情 app/Filament/Widgets/UsersChart.php :
use Livewire\Attributes\On;
use Illuminate\Support\Carbon;
class UsersChart extends ChartWidget
{
protected static ?string $heading = 'Users Chart';
protected static ?int $sort = 3;
public Carbon $fromDate;
public Carbon $toDate;
// ...
#[On('updateFromDate')]
public function updateFromDate(string $from): void
{
$this->fromDate = Carbon::make($from);
$this->updateChartData();
}
#[On('updateToDate')]
public function updateToDate(string $to): void
{
$this->toDate = Carbon::make($to);
$this->updateChartData();
}
}
3. 合并新的过滤器数据
鉴于flowframe/laravel-trend包接受 Carbon 实例,我们将日期字符串转换为 Carbon 对象。随后, updateChartData方法确保图表使用新数据恢复活力
在两个图表小部件的getData方法中:
class OrdersChart extends ChartWidget
{
// ...
protected function getData(): array
{
$fromDate = $this->fromDate ?? now()->subWeek();
$toDate = $this->toDate ?? now();
$data = Trend::model(Order::class)
->between(start: $fromDate, end: $toDate)
->perDay()
->count();
return [
'datasets' => [
[
'label' => 'Orders',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}
}
请记住还要针对用户图表调整此代码片段:
class UsersChart extends ChartWidget
{
// ...
protected function getData(): array
{
$fromDate = $this->fromDate ??= now()->subWeek();
$toDate = $this->toDate ??= now();
$data = Trend::model(User::class)
->between(
start: now()->subWeek(),
end: now(),
start: $fromDate,
end: $toDate,
)
->perDay()
->count();
return [
'datasets' => [
[
'label' => 'Users',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}
// ...
}
在这种情况下,变量仅被设置为默认值或公共属性。