Skip to content
Advertisement

Passing dynamically data via JS to a chart in a Laravel/Livewire project

i’m developing a laravel 8 + livewire application, and in my app I need to dynamically populate charts. When I insert the charts with static data in my view it is populated and shown correctly, but when I try to populate it dynamically it doesn’t show me anything. To pass the data to the script, from my livewire controller I used the dispatchBrowserEvent method and in the view I listened to the event. But by doing so I don’t get anything and I don’t understand why … do you have any suggestions or ideas?

this is my code:

  • livewire component: TableReportResiduiFasce.php
<?php

namespace AppHttpLivewire;

use LivewireComponent;
use IlluminateHttpRequest;
use IlluminateSupportFacadesDB;
use LivewireWithPagination;
use AppTenant;
use IlluminateDatabaseEloquentBuilder;
use IlluminateSupportCarbon;
use AppModelsAnagraficaSoggetto;

class TableReportResiduiFasce extends Component
{
    use WithPagination;

    protected $paginationTheme = 'bootstrap';

    protected $connection = null;
    protected $render = true;
    public $fascia1 = null;
    public $fascia2 = null;
    public $fascia3 = null;
    public $fascia4 = null;
    public $fascia5 = null;
    public $fascia6 = null;
    public $tot_posizioni = null;
    public $tot_residuo = null;

    public function mount(Request $request)
    {
       // Setto la connessione
        if (null !== $request->get('throughMiddleware')) {
            $this->connection = 'tenant';
        } else {
            $this->connection = null;
        }

        $anagrafica = new AnagraficaSoggetto();
        $anagrafica->setConnection($this->connection);

        //query fascia 1, conto il numero di contribuenti con un residuo >0 e < 100
        $this->fascia1 = $anagrafica->select(
            DB::raw('count(anagrafica_soggetto.codiceFiscale) as total'),
            DB::raw('sum(importoResiduo) as residuo')
        )
            ->join('minuta_partita', 'minuta_partita.id_soggetto', '=', 'anagrafica_soggetto.id')
            ->join('partita_pagamenti', 'partita_pagamenti.id_minuta_partita', '=', 'minuta_partita.id', 'left outer')
            ->join('users', 'minuta_partita.id_user', '=', 'users.id', 'left outer')
            ->join('tipologia_imposta', 'minuta_partita.id_tipologia_imposta', '=', 'tipologia_imposta.id')
            ->whereBetween('importoResiduo', [1, 99])->get()->toArray();
    

        //query fascia 2, conto il numero di contribuenti con un residuo >=100 e <=1000
        $this->fascia2 = $anagrafica->select(
            DB::raw('count(anagrafica_soggetto.codiceFiscale) as total'),
            DB::raw('sum(importoResiduo) as residuo')
        )
            ->join('minuta_partita', 'minuta_partita.id_soggetto', '=', 'anagrafica_soggetto.id')
            ->join('partita_pagamenti', 'partita_pagamenti.id_minuta_partita', '=', 'minuta_partita.id', 'left outer')
            ->join('users', 'minuta_partita.id_user', '=', 'users.id', 'left outer')
            ->join('tipologia_imposta', 'minuta_partita.id_tipologia_imposta', '=', 'tipologia_imposta.id')
            ->whereBetween('importoResiduo', [100, 1000])->get()->toArray();
        

        //query fascia 1, conto il numero di contribuenti con un residuo >1000 e <= 5000
        $this->fascia3 = $anagrafica->select(
            DB::raw('count(anagrafica_soggetto.codiceFiscale) as total'),
            DB::raw('sum(importoResiduo) as residuo')
        )
            ->join('minuta_partita', 'minuta_partita.id_soggetto', '=', 'anagrafica_soggetto.id')
            ->join('partita_pagamenti', 'partita_pagamenti.id_minuta_partita', '=', 'minuta_partita.id', 'left outer')
            ->join('users', 'minuta_partita.id_user', '=', 'users.id', 'left outer')
            ->join('tipologia_imposta', 'minuta_partita.id_tipologia_imposta', '=', 'tipologia_imposta.id')
            ->whereBetween('importoResiduo', [1001, 5000])->get()->toArray();
        

        //query fascia 1, conto il numero di contribuenti con un residuo >5000 e <= 10000
        $this->fascia4 = $anagrafica->select(
            DB::raw('count(anagrafica_soggetto.codiceFiscale) as total'),
            DB::raw('sum(importoResiduo) as residuo')
        )
            ->join('minuta_partita', 'minuta_partita.id_soggetto', '=', 'anagrafica_soggetto.id')
            ->join('partita_pagamenti', 'partita_pagamenti.id_minuta_partita', '=', 'minuta_partita.id', 'left outer')
            ->join('users', 'minuta_partita.id_user', '=', 'users.id', 'left outer')
            ->join('tipologia_imposta', 'minuta_partita.id_tipologia_imposta', '=', 'tipologia_imposta.id')
            ->whereBetween('importoResiduo', [5001, 10000])->get()->toArray();
        

        //query fascia 5, conto il numero di contribuenti con un residuo >10000 e <=20000
        $this->fascia5 = $anagrafica->select(
            DB::raw('count(anagrafica_soggetto.codiceFiscale) as total'),
            DB::raw('sum(importoResiduo) as residuo')
        )
            ->join('minuta_partita', 'minuta_partita.id_soggetto', '=', 'anagrafica_soggetto.id')
            ->join('partita_pagamenti', 'partita_pagamenti.id_minuta_partita', '=', 'minuta_partita.id', 'left outer')
            ->join('users', 'minuta_partita.id_user', '=', 'users.id', 'left outer')
            ->join('tipologia_imposta', 'minuta_partita.id_tipologia_imposta', '=', 'tipologia_imposta.id')
            ->whereBetween('importoResiduo', [10001, 200000])->get()->toArray();
        

        //query fascia 1, conto il numero di contribuenti con un residuo >20000
        $this->fascia6 = $anagrafica->select(
            DB::raw('count(anagrafica_soggetto.codiceFiscale) as total'),
            DB::raw('sum(importoResiduo) as residuo')
        )
            ->join('minuta_partita', 'minuta_partita.id_soggetto', '=', 'anagrafica_soggetto.id')
            ->join('partita_pagamenti', 'partita_pagamenti.id_minuta_partita', '=', 'minuta_partita.id', 'left outer')
            ->join('users', 'minuta_partita.id_user', '=', 'users.id', 'left outer')
            ->join('tipologia_imposta', 'minuta_partita.id_tipologia_imposta', '=', 'tipologia_imposta.id')
            ->where('importoResiduo', '>', 20000)->get()->toArray();

        if (!empty($this->fascia1[0])) {
            $this->tot_posizioni = $this->tot_posizioni + $this->fascia1[0]['total'];
            $this->tot_residuo = $this->tot_residuo + $this->fascia1[0]['residuo'];
        }

        if (!empty($this->fascia2[0])) {
            $this->tot_posizioni = $this->tot_posizioni + $this->fascia2[0]['total'];
            $this->tot_residuo = $this->tot_residuo + $this->fascia2[0]['residuo'];
        }

        if (!empty($this->fascia3[0])) {
            $this->tot_posizioni = $this->tot_posizioni + $this->fascia3[0]['total'];
            $this->tot_residuo = $this->tot_residuo + $this->fascia3[0]['residuo'];
        }

        if (!empty($this->fascia4[0])) {
            $this->tot_posizioni = $this->tot_posizioni + $this->fascia4[0]['total'];
            $this->tot_residuo = $this->tot_residuo + $this->fascia4[0]['residuo'];
        }

        if (!empty($this->fascia5[0])) {
            $this->tot_posizioni = $this->tot_posizioni + $this->fascia5[0]['total'];
            $this->tot_residuo = $this->tot_residuo + $this->fascia5[0]['residuo'];
        }

        if (!empty($this->fascia6[0])) {
            $this->tot_posizioni = $this->tot_posizioni + $this->fascia6[0]['total'];
            $this->tot_residuo = $this->tot_residuo + $this->fascia6[0]['residuo'];
        }

        $this->dispatchBrowserEvent('open',['fascia1' => $this->fascia1, 
                                            'fascia2' => $this->fascia2,
                                            'fascia3' => $this->fascia3,
                                            'fascia4' => $this->fascia4,
                                            'fascia5' => $this->fascia5,
                                            'fascia6' => $this->fascia6,
                                            'tot_posizioni' => $this->tot_posizioni]);
        //dd($this->fascia3);
    }

    public function render()
    {
        return view('livewire.table-report-residui-fasce')
        ->with('fascia1', $this->fascia1)
        ->with('fascia2', $this->fascia2)
        ->with('fascia3', $this->fascia3)
        ->with('fascia4', $this->fascia4)
        ->with('fascia5', $this->fascia5)
        ->with('fascia6', $this->fascia6)
        ->with('tot_posizioni', $this->tot_posizioni)
        ->with('tot_residuo', $this->tot_residuo);
    }
}

  • my view: table-report-residui-fasce.blade.php
<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-header">
                <h4 class="card-title">Report residui per fasce</h4>
            </div>
            <div class="card-body">
                <div class="table-responsive">
                    <table class="table table-responsive-md" style="min-width: 845px">
                        <thead>
                            <tr>
                                <th>Fascia</th>
                                <th># Posizioni</th>
                                <th>Residuo &euro;</th>
                                <th>% Posizioni</th>
                                <th>% Residuo</th>
                                <th>Valore Medio &euro;</th>
                            </tr>
                        </thead>
                        <tbody>
                            @if ($fascia1[0]['total'] !== 0)
                                <tr>
                                    <td><span class="badge light badge-lg badge-info">
                                            < 100 &euro;</span>
                                    </td>
                                    <td>{{ $fascia1[0]['total'] }}</td>
                                    <td>{{ $fascia1[0]['residuo'] }} &euro;</td>
                                    <td>{{ round((100 * $fascia1[0]['total']) / $tot_posizioni, 2) }} % </td>
                                    <td>{{ round((100 * $fascia1[0]['residuo']) / $tot_residuo, 2) }} %</td>
                                    <td>
                                        @if (!empty($fascia1[0]['total']))
                                        {{ round($fascia1[0]['residuo'] / $fascia1[0]['total'], 2) }} @else 0
                                        @endif &euro;
                                    </td>
                                </tr>
                            @else
                                <tr>
                                    <td><span class="badge light badge-lg badge-info">
                                            < 100 &euro;</span>
                                    </td>
                                    <td>0</td>
                                    <td>0 &euro;</td>
                                    <td>0 % </td>
                                    <td>0 %</td>
                                    <td>0 &euro;</td>
                                </tr>
                            @endif
                            @if ($fascia2[0]['total'] !== 0)
                                <tr>
                                    <td><span class="badge light badge-lg badge-success">100 - 1000 &euro;</span></td>
                                    <td>{{ $fascia2[0]['total'] }}</td>
                                    <td>{{ $fascia2[0]['residuo'] }} &euro;</td>
                                    <td>{{ round((100 * $fascia2[0]['total']) / $tot_posizioni, 2) }} % </td>
                                    <td>{{ round((100 * $fascia2[0]['residuo']) / $tot_residuo, 2) }} %</td>
                                    <td>
                                        @if (!empty($fascia2[0]['total']))
                                        {{ round($fascia2[0]['residuo'] / $fascia2[0]['total'], 2) }} @else 0
                                        @endif &euro;
                                    </td>
                                </tr>
                            @else
                                <tr>
                                    <td><span class="badge light badge-lg badge-success"> 100 - 1000 &euro;</span></td>
                                    <td>0</td>
                                    <td>0 &euro;</td>
                                    <td>0 % </td>
                                    <td>0 %</td>
                                    <td>0 &euro;</td>
                                </tr>
                            @endif
                            @if ($fascia3[0]['total'] !== 0)
                                <tr>
                                    <td><span class="badge light badge-lg badge-light">1000 - 5000 &euro;</span></td>
                                    <td>{{ $fascia3[0]['total'] }}</td>
                                    <td>{{ $fascia3[0]['residuo'] }} &euro;</td>
                                    <td>{{ round((100 * $fascia3[0]['total']) / $tot_posizioni, 2) }} % </td>
                                    <td>{{ round((100 * $fascia3[0]['residuo']) / $tot_residuo, 2) }} %</td>
                                    <td>
                                        @if (!empty($fascia3[0]['total']))
                                        {{ round($fascia3[0]['residuo'] / $fascia3[0]['total'], 2) }} @else 0
                                        @endif &euro;
                                    </td>
                                </tr>
                            @else
                                <tr>
                                    <td><span class="badge light badge-lg badge-light"> 1000 - 5000 &euro;</span></td>
                                    <td>0</td>
                                    <td>0 &euro;</td>
                                    <td>0 % </td>
                                    <td>0 %</td>
                                    <td>0 &euro;</td>
                                </tr>
                            @endif
                            @if ($fascia4[0]['total'] !== 0)
                                <tr>
                                    <td><span class="badge light badge-lg badge-dark">5000 - 10000 &euro;</span></td>
                                    <td>{{ $fascia4[0]['total'] }}</td>
                                    <td>{{ $fascia4[0]['residuo'] }} &euro;</td>
                                    <td>{{ round((100 * $fascia4[0]['total']) / $tot_posizioni, 2) }} % </td>
                                    <td>{{ round((100 * $fascia4[0]['residuo']) / $tot_residuo, 2) }} %</td>
                                    <td>
                                        @if (!empty($fascia4[0]['total']))
                                        {{ round($fascia4[0]['residuo'] / $fascia4[0]['total'], 2) }} @else 0
                                        @endif &euro;
                                    </td>
                                </tr>
                            @else
                                <tr>
                                    <td><span class="badge light badge-lg badge-dark"> 5000 - 10000 &euro;</span> </td>
                                    <td>0</td>
                                    <td>0 &euro;</td>
                                    <td>0 % </td>
                                    <td>0 %</td>
                                    <td>0 &euro;</td>
                                </tr>
                            @endif
                            @if ($fascia5[0]['total'] !== 0)
                                <tr>
                                    <td><span class="badge light badge-lg badge-warning">10000 - 20000 &euro;</span>
                                    </td>
                                    <td>{{ $fascia5[0]['total'] }}</td>
                                    <td>{{ $fascia5[0]['residuo'] }} &euro;</td>
                                    <td>{{ round((100 * $fascia5[0]['total']) / $tot_posizioni, 2) }} % </td>
                                    <td>{{ round((100 * $fascia5[0]['residuo']) / $tot_residuo, 2) }} %</td>
                                    <td>
                                        @if (!empty($fascia5[0]['total']))
                                        {{ round($fascia5[0]['residuo'] / $fascia5[0]['total'], 2) }} @else 0
                                        @endif &euro;
                                    </td>
                                </tr>
                            @else
                                <tr>
                                    <td><span class="badge light badge-lg badge-warning"> 10000 - 20000 &euro; </span>
                                    </td>
                                    <td>0</td>
                                    <td>0 &euro;</td>
                                    <td>0 % </td>
                                    <td>0 %</td>
                                    <td>0 &euro;</td>
                                </tr>
                            @endif
                            @if ($fascia6[0]['total'] !== 0)
                                <tr>
                                    <td><span class="badge light badge-lg badge-danger"> > 2000 &euro;</span></td>
                                    <td>{{ $fascia6[0]['total'] }}</td>
                                    <td>{{ $fascia6[0]['residuo'] }} &euro;</td>
                                    <td>{{ round((100 * $fascia6[0]['total']) / $tot_posizioni, 2) }} % </td>
                                    <td>{{ round((100 * $fascia6[0]['residuo']) / $tot_residuo, 2) }} %</td>
                                    <td>
                                        @if (!empty($fascia6[0]['total']))
                                        {{ round($fascia6[0]['residuo'] / $fascia6[0]['total'], 2) }} @else 0
                                        @endif &euro;
                                    </td>
                                </tr>
                            @else
                                <tr>
                                    <td><span class="badge light badge-lg badge-danger"> > 20000 &euro;</span> </td>
                                    <td>0</td>
                                    <td>0 &euro;</td>
                                    <td>0 % </td>
                                    <td>0 %</td>
                                    <td>0 &euro;</td>
                                </tr>
                            @endif
                        </tbody>
                        <tfoot>
                            <th></th>
                            <th>Tot posizioni: {{ $tot_posizioni }}</th>
                            <th>Tot residuo: {{ $tot_residuo }} &euro;</th>
                            <th>100%</th>
                            <th>100%</th>
                            <th>Tot medio: @if ($tot_posizioni != 0)
                                {{ round($tot_residuo / $tot_posizioni, 2) }} @else 0 @endif
                                &euro;</th>
                        </tfoot>
                    </table>
                </div>
            </div>
        </div>
    </div>
    <!-- grafichiamo i risultati stampati in tabella -->
    <div class="col-xl-6 col-lg-12">
        <div class="card">
            <div class="card-header">
                <h4 class="card-title">Residui per fasce</h4>
            </div>
            <div class="card-body">
                <div id="morris" class="morris_chart_height">
                    
                </div>
            </div>
        </div>
    </div>

</div>

@push('custom_scripts')
<script>

     
    //Codice per popolare il grafico
    var screenWidth = $(window).width();

    var setChartWidth = function() {
        if (screenWidth <= 768) {
            var chartBlockWidth = 0;
            chartBlockWidth = (screenWidth < 300) ? screenWidth : 300;
            jQuery('.morris_chart_height').css('min-width', chartBlockWidth - 31);
        }
    }
    // VALORI HARD CODED SOLO A FINI DI TEST DI STAMPA A VIDEO DEL GRAFICO
    // VANNO POI MODIFICATI PER ESSERE DINAMICI
    // La somma di questi deve essere uguale a total 

//HERE I'M LISTENING THE EVENT TO TAKE VALUE WITH 'event.detail.fascia[i]['total']' VALUE
 window.addEventListener('open', event => {
    let Data = [{
            label: "Fascia < 100 €", //color: info
            value: 12  //12 commenting the window.addEventListener 
                       //or dynamically value from event.detail
        },
        {
            label: "Fascia 100 - 1000 €", //color: success
            value: 30
        },
        {
            label: "Fascia 1000 - 5000 €",  //color: light
            value: 20
        },
        {
            label: "Fascia 5000 - 10000 €", //color: dark
            value: 20
        },
        {
            label: "Fascia 10000 - 20000 €", //color: warning
            value: 20
        },
        {
            label: "Fascia > 20000 €", //color: danger
            value: 20
        },
    ];
})

    let total = 122; // Numero totale di residui non può essere hard coded
    var browsersChart = Morris.Donut({
            element: 'morris', // Id del div dove va messo il grafico
            data: Data,
            formatter: function(value, data) {
                return Math.floor(value / total * 100) + '%';
            },
            resize: true,
            redraw: true,
            colors: ['rgba(0, 227, 239, 0.533)',
                     'rgba(0, 239, 52, 0.506)',
                     'rgba(171, 168, 168, 0.437)', 
                     'rgba(80, 63, 88, 0.56)', 
                     'rgba(246, 152, 45, 0.608)', 
                     'rgba(251, 39, 39, 0.676)'] // Mettere tanti colori quante sono le fasce
        });
</script>
@endpush

Advertisement

Answer

You can use Laravel’s {{ }} since this JS is inside <script> tags its code will be pre-processed by Laravel blade engine, therefore every {{ }} will be recognized and substituted before sending the page to the client.

So in your specific case you can just do something like this:

let Data = [{
            label: "Fascia < 100 €", //color: info
            value: {{ $fascia1[0]['residuo'] }}
        },
        {
            label: "Fascia 100 - 1000 €", //color: success
            value: {{ $fascia2[0]['residuo'] }}
        },
        {
            label: "Fascia 1000 - 5000 €",  //color: light
            value: {{ $fascia3[0]['residuo'] }}
        },
        {
            label: "Fascia 5000 - 10000 €", //color: dark
            value: {{ $fascia3[0]['residuo'] }}
        },
        {
            label: "Fascia 10000 - 20000 €", //color: warning
            value: {{ $fascia5[0]['residuo'] }}
        },
        {
            label: "Fascia > 20000 €", //color: danger
            value: {{ $fascia6[0]['residuo'] }}
        },
    ];
    let total = {{ $tot_residuo }}; 

Make sure to also check for 0 values since in these cases you don’t want to show the respective label.

Let’s say for example fascia 5000 - 10000 has a value of 0 then you don’t want to show that label otherwise the graph would make no sense.

Also i have a doubt regarding why you are saving the variables $fascia as arrays, this way you will have to access them like you are doing e.g $fascia6[0]['residuo']. Wouldn’t it be easier to avoid the toArray() method and just saving them as they come back from Eloquent (since they are not a collection given your query). That way you can access them just like $fascia6['residuo']

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement