Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

uniqueginun's avatar

Livewire charts

I'm building Apex-Charts inside livewire component like this:

<div class="row justify-content-center mt-lg-5">

    <p class="font-monospace text-center text-danger">
        chart data for: {{ $filter }}
    </p>

    <div class="col-sm-3 mb-3">
        <select class="form-control" wire:model="filter">
            @foreach($filters as $filter)
                <option value="{{ $filter }}">{{ $filter }}</option>
            @endforeach
        </select>
    </div>

    <div class="col-6">
        <div id="chart"></div>
    </div>


    @slot('scripts')

        <script>

            window.addEventListener('DOMContentLoaded', (event) => {
                renderChart(@json($chartData));
            });


            window.addEventListener('renderChart', ({detail}) => {
                renderChart(detail.data);
            }, false);

            const renderChart = chartData => {

                const counts = chartData.map(item => item.count);
                const years = chartData.map(item => item.year);

                const chart = new ApexCharts(document.querySelector("#chart"), {
                    chart: {
                        type: 'line'
                    },
                    series: [{
                        name: 'sales',
                        data: counts
                    }],
                    xaxis: {
                        categories: years
                    }
                });

                chart.render();
            }

        </script>

    @endslot

</div>

Component class

<?php

namespace App\Http\Livewire;

use Illuminate\Support\Facades\DB;
use Livewire\Component;

class Charts extends Component
{
    public $filter = 'male';

    public $chartData;

    public function mount()
    {
        $this->chartData = $this->getCollection();
    }


    public function updatedFilter($value)
    {
        $this->loadChartData();
    }

    public function render()
    {
        return view('livewire.charts', [
            'filters' => DB::table('sales')
                            ->distinct('seller_type')
                            ->pluck('seller_type')
        ]);
    }

    public function loadChartData()
    {
        $this->dispatchBrowserEvent('renderChart', [
            'data' => $this->getCollection()
        ]);
    }


    private function getCollection()
    {
        return DB::table('sales')
            ->selectRaw('count(*) as count, selling_year as year')
            ->groupBy('selling_year')
            ->orderBy('selling_year')
            ->where('seller_type', $this->filter)
            ->get();
    }
}

now the above code is working and everything but notice I have to use this public property $chartData just for the first time when component initialized because front-end won't be able to listen to renderChart event fired from the backend because component won't be initialized yet so I have to send some data to create the chart. and I can't keep using it relaying on that changing $filter variable would change $chartData and the component will render the filtered data again because it is'nt working.

so I had to create this public property to render chart at first time and then firing event and send data to it every time.

my question is: I know there's a better way to do this!!

0 likes
2 replies

Please or to participate in this conversation.