1148 lines
50 KiB
PHP
1148 lines
50 KiB
PHP
<script>
|
|
$(document).ready(function() {
|
|
// Funzione per aggiornare i dati con AJAX
|
|
function updateData() {
|
|
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();
|
|
var groupingField = $('#groupingField').val();
|
|
|
|
// Aggiorna il titolo dinamicamente in base alla selezione del dropdown
|
|
var groupingText = $('#groupingField option:selected').text(); // Ottieni il testo dell'opzione selezionata
|
|
$('#dynamicChartTitle').text(`Rating Distribution by Group: ${groupingText}`); // Aggiorna il titolo
|
|
|
|
|
|
|
|
$.ajax({
|
|
url: 'parsedatachart.php',
|
|
method: 'POST',
|
|
data: {
|
|
startDate: startDate,
|
|
endDate: endDate,
|
|
supplier: supplier,
|
|
productsRefnumber: productsRefnumber,
|
|
productsSeason: productsSeason,
|
|
ageRange: ageRange,
|
|
reportsLabName: reportsLabName,
|
|
reportsTestType: reportsTestType,
|
|
reportsNumberLab: reportsNumberLab,
|
|
groupingField: groupingField
|
|
},
|
|
success: function(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);
|
|
$('#totalReports').text(data.totalReports);
|
|
$('#failedReports').text(data.failedReports);
|
|
$('#failedReportsPercent').text('(' + data.failedReportsPercent.toFixed(2) + '%)');
|
|
$('#totalTests').text(data.totalTests);
|
|
$('#failedTests').text(data.failedTests);
|
|
$('#failedTestsPercent').text('(' + data.failedTestsPercent.toFixed(2) + '%)');
|
|
// Aggiorna il grafico della distribuzione delle analisi
|
|
if (data.analysisDistribution && data.analysisDistribution.length > 0) {
|
|
// Ordina i dati per numero di test e prendi solo i primi 15
|
|
var sortedData = data.analysisDistribution.sort(function(a, b) {
|
|
return b.totalTests - a.totalTests;
|
|
}).slice(0, 15); // Prendi solo le prime 15 analisi
|
|
|
|
var analysisLabels = sortedData.map(function(item) {
|
|
return item.analysisName;
|
|
});
|
|
var analysisCounts = sortedData.map(function(item) {
|
|
return parseInt(item.totalTests, 10); // Converte il conteggio dei test in numeri interi
|
|
});
|
|
|
|
}
|
|
|
|
// remove pie chart and create a new one
|
|
// Funzione per generare la tabella dal pie chart
|
|
function generatePieTable(labels, series) {
|
|
let tableHTML = `
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Category</th>
|
|
<th>Count</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
for (let i = 0; i < labels.length; i++) {
|
|
tableHTML += `
|
|
<tr>
|
|
<td>${labels[i]}</td>
|
|
<td>${series[i]}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
tableHTML += `
|
|
</tbody>
|
|
</table>
|
|
`;
|
|
|
|
return tableHTML;
|
|
}
|
|
|
|
// Pulizia del contenitore
|
|
$('#reportPieChart').html('');
|
|
|
|
var intFailReports = parseInt(data.failReportsPie);
|
|
var intPassReports = parseInt(data.passReportsPie);
|
|
var intOtherReports = parseInt(data.otherReportsPie);
|
|
|
|
// Dati per il grafico a torta
|
|
var pieLabels = ['Fail', 'Pass', 'Others'];
|
|
var pieSeries = [intFailReports, intPassReports, intOtherReports];
|
|
|
|
var options = {
|
|
series: pieSeries,
|
|
chart: {
|
|
width: '100%',
|
|
type: 'pie',
|
|
toolbar: {
|
|
show: true, // Mostra l'hamburger menu
|
|
tools: {
|
|
download: true, // Opzioni di download
|
|
selection: false,
|
|
zoom: false,
|
|
zoomin: false,
|
|
zoomout: false,
|
|
pan: false,
|
|
reset: false
|
|
}
|
|
}
|
|
},
|
|
labels: pieLabels,
|
|
colors: ['#FF4D4D', '#28A745', '#FFA500'],
|
|
responsive: [{
|
|
breakpoint: 480,
|
|
options: {
|
|
chart: {
|
|
width: 250
|
|
},
|
|
legend: {
|
|
position: 'bottom'
|
|
}
|
|
}
|
|
}],
|
|
legend: {
|
|
position: 'bottom',
|
|
offsetY: 0,
|
|
height: 50
|
|
}
|
|
};
|
|
|
|
var chart = new ApexCharts(document.querySelector("#reportPieChart"), options);
|
|
chart.render();
|
|
|
|
// Genera la tabella
|
|
$('#tableChart2').html(generatePieTable(pieLabels, pieSeries));
|
|
|
|
var pieLabels = ['Pass', 'Fail', 'Others']; // Ordine richiesto
|
|
var pieSeries = [intPassReports, intFailReports, intOtherReports]; // Ordine dei dati: Pass, Fail, Others
|
|
|
|
|
|
// Configurazione del grafico a barre
|
|
var barOptions = {
|
|
series: [{
|
|
data: pieSeries // Utilizza i dati aggiornati
|
|
}],
|
|
chart: {
|
|
type: 'bar',
|
|
height: 400, // Altezza del grafico
|
|
toolbar: {
|
|
show: true, // Mostra l'hamburger menu
|
|
tools: {
|
|
download: true, // Opzioni di download
|
|
selection: false,
|
|
zoom: false,
|
|
zoomin: false,
|
|
zoomout: false,
|
|
pan: false,
|
|
reset: false
|
|
}
|
|
}
|
|
},
|
|
plotOptions: {
|
|
bar: {
|
|
horizontal: false,
|
|
columnWidth: '50%',
|
|
distributed: true // Colori diversi per ogni colonna
|
|
}
|
|
},
|
|
dataLabels: {
|
|
enabled: true
|
|
},
|
|
xaxis: {
|
|
categories: pieLabels // Stesse etichette della pie chart
|
|
},
|
|
colors: ['#28A745', '#FF4D4D', '#FFA500'], // Verde, Rosso, Arancione
|
|
legend: {
|
|
show: false
|
|
}
|
|
};
|
|
|
|
// Inizializza e renderizza il grafico a barre
|
|
var barChart = new ApexCharts(document.querySelector("#reportBarChart"), barOptions);
|
|
barChart.render();
|
|
|
|
|
|
|
|
// remove bar chart and create a new one
|
|
// Funzione per generare la tabella
|
|
function generateTable(names, counts) {
|
|
let tableHTML = `
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Analysis</th>
|
|
<th>Number of Failures</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
for (let i = 0; i < names.length; i++) {
|
|
tableHTML += `
|
|
<tr>
|
|
<td>${names[i]}</td>
|
|
<td>${counts[i]}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
tableHTML += `
|
|
</tbody>
|
|
</table>
|
|
`;
|
|
|
|
return tableHTML;
|
|
}
|
|
|
|
// Inizializza il grafico come prima
|
|
$('#worsttenanalysis').html('');
|
|
|
|
|
|
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,
|
|
borderRadius: 10,
|
|
dataLabels: {
|
|
position: 'center'
|
|
}
|
|
}
|
|
},
|
|
dataLabels: {
|
|
enabled: true,
|
|
style: {
|
|
colors: ['black'],
|
|
fontSize: '12px'
|
|
},
|
|
formatter: function(val, opt) {
|
|
return analysisNames[opt.dataPointIndex];
|
|
}
|
|
},
|
|
xaxis: {
|
|
categories: failCounts,
|
|
title: {
|
|
text: 'Number of Failures'
|
|
}
|
|
},
|
|
yaxis: {
|
|
labels: {
|
|
show: false
|
|
},
|
|
title: {
|
|
text: 'Analysis'
|
|
}
|
|
},
|
|
colors: ['orange'],
|
|
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();
|
|
|
|
// Genera la tabella
|
|
$('#tableChartWorst').html(generateTable(analysisNames, failCounts));
|
|
|
|
|
|
|
|
|
|
// Genera il nuovo grafico a barre orizzontali
|
|
$('#horizontalBarChart').html('');
|
|
var horizontalBarData = data.horizontalBarData;
|
|
var categories = horizontalBarData.map(item => item.groupingValue);
|
|
var passData = horizontalBarData.map(item => item.passCount);
|
|
var failData = horizontalBarData.map(item => item.failCount);
|
|
var otherData = horizontalBarData.map(item => item.otherCount);
|
|
|
|
var options = {
|
|
series: [{
|
|
name: 'Pass',
|
|
data: passData
|
|
},
|
|
{
|
|
name: 'Fail',
|
|
data: failData
|
|
},
|
|
{
|
|
name: 'Others',
|
|
data: otherData
|
|
}
|
|
],
|
|
chart: {
|
|
type: 'bar',
|
|
height: 500,
|
|
stacked: true,
|
|
horizontal: true
|
|
},
|
|
xaxis: {
|
|
categories: categories
|
|
},
|
|
colors: ['#28A745', '#FF4D4D', '#FFA500'],
|
|
plotOptions: {
|
|
bar: {
|
|
horizontal: true,
|
|
borderRadius: 5,
|
|
dataLabels: {
|
|
enabled: false
|
|
}
|
|
}
|
|
},
|
|
legend: {
|
|
position: 'top'
|
|
},
|
|
};
|
|
|
|
var chart = new ApexCharts(document.querySelector("#horizontalBarChart"), options);
|
|
chart.render();
|
|
|
|
// Dati per il grafico delle analisi
|
|
var horizontalBarAnalysisData = data.horizontalBarAnalysisData;
|
|
var categoriesAnalysis = horizontalBarAnalysisData.map(item => item.groupingValue);
|
|
var passDataAnalysis = horizontalBarAnalysisData.map(item => item.passCount);
|
|
var failDataAnalysis = horizontalBarAnalysisData.map(item => item.failCount);
|
|
var otherDataAnalysis = horizontalBarAnalysisData.map(item => item.otherCount);
|
|
|
|
// Crea o aggiorna il grafico delle analisi
|
|
$('#horizontalBarAnalysisChart').html('');
|
|
var optionsAnalysis = {
|
|
series: [{
|
|
name: 'Pass',
|
|
data: passDataAnalysis
|
|
},
|
|
{
|
|
name: 'Fail',
|
|
data: failDataAnalysis
|
|
},
|
|
{
|
|
name: 'Others',
|
|
data: otherDataAnalysis
|
|
}
|
|
],
|
|
chart: {
|
|
type: 'bar',
|
|
height: 500,
|
|
stacked: true,
|
|
horizontal: true
|
|
},
|
|
xaxis: {
|
|
categories: categoriesAnalysis
|
|
},
|
|
colors: ['#28A745', '#FF4D4D', '#FFA500'],
|
|
plotOptions: {
|
|
bar: {
|
|
horizontal: true,
|
|
borderRadius: 5,
|
|
dataLabels: {
|
|
enabled: false
|
|
}
|
|
}
|
|
},
|
|
legend: {
|
|
position: 'top'
|
|
},
|
|
};
|
|
var chartAnalysis = new ApexCharts(document.querySelector("#horizontalBarAnalysisChart"), optionsAnalysis);
|
|
chartAnalysis.render();
|
|
|
|
// Funzione per generare la tabella
|
|
function generateSupplierTable(names, failPercentages, totalReports, failedReports) {
|
|
let tableHTML = `
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Supplier</th>
|
|
<th>Failure Percentage (%)</th>
|
|
<th>Failed Reports</th>
|
|
<th>Total Reports</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
for (let i = 0; i < names.length; i++) {
|
|
tableHTML += `
|
|
<tr>
|
|
<td>${names[i]}</td>
|
|
<td>${failPercentages[i].toFixed(2)}%</td>
|
|
<td>${failedReports[i]}</td>
|
|
<td>${totalReports[i]}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
tableHTML += `
|
|
</tbody>
|
|
</table>
|
|
`;
|
|
|
|
return tableHTML;
|
|
}
|
|
|
|
// Rimuove il grafico precedente
|
|
$('#worstSuppliersChart').html('');
|
|
|
|
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: 900
|
|
},
|
|
plotOptions: {
|
|
bar: {
|
|
horizontal: true,
|
|
borderRadius: 5,
|
|
colors: {
|
|
ranges: [{
|
|
from: 0,
|
|
to: 30.00,
|
|
color: '#008000'
|
|
}, // Verde
|
|
{
|
|
from: 30,
|
|
to: 70,
|
|
color: '#FF8C00'
|
|
}, // Arancione
|
|
{
|
|
from: 70,
|
|
to: 100,
|
|
color: '#FF0000'
|
|
} // Rosso
|
|
]
|
|
},
|
|
dataLabels: {
|
|
position: 'center'
|
|
}
|
|
}
|
|
},
|
|
dataLabels: {
|
|
enabled: true,
|
|
style: {
|
|
colors: ['#fff'],
|
|
fontSize: '12px'
|
|
},
|
|
formatter: function(val, opt) {
|
|
var totalReports = totalReportsForSupplier[opt.dataPointIndex];
|
|
var failedReports = failedReportsForSupplier[opt.dataPointIndex];
|
|
return supplierNames[opt.dataPointIndex] + ' (' + val.toFixed(2) + '%) (Fail: ' + failedReports + ' - Total: ' + totalReports + ')';
|
|
}
|
|
},
|
|
xaxis: {
|
|
categories: supplierNames,
|
|
title: {
|
|
text: 'Failure Percentage (%)'
|
|
}
|
|
},
|
|
yaxis: {
|
|
labels: {
|
|
show: false
|
|
},
|
|
title: {
|
|
text: 'Suppliers'
|
|
}
|
|
},
|
|
tooltip: {
|
|
enabled: true,
|
|
y: {
|
|
formatter: function(val, opt) {
|
|
return supplierNames[opt.dataPointIndex] +
|
|
' - ' + val.toFixed(2) + '%' +
|
|
' (Fail: ' + failedReportsForSupplier[opt.dataPointIndex] +
|
|
' - Total: ' + totalReportsForSupplier[opt.dataPointIndex] + ')';
|
|
}
|
|
}
|
|
},
|
|
title: {
|
|
text: 'Top Suppliers with the Highest Failed Reports Percentage',
|
|
align: 'center'
|
|
}
|
|
};
|
|
|
|
|
|
var chart = new ApexCharts(document.querySelector("#worstSuppliersChart"), options);
|
|
chart.render();
|
|
|
|
// Genera la tabella
|
|
$('#tableChartWorstSuppliers').html(
|
|
generateSupplierTable(supplierNames, failPercentages, totalReportsForSupplier, failedReportsForSupplier)
|
|
);
|
|
|
|
|
|
|
|
|
|
// remove bar chart and create a new one
|
|
// Funzione per abbreviare i nomi lunghi dei fornitori
|
|
function abbreviateNames(names, maxLength = 15) {
|
|
return names.map(name => (name.length > maxLength ? name.substring(0, maxLength) + '...' : name));
|
|
}
|
|
|
|
// Funzione per calcolare dinamicamente l'altezza del grafico in base alla lunghezza massima dei nomi
|
|
function calculateChartHeight(names) {
|
|
const maxLength = Math.max(...names.map(name => name.length));
|
|
return maxLength > 15 ? 400 + (maxLength - 15) * 10 : 400;
|
|
}
|
|
|
|
// Funzione per generare la tabella
|
|
function generateProductTable(supplierNames, totalProducts) {
|
|
let tableHTML = `
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Supplier</th>
|
|
<th>Number of Products</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
for (let i = 0; i < supplierNames.length; i++) {
|
|
tableHTML += `
|
|
<tr>
|
|
<td>${supplierNames[i]}</td>
|
|
<td>${totalProducts[i]}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
tableHTML += `
|
|
</tbody>
|
|
</table>
|
|
`;
|
|
|
|
return tableHTML;
|
|
}
|
|
|
|
// Rimuove il contenuto precedente del grafico
|
|
$('#productBySupplierChart').html('');
|
|
|
|
var supplierNames = data.productBySupplier.map(function(item) {
|
|
return item.supplier;
|
|
});
|
|
var totalProducts = data.productBySupplier.map(function(item) {
|
|
return parseInt(item.totalProducts, 10);
|
|
});
|
|
|
|
// Abbrevia i nomi dei fornitori per il grafico
|
|
var supplierNamesAbbreviated = abbreviateNames(supplierNames);
|
|
|
|
var options = {
|
|
series: [{
|
|
name: 'Total Products',
|
|
data: totalProducts
|
|
}],
|
|
chart: {
|
|
type: 'bar',
|
|
height: calculateChartHeight(supplierNames) // Altezza dinamica basata sui nomi completi
|
|
},
|
|
plotOptions: {
|
|
bar: {
|
|
horizontal: false,
|
|
borderRadius: 5,
|
|
columnWidth: '50%',
|
|
dataLabels: {
|
|
position: 'top'
|
|
}
|
|
}
|
|
},
|
|
dataLabels: {
|
|
enabled: true,
|
|
offsetY: -20,
|
|
style: {
|
|
fontSize: '12px',
|
|
colors: ['#000']
|
|
}
|
|
},
|
|
xaxis: {
|
|
categories: supplierNamesAbbreviated, // Usa i nomi abbreviati nel grafico
|
|
labels: {
|
|
rotate: -45, // Ruota le etichette per maggiore leggibilità
|
|
style: {
|
|
fontSize: '12px'
|
|
}
|
|
},
|
|
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();
|
|
|
|
// Genera la tabella con i nomi completi dei fornitori
|
|
$('#tableChartProductsBySupplier').html(
|
|
generateProductTable(supplierNames, totalProducts)
|
|
);
|
|
|
|
|
|
|
|
|
|
// remove bar chart and create a new one
|
|
// Funzione per generare la tabella
|
|
function generateAnalysisTable(analysisNames, totalTests) {
|
|
let tableHTML = `
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Analysis Name</th>
|
|
<th>Total Tests</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
for (let i = 0; i < analysisNames.length; i++) {
|
|
tableHTML += `
|
|
<tr>
|
|
<td>${analysisNames[i]}</td>
|
|
<td>${totalTests[i]}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
tableHTML += `
|
|
</tbody>
|
|
</table>
|
|
`;
|
|
|
|
return tableHTML;
|
|
}
|
|
|
|
// Resetta il contenuto del grafico
|
|
$('#analysisDistributionChart').html('');
|
|
|
|
var analysisNames = data.analysisDistribution.map(function(item) {
|
|
return item.analysisName;
|
|
});
|
|
var totalTests = data.analysisDistribution.map(function(item) {
|
|
return parseInt(item.totalTests, 10);
|
|
});
|
|
|
|
var analysisBarChartOptions = {
|
|
series: [{
|
|
name: 'Total Tests',
|
|
data: totalTests
|
|
}],
|
|
chart: {
|
|
type: 'bar',
|
|
height: 550
|
|
},
|
|
plotOptions: {
|
|
bar: {
|
|
horizontal: true,
|
|
borderRadius: 5,
|
|
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,
|
|
style: {
|
|
fontSize: '12px',
|
|
colors: ['#000']
|
|
}
|
|
},
|
|
title: {
|
|
text: 'Analysis Name'
|
|
}
|
|
},
|
|
fill: {
|
|
opacity: 1,
|
|
colors: ['green']
|
|
},
|
|
tooltip: {
|
|
y: {
|
|
formatter: function(val) {
|
|
return val + " tests";
|
|
}
|
|
}
|
|
},
|
|
title: {
|
|
text: 'Analysis Distribution',
|
|
align: 'center'
|
|
},
|
|
grid: {
|
|
padding: {
|
|
left: 10
|
|
}
|
|
}
|
|
};
|
|
|
|
var analysisBarChart = new ApexCharts(document.querySelector("#analysisDistributionChart"), analysisBarChartOptions);
|
|
analysisBarChart.render();
|
|
|
|
// Genera la tabella con i dati delle analisi
|
|
$('#tableChartAnalysisDistribution').html(
|
|
generateAnalysisTable(analysisNames, totalTests)
|
|
);
|
|
|
|
|
|
|
|
|
|
// remove bar chart and create a new one
|
|
// Funzione per generare la tabella
|
|
function generateAnalytesTable(analyteNames, failCounts) {
|
|
let tableHTML = `
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Analyte Name</th>
|
|
<th>Number of Failures</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
for (let i = 0; i < analyteNames.length; i++) {
|
|
tableHTML += `
|
|
<tr>
|
|
<td>${analyteNames[i]}</td>
|
|
<td>${failCounts[i]}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
tableHTML += `
|
|
</tbody>
|
|
</table>
|
|
`;
|
|
|
|
return tableHTML;
|
|
}
|
|
|
|
// Resetta il contenuto del grafico
|
|
$('#analytesFailChart').html('');
|
|
|
|
var analyteNames = data.failedAnalytes.map(function(item) {
|
|
return item.AnalyteName;
|
|
});
|
|
var failCounts = data.failedAnalytes.map(function(item) {
|
|
return parseInt(item.FailCount, 10);
|
|
});
|
|
|
|
var options = {
|
|
series: [{
|
|
data: failCounts
|
|
}],
|
|
chart: {
|
|
type: 'bar',
|
|
height: 400
|
|
},
|
|
plotOptions: {
|
|
bar: {
|
|
horizontal: true,
|
|
borderRadius: 5,
|
|
dataLabels: {
|
|
position: 'center' // Etichette al centro delle barre
|
|
}
|
|
}
|
|
},
|
|
dataLabels: {
|
|
enabled: true,
|
|
style: {
|
|
colors: ['black'], // Colore del testo all'interno delle barre
|
|
fontSize: '12px'
|
|
},
|
|
textAnchor: 'start', // Allinea il testo a sinistra
|
|
offsetX: -5, // Regola la distanza orizzontale
|
|
formatter: function(val, opt) {
|
|
return analyteNames[opt.dataPointIndex]; // Mostra il nome dell'analita 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: 'Analytes'
|
|
}
|
|
},
|
|
colors: ['#ffa515'], // Colore per i Fail
|
|
title: {
|
|
text: 'Top 10 Analytes with the Most Failures',
|
|
align: 'center'
|
|
}
|
|
};
|
|
|
|
var chart = new ApexCharts(document.querySelector("#analytesFailChart"), options);
|
|
chart.render();
|
|
|
|
$('#tableChartAnalytesFail').html(
|
|
generateAnalytesTable(analyteNames, failCounts)
|
|
);
|
|
},
|
|
error: function() {
|
|
alert('Error retrieving data.');
|
|
}
|
|
});
|
|
|
|
// Funzione per generare la tabella del grafico a torta
|
|
function generatePhasePieTable(labels, values) {
|
|
let tableHTML = `
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Phase</th>
|
|
<th>Total Products</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
for (let i = 0; i < labels.length; i++) {
|
|
tableHTML += `
|
|
<tr>
|
|
<td>${labels[i]}</td>
|
|
<td>${values[i]}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
tableHTML += `
|
|
</tbody>
|
|
</table>
|
|
`;
|
|
|
|
return tableHTML;
|
|
}
|
|
|
|
// Funzione per generare la tabella del grafico a barre
|
|
function generatePhaseBarTable(labels, passCounts, failCounts, otherCounts) {
|
|
let tableHTML = `
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Phase</th>
|
|
<th>Pass</th>
|
|
<th>Fail</th>
|
|
<th>Other</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
for (let i = 0; i < labels.length; i++) {
|
|
tableHTML += `
|
|
<tr>
|
|
<td>${labels[i]}</td>
|
|
<td>${passCounts[i]}</td>
|
|
<td>${failCounts[i]}</td>
|
|
<td>${otherCounts[i]}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
tableHTML += `
|
|
</tbody>
|
|
</table>
|
|
`;
|
|
|
|
return tableHTML;
|
|
}
|
|
|
|
function renderPhasePieChart(phaseData) {
|
|
const labels = phaseData.map(item => item.phase);
|
|
const values = phaseData.map(item => parseInt(item.totalProducts, 10));
|
|
|
|
const options = {
|
|
series: values,
|
|
chart: {
|
|
type: 'pie',
|
|
height: 350,
|
|
toolbar: {
|
|
show: true, // Mostra l'hamburger menu
|
|
tools: {
|
|
download: true, // Opzioni di download
|
|
selection: false,
|
|
zoom: false,
|
|
zoomin: false,
|
|
zoomout: false,
|
|
pan: false,
|
|
reset: false
|
|
}
|
|
}
|
|
},
|
|
labels: labels,
|
|
responsive: [{
|
|
breakpoint: 480,
|
|
options: {
|
|
chart: {
|
|
width: 300
|
|
},
|
|
legend: {
|
|
position: 'bottom'
|
|
}
|
|
}
|
|
}],
|
|
colors: ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#C9CB8D'], // Custom Colors
|
|
legend: {
|
|
position: 'bottom'
|
|
}
|
|
};
|
|
|
|
const chart = new ApexCharts(document.querySelector("#phasePieChart"), options);
|
|
chart.render();
|
|
|
|
// Genera la tabella e inseriscila nel contenitore
|
|
$('#tablePhasePie').html(generatePhasePieTable(labels, values));
|
|
}
|
|
|
|
|
|
function renderPhaseBarChart(phaseRatingsData) {
|
|
const labels = phaseRatingsData.map(item => item.phase);
|
|
const passCounts = phaseRatingsData.map(item => parseInt(item.passCount, 10));
|
|
const failCounts = phaseRatingsData.map(item => parseInt(item.failCount, 10));
|
|
const otherCounts = phaseRatingsData.map(item => parseInt(item.otherCount, 10));
|
|
|
|
const options = {
|
|
series: [{
|
|
name: 'Pass',
|
|
data: passCounts
|
|
},
|
|
{
|
|
name: 'Fail',
|
|
data: failCounts
|
|
},
|
|
{
|
|
name: 'Other',
|
|
data: otherCounts
|
|
}
|
|
],
|
|
chart: {
|
|
type: 'bar',
|
|
height: 400,
|
|
stacked: true,
|
|
horizontal: true
|
|
},
|
|
xaxis: {
|
|
categories: labels,
|
|
title: {
|
|
text: 'Ratings Count'
|
|
}
|
|
},
|
|
colors: ['#28A745', '#FF4D4D', '#FFA500'],
|
|
plotOptions: {
|
|
bar: {
|
|
horizontal: false,
|
|
borderRadius: 5,
|
|
dataLabels: {
|
|
enabled: false
|
|
}
|
|
}
|
|
},
|
|
legend: {
|
|
position: 'top'
|
|
},
|
|
tooltip: {
|
|
y: {
|
|
formatter: val => `${val} reports`
|
|
}
|
|
}
|
|
};
|
|
|
|
$('#phaseBarChart').html(''); // Reset grafico esistente
|
|
const chart = new ApexCharts(document.querySelector("#phaseBarChart"), options);
|
|
chart.render();
|
|
|
|
// Genera la tabella e inseriscila nel contenitore
|
|
$('#tablePhaseBar').html(generatePhaseBarTable(labels, passCounts, failCounts, otherCounts));
|
|
}
|
|
|
|
|
|
// Mostra o nascondi la tabella al clic del pulsante
|
|
$('.toggle-table').on('click', function() {
|
|
const target = $(this).data('target');
|
|
$(target).toggleClass('hidden');
|
|
});
|
|
|
|
// Chiama questa funzione dopo aver recuperato i dati tramite AJAX
|
|
$(document).ready(function() {
|
|
updateData(); // Aggiorna i dati iniziali
|
|
});
|
|
|
|
function updateData() {
|
|
$.ajax({
|
|
url: 'parsedatachart.php', // Endpoint per ottenere i dati
|
|
method: 'POST',
|
|
data: {
|
|
startDate: $('#startDate').val(),
|
|
endDate: $('#endDate').val(),
|
|
supplier: $('#supplierFilter').val(),
|
|
productsRefnumber: $('#productsRefnumber').val(),
|
|
productsSeason: $('#productsSeason').val(),
|
|
ageRange: $('#ageRange').val(),
|
|
reportsLabName: $('#reportsLabName').val(),
|
|
reportsTestType: $('#reportsTestType').val(),
|
|
reportsNumberLab: $('#reportsNumberLab').val(),
|
|
},
|
|
success: function(response) {
|
|
const data = JSON.parse(response);
|
|
|
|
// Aggiorna il grafico della distribuzione per fase
|
|
if (data.phaseData && data.phaseData.length > 0) {
|
|
renderPhasePieChart(data.phaseData);
|
|
} else {
|
|
console.log('No phase data available.');
|
|
}
|
|
|
|
// Aggiorna il grafico delle valutazioni per fase (Bar Chart)
|
|
if (data.phaseRatingsData && data.phaseRatingsData.length > 0) {
|
|
renderPhaseBarChart(data.phaseRatingsData);
|
|
} else {
|
|
console.log('No phase ratings data available for Bar Chart.');
|
|
$('#phaseBarChart').html('<p>No data available</p>');
|
|
}
|
|
},
|
|
error: function() {
|
|
console.log('Error retrieving data.');
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Eventi per applicare i filtri e il cambio di raggruppamento
|
|
$('#startDate, #endDate, #supplierFilter, #productsRefnumber, #productsSeason, #ageRange, #reportsLabName, #reportsTestType, #reportsNumberLab, #groupingField').on('change', function() {
|
|
updateData();
|
|
});
|
|
|
|
// Clear filters
|
|
$('#clearFilters').on('click', function() {
|
|
$('#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();
|
|
});
|
|
|
|
// Chiamata iniziale per caricare i dati alla prima visualizzazione della pagina
|
|
updateData();
|
|
});
|
|
</script> |