Search by

koassi / filament-highcharts

koassi

Filament Integration for Highcharts

Package info

github.com/KoassiAkakpo/filament-highcharts

pkg:composer/koassi/filament-highcharts

Fund package maintenance!

Koassi

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.1.1 2026-07-19 01:44 UTC

This package is auto-updated.

Last update: 2026-09-19 02:12:14 UTC


README

Latest Version on Packagist GitHub Code Style Action Status Total Downloads

Strongly inspired by Leandro Ferreira's Apex Charts plugin, this plugin delivers Highcharts integration for Filament panels.

Filament dashboard showing an area chart widget and a column chart widget with schema filters

Line chart widget with a simple select filter and polling Pie chart widget using defer loading and extraJsOptions

Requirements

  • PHP 8.3+
  • Filament 5.x

Note: Highcharts is free for personal/non-commercial use. For commercial use, please review the Highcharts license.

Installation

You can install the package via composer:

composer require koassi/filament-highcharts

Register the plugin for the Filament Panels you want to use it in:

use Koassi\FilamentHighcharts\FilamentHighchartsPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FilamentHighchartsPlugin::make(),
        ]);
}

Usage

Start by creating a widget with the command:

php artisan make:filament-highcharts BlogPostsChart

The command will interactively ask for the chart type, and where to create the widget (panel, resource, or alongside your Livewire components).

Your widget extends Koassi\FilamentHighcharts\Widgets\HighchartsWidget and defines its chart through the getOptions() method, which returns a standard Highcharts configuration array:

use Koassi\FilamentHighcharts\Widgets\HighchartsWidget;

class BlogPostsChart extends HighchartsWidget
{
    protected static ?string $chartId = 'blogPostsChart';

    protected static ?string $heading = 'Blog Posts';

    protected function getOptions(): array
    {
        return [
            'chart' => [
                'type' => 'line',
                'styledMode' => true,
            ],
            'title' => [
                'text' => 'Blog Posts per Quarter',
            ],
            'xAxis' => [
                'categories' => ['Q1', 'Q2', 'Q3', 'Q4'],
            ],
            'series' => [
                [
                    'name' => '2025',
                    'data' => [49.9, 71.5, 106.4, 129.2],
                ],
            ],
        ];
    }
}

Don't forget to register the widget in your panel/resource/page, as with any Filament widget.

Ready-to-use widgets demonstrating filters, polling, deferred loading and raw JS options — the ones behind the screenshots above — are available in the examples/ directory.

Available chart samples

The generator ships with ready-to-use stubs for the following chart types. For more samples, please refer to the Highcharts documentation.

Chart Chart Chart
Line chart Bar chart Pie chart
Area chart Arearange chart Areaspline chart
Areasplinerange chart Bellcurve chart Boxplot chart
Bubble chart Bullet chart Column chart
Columnpyramid chart Columnrange chart Cylinder chart
Dependencywheel chart Dumbbell chart Errorbar chart
Funnel chart Funnel3d chart Gauge chart
Heatmap chart Histogram chart Item chart
Lollipop chart Networkgraph chart Organization chart
Packedbubble chart Pareto chart Pictorial chart
Polygon chart Pyramid chart Pyramid3d chart
Sankey chart Scatter chart Scatter3d chart
Solidgauge chart Spline chart Streamgraph chart
Sunburst chart Tilemap chart Timeline chart
Treegraph chart Treemap chart Variablepie chart
Variwide chart Vector chart Venn chart
Waterfall chart Windbarb chart Wordcloud chart
Xrange chart Arcdiagram chart

The list of available chart types is defined in the chart_options key of the package config file.

Setting a widget title

You may set a widget title (heading):

protected static ?string $heading = 'Blog Posts Chart';

Optionally, you can use the getHeading() method.

Setting a widget subheading

You may set a widget subheading:

protected static ?string $subheading = 'This is a subheading';

Optionally, you can use the getSubheading() method.

Setting a chart id

You may set a chart id:

protected static ?string $chartId = 'blogPostsChart';

If none is provided, a random id is generated.

Making a widget collapsible

You may set a widget to be collapsible:

protected static bool $isCollapsible = true;

You can also use the isCollapsible() method:

protected function isCollapsible(): bool
{
    return true;
}

Setting a widget height

By default, the widget height is set to 300px. You may set a custom height:

protected static int $contentHeight = 400; //px

Optionally, you can use the getContentHeight() method:

protected function getContentHeight(): ?int
{
    return 400;
}

Setting a widget footer

You may set a widget footer:

protected static ?string $footer = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.';

You can also use the getFooter() method:

Custom view:

use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Contracts\View\View;

protected function getFooter(): null|string|Htmlable|View
{
    return view('custom-footer', ['text' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.']);
}
<!--resources/views/custom-footer.blade.php-->
<div>
    <p class="text-danger-500">{{ $text }}</p>
</div>

Html string:

use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Contracts\View\View;
use Illuminate\Support\HtmlString;

protected function getFooter(): null|string|Htmlable|View
{
    return new HtmlString('<p class="text-danger-500">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>');
}

Hiding header content

You can hide header content by NOT providing these:

  • $heading / getHeading()
  • $subheading / getSubheading()

Filtering chart data

You can set up chart filters to change the data shown on the chart. Commonly, this is used to change the time period that chart data is rendered for.

Filter schema

You may use components from the Schemas package to create custom filter forms. Use the HasFiltersSchema trait and implement the filtersSchema() method to define the filter form schema:

use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;
use Filament\Widgets\ChartWidget\Concerns\HasFiltersSchema;
use Koassi\FilamentHighcharts\Widgets\HighchartsWidget;

class BlogPostsChart extends HighchartsWidget
{
    use HasFiltersSchema;

    public function filtersSchema(Schema $schema): Schema
    {
        return $schema->components([
            TextInput::make('title')
                ->default('Blog Posts Chart'),

            DatePicker::make('date_start')
                ->default('2025-07-01'),

            DatePicker::make('date_end')
                ->default('2025-07-31'),
        ]);
    }

    /**
     * Use this method to update the chart options when the filter form is submitted.
     */
    public function updatedInteractsWithSchemas(string $statePath): void
    {
        $this->updateOptions();
    }
}

The data from the custom filter is available in the $this->filters array. You can use the active filter values within your getOptions() method:

protected function getOptions(): array
{
    $title = $this->filters['title'];
    $dateStart = $this->filters['date_start'];
    $dateEnd = $this->filters['date_end'];

    return [
        //chart options
    ];
}

Single select

To set a default filter value, set the $filter property:

public ?string $filter = 'today';

Then, define the getFilters() method to return an array of values and labels for your filter:

protected function getFilters(): ?array
{
    return [
        'today' => 'Today',
        'week' => 'Last week',
        'month' => 'Last month',
        'year' => 'This year',
    ];
}

You can use the active filter value within your getOptions() method:

protected function getOptions(): array
{
    $activeFilter = $this->filter;

    return [
        //chart options
    ];
}

Live updating (polling)

By default, chart widgets refresh their data every 5 seconds.

To customize this, you may override the $pollingInterval property on the class to a new interval:

protected ?string $pollingInterval = '10s';

Alternatively, you may disable polling altogether:

protected ?string $pollingInterval = null;

Defer loading

This can be helpful when you have slow queries and you don't want to hold up the entire page load:

protected static bool $deferLoading = true;

protected function getOptions(): array
{
    //showing a loading indicator immediately after the page load
    if (! $this->readyToLoad) {
        return [];
    }

    //slow query
    sleep(2);

    return [
        //chart options
    ];
}

Loading indicator

You can change the loading indicator:

protected static ?string $loadingIndicator = 'Loading...';

You can also use the getLoadingIndicator() method:

use Illuminate\Contracts\View\View;

protected function getLoadingIndicator(): null|string|View
{
    return view('custom-loading-indicator');
}
<!--resources/views/custom-loading-indicator.blade.php-->
<div>
    <p class="text-danger-500">Loading...</p>
</div>

Dark mode

Dark mode is supported and enabled by default. It follows the Filament theme (light / dark / system) and reacts to theme changes in real time. For the best result, enable styled mode in your chart options:

'chart' => [
    'styledMode' => true,
],

Extra options and Formatters

Chart options returned by getOptions() are converted to JSON, so they cannot contain JavaScript functions. Use the extraJsOptions() method to add raw JavaScript options (formatters, callbacks...) that are merged into the chart options on the client side:

use Filament\Support\RawJs;

protected function extraJsOptions(): ?RawJs
{
    return RawJs::make(<<<'JS'
        {
            xAxis: {
                labels: {
                    formatter: function() {
                        const label = this.axis.defaultLabelFormatter.call(this);
                        // Use thousands separator for four-digit numbers too
                        if (/^[0-9]{4}$/.test(label)) {
                            return Highcharts.numberFormat(this.value, 0);
                        }
                        return label;
                    }
                }
            }
        }
    JS);
}

Publishing config

Optionally, you can publish the config file (to customize the chart types offered by the generator command, or the Highcharts version loaded from the CDN) using:

php artisan vendor:publish --tag="filament-highcharts-config"

Highcharts version

The Highcharts library is loaded from the code.highcharts.com CDN, pinned to the version set in the config file so that a new Highcharts major release cannot silently break your charts:

'highcharts_version' => '12.6.0',

Publishing views

Optionally, you can publish the views using:

php artisan vendor:publish --tag="filament-highcharts-views"

Publishing translations

Optionally, you can publish the translations using:

php artisan vendor:publish --tag="filament-highcharts-translations"

Publishing stubs

Optionally, you can publish the widget stubs used by the make:filament-highcharts command using:

php artisan vendor:publish --tag="filament-highcharts-stubs"

Testing

vendor/bin/pest

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.