Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
568 views
in Technique[技术] by (71.8m points)

php - How to update Chart.js based on dropdown list?

UPDATED

I have added a dropdown to my chart which allows the user to select among the available operator names. I need your help so that when selecting an available operator name, the graphic is updated showing only the information of the selected operator.

grafico de ordenes

From all my JSON response, for this example it should only show the information in a red box:

json

As you can see in the image, if I select the Luis operator, this graph should update and show me only the Luis operator (he has 2 work orders in finished state).

Below my report.js file which I use to make the graph.

getChartData () method:

I use ajax, basically I'm getting the data and loading my select with the names of the available operators.

renderChart () method: ? I am passing it as a parameter "label and data" with these parameters I can make my graph also I am configuring some available options.

select.on ('change', function ():

here I do not understand how to tell my chart to update depending on the option selected, then I would have to call the renderChart method again to graph again with the selected data but it does not work, I do not know how to solve it, it is what I am trying.

report.js

function getChartData(user) {    
    $.ajax({
         url: '/admin/reports/getChart/' + user,
        type: 'GET',
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          },
        dataType: 'json',
        success: function (response) {             
            console.log(response);
            var data = [];
            var labels = [];         

            for (var i in response.orders) {

                data.push(response.orders[i].orders_by_user);
                labels.push(response.orders[i].name);  
                $("#operator").append('<option value='+response.orders[i].id+'>'+response.orders[i].name+'</option>');    
            }   
            renderChart(data, labels);              
        },

        error: function (response) {        
            console.log(response);
        }
    });
}

function renderChart(data, labels) {
    var ctx = document.getElementById("orders").getContext('2d');
    var myChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: labels,
            datasets: [{
                label: 'Terminadas',
                data: data,
                borderColor: 'rgba(75, 192, 192, 1)',
                backgroundColor: "#229954",
                borderWidth: 1,
                yAxisID: 'Ordenes',
                xAxisID: 'Operarios',
            }]
        },
        options: {
            scales: {
                yAxes: [{
                    id: "Ordenes",
                    ticks: {
                        beginAtZero: true

                    },
                    scaleLabel: {
                        display: true,
                        labelString: 'Ordenes'
                    }
                }],
                xAxes: [{
                    id: "Operarios",
                    scaleLabel: {
                        display: true,
                        labelString: 'Operarios'
                    }

                }],
            },
            title: {
                display: true,
                text: "Ordenes en estado terminado"
            },
            legend: {
                display: true,
                position: 'bottom',
                labels: {
                  fontColor: "#17202A",
                }
            },
        }
    });

    function updateChart() {       
        myChart.destroy();     
        myChart = new Chart(ctx, {
            type: document.getElementById("operator").value,
            data: data
        });
    };

}

getChartData();

$('#operator').select2({
    placeholder: 'Selecciona un operario',
    tags: false              
});


 var select = $('#operator'); 
 var pElem = document.getElementById('p')           

   select.on('change', function() {                
     var item = $(this).val();               
     pElem.innerHTML = 'selectedValue: ' + item;
     var data = {
        labels: labels,
        datasets: data
     }
     var ctx = document.getElementById("orders").getContext('2d');
     var myChart = new Chart(ctx, {
          type: 'line',
          data: data
        });
 }); 

My select:

<select class="form-control" name="operator" id="operator">
    <option></option>                                                            
</select> 

I get lost trying to link the selected option and the information to show (update the graph). Could you please tell me how to solve this?

UPDATED 1

My select:

<select class="form-control" name="operator" id="operator">
    <option></option>                                                            
</select> 

Through ajax I load my select options:

 for (var i in response.orders) {

   order.push(response.orders[i].orders_by_user);
   user.push(response.orders[i].name);              
   $("#operator").append('<option value='+response.orders[i].id+'>'+response.orders[i].name+'</option>');
 }      
 renderChart(order, user); 

With the answer you have given me, modify my report.js file exactly my function renderChart(order, user) and it is as follows:

function renderChart(order, user) {
    var ctx = document.getElementById("orders").getContext('2d');
    var myChart = new Chart(ctx, {
      //code...
    }); 

    //my select
    var selectOption = $('#operator');                    
    selectOption.on('change', function() {  

        var option = $("#operator").val();
        myChart.data.labels = option;
        if (option == 'All') {
           myChart.data.labels = user,
           myChart.data.datasets[0].data = order;
        } else {
          myChart.data.labels = option;
          myChart.data.datasets[0].data = order;
        }
        myChart.update();
    });            

}

The graph is updated incorrectly an error occurs you can see it in the image:

option jose

Obviously if I select the "All" option, it shows and graphs correctly, now if I select "jose" the following happens:

The graph does not respect the scale, I know that Jose has only 1 work order, and up to 2 on the scale.

On the x axis instead of showing me the name in this case "Jose" is showing me the selection id which in this case is 6.

The same happens with the option "Miguel".

Please help me correct this section:

var selectOption = $('#operator');                    
    selectOption.on('change', function() {  

        var option = $("#operator").val();
        myChart.data.labels = option;
        if (option == 'All') {
           myChart.data.labels = user,
           myChart.data.datasets[0].data = order;
        } else {
          myChart.data.labels = option;
          myChart.data.datasets[0].data = order;
        }
        myChart.update();
    });
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When the selected options changes, you must not destroy the chart. All you need to do is performing the following steps.

  1. Change the data.labels
  2. Change the data of the unique dataset
  3. Update the chart itself

This is basically done as follows.

myChart.data.labels = <new labels>;
myChart.data.datasets[0].data = <new values>;
myChart.update();

The following example illustrates how this can be done in JavaScript.

orders = [
  { name: 'Luis', orders_by_user: '2' },
  { name: 'Jose', orders_by_user: '1' },
  { name: 'Miguel', orders_by_user: '3' }
];

const myChart = new Chart(document.getElementById('orders'), {
  type: 'bar',
  data: {
    labels: orders.map(o => o.name),
    datasets: [{
      label: 'Terminadas',
      data: orders.map(o => o.orders_by_user),
      borderColor: 'rgba(75, 192, 192, 1)',
      backgroundColor: "#229954",
      borderWidth: 1,
      yAxisID: 'Ordenes',
      xAxisID: 'Operarios',
    }]
  },
  options: {
    scales: {
      yAxes: [{
        id: "Ordenes",
        ticks: {
          beginAtZero: true,
          stepSize: 1
        },
        scaleLabel: {
          display: true,
          labelString: 'Ordenes'
        }
      }],
      xAxes: [{
        id: "Operarios",
        scaleLabel: {
          display: true,
          labelString: 'Operarios'
        }

      }],
    },
    title: {
      display: true,
      text: "Ordenes en estado terminado"
    },
    legend: {
      display: true,
      position: 'bottom',
      labels: {
        fontColor: "#17202A",
      }
    },
  }
});

orders.forEach(o => {
  const opt = document.createElement('option');
  opt.value = o.name;
  opt.appendChild(document.createTextNode(o.name));
  document.getElementById('operator').appendChild(opt);
});

function refreshChart(name) {
  myChart.data.labels = [name];
  if (name == 'All') {
     myChart.data.labels = orders.map(o => o.name),
     myChart.data.datasets[0].data = orders.map(o => o.orders_by_user);
  } else {
    myChart.data.labels = [name];
    myChart.data.datasets[0].data = orders.find(o => o.name == name).orders_by_user;
  }
  myChart.update();
}
Operarios:
<select id="operator" onchange="refreshChart(this.value)">
    <option>All</option>                                                            
</select> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="orders" height="90"></canvas>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...