Code Monkey home page Code Monkey logo

filament-apex-charts's Introduction

Hello, I'm Leandro ✌️

PHP/Laravel developer from Brazil 🇧🇷

Currently, I'm engaged in my role as a member of the Filament core team, where I provide assistance to users across GitHub discussions and Discord platforms.

Additionally, I'm the creator behind https://youtube.com/@filamentbr, a dedicated YouTube channel focused on all things Filament within the Brazilian community.

👉 Tech Stack

Here are a few things I've picked up along my learning journey.

PHP MySQL JavaScript Laravel Livewire AlpineJs TailwindCss Filament Asterisk

📝 Latest Blog Posts

⚡ Plugins

📫 Get in touch

Mail

Twitter Follow Linkedin: oleandroferreira Instagram: oleandro.ferreira

filament-apex-charts's People

Contributors

adam-code-labx avatar anivon avatar billmn avatar cheesegrits avatar dependabot[bot] avatar github-actions[bot] avatar howdu avatar leandrocfe avatar stephanus-tantiono avatar valpuia avatar wilfredchen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

filament-apex-charts's Issues

Laravel can't locate Component

Hi,

I've been upgraded package from v1 to v2. But after i publish the views and try to run in filament it send me this error
image

Am i missing something?

extraJsOptions

Filament-Apex-Charts is a wonderful package, thank you for that!

I don't know whether it is a bug or I don't understand how to use it, but I can't get the extraJsOptions to work.

I tried to replicate the Revenue bar chart from your Demo application in a simplified form.
What I want is to format the labels on the Y-axis, where the values should be prefixed with a '$'.

However, it does not show up. I tried several other parameters like the y-axis title, but nothing seems to work.

Do I miss something?

The code is as follows:

namespace App\Filament\Widgets;

use Filament\Support\RawJs;
use Illuminate\Support\Facades\Log;
use Leandrocfe\FilamentApexCharts\Widgets\ApexChartWidget;

class RevenueOverview extends ApexChartWidget
{
    /**
     * Chart Id
     *
     * @var string
     */
    protected static ?string $chartId = 'RevenueOverview';

    /**
     * Widget Title
     *
     * @var string|null
     */
    protected static ?string $heading = 'Revenue';

    /**
     * Chart options (series, labels, types, size, animations...)
     * https://apexcharts.com/docs/options
     *
     * @return array
     */
    protected function getOptions(): array
    {
        return [
            'chart' => [
                'type' => 'bar',
                'height' => 300,
                'stacked' => true,
                'toolbar' => [
                    'show' => false,
                ],
            ],
            'dataLabels' => [
                'enabled' => false,
            ],
            'series' => [
                [
                    'name' => 'Earnings',
                    'data' => [70, 43, 68, 103, 141, 73, 57, 92, 102, 159, 130, 184],
                ],
                [
                    'name' => 'Expenses',
                    'data' => [-7, -4, -6, -10, -14, -7, -5, -9, -10, -15, -13, -18],
                ],
            ],
        ];
    }

    protected function extraJsOptions(): ?RawJs
    {
        return RawJs::make(<<<'JS'
        {
            yaxis: {
                labels: {
                    formatter: function (val, index) {
                        return '$' + val
                    }
                }
            }
        }
        JS);
    }
}

Cannot install this package

Hey, do you have any idea why I always try to install this package in my Filament php 2.x project and get this message

image

Zoom buttons in toolbar doesn't work

Hi!

chart.toolbar.tools (selection, zoom, pan) and chart.zoom from docs doesn't work. Only download button works.

Docs: https://apexcharts.com/docs/interactivity/

<?php

namespace App\Filament\Widgets;

use Leandrocfe\FilamentApexCharts\Widgets\ApexChartWidget;

class ParkingMeterPaymentChart extends ApexChartWidget
{
    protected static string $chartId = 'parkingMeterPaymentChart';
    protected static ?string $heading = 'ParkingMeterPaymentChart';
    protected int | string | array $columnSpan = 'full';
    protected static ?string $pollingInterval = null;

    protected function getOptions(): array
    {
        return [
            'chart' => [
                'type' => 'bar',
                'height' => 480,
                'toolbar' => [
                    'show' => true,
                    'tools' => [
                        'download' => true,
                        'selection' => true,
                        'zoom' => true,
                        'zoomin' => true,
                        'zoomout' => true,
                        'pan' => true,
                    ],
                ],
                'zoom' => [
                    'enabled' => true
                ],
            ],
            'series' => [
                [
                    'name' => 'BasicColumnChart',
                    'data' => [7, 4, 6, 10, 14, 7, 5, 9, 10, 15, 13, 18,],
                ],
            ],
            'xaxis' => [
                'categories' => [
                    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
                ],
                'labels' => [
                    'rotate' => -90,
                    'style' => [
                        'colors' => '#9ca3af',
                    ],
                ],
            ],
            'yaxis' => [
                'labels' => [
                    'style' => [
                        'colors' => '#9ca3af',
                        'fontWeight' => 600,
                    ],
                ],
            ],
            'colors' => ['#f59e0b'],
        ];
    }
}

Xnip2023-12-08_18-28-15

Rendering problem using single select filter

There is some rendering problem on single select filter change, this is the result:

Registrazione.schermo.2023-05-26.alle.15.56.01.mov

With filters form all works fine.

I have used this example code:

class TestApexTicketsChart extends ApexChartWidget
{
    protected static string $chartId = 'testApexChart';

    protected static ?string $heading = 'Test Apex Chart';

    protected int | string | array $columnSpan = 'full';

    public ?string $filter = '6_months';

    protected function getFilters(): ?array
    {
        return [
            '6_months' => 'Last 6 months',
            '12_months' => 'Last 12 months',
            '24_months' => 'Last 24 months',
        ];
    }

    protected function getOptions(): array
    {
        return [
            'chart' => [
                'type' => 'line',
                'height' => 300,
            ],
            'series' => [
                [
                    'name' => 'Test Apex Chart',
                    'data' => [2, 4, 6, 10, 14, 7, 2, 9, 10, 15, 13, 18],
                ],
            ],
            'xaxis' => [
                'categories' => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
            ],
        ];
    }
}

Problem in light mode

When I change from dark to light mode, the colors are set correctly.
image

However, when I refresh the page, this problem occurs.
image

dropdownOpen not defined

Hello,
Every time I add a chart I get an error where "dropdownOpen" is not defined. This causes charts not to load properly and filters not to work at all.

Version:
"leandrocfe/filament-apex-charts": "^3.0",

image

ApexCharts is not defined after update

Hi,

I updated the filament a few weeks ago and i got an error in chrome console

Uncaught ReferenceError: ApexCharts is not defined at Proxy.init (eval at safeAsyncFunction (livewire.js?id=e2b302e9:1249:21), <anonymous>:16:38) at livewire.js?id=e2b302e9:1235:25 at tryCatch (livewire.js?id=e2b302e9:1191:14) at evaluate (livewire.js?id=e2b302e9:1215:34) at Function.<anonymous> (livewire.js?id=e2b302e9:3479:29) at flushHandlers (livewire.js?id=e2b302e9:1353:48) at stopDeferring (livewire.js?id=e2b302e9:1358:7) at deferHandlingDirectives (livewire.js?id=e2b302e9:1361:5) at initTree (livewire.js?id=e2b302e9:876:5) at livewire.js?id=e2b302e9:824:23

and the charts do not appear. the updated versions:

  • filament/filament v3.1.24
  • leandrocfe/filament-apex-charts 3.0.2

I was waiting for a newer version, I just updated to these:

  • filament/filament v3.2.10
  • leandrocfe/filament-apex-charts 3.1.2

but the error is the same.

can you help me to find the error?

thanks

Component namespacing?

Hi,

I was wondering if it would be possible to namespace the used components since it is conflicting with components we use in our own project?

We use <x-header> ourselves but since installing your package, this now throws an exception. Therefore, I was wondering whether maybe it would be possible to namespace the components so it would be something like <x-filament-apex-charts::header>?

Widget Register Issue

I've create a widget and I used the on an Edit or View page, however the Filament still showing that to the dashboard even if the widget is not registered on the filament config.

Not sure if this issues is on the plug-in or on the filament it self.

Change on single filter doesnt update

Hi,

I copied a working graph from v2 in filament v2 to current version 3.0.1 in Filament 3.027

Upon selecting single filter, there is no update request.

public ?string $filter = '2023';

/**
 * Filter Options
 */
protected function getFilters(): ?array
{
    $years = range(now()->year, 2015);

    foreach ($years as $year) {
        $newYears[$year] = $year;
    }

    return $newYears;
}

/**
 * Chart options (series, labels, types, size, animations...)
 * https://apexcharts.com/docs/options
 *
 * @return array
 */
protected function getOptions(): array
{
    $activeFilter = $this->filter;

    $data = Trend::query(Stat::where('type', 'sales')->where('system', 'MY'))
        ->between(
            start: Carbon::create($activeFilter)->startOfYear(),
            end: Carbon::create($activeFilter)->endOfYear(),
        )
        ->perMonth()
        ->sum('data');

    return [

        'chart' => [
            'type' => 'line',
            'height' => 300,
            'toolbar' => [
                'show' => false,
            ],
        ],
        'series' => [
            [
                'name' => 'RM',
                'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
                'type' => 'column',
            ],
        ],
        'stroke' => [
            'width' => [0, 4],
            'curve' => 'smooth',
        ],
        'xaxis' => [
            'categories' => $data->map(fn (TrendValue $value) => Carbon::parse($value->date)->format('M')),
            'labels' => [
                'style' => [
                    'colors' => '#9ca3af',
                    'fontWeight' => 600,
                ],
            ],
        ],
        'yaxis' => [
            'labels' => [
                'style' => [
                    'colors' => '#9ca3af',
                    'fontWeight' => 600,
                ],
            ],
        ],
        'legend' => [
            'labels' => [
                'colors' => '#9ca3af',
                'fontWeight' => 600,
            ],
        ],
        'colors' => ['#6366f1', '#38bdf8'],
        'fill' => [
            'type' => 'gradient',
            'gradient' => [
                'shade' => 'dark',
                'type' => 'vertical',
                'shadeIntensity' => 0.5,
                'gradientToColors' => ['#d946ef'],
                'inverseColors' => true,
                'opacityFrom' => 1,
                'opacityTo' => 1,
                'stops' => [0, 100],
            ],
        ],
        'plotOptions' => [
            'bar' => [
                'borderRadius' => 10,
            ],
        ],
    ];
}

public function data($i)
{
    $stat = new stat;

    return $stat->select('data')
        ->whereBetween('created_at', [now()->firstOfYear()->addMonths($i - 1)->toDateString(), now()->firstOfYear()->addMonths($i - 1)->endOfMonth()->toDateString()])
        ->sum('data');
}

The documentation were just being updated with adding reactive if using getFormSchema().

Is this a bug or something i am missing when using getFilters()

Fix stub path for non-Windows environments

Problem

The following exception occurs:

file_get_contents(/app/vendor/leandrocfe/filament-apex-charts/src/CommandsLine.stub): Failed to open stream: No such file or directory

Steps to reproduce

Within a Linux container, run php artisan make:filament-apex-charts BlogPostsChart.

Proposed resolution

It is my understanding that Windows supports forward slashes.

Update getStubPath to use forward slashes:

        $path = Str::of(__DIR__)
            ->replace('src/Commands', 'stubs/')

If this does not work on Windows, then this works too:

        $path = Str::of(__DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR)

Though, judging by FortifyServiceProvider.php, this seems like the way to go:

        $path = Str::of(__DIR__.'../../stubs/')

Chart id is not unique when rendering component in a loop.

If I try to render a Chart Widget in a loop, all of the charts get appended to the first component.

I guess it is due to protected static string $chartId = 'apexChart' being assigned a default value. Hence

/**
* Retrieves the chart id.
*
* @return string|null The chart id.
*/
protected function getChartId(): ?string
{
    return static::$chartId ?? 'apexChart_'.Str::random(10);
}

will never append a random string.

Changing the property to protected static ?string $chartId will do the trick but I'm not sure if this leads to unwanted side effects.

image

If you think making the property nullable will do the trick, I'm happy to submit a PR.

Graphs in darkmode

Hi
using the graphs in dark mode, makes labels unreadable
see screenshots
Screenshot 2023-02-02 at 10 34 25
Screenshot 2023-02-02 at 10 34 18
vs
Screenshot 2023-02-02 at 10 34 08

Label not visible in light theme

Screenshot from 2023-06-03 09-14-36

Label is not visible in light mode, but in dark it's correct

"version": "1.0.3",

Updated: Label can visible if you change your theme to dark and change again.. otherwise it's like image

Lazy Load Widgets

Would you be open to integrating this project with Livewire's deferred loading feature?

If so, would you like me to create a pull request for the changes?

I'm using a 3rd party API to populate the APEX Charts, which makes the page extremely slow to load on the first time when the data is not cached, but the deferred loading feature is a nice fix.

Apex chart squashed in mobile view

Using Filament v3.2.15 with the Apex charts plugin v3.1.2, my stacked bar chart is coming out squashed almost flat on a mobile phone.

Screenshot_20240205_105220_Chrome

My code:

<?php

namespace App\Filament\Widgets;

use App\Models\Quote;
use Illuminate\Support\Carbon;
use Filament\Forms\Components\DatePicker;
use Leandrocfe\FilamentApexCharts\Widgets\ApexChartWidget;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;

class QuotesChart extends ApexChartWidget
{
    /**
     * Chart Id
     *
     * @var string
     */
    protected static ?string $chartId = 'quotesChart';

    /**
     * Widget Title
     *
     * @var string|null
     */
    protected static ?string $heading = 'Quotes';

    // Set to full width
    protected int | string | array $columnSpan = 'full';

    // Filter options
    protected function getFormSchema(): array
    {
        return [

            DatePicker::make('date_start')
                ->default(now()->subRealMonths(6)),
            DatePicker::make('date_end')
                ->default(now()),
        ];
    }

    /**
     * Chart options (series, labels, types, size, animations...)
     * https://apexcharts.com/docs/options
     *
     * @return array
     */
    protected function getOptions(): array
    {
        $dateStart = Carbon::parse($this->filterFormData['date_start']);
        $dateEnd = Carbon::parse($this->filterFormData['date_end']);

        $yAxis = Trend::model(Quote::class)
            ->between(
                start: $dateStart,
                end: $dateEnd,
            )
            ->perMonth()
            ->count();

        //@TODO Sort out code repetition below. No need for separate block for each status

        $declined = Trend::query(Quote::query()->where('status', 'declined'))
            ->between(
                start: $dateStart,
                end: $dateEnd,
            )
            ->perMonth()
            ->count();

        $draft = Trend::query(Quote::query()->where('status', 'draft'))
            ->between(
                start: $dateStart,
                end: $dateEnd,
            )
            ->perMonth()
            ->count();

        $published = Trend::query(Quote::query()->where('status', 'published'))
            ->between(
                start: $dateStart,
                end: $dateEnd,
            )
            ->perMonth()
            ->count();

        $review = Trend::query(Quote::query()->where('status', 'review'))
            ->between(
                start: $dateStart,
                end: $dateEnd,
            )
            ->perMonth()
            ->count();

        $accepted = Trend::query(Quote::query()->where('status', 'accepted'))
            ->between(
                start: $dateStart,
                end: $dateEnd,
            )
            ->perMonth()
            ->count();

        return [
            'chart' => [
                'type' => 'bar',
                'stacked' => true,
                'responsive' => [
                    'breakpoint' => '435px',
                    'options' => [
                        'height' => '300px',
                    ],
                ],
            ],
            //@TODO Sort out code repetition below. No need for separate block for each status
            'series' => [
                [
                    'name' => 'draft',
                    'data' => $draft->map(fn (TrendValue $value) => $value->aggregate),
                ],
                [
                    'name' => 'published',
                    'data' => $published->map(fn (TrendValue $value) => $value->aggregate),
                ],
                [
                    'name' => 'review',
                    'data' => $review->map(fn (TrendValue $value) => $value->aggregate),
                ],
                [
                    'name' => 'declined',
                    'data' => $declined->map(fn (TrendValue $value) => $value->aggregate),
                ],
                [
                    'name' => 'accepted',
                    'data' => $accepted->map(fn (TrendValue $value) => $value->aggregate),
                ],
            ],
            'xaxis' => [
                'categories' => $yAxis->map(fn (TrendValue $value) => date_format(date_create($value->date), 'M y')),
                'labels' => [
                    'style' => [
                        'fontFamily' => 'inherit',
                    ],
                ],
            ],
            'yaxis' => [
                'labels' => [
                    'style' => [
                        'fontFamily' => 'inherit',
                    ],
                ],
            ],
            'dataLabels'=> [
                'enabled' => true,
            ],
            'colors' => ['#d3d3d3', '#00bfff', '#ff7e00', '#ff0000', '#32cd32'],
            'plotOptions' => [
                'column' => [
                    'borderRadius' => 3,
                    'horizontal' => false,
                ],
            ],
        ];
    }
}

Circle chart

Hi, thanks for this awesome package,
As I checked, I think the circle type is missing, how can I add it? thanks

Datalabel formatter

Hi,

How can I make use of the datalabel formatter?

I have the following array I return;

return [
            'chart' => [
                'type' => 'bar',
                'height' => 300,
                'animations' => [
                    'enabled' => false
                ],
            ],
            'series' => [
                [
                    'name' => 'Sales',
                    'data' => $totalSoldByProduct->pluck('total_revenue')->toArray(),
                ],
            ],
            'xaxis' => [
                'categories' => $totalSoldByProduct->pluck('name')->toArray(),
                'labels' => [
                    'style' => [
                        'colors' => '#9ca3af',
                        'fontWeight' => 600,
                    ],
                ],
            ],
            'yaxis' => [
                'labels' => [
                    'style' => [
                        'colors' => '#9ca3af',
                        'fontWeight' => 600,
                    ],
                ],
            ],
            'dataLabels' => [
                'enabled' => true,
                'formatter' => 'function(val, opts) {
                    return "Sold " + val;
                }',
                'style' => [
                    'colors' => ['#fff'],
                ],
            ],
            'colors' => ['#1da6e7'],
        ];

As you see, there is a formatter;

 'formatter' => 'function(val, opts) {
                    return "Sold " + val;
                }',

But this does not work? How can I achieve this to work?

Make chart title div empty if null is passed in header

Note: This is not an issue, it more like feature suggesstion..

I want to display pie chart, but I don't want Title and other related headings data..

If I passed protected static ?string $heading = null; or 'getHeading(return null)` It display empty div content..

I published vendor file and change according to my need like below (return header content if not null)

<div>
    @if ($heading != null)
        ... // original code

        <x-filament::hr class="py-2" />
    @endif
</div>

Will it be great to return like this (or maybe improvement) if the heading == null or other flag like noHeading

or is there any other way to display chart without header or header content (title, div content, filter etc)

Updating chart data not working

Hey, I have problems with updating the chart data. I change the data outside of my chart component and use Livewire's Reactive attribute to trigger the update. However, nothing happens. This is my setup:

<?php

namespace App\Livewire;

use Leandrocfe\FilamentApexCharts\Widgets\ApexChartWidget;
use Livewire\Attributes\Reactive;

class FooChart extends ApexChartWidget
{
    #[Reactive]
    public array $data = [];

    protected function getOptions(): array
    {
        return [
            'chart' => [
                'type' => 'line',
                'height' => 300,
            ],
            'series' => [
                [
                    'name' => 'BasicLineChart',
                    'data' => $this->data,
                ],
            ],
        ];
    }
}

I've checked the source code of Filaments ChartWidget and noticed a rendering() method that is missing in ApexChartWidget. If we add that, updating works as expected:

# vendor/leandrocfe/filament-apex-charts/src/Widgets/ApexChartWidget.php

/**
 * Updates the options of the class and emits an event if the options have changed.
 */
public function updateOptions(): void
{
    if ($this->options !== $this->getOptions()) {

        $this->options = $this->getOptions();

        if (!$this->dropdownOpen) {
            $this
                ->dispatch('updateOptions', options: $this->options)
                ->self();
        }
    }
}

public function rendering(): void
{
    $this->updateOptions();
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.