leandrocfe/filament-apex-charts
Installation:
composer require leandrocfe/filament-apex-charts:"^5.0"
Register the plugin in your Panel configuration:
use Leandrocfe\FilamentApexCharts\FilamentApexChartsPlugin;
public function panel(Panel $panel): Panel {
return $panel->plugins([FilamentApexChartsPlugin::make()]);
}
Generate a Chart Widget:
php artisan make:filament-apex-charts BlogPostsChart
This creates a BlogPostsChart.php file in app/Filament/Widgets/ with a basic bar chart configuration.
First Use Case:
getOptions() method to customize the chart (e.g., change chart type, data, or styling).ApexChartTypeEnum::Bar with ApexChartTypeEnum::Line for a line chart.BlogPostsChart.php file serves as a template for all chart types.Chart Types:
Use the ApexChartTypeEnum to define chart types (e.g., ApexChartTypeEnum::Pie, ApexChartTypeEnum::Donut). Example:
'chart' => [
'type' => ApexChartTypeEnum::Pie,
'height' => 350,
],
Dynamic Data:
Fetch data dynamically in getOptions() using Eloquent or API calls. Example:
protected function getOptions(): array {
$data = Post::query()->selectRaw('MONTH(created_at) as month, COUNT(*) as count')
->groupBy('month')
->pluck('count', 'month')
->toArray();
return [
'series' => [['data' => $data]],
'xaxis' => ['categories' => array_keys($data)],
];
}
Reusable Components:
Extend ApexChartWidget for shared functionality. Example:
class BaseSalesChart extends ApexChartWidget {
protected static ?string $chartId = 'baseSalesChart';
protected static ?int $contentHeight = 300;
}
Then extend it for specific charts:
class MonthlySalesChart extends BaseSalesChart {
protected function getOptions(): array { ... }
}
Filter Integration:
Use HasFiltersSchema trait to add interactive filters. Example:
use Filament\Schemas\Schema;
use Filament\Forms\Components\Select;
public function filtersSchema(Schema $schema): Schema {
return $schema->components([
Select::make('period')
->options(['monthly' => 'Monthly', 'yearly' => 'Yearly'])
->default('monthly'),
]);
}
public function updatedInteractsWithSchemas(string $statePath): void {
$this->updateOptions();
}
Real-Time Updates: Leverage polling for live data. Example:
protected static ?string $pollingInterval = '15s';
Or disable polling:
protected static ?string $pollingInterval = null;
Dashboard Integration:
Add the widget to your dashboard by including it in the getWidgets() method of your dashboard class:
protected function getWidgets(): array {
return [
BlogPostsChart::class,
MonthlySalesChart::class,
];
}
Resource Pages:
Embed charts in resource pages using Widget:
public static function getWidgets(): array {
return [
Widgets\SalesOverviewChart::class,
];
}
Custom Views: Use Blade views for complex footers or loading indicators. Example:
protected function getFooter(): View {
return view('filament.widgets.custom-footer', ['data' => $this->getChartData()]);
}
Theme Consistency:
Use the theme option in getOptions() to match Filament’s dark/light mode:
'theme' => [
'mode' => Filament::getCurrentPanel()?->darkMode() ? 'dark' : 'light',
],
Performance:
For large datasets, use deferLoading to avoid blocking page load:
protected static bool $deferLoading = true;
Localization: Publish translations to customize labels:
php artisan vendor:publish --tag=filament-apex-charts-translations
Testing: Test chart rendering with:
php artisan test
Mock data in tests to avoid database dependencies.
Chart Not Rendering:
getOptions() method or empty return array.getOptions() returns a valid ApexCharts configuration. Example:
return [
'chart' => ['type' => ApexChartTypeEnum::Line],
'series' => [['data' => [1, 2, 3]]],
];
Filter Data Not Updating:
updateOptions() in updatedInteractsWithSchemas().public function updatedInteractsWithSchemas(string $statePath): void {
$this->updateOptions();
}
Polling Conflicts:
$pollingInterval causing rapid API calls.Dark Mode Issues:
!important sparingly.Z-Index Problems:
z-index in extraJsOptions():
protected function extraJsOptions(): ?RawJs {
return RawJs::make('{ "chart": { "foreColor": "#fff", "zIndex": 1000 } }');
}
Console Errors:
Check browser console for ApexCharts errors (e.g., missing data or invalid options). Use console.log in extraJsOptions() for debugging:
protected function extraJsOptions(): ?RawJs {
return RawJs::make(<<<'JS'
{
chart: {
events: {
mounted: function(ctx) { console.log("Chart mounted", ctx); }
}
}
}
JS);
}
Network Requests: Use browser dev tools to inspect API responses for dynamic data. Ensure CORS headers are set if fetching from external APIs.
Filament Logs:
Enable Filament’s debug mode in .env:
FILAMENT_DEBUG=true
Check logs for widget initialization errors.
Reusable Options: Extract common chart options into a trait or base class to avoid repetition:
trait CommonChartOptions {
protected function getCommonOptions(): array {
return [
'colors' => ['#3b82f6', '#10b981'],
'stroke' => ['width' => 2],
'markers' => ['size' => 4],
];
}
}
Responsive Design: Use ApexCharts’ responsive options to ensure charts adapt to screen size:
'chart' => [
'type' => ApexChartTypeEnum::Line,
'height' => '100%',
'width' => '100%',
],
'responsive' => [
'end' => [100, 150],
],
Custom Tooltips: Enhance interactivity with custom tooltips:
'tooltip' => [
'custom' => function({ value, seriesIndex, dataPointIndex, w }) {
return `<div class="filament-apex-tooltip">
<span>${w.config.series[seriesIndex].name}</span>
<span>${value} units</span>
</div>`;
},
],
Animation Control:
How can I help you explore Laravel packages today?