digital-creative/nova-apex-chart
Digital Creative's Nova Apex Chart package adds ApexCharts-powered chart cards to Laravel Nova dashboards. Build customizable line, bar, area, pie, donut, and radial charts from model data using a simple fluent PHP API, with responsive layouts and easy configuration.
Install the package and verify it matches your Nova version before wiring it into a dashboard:
composer require digital-creative/nova-apex-chart
The package is a thin Nova card wrapper around ApexCharts. Start by reading:
README.md for the supported fluent APIsrc/ApexChart.php for the actual card methods and meta keysresources/js/ or dist/js/ for the Vue component and bundled ApexCharts behaviorThe first practical use case is a dashboard trend card. Add it to app/Nova/Dashboards/Main.php:
use DigitalCreative\NovaApexChart\ApexChart;
public function cards(): array
{
return [
ApexChart::make('Signups - last 14 days')
->type('area')
->series([
[
'name' => 'Signups',
'data' => [4, 8, 6, 12, 9, 15, 18, 14, 20, 22, 19, 25, 24, 30],
],
])
->options([
'xaxis' => [
'categories' => ['Jun 1', 'Jun 2', 'Jun 3', 'Jun 4', 'Jun 5', 'Jun 6', 'Jun 7', 'Jun 8', 'Jun 9', 'Jun 10', 'Jun 11', 'Jun 12', 'Jun 13', 'Jun 14'],
],
'stroke' => ['curve' => 'smooth'],
'dataLabels' => ['enabled' => false],
]),
];
}
If the fluent method names differ in your installed version, treat ApexChart.php as the source of truth and map the same concepts: chart type, series, and ApexCharts options. The PHP side is mostly passing structured metadata to the Vue card.
Use dashboard/resource card methods as the data boundary. Build chart data server-side in a small private method so cards() stays readable:
protected function signupsChart(): ApexChart
{
$rows = User::query()
->selectRaw('DATE(created_at) as day, COUNT(*) as total')
->where('created_at', '>=', now()->subDays(30))
->groupBy('day')
->orderBy('day')
->pluck('total', 'day');
return ApexChart::make('Signups - 30 days')
->type('line')
->series([
[
'name' => 'Signups',
'data' => $rows->values()->all(),
],
])
->options([
'xaxis' => ['categories' => $rows->keys()->all()],
'dataLabels' => ['enabled' => false],
]);
}
Keep series and options separate. ApexCharts expects data under series and visual/config behavior under options. Do not put categories at the top level of the card unless the package explicitly supports it.
Normalize data before passing it to the card. Eloquent collections, Carbon objects, and associative arrays can serialize differently than expected. Prefer ->values()->all() and ->keys()->all():
$labels = $rows->keys()->map(fn ($date) => Carbon::parse($date)->format('M j'))->all();
$values = $rows->values()->all();
Reuse common chart options. If most charts share colors, toolbar behavior, or grid styling, create a helper or subclass:
class BaseApexChart extends ApexChart
{
public function commonOptions(): static
{
return $this->options(array_replace_recursive([
'chart' => ['toolbar' => ['show' => false]],
'dataLabels' => ['enabled' => false],
'stroke' => ['curve' => 'smooth'],
], $this->meta()['options'] ?? []));
}
}
Adjust this to the package's actual option-merging behavior; if it overwrites options wholesale, merge arrays yourself before calling ->options().
Cache expensive aggregates. Since the card is rendered as part of a Nova request, an expensive query will slow the dashboard:
$rows = Cache::remember('nova.signups.30d', now()->addMinutes(5), function () {
return User::query()
->selectRaw('DATE(created_at) as day, COUNT(*) as total')
->where('created_at', '>=', now()->subDays(30))
->groupBy('day')
->orderBy('day')
->pluck('total', 'day');
});
Use it for operational dashboards, not complex analytics. The package exposes ApexCharts but is not a query/filter framework. For dashboard filters, date ranges, or per-user drill-downs, compute the selected state in PHP from the request/Nova filter state and pass the resulting data into the card. Do not assume Nova filters will automatically mutate card data.
For resource detail pages, use the same card shape. If the installed Nova version supports resource cards, add the chart to the resource's cards() method and reuse the same chart factory used by the dashboard. This keeps dashboard and detail-page visualizations consistent.
Prefer a local card over fighting the package if customization grows. The package is small and MIT-licensed. If you need live polling, custom tooltips, click handlers, or cross-filtering, create your own Nova card that imports ApexCharts directly. Use this package as a reference for Nova card registration and metadata shape rather than as a long-term chart framework.
src/ApexChart.php before writing many charts.dataLabels, xaxis, yaxis, stroke, tooltip, etc. PHP snake_case keys will be serialized as-is and ignored by ApexCharts.How can I help you explore Laravel packages today?