rjruiz
3 months ago
622
1
Vue

Dynamic graph with chart.js and vue.js

Posted 3 months ago by rjruiz

I have the following bar graph:

Grafico

As you can see I am showing all work orders in finished state that were assigned to users with the operator role. To this graph I have added a select that allows me to filter by operator name and then graph, that is, if I choose the operator Luis and press the search button, I should only graph Luis operator with all his completed orders, which in this case, you only have 2 orders in finished state.

I have the query, I have the graph working, I have the select.

My problem is not knowing how to graph again once the operator is selected from the input select, showing only the orders that the selected operator has. I suppose that the solution to this will be done within the script from where I am giving my variables, making the query to the url, etc.

How can I solve this problem?.

For the graph I am using the library chart.js and vue.js. So far everything stated above:

DashboardController:

With this GetOperator () method I get the users with the operator role in the input select.

public function GetOperator()
    {
        $operator = User::NotRole(['Admin', 'Supervisor'])->get();

        $data = [];
        $data[0] = [
            'id'   => 0,
            'text' =>'Seleccione',
        ];
        foreach ($operator as $key => $value) {
            $data[$key+1] =[
                'id'   => $value->id,
                'text' => $value->name,
            ];
            # code...
        }
        return response()->json($data);
    }

With this getOrders method ($ user = null, $ status = null, $ month = null), I query the database.

public function getOrders($user=null, $status=null, $month=null)
    {      

        $_orders = DB::table('users')
                        ->join('orders','orders.user_id','=','users.id')
                        ->join('model_has_roles', 'users.id', '=', 'model_has_roles.model_id')                        
                        ->select('users.id','users.name', DB::raw('COUNT(orders.id) as orders_by_user'), 'model_has_roles.role_id as rol')                   
                        ->where('model_has_roles.role_id', '2');
        if($status!=0){
            $_orders->where('orders.status', $status);
        }
        if($user!=0){ // suponiendo que viene id de usuario
            $_orders->where('users.id', $user);
        }

        if($month!=0){ // suponiendo que viene id de usuario
            // $query->where('title', "LIKE", "%$title%");
            $_orders->where('orders.date', 'LIKE', "%-{$month}-%");
        }
                        $_orders->groupBy('orders.user_id', 'users.id',  'users.name',  'model_has_roles.role_id');
                        $orders=$_orders->get();

        return ['orders' => $orders, 'users'=> User::NotRole(['Admin', 'Supervisor'])->get()];


    }

}

Dashboard.vue:

Here I show the graph and the select

<div class="row">
    <div class="col-md-6">
        <div class="box box-primary">
            <div class="box-header with-border">
                <h3 class="box-title">Ordenes por operario</h3>
                <div class="box-tools pull-right">
                    <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
                    </button>
                    <button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
                </div>
            </div>
            <div class="box-body"> 
                <div class="card card-chart">
                    <div class="card-header">
                        <h4>Seleccione Operario</h4>                                          
                        <form class="form-inline">
                            <div class="form-group mx-sm-3">
                                <label for="exampleFormControlSelect1" class="sr-only">Operario</label>                                                        
                                <select class="form-control" id="select_users">
                                    <option></option>                                                            
                                </select>  

                            </div>                                                   
                            <button type="submit" class="btn btn-primary">Buscar</button>
                        </form>
                    </div>
                    <div class="card-content">
                        <div class="ct-chart">
                            <canvas id="order">
                            </canvas>
                        </div>                               
                    </div>
                    <div class="card-footer">
                        <p>Ordenes.</p>
                    </div>
                </div>                                          
            </div>
        </div>
    </div>
</div>        

Script:

Well inside the script in data, I define my variables, in the getOperarios method I make the query to the url '/ admin / dashboard / getOrders /' + user + '/' + status + '/' + month; I fill the select with the names of users with the role of operator and in turn I invoke the loadOperarios () method that will graph based on the past data.

<script>    

    export default {          
        data (){
            return {                    

                varOrders:null,
                charOrders:null,
                orders:[],
                varTotalOrders:[],               
                varMesOrders:[],

            }              
        },
        methods : {

            getOperarios(user=0,status=0,month=0){
                let me=this;
                var url= '/admin/dashboard/getOrders/'+user+'/'+status+'/'+month;
                axios.get(url).then(function (response) {
                    //  console.log(response);
                    var respuesta = response.data;
                    me.orders = respuesta.orders;
                    me.users = respuesta.users;
                    var select_users = document.getElementById("select_users");
                    $.each(me.users, function(key, value) {

                        var option = document.createElement("option");
                        option.text = value.name;
                        option.value = value.id;
                        select_users.add(option);
                    });
                    // //cargamos los datos del chart
                    me.loadOperarios();
                })
                .catch(function (error) {
                    console.log(error);
                });
            }, 

            loadOperarios(){
                let me=this;
                me.orders.map(function(x){                    
                    me.varMesOrders.push(x.name);
                    me.varTotalOrders.push(x.orders_by_user);
                    // me.varUser_id.push(x.user_id);

                });
                me.varOrders=document.getElementById('order').getContext('2d');

                me.charOrders = new Chart(me.varOrders, {
                    type: 'bar',
                    data: {
                        labels: me.varMesOrders, 
                        datasets: [{
                            label: 'Ordenes',
                            data: me.varTotalOrders,
                            backgroundColor: 'rgba(25, 111, 61, 0.5)',
                            borderColor: 'rgba(25, 111, 61, 0.5)',                         
                            borderWidth: 1
                        }]
                    },
                    options: {
                        scales: {
                            yAxes: [{
                                ticks: {
                                    beginAtZero:true
                                }
                            }]
                        }
                    }
                });
            } 

        }, 

        mounted() {

            this.getOperarios(); 

        }

    }

</script>

I honestly don't have much knowledge in vue.js so I need to move forward, I need someone to guide me with the solution, I think you can also get the same result by implementing char.js alongside jajax and jquery if necessary I am willing to change my mind.

Please sign in or create an account to participate in this conversation.