Widgets
图表 Widget
概述
Filament 带有许多图表 Widget 模板,可用来展示实时、交互式图表。
使用如下命令创建 Widget:
php artisan make:filament-widget BlogPostsChart --chart
有一个 ChartWidget
类用于所有图表。图表的类型由 getType()
方法设置。本例中,该方法返回字符串 'line'
。
protected static ?string $heading
变量用于设置描述该图表的标题。如果你想设置动态标题,你可以重写 getHeading()
方法。
getData()
方法用于返回一个包含数据集和标签的数组。每个数据集都是一个用来绘制到图表的点构成的标签化数组,每个标签都是一个字符串。Filament 用来渲染图表的这种数据结构,与 Chart.js 库是一致的。你可以借助 Chart.js 文档去了解 getData()
方法基于图表类型可能的返回值。
<?php namespace App\Filament\Widgets; use Filament\Widgets\ChartWidget; class BlogPostsChart extends ChartWidget{ protected static ?string $heading = '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'], ]; } protected function getType(): string { return 'line'; }}
现在,你可以到仪表盘上查看该 Widget 了。
可用图表类型
以下是你可以继承的图表 Widget 类清单,以及他们对应的 Chart.js 文档页面,从中你可以了解 getData()
应该怎么返回哪些值。
- Bar chart - Chart.js 文档
- Bubble chart - Chart.js 文档
- Doughnut chart - Chart.js 文档
- Line chart - Chart.js 文档
- Pie chart - Chart.js 文档
- Polar area chart - Chart.js 文档
- Radar chart - Chart.js 文档
- Scatter chart - Chart.js 文档
自定义图表颜色
你可以将 $color
属性设置成 danger
、gray
、info
、primary
、success
或 warning
,自定义图表数据的颜色:
protected static string $color = 'info';
如果你要进一步自定义颜色,或者在多个数据集中使用多种颜色,仍然可以在数据中使用 Chart.js 的颜色选项:
protected function getData(): array{ return [ 'datasets' => [ [ 'label' => 'Blog posts created', 'data' => [0, 10, 5, 2, 21, 32, 45, 74, 65, 45, 77, 89], 'backgroundColor' => '#36A2EB', 'borderColor' => '#9BD0F5', ], ], 'labels' => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], ];}
从 Eloquent 模型中生成图表数据
要想从 Eloquent 模型中生成图表数据,Filament 推荐你安装 flowframe/laravel-trend
包。查看其文档。
以下是使用 laravel-trend
包从模型中生成图表数据的一个示例:
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), ];}
过滤图表数据
你可以安装图表过滤器,用以调整图表上显示的数据。通常用来调整图表数据渲染的时间周期:
要设置过滤器的默认值,使用 $filter
属性:
public ?string $filter = 'today';
然后,定义 getFilters()
方法,返回一个值和标签组成的数组给过滤器:
protected function getFilters(): ?array{ return [ 'today' => 'Today', 'week' => 'Last week', 'month' => 'Last month', 'year' => 'This year', ];}
你可以在 getData()
方法内使用当前活跃的过滤值:
protected function getData(): array{ $activeFilter = $this->filter; // ...}
实时更新图表数据(轮询)
图表 Widget 默认每 5 秒钟刷新一次数据。
你可以通过重写类上的 $pollingInterval
属性自定义间隔时间:
protected static ?string $pollingInterval = '10s';
或者,也可以完全禁用轮询:
protected static ?string $pollingInterval = null;
设置图表最大高度
使用 $maxHeight
属性,你可以在图表上设置一个最大高度,以避免其变得太大:
protected static ?string $maxHeight = '300px';
设置图表配置项
你可以在图表类中指定 $options
属性,用以控制 Chart.js 库提供的多个配置项。比如,你想让 Line Chart 关闭 legend。
protected static ?array $options = [ 'plugins' => [ 'legend' => [ 'display' => false, ], ],];
此外,你可以重写 getOptions()
方法,返回选项的动态数组:
protected function getOptions(): array{ return [ 'plugins' => [ 'legend' => [ 'display' => false, ], ], ];}
这些 PHP 数组会在图表渲染时转换成 JSON 对象。如果你想在该方法中返回原始 JavaScript,可以返回 RawJs
对象。如果你想使用 JavaScript 回调函数,这就很有用。比如:
use Filament\Support\RawJs; protected function getOptions(): RawJs{ return RawJs::make(<<<JS { scales: { y: { ticks: { callback: (value) => '€' + value, }, }, }, } JS);}
添加描述
使用 getDescription()
方法,你可以在图表的标题下面添加描述:
public function getDescription(): ?string{ return 'The number of blog posts published per month.';}
禁用懒加载
默认情况下,Widget 使用懒加载。这意味着只有当它们在页面中可见时才会加载。
要禁用该行为,你可以在 Widget 类中重写 $isLazy
属性:
protected static bool $isLazy = true;
使用自定义 Chart.js 插件
Chart.js 提供了强大的插件系统,允许你扩展功能并创建自定义图表行为。本指南将详解如何在图表 Widget 中使用它们。
步骤 1: 使用 NPM 安装插件
要开始使用,请先在项目中使用 NPM 安装该插件。本指南中,我们将安装 chartjs-plugin-datalabels
:
npm install chartjs-plugin-datalabels --save-dev
步骤 2: 创建 JavaScript 文件引入该插件
你可以创建 JavaScript 文件,在其中定义自定义插件。本指南针中,我们称之为 filament-chart-js-plugins
。引入该插件,并将其添加到 window.filamentChartJsPlugins
数组:
import ChartDataLabels from 'chartjs-plugin-datalabels' window.filamentChartJsPlugins ??= []window.filamentChartJsPlugins.push(ChartDataLabels)
如果数组还没有初始化,那么在推送之前对其进行初始化是很重要的。这可以确保注册 Chart.js 插件的多个 JavaScript 文件(尤其是来自 Filament 插件的文件)不会相互覆盖,无论它们的启动顺序如何。
你可以将想要的插件推入到 filamentChartJsPlugins
数组,你无需单独文件来引入每个插件:
步骤 3: 使用 Vite 编译 JavaScript 文件
现在,你需要使用 Vite 或者你选择的捆绑器编译 JavaScript 文件。在 Vite 配置(通常是 vite.config.js
)中引入该文件。比如:
import { defineConfig } from 'vite';import laravel from 'laravel-vite-plugin'; export default defineConfig({ plugins: [ laravel({ input: [ 'resources/css/app.css', 'resources/js/app.js', 'resources/css/filament/admin/theme.css', 'resources/js/filament-chart-js-plugins.js', // Include the new file in the `input` array so it is built ], }), ],});
使用 npm run build
编译该文件。
步骤 4: 在 Filament 中注册该 JavaScript 文件
Filament 需要知道在渲染图表 Widget 时是否引入此 JavaScript 文件。你可以在类似 AppServiceProvider
的服务提供者的 boot()
方法中执行此操作:
use Filament\Support\Assets\Js;use Filament\Support\Facades\FilamentAsset;use Illuminate\Support\Facades\Vite; FilamentAsset::register([ Js::make('chart-js-plugins', Vite::asset('resources/js/filament-chart-js-plugins.js'))->module(),]);
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion