So I'm trying to do an automatic update for my Chart.Js pie chart, but I'm a bit stuck on how to proceed.
I have in my .php file a MySQL
database which is where I got my JS variables from (they are just hardcoded in the example). At the moment when I load the page I do a SQL call, and then run the PieChart(...)
function with the retrieved SQL data.
BUT how can I have a button which automatically updates the PieChart, onclick?
I've read that ChartJS has this updater
myLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
myLineChart.update(); // Calling update now animates the position of March from 90 to 50.
But how would I use that?
What I have at the moment is a php function that does the SQL call and returns all the information needed for updating the PieChart:
$OverviewResult = pieChartUpdater($FirstItemDD[0]);
This just have to be implemented into these variables
var Passed = "<?php echo $OverviewResult[0]; ?>";
var Failed = "<?php echo $OverviewResult[1]; ?>";
var Notrun = "<?php echo $OverviewResult[2]; ?>";
var Err = "<?php echo $OverviewResult[3]; ?>";
var Na = "<?php echo $OverviewResult[4]; ?>";
var PercentagePassed = "<?php echo $OverviewResult[5]; ?>";
var PercentageFailed = "<?php echo $OverviewResult[6]; ?>";
var PercentageNotrun = "<?php echo $OverviewResult[7]; ?>";
var PercentageError = "<?php echo $OverviewResult[8]; ?>";
var PercentageNa = "<?php echo $OverviewResult[9]; ?>";
Then the js function PieChart(...)
is excecuded.
Should I on a button click maybe make a PieChartUpdater()
function, that calles the SQL function and then the update ChartJS part? Or how does it work?
var Passed = "198";
var Failed = "37";
var Notrun = "0";
var Err = "0";
var Na = "0";
var PercentagePassed = "84.26";
var PercentageFailed = "15.74";
var PercentageNotrun = "0";
var PercentageError = "0";
var PercentageNa = "0";
/**
* Creates a PieChart overview of results
*
* @param {number} pass Amount of passed results
* @param {number} fail Amount of failed results
* @param {number} notRun Amount of not run results
* @param {number} err Amount of error results
* @param {number} nA Amount of not applicable results
* @param {number} percentagePassed Percentage of passed amount
* @param {number} percentageFailed Percentage of failed amount
* @param {number} percentageNotRun Percentage of not run amount
* @param {number} percentageError Percentage of error amount
* @param {number} percentageNA Percentage of not applicable amount
*/
function PieChart(pass, fail, notRun, err, nA, percentagePassed, percentageFailed, percentageNotRun, percentageError, percentageNA) {
window.chartColors = {
red: '#dc3545',
green: '#1cc88a',
blue: '#4e73df',
yellow: '#f6c23e',
black: '#5a5c69'
};
var config = {
type: 'pie',
data: {
datasets: [{
data: [
nA,
err,
notRun,
fail,
pass
],
backgroundColor: [
window.chartColors.black,
window.chartColors.yellow,
window.chartColors.blue,
window.chartColors.red,
window.chartColors.green,
],
label: 'Dataset 1'
}],
labels: [
percentageNA "% NA",
percentageError "% Error",
percentageNotRun "% Not Run",
percentageFailed "% Failed",
percentagePassed "% Passed"
]
},
options: {
responsive: true
}
};
window.onload = function() {
var ctx = document.getElementById('chart-area').getContext('2d');
window.myPie = new Chart(ctx, config);
};
}
PieChart(Passed, Failed, Notrun, Err, Na, PercentagePassed, PercentageFailed, PercentageNotrun, PercentageError, PercentageNa);
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div id="canvas-holder" style="width:50%">
<div class="chartjs-size-monitor">
<div class="chartjs-size-monitor-expand">
<div class=""></div>
</div>
<div class="chartjs-size-monitor-shrink">
<div class=""></div>
</div>
</div>
<canvas id="chart-area" style="display: block; width: 762px; height: 381px;" width="762" height="381" class="chartjs-render-monitor"></canvas>
</div>
What I'm trying to create
CodePudding user response:
Well, you'll have to do a bit of cleanup and new steps:
1. Separate a bit your code into several files:
src/config.php
: where you put your DB settings, etc.src/data-functions.php
: store some DB query functions.index.php
: your HTML page.chart-data.php
: a service to just retrieve fresh data in JSON.
2. In src/data-functions.php
put your logic to retrieve the data in a PHP array:
<?php
/**
* Get the pie chart data from the DB.
*
* @return array
*/
function getPieChartData()
{
// Do the SQL queries and return an array with the labels,
// values and colors. We'll be able to convert it to JS later.
$data = [
[
'value' => rand(50, 200),
'label' => '%.2f%% passed', // sprintf() format to inject pourcentage after.
'color' => '#1cc88a', // green
],
[
'value' => rand(0, 30),
'label' => '%.2f%% failed', // sprintf() format to inject pourcentage after.
'color' => '#dc3545', // red
],
[
'value' => rand(0, 3),
'label' => '%.2f%% not run', // sprintf() format to inject pourcentage after.
'color' => '#4e73df', // blue
],
[
'value' => rand(0, 10),
'label' => '%.2f%% NA', // sprintf() format to inject pourcentage after.
'color' => '#5a5c69', // gray
],
[
'value' => rand(0, 2),
'label' => '%.2f%% Error', // sprintf() format to inject pourcentage after.
'color' => '#f59f00', // orange
],
];
// Calculate the sum of the values so that we can calculate the % to put in the labels.
$sum = 0;
foreach ($data as $item) {
$sum = $item['value'];
}
// Walk accross the array to replace the labels by the calculated % in the label.
foreach ($data as $i => $item) {
$data[$i]['label'] = sprintf($item['label'], $item['value'] * 100 / $sum);
}
return $data;
}
3. In index.php
you generate the HTML and JavaScript code
<?php
require 'src/config.php';
require 'src/data-functions.php';
// Get the data from the DB.
$data = getPieChartData();
// Convert the PHP array to a JS array.
$data_json = json_encode($data);
// The URL to get the data in JSON format.
$data_json_url = '/chart-data.php';
// Print your HTML and JavaScript which will be done once
// at the first page load.
?>
<div id="canvas-holder" style="width:50%">
<div class="chartjs-size-monitor">
<div class="chartjs-size-monitor-expand">
<div class=""></div>
</div>
<div class="chartjs-size-monitor-shrink">
<div class=""></div>
</div>
</div>
<canvas id="chart-area" style="display: block; width: 762px; height: 381px;" width="762" height="381" class="chartjs-render-monitor"></canvas>
<button id="chart-refresh-button">Refresh data</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="text/javascript">
/**
* @param array data The data for the pie chart.
* @param string jsonDataUrl The URL of the pie chart JSON data.
*/
function initPieChart(data, jsonDataUrl) {
var config = {
type: 'pie',
data: {
datasets: [{
label: 'Dataset 1',
data: [], // filled later
backgroundColor: [] // filled later
}],
labels: [] // filled later
},
options: {
responsive: true
}
};
/**
* Helper function to set the data values, labels and colors.
*
* @param array data The new data to use.
* @param object chart_data_to_set The chart.js data object to set.
*/
function setData(data, chart_data_to_set) {
// Loop over the data to fill the data object for chart.js.
data.forEach((item, i) => {
chart_data_to_set.datasets[0].data[i] = item.value;
chart_data_to_set.datasets[0].backgroundColor[i] = item.color;
chart_data_to_set.labels[i] = item.label;
});
}
// Fill the config with all our data, labels and colors.
setData(data, config.data);
// Once JS is loaded and DOM ready (images & CSS later).
document.addEventListener("DOMContentLoaded", () => {
var ctx = document.getElementById('chart-area').getContext('2d');
var myPie = new Chart(ctx, config);
var updateButton = document.getElementById('chart-refresh-button');
// Add a click handler on the refresh button.
updateButton.addEventListener('click', function(event) {
// Do an Ajax call to the server to just get the fresh data.
fetch(jsonDataUrl).then(response => {
return response.json();
})
.then(freshData => {
// Update the chart data with the fresh data.
setData(freshData, myPie.data);
myPie.update();
})
.catch(error => {
console.log('An error occured while fetching data from the server', error);
});
});
});
}
initPieChart(<?php echo $data_json; ?>, '<?php echo $data_json_url; ?>');
</script>
As you can see, the PHP array is converted to a JavaScript array with the help of json_encode()
and is printed in place of $data_json
inside the HTML/JS output. This way you don't need all the JS variables which where confusing and messing up the code. This solution is more generic since you could change your data in PHP and all the rest would update without changing the JS code.
4. Create chart-data.php
to return the fresh data in JSON
<?php
require 'src/config.php';
require 'src/data-functions.php';
// We won't print any HTML but just return the data in JSON.
$data = getPieChartData();
// Sent the correct MIME type for JSON and return the fresh data.
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);