0

This one is a two parter. Firstly I have a form with a bunch of values defaultly assigned and I'm displaying a chart.js chart.

Ideally I would like the user to be able to submit those values and then update the values in the chart by calling a function when the form is submitted.

At the moment I am having an issue when trying to acess the property of Chart.data.datasets.data when using .notation. I get an error in the console mentioning that datasets is undefined. I'm wondering if anyone has an insight into a better way to access this?

The Second part is that I'm using jQuery to access all the individual values from the inputs and capture them. Those values are then stored in another variable in their own array.

What I would like to do is access the previously mentioned property and replace the array with the upated array of my own in order to update the chart.

Is it possible to change the property value to a variable or only use literals?

Thanks for your time in advance.

        <html>
   <head> 
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>  
    <!-- Add jQuery-->
      <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU="crossorigin="anonymous"></script>
      <style>
        html,
        body {
          margin: 30px;
        }
        
        #chart {
          height: 400px;
          width: 400px;
        }

        .container{
            width:600px; 
            height:600px;
        }

      </style>
   
    </head> 
   <body> 

    <form>
        <label for="inputSafeVans">Safe Vans:</label><br>
        <input type="number" id="inputSafeVans" name="inputSafeVans" value="60"><br><br>

        <label for="inputDriverLicences">Driver Licences:</label><br>
        <input type="number" id="inputDriverLicences" name="inputDriverLicences" value="100"><br><br>

        <label for="inputFitnessToDrive">Fitness To Drive:</label><br>
        <input type="number" id="inputFitnessToDrive" name="inputFitnessToDrive" value="30"><br><br>

        <label for="inputDriveCompetence">Driver Competence:</label><br>
        <input type="number" id="inputDriveCompetence" name="inputDriveCompetence" value="40"><br><br>
    
        <label for="inputLoadLimits">Load Limits:</label><br>
        <input type="number" id="inputLoadLimits" name="inputLoadLimits" value="50"><br><br>

        <label for="inputSecureLoads">Secure Loads:</label><br>
        <input type="number" id="inputSecureLoads" name="inputSecureLoads" value="60"><br><br>

        <button type="button" value="Submit" onclick="getData()">Submit</button>
    </form> 
    
      <div class="container">
        <canvas id="myChart" width="400" height="400"></canvas> 
      </div>
      <script>

        const ctx = document.getElementById('myChart');
        // declare object 
        var myChart = new Chart(ctx, {
          type: 'polarArea',
          data: {
            labels: [
                '1. Safe Vans',
                '2. Driver Licences',
                '3. Fitness to Drive',
                '4. Driver Competence',
                '5. Load Limits',
                '6. Secure Loads'
              ],
            datasets: [{
                label: 'Score',
                // this is the chart data we want to change
                data: [45, 20, 50, 65, 80, 100],
                backgroundColor: '#76b82a',
            }]
          },
          options: {
            plugins: {
              legend: {
                display: false
              }
            },
            elements: {
              arc: {
                circular: false
              }
            },
            responsive: true,
            scales: {
              r: {
                startAngle: -30,
                min: 0,
                max: 100,
                grid: {
                  display: true,
                  circular: false,
                  color: '#173040',
                  lineWidth: 3,
                  z: 1
                },
                angleLines: {
                  display: true,
                  color: '#173040',
                  lineWidth: 3
                },
                ticks: {
                  display: false,
                  stepSize: 100
                },
                border: {
                  display: true,
                  color: '#000',
                  width: 2,
                },
                pointLabels: {
                  display: true,
                  centerPointLabels: true,
                  color: '#173040',
                  font: {
                    size: 18,
                    weight: 700
                  }
                },
                title: {
                  align: 'center'
                },
              }
            },
          }
        });

        /** 
         * function to grab the data from the input fields, store them in an array and then update the chart
         * with the data captured 
         **/

        function getData(){
          // declare variables
          var inputSafeVans = $("#inputSafeVans").val();
          var inputDriverLicences = $("#inputDriverLicences").val();
          var inputFitnessToDrive = $("#inputFitnessToDrive").val();
          var inputDriverCompetence = $("#inputDriveCompetence").val();
          var inputLoadLimits = $("#inputLoadLimits").val();
          var inputSecureLoads = $("#inputSecureLoads").val();



          //conditional check to see if stored values exceed 100, if they do then round them down to 100
          if (inputSafeVans < 0){
            inputSafeVans = 0;
          }
          else if (inputSafeVans > 100){
            inputSafeVans = 100;
          }
          if (inputDriverLicences < 0){
            inputDriverLicences = 0;
          }
          else if (inputDriverLicences > 100){
            inputDriverLicences = 100;
          }
          if (inputFitnessToDrive < 0){
            inputFitnessToDrive = 0;
          }
          else if (inputFitnessToDrive > 100){
            inputFitnessToDrive = 100;
          }
          if (inputDriverCompetence < 0){
            inputDriverCompetence = 0
          }
          else if (inputDriverCompetence > 100){
            inputDriverCompetence = 100;
          }
          if (inputLoadLimits < 0){
            inputLoadLimits = 0
          }
          else if (inputLoadLimits > 100){
            inputLoadLimits = 100;
          }
          if (iinputSecureLoads < 0){
            inputSecureLoads = 0
          }
          else if (inputSecureLoads > 100){
            inputSecureLoads = 100;
          }
  
          //store variable data in array
          var captureInput = [inputSafeVans, inputDriverLicences, inputFitnessToDrive, inputDriverCompetence, inputLoadLimits, inputSecureLoads];


          //access the object
          myChart.data.datasets[0].data = captureInput;
          //update the chart
          myChart.update();
        }
    
      </script>  
   </body>
</html>

I have tried .notation and other methods to access the property with the same result.

  • `Chart.data.datasets` is an array, so you'd need `Chart.data.datasets[0].data` – mykaf Feb 27 '23 at 14:51
  • Hi mykaf I did try that before loading this up but unfortunately, it doesn't work. I have tried various combinations and nothing so far. Inside the datasets array there are open and closing curly brackets I'm wondering if this is the issue. However the Chart.js API requires this. Bit of a head scratcher lol –  Feb 27 '23 at 15:44
  • `but unfortunately, it doesn't work.`: please elaborate. Is there an error? What happens or doesn't happen? Per your `new Chart(`, `Chart.data.datasets` *is* an array of objects: `datasets: [{` but you don't seem to be accounting for that. – mykaf Feb 27 '23 at 15:47
  • Hi mykaf. The console error reads properties of undefined reading 'datasets' –  Feb 27 '23 at 15:53
  • Okay, at that point, what's in the variable `Chart.data`? – mykaf Feb 27 '23 at 15:54
  • Chart.data contains two objects called labels and datasets. Both of which I should be able to access via dot notation from what I understand. If I account for datasets as an array object and reference like so Chart.data.datasets[1]; I still unfortunately get the same error –  Feb 27 '23 at 16:49
  • What about `Chart.data.datasets[0]`? It only has one element, so of course `Chart.data.datasets[1]` will error. – mykaf Feb 27 '23 at 17:20
  • Unfortunately the error remains the same. I also get an error even if I only reference Chart.type which only has a singular property. However this is the output recommended by Chart.js and the chart works just fine. According to this URL https://www.chartjs.org/docs/latest/charts/polar.html Where dataset properties are mentioned Chart.data.datasets[index] should work. –  Feb 27 '23 at 17:27

1 Answers1

0

Since your dataset is a collection, you need to access the data within by doing this:

Chart.data.datasets[0].data; // the index is what you need

Also, you need to move the value getting inside your getData(), and then update the chart, like so:


function getData() {
    var inputSafeVans = $("#inputSafeVans").val();
    var inputDriverLicences = $("#inputDriverLicences").val();
    var inputFitnessToDrive = $("#inputFitnessToDrive").val();
    var inputDriverCompetence = $("#inputDriveCompetence").val();
    var inputLoadLimits = $("#inputLoadLimits").val();
    var inputSecureLoads = $("#inputSecureLoads").val();

    var captureInput = [inputSafeVans, inputDriverLicences, inputFitnessToDrive, inputDriverCompetence, inputLoadLimits, inputSecureLoads];

    Chart.data.datasets[0].data = captureInput;
    Chart.update();
}

Some advice - since Chart is also the name of the constructor, you might want to reconsider the way you name your variable, and the way you initialize the chart. I would go with something as simple as:

var myChart = new Chart(ctx,....);

// ... rest of your code

function getData() {
    // ...
    myChart.data.datasets[0].data = ...;
    myChart.update();
}

Another thing I'd consider changing - instead of using input type="submit", why not button type="button"? If you're actually submitting the form, you won't update your graph with the new data (the one from the inputs).

Also - consider the max values set in the initialization of your chart, and then the values which are currently in your inputs. If you use them, and go over the max value, the green will be spilling out of your polar chart.

FiddlingAway
  • 1,598
  • 3
  • 14
  • 30