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.
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.