diff --git a/public/userarea/assets/pages/dashboard.js b/public/userarea/assets/pages/dashboard.js
index 540b2dc..14427d5 100644
--- a/public/userarea/assets/pages/dashboard.js
+++ b/public/userarea/assets/pages/dashboard.js
@@ -11,7 +11,9 @@
//line-chart
-var ctx = document.getElementById('lineChart').getContext('2d');
+if( $('#lineChart').length > 0 ){
+ var ctx = document.getElementById('lineChart').getContext('2d');
+}
gradientStroke1 = ctx.createLinearGradient(0, 0, 0, 300);
gradientStroke1.addColorStop(0, '#008cff');
diff --git a/public/userarea/statkpi/parsedatachart.php b/public/userarea/statkpi/parsedatachart.php
index 9f9f30d..61a7c61 100644
--- a/public/userarea/statkpi/parsedatachart.php
+++ b/public/userarea/statkpi/parsedatachart.php
@@ -1,11 +1,97 @@
query($totalProductsQuery);
$totalProducts = $totalProductsResult->fetch_assoc()['totalProducts'];
@@ -138,13 +256,28 @@ while ($row = $worstSuppliersResult->fetch_assoc()) {
];
}
+$suPfilters='';
// Statistic for products by suppliers
+
+if(!empty($supplierFilter)){
+ $suPfilters .= " AND p.namesupplier IN ($supplierFilter)";
+}
+if(!empty($refNumberFilter)){
+ $suPfilters .= " AND p.products_refnumber IN ($refNumberFilter)";
+}
+if(!empty($productsSeasonFilter)){
+ $suPfilters .= " AND p.products_season IN ($productsSeasonFilter)";
+}
+if(!empty($ageRangeFilter)){
+ $suPfilters .= " AND p.agerange IN ($ageRangeFilter)";
+}
$productBySupplierQuery = "
SELECT p.namesupplier AS supplier, COUNT(p.idproducts) AS totalProducts
FROM products p
- WHERE p.namesupplier IS NOT NULL
+ WHERE p.namesupplier IS NOT NULL $suPfilters
GROUP BY p.namesupplier
- ORDER BY totalProducts DESC";
+ ORDER BY totalProducts DESC";
+
$productBySupplierResult = $conn->query($productBySupplierQuery);
$productBySupplier = [];
while ($row = $productBySupplierResult->fetch_assoc()) {
@@ -153,6 +286,96 @@ while ($row = $productBySupplierResult->fetch_assoc()) {
'totalProducts' => $row['totalProducts']
];
}
+// refNumbers
+$refNumbersQuery = "
+ SELECT p.products_refnumber AS refNumber
+ FROM products p
+ WHERE p.products_refnumber IS NOT NULL
+ GROUP BY p.products_refnumber
+";
+$refNumbersResult = $conn->query($refNumbersQuery);
+$refNumbers = [];
+while ($row = $refNumbersResult->fetch_assoc()) {
+ $refNumbers[] = [
+ 'refNumber' => $row['refNumber']
+ ];
+}
+// productsSeason
+$productsSeasonQuery = "
+ SELECT p.products_season AS season
+ FROM products p
+ WHERE p.products_season IS NOT NULL
+ GROUP BY p.products_season
+";
+$productsSeasonResult = $conn->query($productsSeasonQuery);
+$productsSeasons = [];
+while ($row = $productsSeasonResult->fetch_assoc()) {
+ $productsSeasons[] = [
+ "season" => $row['season']
+ ];
+}
+
+// ageRanges
+$ageRangeQuery = "
+ SELECT p.agerange AS ageRange
+ FROM products p
+ WHERE p.agerange IS NOT NULL
+ GROUP BY p.agerange
+";
+
+$ageRangeResult = $conn->query($ageRangeQuery);
+$ageRange = [];
+while ($row = $ageRangeResult->fetch_assoc()) {
+ $ageRange[] = [
+ "ageRange" => $row['ageRange']
+ ];
+}
+
+// labNames
+$labNameQuery = "
+ SELECT r.reports_LabName AS LabName
+ FROM reports r
+ WHERE r.reports_LabName IS NOT NULL
+ GROUP BY r.reports_LabName
+";
+$labNameResult = $conn->query($labNameQuery);
+$labName = [];
+while ($row = $labNameResult->fetch_assoc()) {
+ $labName[] = [
+ "LabName" => $row['LabName']
+ ];
+}
+
+// tesTypes
+$tesTypeQuery = "
+ SELECT r.reports_testype AS tesType
+ FROM reports r
+ WHERE r.reports_testype IS NOT NULL
+ GROUP BY r.reports_testype
+";
+$tesTypeResult = $conn->query($tesTypeQuery);
+$tesType = [];
+while ($row = $tesTypeResult->fetch_assoc()) {
+ $tesType[] = [
+ "tesType" => $row['tesType']
+ ];
+}
+
+// numberLabs
+$numberLabsQuery = "
+ SELECT r.reportsNumberLab as reportNumber
+ FROM reports r
+ WHERE r.reportsNumberLab IS NOT NULL
+ GROUP BY r.reportsNumberLab
+";
+$numberLabsResult = $conn->query($numberLabsQuery);
+$numberLabs = [];
+while ($row = $numberLabsResult->fetch_assoc()) {
+ $numberLabs[] = [
+ "reportNumber" => $row['reportNumber']
+ ];
+}
+
// New Query: Distribution of analyses (for pie chart)
$analysisDistributionQuery = "
@@ -192,6 +415,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'topFailingAnalysis' => $topFailingAnalysis,
'worstSuppliers' => $worstSuppliers,
'productBySupplier' => $productBySupplier,
+ 'refNumbers' => $refNumbers,
+ 'productsSeasons' => $productsSeasons,
+ 'ageRange' => $ageRange,
+ 'labName' => $labName,
+ 'tesType' => $tesType,
+ 'numberLabs' => $numberLabs,
'analysisDistribution' => $analysisDistribution // Distribuzione delle analisi per il grafico a torta
]);
exit; // Ferma l'esecuzione del resto dello script dopo aver risposto all'AJAX
diff --git a/public/userarea/statkpi/statkpi.php b/public/userarea/statkpi/statkpi.php
index 872e130..5debed4 100644
--- a/public/userarea/statkpi/statkpi.php
+++ b/public/userarea/statkpi/statkpi.php
@@ -186,8 +186,7 @@ include('parsedatachart.php');
}
.filters-applied {
- display: inline-block;
- background-color: #3368ff;
+ display: inline-block;
color: white;
border-radius: 5px;
padding: 5px 10px;
@@ -208,6 +207,28 @@ include('parsedatachart.php');
+
+
+
+
+
@@ -242,6 +263,116 @@ include('parsedatachart.php');
+
+
+
+
+
+
+
@@ -262,8 +393,7 @@ include('parsedatachart.php');
+
Active Filters:
-
+
@@ -351,7 +481,7 @@ include('parsedatachart.php');
-
Reports Overview
+
Reports Overview
@@ -416,74 +546,6 @@ include('parsedatachart.php');
@@ -495,6 +557,12 @@ include('parsedatachart.php');
var startDate = $('#startDate').val();
var endDate = $('#endDate').val();
var supplier = $('#supplierFilter').val();
+ var productsRefnumber = $('#productsRefnumber').val();
+ var productsSeason = $('#productsSeason').val();
+ var ageRange = $('#ageRange').val();
+ var reportsLabName = $('#reportsLabName').val();
+ var reportsTestType = $('#reportsTestType').val();
+ var reportsNumberLab = $('#reportsNumberLab').val();
$.ajax({
url: 'parsedatachart.php',
@@ -502,10 +570,22 @@ include('parsedatachart.php');
data: {
startDate: startDate,
endDate: endDate,
- supplier: supplier
+ supplier: supplier,
+ productsRefnumber: productsRefnumber,
+ productsSeason: productsSeason,
+ ageRange: ageRange,
+ reportsLabName: reportsLabName,
+ reportsTestType: reportsTestType,
+ reportsNumberLab: reportsNumberLab
},
success: function(response) {
- var data = JSON.parse(response);
+ if (!response) {
+ alert('No data found.');
+ data = {};
+ return;
+ }else{
+ var data = JSON.parse(response);
+ }
// Aggiorna le cards con i nuovi dati
$('#totalProducts').text(data.totalProducts);
@@ -530,16 +610,326 @@ include('parsedatachart.php');
return parseInt(item.totalTests, 10); // Converte il conteggio dei test in numeri interi
});
- // Aggiorna il grafico a barre verticali
- analysisBarChart.updateOptions({
- xaxis: {
- categories: analysisLabels // Aggiorna le etichette
- }
- });
- analysisBarChart.updateSeries([{
- data: analysisCounts // Aggiorna i dati del grafico
- }]);
}
+
+ // remove pie chart and create a new one
+ $('#reportPieChart').html('');
+
+ var intFailReports = parseInt(data.failReportsPie);
+ var intPassReports = parseInt(data.passReportsPie);
+ var intOtherReports = parseInt(data.otherReportsPie);
+
+ // Data for pie chart (Reports: Fail, Pass, Others)
+ var options = {
+ series: [intFailReports, intPassReports, intOtherReports],
+ chart: {
+ width: '100%', // Mantieni la larghezza al 100% all'interno della colonna Bootstrap
+ type: 'pie',
+ },
+ labels: ['Fail', 'Pass', 'Others'],
+ colors: ['#FF4D4D', '#28A745', '#FFA500'], // Red for Fail, Green for Pass, Orange for Others
+ responsive: [{
+ breakpoint: 480,
+ options: {
+ chart: {
+ width: 250 // Riduci la larghezza sui dispositivi mobili
+ },
+ legend: {
+ position: 'bottom'
+ }
+ }
+ }],
+ legend: {
+ position: 'bottom', // Posiziona la legenda sotto il grafico
+ offsetY: 0,
+ height: 50, // Altezza della legenda
+ }
+ };
+
+ var chart = new ApexCharts(document.querySelector("#reportPieChart"), options);
+ chart.render();
+
+ // remove bar chart and create a new one
+ $('#worsttenanalysis').html('');
+
+ // Data for the bar chart
+ var analysisNames = data.topFailingAnalysis.map(function(item) {
+ return item.name;
+ });
+ var failCounts = data.topFailingAnalysis.map(function(item) {
+ return parseInt(item.failCount, 10);
+ });
+
+ var options = {
+ series: [{
+ data: failCounts
+ }],
+ chart: {
+ type: 'bar',
+ height: 350
+ },
+ plotOptions: {
+ bar: {
+ horizontal: true,
+ dataLabels: {
+ position: 'center' // Posiziona i nomi delle analisi al centro delle barre
+ }
+ }
+ },
+ dataLabels: {
+ enabled: true,
+ style: {
+ colors: ['#fff'], // Colore del testo all'interno delle barre (bianco)
+ fontSize: '12px'
+ },
+ formatter: function(val, opt) {
+ return analysisNames[opt.dataPointIndex]; // Mostra il nome dell'analisi dentro la barra
+ }
+ },
+ xaxis: {
+ categories: failCounts, // Visualizza solo i numeri sull'asse X
+ title: {
+ text: 'Number of Failures'
+ }
+ },
+ yaxis: {
+ labels: {
+ show: false // Nascondiamo le etichette dell'asse Y
+ },
+ title: {
+ text: 'Analysis'
+ }
+ },
+ colors: ['#FF4D4D'], // Rosso per i Fail
+ responsive: [{
+ breakpoint: 480,
+ options: {
+ chart: {
+ height: 300
+ },
+ xaxis: {
+ labels: {
+ show: true
+ }
+ }
+ }
+ }],
+ title: {
+ text: 'Top 10 Analyses with the Most Failures',
+ align: 'center'
+ }
+ };
+
+ var chart = new ApexCharts(document.querySelector("#worsttenanalysis"), options);
+ chart.render();
+
+ // remove bar chart and create a new one
+ $('#worstSuppliersChart').html('');
+
+ // Data for the bar chart of worst suppliers
+ var supplierNames = data.worstSuppliers.map(function(item) {
+ return item.supplier;
+ });
+ var failPercentages = data.worstSuppliers.map(function(item) {
+ return parseFloat(item.failPercentage);
+ });
+ var totalReportsForSupplier = data.worstSuppliers.map(function(item) {
+ return parseInt(item.totalReports, 10);
+ });
+ var failedReportsForSupplier = data.worstSuppliers.map(function(item) {
+ return parseInt(item.failedReports, 10);
+ });
+
+ var options = {
+ series: [{
+ data: failPercentages
+ }],
+ chart: {
+ type: 'bar',
+ height: 400
+ },
+ plotOptions: {
+ bar: {
+ horizontal: true,
+ dataLabels: {
+ position: 'center' // Etichette al centro delle barre
+ }
+ }
+ },
+ dataLabels: {
+ enabled: true,
+ style: {
+ colors: ['#fff'], // Colore del testo all'interno delle barre
+ fontSize: '12px'
+ },
+ formatter: function(val, opt) {
+ // Aggiungi nome del fornitore, percentuale, numero di fail e numero totale di report
+ var totalReports = totalReportsForSupplier[opt.dataPointIndex]; // Numero totale di report
+ var failedReports = failedReportsForSupplier[opt.dataPointIndex]; // Numero di report falliti
+ return supplierNames[opt.dataPointIndex] + ' (' + val.toFixed(2) + '%) (Fail: ' + failedReports + ' - Total: ' + totalReports + ')';
+ }
+ },
+ xaxis: {
+ categories: supplierNames, // Visualizza i nomi dei fornitori
+ title: {
+ text: 'Failure Percentage (%)'
+ }
+ },
+ yaxis: {
+ labels: {
+ show: false // Nascondiamo le etichette dell'asse Y
+ },
+ title: {
+ text: 'Suppliers'
+ }
+ },
+ colors: ['#3368FF'], // Colore blu chiaro per le barre
+ title: {
+ text: 'Top 10 Suppliers with the Highest Failed Reports Percentage',
+ align: 'center'
+ }
+ };
+
+ var chart = new ApexCharts(document.querySelector("#worstSuppliersChart"), options);
+ chart.render();
+
+ // remove bar chart and create a new one
+ $('#productBySupplierChart').html('');
+
+ // Prepara i dati per il grafico
+ var supplierNames = data.productBySupplier.map(function(item) {
+ return item.supplier;
+ });
+ var totalProducts = data.productBySupplier.map(function(item) {
+ return parseInt(item.totalProducts, 10);
+ });
+
+ var options = {
+ series: [{
+ name: 'Total Products',
+ data: totalProducts
+ }],
+ chart: {
+ type: 'bar',
+ height: 400
+ },
+ plotOptions: {
+ bar: {
+ horizontal: false, // Imposta il grafico a barre verticali
+ columnWidth: '50%',
+ dataLabels: {
+ position: 'top', // Etichette nella parte superiore delle barre
+ }
+ }
+ },
+ dataLabels: {
+ enabled: true,
+ offsetY: -20,
+ style: {
+ fontSize: '12px',
+ colors: ['#000']
+ }
+ },
+ xaxis: {
+ categories: supplierNames,
+ title: {
+ text: 'Suppliers'
+ }
+ },
+ yaxis: {
+ title: {
+ text: 'Number of Products'
+ }
+ },
+ colors: ['#3368FF'],
+ title: {
+ text: 'Number of Products by Supplier',
+ align: 'center'
+ }
+ };
+
+ var chart = new ApexCharts(document.querySelector("#productBySupplierChart"), options);
+ chart.render();
+
+ // remove bar chart and create a new one
+ $('#analysisDistributionChart').html('');
+
+ var analysisNames = data.analysisDistribution.map(function(item) {
+ return item.analysisName;
+ });
+ var totalTests = data.analysisDistribution.map(function(item) {
+ return parseInt(item.totalTests, 10);
+ });
+ // Define the horizontal bar chart for analysis distribution
+ var analysisBarChartOptions = {
+ series: [{
+ name: 'Total Tests',
+ data: totalTests // Initially empty, will be filled via AJAX
+ }],
+ chart: {
+ type: 'bar',
+ height: 500
+ },
+ plotOptions: {
+ bar: {
+ horizontal: true,
+ columnWidth: '100%',
+ endingShape: 'rounded'
+ }
+ },
+ dataLabels: {
+ enabled: true
+ },
+ stroke: {
+ show: true,
+ width: 2,
+ colors: ['transparent']
+ },
+ xaxis: {
+ categories: analysisNames,
+ title: {
+ text: 'Number of Tests'
+ }
+ },
+ yaxis: {
+ labels: {
+ show: true,
+ maxWidth: 700, // Increased max width for labels
+ style: {
+ fontSize: '12px',
+ colors: ['#000']
+ }
+ },
+ title: {
+ text: 'Analysis Name'
+ }
+ },
+ fill: {
+ opacity: 1,
+ colors: ['#004d00']
+ },
+ tooltip: {
+ y: {
+ formatter: function(val) {
+ return val + " tests";
+ }
+ }
+ },
+ title: {
+ text: 'Analysis Distribution',
+ align: 'center'
+ },
+ grid: {
+ padding: {
+ left: 10 // Increased left padding for more label space
+ }
+ }
+ };
+
+ // Create the initial chart
+ var analysisBarChart = new ApexCharts(document.querySelector("#analysisDistributionChart"), analysisBarChartOptions);
+ analysisBarChart.render();
+
},
error: function() {
alert('Error retrieving data.');
@@ -548,7 +938,7 @@ include('parsedatachart.php');
}
// Eventi per applicare i filtri
- $('#startDate, #endDate, #supplierFilter').on('change', function() {
+ $('#startDate, #endDate, #supplierFilter, #productsRefnumber, #productsSeason, #ageRange, #reportsLabName, #reportsTestType, #reportsNumberLab').on('change', function() {
updateData();
});
@@ -557,8 +947,14 @@ include('parsedatachart.php');
$('#startDate').val('');
$('#endDate').val('');
$('#supplierFilter').val('').trigger('change');
+ $('#productsRefnumber').val('').trigger('change');
+ $('#productsSeason').val('').trigger('change');
+ $('#ageRange').val('').trigger('change');
+ $('#reportsLabName').val('').trigger('change');
+ $('#reportsTestType').val('').trigger('change');
+ $('#reportsNumberLab').val('').trigger('change');
updateData();
- $('#activeFilters').hide();
+ // $('#activeFilters').hide();
});
// Chiamata iniziale per caricare i dati alla prima visualizzazione della pagina
@@ -577,220 +973,16 @@ include('parsedatachart.php');
document.getElementById('failedTestsPercent').innerText = "(%)";
-
-
-
-
-
-
+ // for multiple select
+ $(document).ready(function() {
+ $('.select2').select2({
+ placeholder: "Select options",
+ allowClear: true,
+ width: '100%'
+ });
+ });
+