PHPackages                             asharif88/filament-plotly - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. asharif88/filament-plotly

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

asharif88/filament-plotly
=========================

Inspired by https://filamentphp.com/plugins/leandrocfe-apex-charts &amp; https://filamentphp.com/plugins/elemind-echarts this plugin delivers plotly.js integration for Filament.

1.1.2(3mo ago)7521—0%1[2 PRs](https://github.com/Asharif88/filament-plotly/pulls)MITPHPPHP ^8.2CI passing

Since Dec 21Pushed 1mo agoCompare

[ Source](https://github.com/Asharif88/filament-plotly)[ Packagist](https://packagist.org/packages/asharif88/filament-plotly)[ Docs](https://github.com/asharif88/filament-plotly)[ GitHub Sponsors](https://github.com/Asharif88)[ RSS](/packages/asharif88-filament-plotly/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (4)Dependencies (8)Versions (7)Used By (0)

Filament Plotly.js Widget
=========================

[](#filament-plotlyjs-widget)

Inspired by [Leandro Ferreira’s Apex Charts plugin](https://filamentphp.com/plugins/leandrocfe-apex-charts) &amp; [Elemind's Echarts plugin](https://filamentphp.com/plugins/elemind-echarts) this plugin delivers plotly.js integration for Filament.

[![Latest Version on Packagist](https://camo.githubusercontent.com/0052e1e0d3cb84144a299930f5c6f906e338ed090aba13fd22f7c04e406c90b3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6173686172696638382f66696c616d656e742d706c6f746c792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/asharif88/filament-plotly)[![GitHub Tests Action Status](https://camo.githubusercontent.com/3084d216a7449ac21eb5d3870f104fa3e123a460cdf1500c86de443fa04bdc52/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6173686172696638382f66696c616d656e742d706c6f746c792f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/asharif88/filament-plotly/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/8a02db02041ce8df2945367c887a7a4fcfac5b96660892ce427789165ef65759/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6173686172696638382f66696c616d656e742d706c6f746c792f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/asharif88/filament-plotly/actions?query=workflow%3A%22Fix+PHP+code+styling%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/4342312af6ace6a4a6a1540a4e894a543f0f9575ecf75da2d3816a743b66b36b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6173686172696638382f66696c616d656e742d706c6f746c792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/asharif88/filament-plotly)

Table of Contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Usage](#usage)
    - [Setting a widget title](#setting-a-widget-title)
    - [Setting a widget subheading](#setting-a-widget-subheading)
    - [Setting a chart id](#setting-a-chart-id)
    - [Making a widget collapsible](#making-a-widget-collapsible)
    - [Setting a widget height](#setting-a-widget-height)
    - [Setting a widget footer](#setting-a-widget-footer)
    - [Header &amp; Footer Actions](#header--footer-actions)
    - [Hiding header content](#hiding-header-content)
    - [Filtering chart data](#filtering-chart-data)
    - [Live updating (polling)](#live-updating-polling)
    - [Defer loading](#defer-loading)
    - [Loading indicator](#loading-indicator)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [Credits](#credits)
- [License](#license)

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require asharif88/filament-plotly
```

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

```
use Asharif88\FilamentPlotly\FilamentPlotlyPlugin;
public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FilamentPlotlyPlugin::make()
        ]);
}
```

Usage
-----

[](#usage)

Start by creating a widget with the command:

```
php artisan make:filament-plotly BlogPostsChart
```

The plugin uses the [Plotly.react](https://plotly.com/javascript/plotlyjs-function-reference/#plotlyreact) function to render charts. This function takes in the chart `data`, `layout` and `config` as parameters.

You need to implement the `getChartData()` method to return an array with `data`, `layout` and `config` keys:

```
use Asharif88\FilamentPlotly\Widgets\PlotlyWidget;

class BlogPostsChart extends PlotlyWidget
{
    protected function getChartData(): array
    {
        return [
            'data' => [
                [
                    'x' => ['2025-07-01', '2025-07-02', '2025-07-03', '2025-07-04', '2025-07-05'],
                    'y' => [10, 15, 13, 17, 22],
                    'type' => 'scatter',
                    'mode' => 'lines+markers',
                    'name' => 'Blog Posts',
                ],
            ],
            'layout' => [
                'title' => 'Blog Posts Over Time',
                'xaxis' => [
                    'title' => 'Date',
                ],
                'yaxis' => [
                    'title' => 'Number of Posts',
                ],
            ],
            'config' => [
                'responsive' => true,
            ],
        ];
    }
}
```

Alternatively, you can set the `data`, `layout` and `config` separately by implementing the following methods:

```
protected function getChartData(): array
{
    return [
        [
            'x' => ['2025-07-01', '2025-07-02', '2025-07-03', '2025-07-04', '2025-07-05'],
            'y' => [10, 15, 13, 17, 22],
            'type' => 'scatter',
            'mode' => 'lines+markers',
            'name' => 'Blog Posts',
        ],
    ];
}

protected function getChartLayout(): array
{
    return [
        'title' => 'Blog Posts Over Time',
        'xaxis' => [
            'title' => 'Date',
        ],
        'yaxis' => [
            'title' => 'Number of Posts',
        ],
    ];
}

protected function getChartConfig(): array
{
    return [
        'responsive' => true,
    ];
}
```

Setting a widget title
----------------------

[](#setting-a-widget-title)

You may set a widget title:

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

Optionally, you can use the `getHeading()` method.

Setting a widget subheading
---------------------------

[](#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.

Adding custom content
---------------------

[](#adding-custom-content)

You can add custom content before chart within the widget container using the `getbeforeContent()` method.

```
public function getBeforeContent(): null|string|Htmlable|View
{
    return '...';
}
```

Setting a chart id
------------------

[](#setting-a-chart-id)

You may set a chart id:

```
protected static string $chartId = 'blogPostsChart';
```

Making a widget collapsible
---------------------------

[](#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
-----------------------

[](#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
-----------------------

[](#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.']);
}
```

```

    {{ $text }}

```

Html string:

```
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Contracts\View\View;
protected function getFooter(): null|string|Htmlable|View
{
    return new HtmlString('Lorem Ipsum is simply dummy text of the printing and typesetting industry.');
}
```

Header &amp; Footer Actions
---------------------------

[](#header--footer-actions)

You can register Filament actions to appear in the widget header or footer. Override `getHeaderActions()` / `getFooterActions()` on your widget to return an array of `Filament\Actions\Action` (or `ActionGroup`) instances. These actions are rendered by Filament's actions component and respect alignment settings.

Example — simple header actions:

```
use Filament\Actions\Action;
use Filament\Support\Enums\Alignment;

protected function getHeaderActions(): array
{
    return [
        Action::make('refresh')
            ->label('Refresh')
            ->icon('heroicon-o-refresh')
            ->action('updateOptions')
            ->button(),

        Action::make('download')
            ->label('Download')
            ->url(route('reports.export'))
            ->color('secondary'),
    ];
}

protected function getHeaderActionsAlignment(): ?Alignment
{
    return Alignment::End; // align header actions to the right
}
```

Example — footer actions:

```
use Filament\Actions\Action;
use Filament\Support\Enums\Alignment;

protected function getFooterActions(): array
{
    return [
        Action::make('details')
            ->label('Details')
            ->url(route('reports.details'))
            ->button(),
    ];
}

protected function getFooterActionsAlignment(): ?Alignment
{
    return Alignment::Center; // center footer actions
}
```

Notes:

- You may return `ActionGroup` instances if you need grouped or dropdown actions.
- Header actions are rendered next to any filter controls defined on the widget.
- Footer actions render above the footer content returned by `getFooter()`.

Hiding header content
---------------------

[](#hiding-header-content)

You can hide header content by **NOT** providing these

- $heading
- getHeading()
- $subheading
- getSubheading()
- getOptions()

Filtering chart data
--------------------

[](#filtering-chart-data)

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

### Filter schema

[](#filter-schema)

You may use components from the [Schemas](https://filamentphp.com/docs/4.x/schemas/overview#available-components) to create custom filters. You need to use `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 Asharif88\FilamentPlotly\Widgets\PlotlyWidget;

class BlogPostsChart extends PlotlyWidget
{
    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 `getChartData()` method:

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

    return [
        //chart options
    ];
}
```

### Single select

[](#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)
-----------------------

[](#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 static ?string $pollingInterval = '10s';
```

Alternatively, you may disable polling altogether:

```
protected static ?string $pollingInterval = null;
```

Defer loading
-------------

[](#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 getChartData(): array
{
    //showing a loading indicator immediately after the page load
    if (!$this->readyToLoad) {
        return [];
    }

    //slow query
    sleep(2);

    return [
        //chart options
    ];
}
```

Loading indicator
-----------------

[](#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');
}
```

```

    Loading...

```

Dark mode
---------

[](#dark-mode)

The dark mode is supported and enabled by default.

Publishing views
----------------

[](#publishing-views)

Optionally, you can publish the views using

```
php artisan vendor:publish --tag="filament-plotly-views"
```

Publishing translations
-----------------------

[](#publishing-translations)

Optionally, you can publish the translations using:

```
php artisan vendor:publish --tag=filament-plotly-translations
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](.github/SECURITY.md) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Ahmad SHARIF](https://github.com/Asharif88)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance86

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~9 days

Total

5

Last Release

112d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7bc3352a55b3d4643b40bfa1d42b4a3729f2729300e65e924a2e8b09fd31964f?d=identicon)[asharif88](/maintainers/asharif88)

---

Top Contributors

[![Asharif88](https://avatars.githubusercontent.com/u/1073094?v=4)](https://github.com/Asharif88 "Asharif88 (20 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

filament-widgetfilamentphplaravelplotlyplotlyjslaravelfilament-pluginfilamentphpfilament-v5filament-v4plotly.jsFilament Widgetsfilament-plotlyAhmad SHARIFAsharif88

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/asharif88-filament-plotly/health.svg)

```
[![Health](https://phpackages.com/badges/asharif88-filament-plotly/health.svg)](https://phpackages.com/packages/asharif88-filament-plotly)
```

###  Alternatives

[dotswan/filament-map-picker

Easily pick and retrieve geo-coordinates using a map-based interface in your Filament applications.

124139.3k2](/packages/dotswan-filament-map-picker)[bezhansalleh/filament-google-analytics

Google Analytics integration for FilamentPHP

205144.8k5](/packages/bezhansalleh-filament-google-analytics)[jibaymcs/filament-tour

Bring the power of DriverJs to your Filament panels and start a tour !

12247.8k](/packages/jibaymcs-filament-tour)[schmeits/filament-character-counter

This is a Filament character counter TextField and Textarea form field for Filament v4 and v5

33184.7k6](/packages/schmeits-filament-character-counter)[jiten14/jitone-ai

jitone-ai is a powerful FilamentPHP plugin that integrates AI-powered features directly into your Filament forms.

213.1k](/packages/jiten14-jitone-ai)[lara-zeus/popover

Zeus Popover is filamentphp component to show a Popover with custom content in tables and infolist

2968.2k3](/packages/lara-zeus-popover)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
