0

I try to get some chart with chart.js with data from a database.

If I put it directly inside the array its works fine, if i try to bind it inside a foreach loop I get "the variable $subs" is assigned, but never been used and there is no chart inside the view.

My Component :

   <?php
    
    namespace App\Livewire\Charts;
    
    use Livewire\Component;
    use App\Models\wine;
    use App\Models\Grape;
    use App\Models\WineGrape;
    
    class GrapeCharts extends Component
    {
        public $wines;
    
        public $values;
    
        public $grape;
    
        public $subs = [];
    
        //public $subs = [
    
        //    ['Grape' => 'Grenache', 'Value' => 75],
    
        //    ['Grape' => 'Syrah', 'Value' => 25],
        //];   ->> This works as intended
    
    
        public function mount($wine_id)
        {
            $this->wines = Wine::where('id', '=', $wine_id)->first();
    
            $this->values = WineGrape::where('wine_id', '=', $wine_id)->get();
    
            foreach ($this->values as $value) {
                $this->grape = Grape::where('id', '=', $value->grape_id)->first();
    
                $subs = [
                    ['Grape' => $this->grape->grapename, 'Value' => $value->amount],
                ];
            }
        }
    
    
        public function render()
        {
    
            return view('livewire.charts.grape-charts');
        }
    }

My View :

<style type="text/css">
    .ChartBox {
        height: 600px;
    }
</style>
<div class="row">
    <div class="ChartBox col-6" wire:ignore>
        <canvas id="myChart"></canvas>
    </div>

</div>

@assets <script type="text/javascript" src="{{ asset('assets/js/chart.min.js') }}"></script>@endassets
@script <script>
    const ctx=document.getElementById('myChart');
 //   const ctx2=document.getElementById('myChart2');
    const subs=$wire.subs;

    const Labels=subs.map(item=>item.Grape);
    const values=subs.map(item=>item.Value);

    new Chart(ctx, {

        type: 'pie',
        data: {

            labels: Labels,
            datasets: [ {
                label: '%',
                data: values,
                borderWidth: 1
            }

            ]
        }

        ,
        options: {
           responsive:  true
        }
    });


</script>
@endscript

It seems as if the variable $subs is not getting to the view. What is the correct way to bind the data and get it to the view ?

1 Answer 1

0

I changed to JSON and created a DB::SELECT now it works fine .

The Component:

<?php

namespace App\Livewire\Charts;

use Livewire\Component;
use App\Models\wine;
use App\Models\WineGrape;
use Illuminate\Support\Facades\DB;

class GrapeCharts extends Component
{
    public $wines;

    public $values;

    public $grape;

    public $testselect;


    public function mount($wine_id)
    {
        $this->wines = Wine::where('id', '=', $wine_id)->first();

        $this->values = WineGrape::where('wine_id', '=', $wine_id)->get();

        $this->testselect = DB::table('grapes')
            ->join('wine_grapes', 'grapes.id', '=', 'wine_grapes.grape_id')
            ->where('wine_id', '=', $wine_id)
            ->select(
                'grapes.grapename',
                'wine_grapes.amount'
            )
            ->get();
    }


    public function render()
    {
        return view('livewire.charts.grape-charts');
    }
}

And the blade file :

<style type="text/css">
    .ChartBox {
        height: 500px;
    }
</style>
<div class="row">
    <div class="ChartBox col-6" wire:ignore>
        <canvas chlass="ChartBox" id="myChart"></canvas>
    </div>

    <div class="ChartBox col-6" wire:ignore>
        <canvas id="myChart2"></canvas>
    </div>

</div>

@assets <script type="text/javascript" src="{{ asset('assets/js/chart.min.js') }}"></script>@endassets
@script
<script>
    const data = {
        labels: @json($testselect->map(fn ($testselect) => $testselect->grapename)),
        datasets: [{
        label: 'Grapevariety in Wine',
        data: @json($testselect->map(fn ($testselect) => $testselect->amount)),
        }]
    };

    const config = {
        type: 'doughnut',
        data: data
    };

    const config2 = {
    type: 'pie',
    data: data
    };
    const myChart = new Chart(
        document.getElementById('myChart'),
        config
    );

    const myChart2 = new Chart(
    document.getElementById('myChart2'),
    config2
    );


</script>
@endscript
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.