update
This commit is contained in:
parent
1e1e078489
commit
6752d3515f
@ -1,8 +1,8 @@
|
||||
<!-- ========== Left Sidebar Start ========== -->
|
||||
<div class="left side-menu">
|
||||
<button type="button" class="button-menu-mobile button-menu-mobile-topbar open-left waves-effect">
|
||||
<!-- <button type="button" class="button-menu-mobile button-menu-mobile-topbar open-left waves-effect">
|
||||
<i class="ion-close"></i>
|
||||
</button>
|
||||
</button> -->
|
||||
|
||||
<!-- LOGO -->
|
||||
<div class="topbar-left">
|
||||
|
||||
@ -125,6 +125,47 @@
|
||||
transform: translateY(30px);
|
||||
}
|
||||
}
|
||||
|
||||
body.sidebar-collapsed .left.side-menu {
|
||||
width: 80px;
|
||||
/* Riduci la larghezza della sidebar */
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
body.sidebar-collapsed .content-page {
|
||||
margin-left: 80px;
|
||||
/* Adatta il contenuto */
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
body.sidebar-collapsed .left.side-menu ul li a span {
|
||||
display: none;
|
||||
/* Nascondi il testo dei link */
|
||||
}
|
||||
|
||||
body.sidebar-collapsed .left.side-menu ul li a {
|
||||
text-align: center;
|
||||
/* Centra le icone */
|
||||
}
|
||||
|
||||
body.sidebar-collapsed .left.side-menu .sidebar-user h6,
|
||||
body.sidebar-collapsed .left.side-menu .sidebar-user p {
|
||||
display: none;
|
||||
/* Nascondi dettagli utente */
|
||||
}
|
||||
|
||||
.button-menu-mobile {
|
||||
display: inline-block;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mdi-menu {
|
||||
font-size: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<nav class="navbar-custom">
|
||||
@ -192,9 +233,9 @@
|
||||
</div>
|
||||
|
||||
<!-- item-->
|
||||
<div id="notificationItemDiv">
|
||||
<div id="notificationItemDiv">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- <a href="javascript:void(0);" class="dropdown-item notify-item">
|
||||
<div class="notify-icon bg-primary"><i class="mdi mdi-cart-outline"></i></div>
|
||||
<p class="notify-details"><b>Your order is placed</b><small class="text-muted">Dummy text of the printing and typesetting industry.</small></p>
|
||||
@ -228,9 +269,10 @@
|
||||
|
||||
<ul class="list-inline menu-left mb-0">
|
||||
<li class="float-left">
|
||||
<button class="button-menu-mobile open-left waves-light waves-effect">
|
||||
<button id="toggle-sidebar" class="button-menu-mobile open-left waves-light waves-effect">
|
||||
<i class="mdi mdi-menu"></i>
|
||||
</button>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@ -308,13 +350,13 @@
|
||||
$.post("<?php echo USERAREA_PATH; ?>include/getNotifications.php", {
|
||||
method: 'getNotifications'
|
||||
}, function(data) {
|
||||
unseen_notifications =data.unseen_notifications;
|
||||
unseen_notifications = data.unseen_notifications;
|
||||
$("#notificationQuantity").text(unseen_notifications.length);
|
||||
$("#notificationQuantityDropDown").text(unseen_notifications.length);
|
||||
|
||||
$("#notificationItemDiv").empty();
|
||||
|
||||
for(var i=0; i<data.unseen_notifications.length; i++){
|
||||
for (var i = 0; i < data.unseen_notifications.length; i++) {
|
||||
$("#notificationItemDiv").append(`
|
||||
<a href="javascript:void(0);" class="dropdown-item notify-item">
|
||||
<div class="notify-icon bg-primary">
|
||||
@ -324,20 +366,20 @@
|
||||
</a>
|
||||
`);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="notification-space" id="mainNotificationDiv">
|
||||
<!-- Notifications will be displayed here -->
|
||||
</div>
|
||||
|
||||
<script src="<?php echo USERAREA_PATH;?>assets/js/popper.min.js"></script>
|
||||
<script src="<?php echo USERAREA_PATH;?>assets/js/bootstrap.min.js"></script>
|
||||
<script src="<?php echo USERAREA_PATH; ?>assets/js/popper.min.js"></script>
|
||||
<script src="<?php echo USERAREA_PATH; ?>assets/js/bootstrap.min.js"></script>
|
||||
|
||||
<script src="../assets/js/jquery.slimscroll.js"></script>
|
||||
<!-- App js -->
|
||||
<script src="<?php echo USERAREA_PATH;?>assets/js/app.js"></script>
|
||||
<script src="<?php echo USERAREA_PATH;?>assets/plugins/alertify/js/alertify.js"></script>
|
||||
<script src="../assets/js/jquery.slimscroll.js"></script>
|
||||
<!-- App js -->
|
||||
<script src="<?php echo USERAREA_PATH; ?>assets/js/app.js"></script>
|
||||
<script src="<?php echo USERAREA_PATH; ?>assets/plugins/alertify/js/alertify.js"></script>
|
||||
<!-- Top Bar End -->
|
||||
@ -35,17 +35,26 @@ SELECT
|
||||
WHEN LOWER(ap.test_Rating) NOT IN ('pass', 'p', 'comply', 'complies', 'fail', 'f', 'doesn\'t comply') THEN 1
|
||||
ELSE 0
|
||||
END) AS data_analyses,
|
||||
GREATEST(0, 10 - (
|
||||
SUM(
|
||||
CASE
|
||||
WHEN LOWER(ap.test_Rating) IN ('fail', 'f', 'doesn\'t comply') THEN
|
||||
COALESCE(asv.severity, 1) *
|
||||
CASE WHEN COALESCE(asv.is_legal, 'N') = 'Y' THEN 1.5 ELSE 1.0 END
|
||||
ELSE 0
|
||||
END
|
||||
) * (1 + SUM(CASE WHEN LOWER(ap.test_Rating) IN ('fail', 'f', 'doesn\'t comply') THEN 1 ELSE 0 END) / NULLIF(COUNT(ap.idAnalysis_Project), 0))
|
||||
/ NULLIF(COUNT(ap.idAnalysis_Project), 0) * 100
|
||||
)) AS rating,
|
||||
CASE
|
||||
WHEN SUM(CASE WHEN LOWER(ap.test_Rating) IN ('fail', 'f', 'doesn\'t comply') THEN 1 ELSE 0 END) = 0
|
||||
AND SUM(CASE WHEN LOWER(ap.test_Rating) NOT IN ('pass', 'p', 'comply', 'complies', 'fail', 'f', 'doesn\'t comply') THEN 1 ELSE 0 END) = 0
|
||||
THEN 100
|
||||
ELSE GREATEST(0, 100 - (
|
||||
SUM(
|
||||
CASE
|
||||
WHEN LOWER(ap.test_Rating) IN ('fail', 'f', 'doesn\'t comply') THEN
|
||||
POWER(COALESCE(asv.severity, 1), 2) *
|
||||
CASE WHEN COALESCE(asv.is_legal, 'N') = 'Y' THEN 2.0 ELSE 1.0 END
|
||||
ELSE 0
|
||||
END
|
||||
) / NULLIF(COUNT(ap.idAnalysis_Project), 0) * 100 *
|
||||
(1 + 2 * (SUM(CASE WHEN LOWER(ap.test_Rating) IN ('fail', 'f', 'doesn\'t comply') THEN 1 ELSE 0 END) / NULLIF(COUNT(ap.idAnalysis_Project), 0)))
|
||||
+ SUM(CASE
|
||||
WHEN LOWER(ap.test_Rating) NOT IN ('pass', 'p', 'comply', 'complies', 'fail', 'f', 'doesn\'t comply') THEN 0.3
|
||||
ELSE 0
|
||||
END)
|
||||
))
|
||||
END AS rating,
|
||||
NOW() AS calculation_date
|
||||
FROM products p
|
||||
JOIN reports r ON p.idproducts = r.idproducts
|
||||
@ -61,7 +70,6 @@ ON DUPLICATE KEY UPDATE
|
||||
data_analyses = VALUES(data_analyses),
|
||||
rating = VALUES(rating),
|
||||
calculation_date = VALUES(calculation_date);
|
||||
|
||||
";
|
||||
|
||||
if ($conn->query($query) === TRUE) {
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
|
||||
<script src="https://cdn.datatables.net/buttons/2.3.7/js/buttons.html5.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/buttons/2.3.7/js/buttons.print.min.js"></script>
|
||||
<link href="https://cdn.materialdesignicons.com/5.4.55/css/materialdesignicons.min.css" rel="stylesheet">
|
||||
|
||||
|
||||
</head>
|
||||
@ -46,14 +47,22 @@
|
||||
|
||||
<div class="page-content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="page-title-box">
|
||||
<h4 class="page-title">Supplier Ratings</h4>
|
||||
<br>
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card p-4">
|
||||
<div class="rating-box">
|
||||
<h3 class="m-0">
|
||||
RATE&GO
|
||||
</h3>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Button for Rating Calculation -->
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-right">
|
||||
@ -64,6 +73,24 @@
|
||||
</div>
|
||||
|
||||
<!-- Chart Section -->
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-right">
|
||||
<label for="rating-filter">Filter by Rating:</label>
|
||||
<select id="rating-filter" class="form-control w-auto d-inline-block">
|
||||
<option value="green">Green (80-100)</option>
|
||||
<option value="orange">Orange (50-79)</option>
|
||||
<option value="red">Red (0-49)</option>
|
||||
<option value="all">All</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="supplier-rating-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="supplier-rating-chart"></div>
|
||||
@ -105,11 +132,17 @@
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Funzione per aggiornare il grafico
|
||||
function updateChart(response) {
|
||||
const suppliers = response.map(s => s.name);
|
||||
const ratings = response.map(s => s.rating);
|
||||
const colors = response.map(s => s.color);
|
||||
let chart; // Variabile per memorizzare l'istanza del grafico
|
||||
|
||||
// Funzione per generare il grafico
|
||||
function renderChart(filteredData) {
|
||||
const suppliers = filteredData.map(s => s.name);
|
||||
const ratings = filteredData.map(s => s.rating);
|
||||
const colors = filteredData.map(s => {
|
||||
if (s.rating >= 80) return '#28a745'; // Green
|
||||
if (s.rating >= 50) return '#ffc107'; // Orange
|
||||
return '#dc3545'; // Red
|
||||
});
|
||||
|
||||
const options = {
|
||||
series: [{
|
||||
@ -117,26 +150,92 @@
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400
|
||||
height: Math.max(filteredData.length * 18, 300), // Altezza dinamica
|
||||
toolbar: {
|
||||
show: true
|
||||
},
|
||||
animations: {
|
||||
enabled: true, // Abilita animazioni fluide
|
||||
easing: 'easeinout',
|
||||
speed: 800
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
distributed: true,
|
||||
horizontal: true,
|
||||
barHeight: '80%', // Altezza barra
|
||||
dataLabels: {
|
||||
position: 'inside' // Valori all'interno delle barre
|
||||
}
|
||||
}
|
||||
},
|
||||
colors: colors,
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#000'], // Colore nero per i valori
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
formatter: function(val) {
|
||||
return val; // Mostra il valore direttamente
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: suppliers
|
||||
categories: suppliers,
|
||||
labels: {
|
||||
style: {
|
||||
fontSize: '12px'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
title: {
|
||||
text: 'Supplier Ratings',
|
||||
text: 'Supplier Ratings (Filtered)',
|
||||
align: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
// Renderizza il grafico
|
||||
const chart = new ApexCharts(
|
||||
document.querySelector("#supplier-rating-chart"),
|
||||
options
|
||||
);
|
||||
// Distruggi il grafico precedente, se esiste
|
||||
if (chart) {
|
||||
chart.destroy();
|
||||
}
|
||||
|
||||
// Crea un nuovo grafico
|
||||
chart = new ApexCharts(document.querySelector("#supplier-rating-chart"), options);
|
||||
chart.render();
|
||||
}
|
||||
|
||||
// Funzione per filtrare i dati
|
||||
function filterData(data, filter) {
|
||||
if (filter === "green") return data.filter(s => s.rating >= 80);
|
||||
if (filter === "orange") return data.filter(s => s.rating >= 50 && s.rating < 80);
|
||||
if (filter === "red") return data.filter(s => s.rating < 50);
|
||||
return data; // All
|
||||
}
|
||||
|
||||
// Caricamento iniziale
|
||||
$.get('get_supplier_ratings.php', function(response) {
|
||||
const allData = response;
|
||||
|
||||
// Filtro predefinito: Green
|
||||
const defaultFilter = "green";
|
||||
const filteredData = filterData(allData, defaultFilter);
|
||||
$("#rating-filter").val(defaultFilter); // Imposta il filtro predefinito nel dropdown
|
||||
|
||||
// Renderizza il grafico iniziale
|
||||
renderChart(filteredData);
|
||||
|
||||
// Cambia filtro
|
||||
$("#rating-filter").on('change', function() {
|
||||
const selectedFilter = $(this).val();
|
||||
const filteredData = filterData(allData, selectedFilter);
|
||||
renderChart(filteredData); // Re-renderizza il grafico con i dati filtrati
|
||||
});
|
||||
});
|
||||
|
||||
// Inizializza DataTables
|
||||
const supplierTable = $('#supplierTable').DataTable({
|
||||
ajax: {
|
||||
@ -167,7 +266,7 @@
|
||||
{
|
||||
data: 'rating',
|
||||
render: function(data, type, row) {
|
||||
const color = data >= 8 ? '#28a745' : data >= 5 ? '#ffc107' : '#dc3545';
|
||||
const color = data >= 80 ? '#28a745' : data >= 50 ? '#ffc107' : '#dc3545';
|
||||
return `<span style="color: ${color}; font-weight: bold;">${data}</span>`;
|
||||
}
|
||||
},
|
||||
@ -184,12 +283,15 @@
|
||||
buttons: [
|
||||
'copy', 'csv', 'excel', 'pdf', 'print' // Tipi di esportazione
|
||||
],
|
||||
lengthMenu: [
|
||||
[10, 25, 50, 100, -1], // Valori
|
||||
[10, 25, 50, 100, "All"] // Etichette corrispondenti
|
||||
],
|
||||
initComplete: function(settings, json) {
|
||||
updateChart(json); // Aggiorna il grafico dopo aver caricato la tabella
|
||||
renderChart(json); // Aggiorna il grafico dopo aver caricato la tabella
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Funzione per calcolare i rating e aggiornare grafico e tabella
|
||||
$('#calculate-rating').on('click', function() {
|
||||
$.ajax({
|
||||
@ -199,7 +301,7 @@
|
||||
alert('Ratings calculated successfully!');
|
||||
supplierTable.ajax.reload(); // Ricarica la tabella
|
||||
$.get('get_supplier_ratings.php', function(response) {
|
||||
updateChart(response); // Aggiorna il grafico
|
||||
renderChart(response); // Aggiorna il grafico
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
@ -211,6 +313,7 @@
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -171,7 +171,7 @@ if (!$supplier) {
|
||||
<?php echo htmlspecialchars($supplier['name']); ?>
|
||||
</h3>
|
||||
<div class="rating-score
|
||||
<?php echo $supplier['rating'] >= 8 ? 'rating-high' : ($supplier['rating'] >= 5 ? 'rating-medium' : 'rating-low'); ?>">
|
||||
<?php echo $supplier['rating'] >= 80 ? 'rating-high' : ($supplier['rating'] >= 50 ? 'rating-medium' : 'rating-low'); ?>">
|
||||
<?php echo number_format($supplier['rating'], 2); ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -224,6 +224,18 @@ if (!$supplier) {
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Analysis Distribution</h5>
|
||||
<div id="pie-chart"></div>
|
||||
<button id="toggle-pie-table" class="btn btn-secondary mt-3">Toggle Table</button>
|
||||
<div id="pie-table-container" style="display: none;">
|
||||
<table class="table table-bordered mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th>Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="pie-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -233,6 +245,18 @@ if (!$supplier) {
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Analysis Summary</h5>
|
||||
<div id="stacked-bar-chart"></div>
|
||||
<button id="toggle-stacked-table" class="btn btn-secondary mt-3">Toggle Table</button>
|
||||
<div id="stacked-table-container" style="display: none;">
|
||||
<table class="table table-bordered mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th>Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="stacked-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -245,18 +269,16 @@ if (!$supplier) {
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Total Analysis Distribution</h5>
|
||||
<div id="distribution-bar-chart"></div>
|
||||
<button class="collapsible">Toggle Table</button>
|
||||
<div class="collapsible-content">
|
||||
<table class="table table-bordered">
|
||||
<button id="toggle-distribution-table" class="btn btn-secondary mt-3">Toggle Table</button>
|
||||
<div id="distribution-table-container" style="display: none;">
|
||||
<table class="table table-bordered mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Analysis Name</th>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="distribution-table-body">
|
||||
<!-- Data loaded dynamically -->
|
||||
</tbody>
|
||||
<tbody id="distribution-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -272,40 +294,36 @@ if (!$supplier) {
|
||||
<h5 class="card-title">Top FAIL Analyses</h5>
|
||||
<div id="fail-bar-chart"></div>
|
||||
<!-- Pulsante Toggle Table -->
|
||||
<button id="toggle-fail-table" class="btn btn-secondary">Toggle Table</button>
|
||||
<button id="toggle-fail-table" class="btn btn-secondary mt-3">Toggle Table</button>
|
||||
<div id="fail-table-container" style="display: none;">
|
||||
<table class="table table-bordered">
|
||||
<table class="table table-bordered mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Analysis Name</th>
|
||||
<th>Fail Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="fail-table-body">
|
||||
<!-- Popolato dinamicamente -->
|
||||
</tbody>
|
||||
<tbody id="fail-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Pulsante View Fail Details -->
|
||||
<button id="view-fail-details" class="btn btn-primary">View Fail Details</button>
|
||||
<button id="view-fail-details" class="btn btn-primary mt-3">View Fail Details</button>
|
||||
<div id="fail-details-container" style="display: none;">
|
||||
<table class="table table-bordered">
|
||||
<table class="table table-bordered mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Analysis Name</th>
|
||||
<th>Report Number</th>
|
||||
<th>Ref Numb.</th>
|
||||
<th>Ref Number</th>
|
||||
<th>Product Description</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="fail-details-table-body">
|
||||
<!-- Popolato dinamicamente -->
|
||||
</tbody>
|
||||
<tbody id="fail-details-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -315,12 +333,133 @@ if (!$supplier) {
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Dati per i grafici principali
|
||||
const supplierName = "<?php echo htmlspecialchars($supplier['name']); ?>";
|
||||
|
||||
// Pie Chart Configuration (Analysis Distribution)
|
||||
const passCount = <?php echo isset($supplier['pass_analyses']) ? $supplier['pass_analyses'] : 0; ?>;
|
||||
const failCount = <?php echo isset($supplier['fail_analyses']) ? $supplier['fail_analyses'] : 0; ?>;
|
||||
const dataCount = <?php echo isset($supplier['data_analyses']) ? $supplier['data_analyses'] : 0; ?>;
|
||||
|
||||
// Pie Chart Configuration
|
||||
|
||||
$.getJSON(`get_fail_details.php?supplier=${supplierName}`, function(data) {
|
||||
if (data.error) {
|
||||
alert(data.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Configurazione del grafico
|
||||
const failChartOptions = {
|
||||
series: [{
|
||||
data: data.failDistribution.map(item => item.fail)
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 350,
|
||||
horizontal: true
|
||||
},
|
||||
xaxis: {
|
||||
categories: data.failDistribution.map(item => item.analysis_name),
|
||||
title: {
|
||||
text: 'Fail Count'
|
||||
}
|
||||
},
|
||||
colors: ['#dc3545'],
|
||||
title: {
|
||||
text: 'Top FAIL Analyses',
|
||||
align: 'center'
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
barHeight: '50%'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const failChart = new ApexCharts(document.querySelector("#fail-bar-chart"), failChartOptions);
|
||||
failChart.render();
|
||||
|
||||
// Popola la tabella di riepilogo delle analisi fallite
|
||||
const failTableBody = document.querySelector("#fail-table-body");
|
||||
data.failDistribution.forEach(row => {
|
||||
failTableBody.innerHTML += `
|
||||
<tr>
|
||||
<td>${row.analysis_name}</td>
|
||||
<td>${row.fail}</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
// Gestione del pulsante "View Fail Details"
|
||||
|
||||
|
||||
const failDetailsButton = document.querySelector("#view-fail-details");
|
||||
if (!failDetailsButton) {
|
||||
console.error("Pulsante #view-fail-details non trovato nel DOM.");
|
||||
} else {
|
||||
console.log("Pulsante trovato:", failDetailsButton);
|
||||
}
|
||||
|
||||
|
||||
// Gestione del pulsante "View Fail Details"
|
||||
document.querySelector("#view-fail-details").addEventListener("click", function() {
|
||||
console.log("View Fail Details clicked");
|
||||
const detailsContainer = document.querySelector("#fail-details-container");
|
||||
|
||||
if (!detailsContainer) {
|
||||
console.error("The #fail-details-container was not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
const detailsTableBody = document.querySelector("#fail-details-table-body");
|
||||
|
||||
if (!detailsTableBody) {
|
||||
console.error("The #fail-details-table-body was not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the nested AJAX call and use the existing data from the first AJAX call
|
||||
if (!detailsContainer.hasAttribute("data-loaded")) {
|
||||
// Use the data from the first AJAX call
|
||||
const details = data; // This assumes 'data' is in scope from the previous $.getJSON call
|
||||
|
||||
// Clear any existing content
|
||||
detailsTableBody.innerHTML = '';
|
||||
|
||||
// Populate the table with fail details
|
||||
details.failDetails.forEach(detail => {
|
||||
detailsTableBody.innerHTML += `
|
||||
<tr>
|
||||
<td>${detail.analysis_name}</td>
|
||||
<td>${detail.report_number}</td>
|
||||
<td>${detail.product_refnumber}</td>
|
||||
<td>${detail.product_description}</td>
|
||||
<td>
|
||||
<a href="../products/reportdetails.php?idreports=${detail.report_id}" target="_blank" class="btn btn-sm btn-primary">
|
||||
View Details
|
||||
</a>
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
detailsContainer.setAttribute("data-loaded", "true");
|
||||
detailsContainer.style.display = "block";
|
||||
} else {
|
||||
// Toggle visibility if already loaded
|
||||
detailsContainer.style.display = detailsContainer.style.display === "block" ? "none" : "block";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Toggle per la tabella Fail Summary
|
||||
document.querySelector("#toggle-fail-table").addEventListener("click", function() {
|
||||
const table = document.querySelector("#fail-table-container");
|
||||
table.style.display = table.style.display === "block" ? "none" : "block";
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
const pieChartOptions = {
|
||||
series: [passCount, failCount, dataCount],
|
||||
chart: {
|
||||
@ -347,7 +486,7 @@ if (!$supplier) {
|
||||
const pieChart = new ApexCharts(document.querySelector("#pie-chart"), pieChartOptions);
|
||||
pieChart.render();
|
||||
|
||||
// Stacked Bar Chart Configuration
|
||||
// Stacked Bar Chart Configuration (Analysis Summary)
|
||||
const stackedBarChartOptions = {
|
||||
series: [{
|
||||
name: 'PASS',
|
||||
@ -393,16 +532,14 @@ if (!$supplier) {
|
||||
const stackedBarChart = new ApexCharts(document.querySelector("#stacked-bar-chart"), stackedBarChartOptions);
|
||||
stackedBarChart.render();
|
||||
|
||||
// Fetch and populate data for additional charts and tables
|
||||
const supplierName = "<?php echo htmlspecialchars($supplier['name']); ?>";
|
||||
|
||||
// Fetch Data for Additional Charts and Tables
|
||||
$.getJSON(`get_analysis_data.php?supplier=${supplierName}`, function(data) {
|
||||
if (data.error) {
|
||||
alert(data.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Distribuzione delle analisi totali
|
||||
// Distribution Bar Chart (Total Analysis Distribution)
|
||||
const distributionChartOptions = {
|
||||
series: [{
|
||||
data: data.analysisDistribution.map(item => item.total)
|
||||
@ -412,12 +549,6 @@ if (!$supplier) {
|
||||
height: 350,
|
||||
horizontal: true
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
barHeight: '50%'
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: data.analysisDistribution.map(item => item.analysis_name),
|
||||
title: {
|
||||
@ -428,22 +559,29 @@ if (!$supplier) {
|
||||
title: {
|
||||
text: 'Total Analysis Distribution',
|
||||
align: 'center'
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
barHeight: '50%'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const distributionChart = new ApexCharts(document.querySelector("#distribution-bar-chart"), distributionChartOptions);
|
||||
distributionChart.render();
|
||||
|
||||
// Aggiorna tabella per Distribuzione Totale
|
||||
// Populate Distribution Table
|
||||
const distTableBody = document.querySelector("#distribution-table-body");
|
||||
data.analysisDistribution.forEach(row => {
|
||||
distTableBody.innerHTML += `<tr>
|
||||
<td>${row.analysis_name}</td>
|
||||
<td>${row.total}</td>
|
||||
</tr>`;
|
||||
distTableBody.innerHTML += `
|
||||
<tr>
|
||||
<td>${row.analysis_name}</td>
|
||||
<td>${row.total}</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
// Distribuzione delle analisi FAIL
|
||||
// Fail Analysis Chart (Top FAIL Analyses)
|
||||
const failChartOptions = {
|
||||
series: [{
|
||||
data: data.failDistribution.map(item => item.fail)
|
||||
@ -453,12 +591,6 @@ if (!$supplier) {
|
||||
height: 350,
|
||||
horizontal: true
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
barHeight: '50%'
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: data.failDistribution.map(item => item.analysis_name),
|
||||
title: {
|
||||
@ -469,58 +601,40 @@ if (!$supplier) {
|
||||
title: {
|
||||
text: 'Top FAIL Analyses',
|
||||
align: 'center'
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
barHeight: '50%'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const failChart = new ApexCharts(document.querySelector("#fail-bar-chart"), failChartOptions);
|
||||
failChart.render();
|
||||
|
||||
// Aggiorna tabella per Distribuzione FAIL
|
||||
// Populate Fail Table
|
||||
const failTableBody = document.querySelector("#fail-table-body");
|
||||
data.failDistribution.forEach(row => {
|
||||
failTableBody.innerHTML += `<tr>
|
||||
<td>${row.analysis_name}</td>
|
||||
<td>${row.fail}</td>
|
||||
</tr>`;
|
||||
failTableBody.innerHTML += `
|
||||
<tr>
|
||||
<td>${row.analysis_name}</td>
|
||||
<td>${row.fail}</td>
|
||||
</tr>`;
|
||||
});
|
||||
});
|
||||
|
||||
// Gestione Toggle Table
|
||||
// Toggle Tables
|
||||
document.querySelector("#toggle-distribution-table").addEventListener("click", function() {
|
||||
const table = document.querySelector("#distribution-table-container");
|
||||
table.style.display = table.style.display === "block" ? "none" : "block";
|
||||
});
|
||||
|
||||
document.querySelector("#toggle-fail-table").addEventListener("click", function() {
|
||||
const table = document.querySelector("#fail-table-container");
|
||||
table.style.display = table.style.display === "block" ? "none" : "block";
|
||||
});
|
||||
|
||||
// Gestione View Fail Details
|
||||
document.querySelector("#view-fail-details").addEventListener("click", function() {
|
||||
const table = document.querySelector("#fail-details-container");
|
||||
|
||||
// Evita di richiamare più volte lo stesso contenuto
|
||||
if (!table.hasAttribute("data-loaded")) {
|
||||
$.getJSON(`get_fail_details.php?supplier=${supplierName}`, function(data) {
|
||||
const failDetailsTableBody = document.querySelector("#fail-details-table-body");
|
||||
|
||||
data.failDetails.forEach(row => {
|
||||
failDetailsTableBody.innerHTML += `
|
||||
<tr>
|
||||
<td>${row.analysis_name}</td>
|
||||
<td>${row.report_number}</td>
|
||||
<td>${row.product_refnumber}</td>
|
||||
<td>${row.product_description}</td>
|
||||
<td>
|
||||
<a href="../products/reportdetails.php?idreports=${row.report_id}" target="_blank" class="btn btn-sm btn-primary">
|
||||
View Details
|
||||
</a>
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
table.setAttribute("data-loaded", "true");
|
||||
});
|
||||
}
|
||||
|
||||
table.style.display = table.style.display === "block" ? "none" : "block";
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ if ($_POST['method'] == 'save') {
|
||||
}
|
||||
$conn->query($sql);
|
||||
echo 'Data saved';
|
||||
|
||||
} else if($_POST['method'] == 'load') {
|
||||
$sql = "SELECT `order` FROM chart_order WHERE user_id = $iduserlogin ORDER BY insert_date DESC LIMIT 1";
|
||||
$result = $conn->query($sql);
|
||||
|
||||
@ -248,16 +248,22 @@ $otherConditions = implode("', '", array_map('addslashes', RATING_OTHER));
|
||||
|
||||
// Query per il grafico a barre orizzontali con sezioni multicolore
|
||||
$horizontalBarQuery = "
|
||||
SELECT
|
||||
COALESCE(p.$groupingField, 'empty') AS groupingValue,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) IN ('$passConditions') THEN 1 ELSE 0 END) AS passCount,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) IN ('$failConditions') THEN 1 ELSE 0 END) AS failCount,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) NOT IN ('$passConditions', '$failConditions') THEN 1 ELSE 0 END) AS otherCount
|
||||
FROM reports r
|
||||
LEFT JOIN products p ON r.idproducts = p.idproducts
|
||||
$filters
|
||||
GROUP BY COALESCE(p.$groupingField, 'empty')
|
||||
LIMIT 20
|
||||
SELECT
|
||||
COALESCE(p.$groupingField, 'empty') AS groupingValue,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) IN ('$passConditions') THEN 1 ELSE 0 END) AS passCount,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) IN ('$failConditions') THEN 1 ELSE 0 END) AS failCount,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) NOT IN ('$passConditions', '$failConditions') THEN 1 ELSE 0 END) AS otherCount
|
||||
FROM
|
||||
reports r
|
||||
LEFT JOIN
|
||||
products p ON r.idproducts = p.idproducts
|
||||
$filters
|
||||
GROUP BY
|
||||
COALESCE(p.$groupingField, 'empty')
|
||||
ORDER BY
|
||||
failCount DESC
|
||||
LIMIT 20;
|
||||
|
||||
";
|
||||
|
||||
|
||||
@ -285,6 +291,8 @@ $horizontalBarAnalysisQuery = "
|
||||
LEFT JOIN products p ON r.idproducts = p.idproducts
|
||||
$filters
|
||||
GROUP BY COALESCE(p.$groupingField, 'empty')
|
||||
ORDER BY
|
||||
failCount DESC
|
||||
LIMIT 20
|
||||
";
|
||||
|
||||
@ -302,15 +310,22 @@ while ($row = $horizontalBarAnalysisResult->fetch_assoc()) {
|
||||
|
||||
// Statistic for worst suppliers based on % of failed reports
|
||||
$worstSuppliersQuery = "
|
||||
SELECT p.namesupplier AS supplier, COUNT(r.idreports) AS totalReports,
|
||||
SELECT
|
||||
p.namesupplier AS supplier,
|
||||
COUNT(r.idreports) AS totalReports,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') THEN 1 ELSE 0 END) AS failedReports,
|
||||
(SUM(CASE WHEN UPPER(r.reportsRating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') THEN 1 ELSE 0 END) / COUNT(r.idreports)) * 100 AS failPercentage
|
||||
FROM reports r
|
||||
LEFT JOIN products p ON r.idproducts = p.idproducts
|
||||
$filters
|
||||
GROUP BY p.namesupplier
|
||||
ORDER BY failPercentage DESC
|
||||
LIMIT 10
|
||||
FROM
|
||||
reports r
|
||||
LEFT JOIN
|
||||
products p ON r.idproducts = p.idproducts
|
||||
$filters
|
||||
GROUP BY
|
||||
p.namesupplier
|
||||
ORDER BY
|
||||
failPercentage DESC,
|
||||
failedReports DESC
|
||||
LIMIT 30;
|
||||
";
|
||||
$worstSuppliersResult = $conn->query($worstSuppliersQuery);
|
||||
$worstSuppliers = [];
|
||||
|
||||
@ -280,7 +280,7 @@ include('parsedatachart.php');
|
||||
<!-- Begin page -->
|
||||
<div id="wrapper">
|
||||
|
||||
<?php // include('../include/navigationbar.php');
|
||||
<?php include('../include/navigationbar.php');
|
||||
?>
|
||||
|
||||
<!-- Start right Content here -->
|
||||
@ -484,10 +484,14 @@ include('parsedatachart.php');
|
||||
</div>
|
||||
</div>
|
||||
<!-- end row -->
|
||||
<div class="container my-4" data-id="1">
|
||||
<h2 class="text-center text-primary fw-bold">Product Statistic</h2>
|
||||
<hr class="my-3">
|
||||
</div>
|
||||
|
||||
<div class="chart-container" id="charts">
|
||||
|
||||
<div class="row chart-box" id="chart1" data-id="1">
|
||||
<div class="row chart-box" id="chart1" data-id="2">
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -548,7 +552,7 @@ include('parsedatachart.php');
|
||||
</div>
|
||||
<!-- end row -->
|
||||
|
||||
<div class="row chart-box" id="chart2" data-id="2">
|
||||
<div class="row chart-box" id="chart2" data-id="3">
|
||||
<div class="col-md-4"> <!-- Colonna per il primo grafico (Pie Chart) -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -565,19 +569,19 @@ include('parsedatachart.php');
|
||||
<div class="col-md-8"> <!-- Colonna per il secondo grafico -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Worst Analysis</h5>
|
||||
<div id="worsttenanalysis"></div>
|
||||
<!-- Pulsante per mostrare/nascondere la tabella -->
|
||||
<button class="btn btn-sm btn-primary toggle-table" data-target="#tableChartWorst">Toggle Data Table</button>
|
||||
<!-- Contenitore per la tabella -->
|
||||
<div id="tableChartWorst" class="hidden table-container"></div>
|
||||
<h5 class="card-title">Reports Breakdown</h5>
|
||||
<div id="reportBarChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row chart-box" id="chart3" data-id="3">
|
||||
<div class="container my-4" data-id="4">
|
||||
<h2 class="text-center text-primary fw-bold">Supplier Statistic</h2>
|
||||
<hr class="my-3">
|
||||
</div>
|
||||
|
||||
<div class="row chart-box" id="chart3" data-id="5">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -593,7 +597,7 @@ include('parsedatachart.php');
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row chart-box" id="chart4" data-id="4">
|
||||
<div class="row chart-box" id="chart4" data-id="6">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -608,8 +612,12 @@ include('parsedatachart.php');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container my-4" data-id="7">
|
||||
<h2 class="text-center text-primary fw-bold">Analysis Statistic</h2>
|
||||
<hr class="my-3">
|
||||
</div>
|
||||
|
||||
<div class="row chart-box" id="chart5" data-id="5">
|
||||
<div class="row chart-box" id="chart5" data-id="8">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -624,8 +632,29 @@ include('parsedatachart.php');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row chart-box" id="chart5" data-id="9">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Worst Analysis</h5>
|
||||
<div id="worsttenanalysis"></div>
|
||||
<!-- Pulsante per mostrare/nascondere la tabella -->
|
||||
<button class="btn btn-sm btn-primary toggle-table" data-target="#tableChartWorst">Toggle Data Table</button>
|
||||
<!-- Contenitore per la tabella -->
|
||||
<div id="tableChartWorst" class="hidden table-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row chart-box" id="chart6" data-id="6">
|
||||
|
||||
|
||||
<div class="container my-4" data-id="10">
|
||||
<h2 class="text-center text-primary fw-bold">Components/Substances Statistic</h2>
|
||||
<hr class="my-3">
|
||||
</div>
|
||||
|
||||
<div class="row chart-box" id="chart6" data-id="11">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -640,8 +669,12 @@ include('parsedatachart.php');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container my-4" data-id="12">
|
||||
<h2 class="text-center text-primary fw-bold">Other Parameter Statistic</h2>
|
||||
<hr class="my-3">
|
||||
</div>
|
||||
|
||||
<div class="row chart-box" id="chart7" data-id="7">
|
||||
<div class="row chart-box" id="chart7" data-id="13">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -672,7 +705,7 @@ include('parsedatachart.php');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="row mt-4" data-id="14">
|
||||
<!-- Colonna Sinistra per il Grafico a Torta -->
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
@ -905,7 +938,19 @@ include('parsedatachart.php');
|
||||
series: pieSeries,
|
||||
chart: {
|
||||
width: '100%',
|
||||
type: 'pie'
|
||||
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'],
|
||||
@ -933,35 +978,83 @@ include('parsedatachart.php');
|
||||
// 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>
|
||||
`;
|
||||
<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>
|
||||
`;
|
||||
<tr>
|
||||
<td>${names[i]}</td>
|
||||
<td>${counts[i]}</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
tableHTML += `
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
|
||||
return tableHTML;
|
||||
}
|
||||
@ -969,6 +1062,7 @@ include('parsedatachart.php');
|
||||
// Inizializza il grafico come prima
|
||||
$('#worsttenanalysis').html('');
|
||||
|
||||
|
||||
var analysisNames = data.topFailingAnalysis.map(function(item) {
|
||||
return item.name;
|
||||
});
|
||||
@ -987,6 +1081,7 @@ include('parsedatachart.php');
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
borderRadius: 10,
|
||||
dataLabels: {
|
||||
position: 'center'
|
||||
}
|
||||
@ -995,7 +1090,7 @@ include('parsedatachart.php');
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#fff'],
|
||||
colors: ['black'],
|
||||
fontSize: '12px'
|
||||
},
|
||||
formatter: function(val, opt) {
|
||||
@ -1016,7 +1111,7 @@ include('parsedatachart.php');
|
||||
text: 'Analysis'
|
||||
}
|
||||
},
|
||||
colors: ['#FF4D4D'],
|
||||
colors: ['orange'],
|
||||
responsive: [{
|
||||
breakpoint: 480,
|
||||
options: {
|
||||
@ -1069,7 +1164,7 @@ include('parsedatachart.php');
|
||||
],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400,
|
||||
height: 500,
|
||||
stacked: true,
|
||||
horizontal: true
|
||||
},
|
||||
@ -1080,6 +1175,7 @@ include('parsedatachart.php');
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
borderRadius: 5,
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
}
|
||||
@ -1118,7 +1214,7 @@ include('parsedatachart.php');
|
||||
],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400,
|
||||
height: 500,
|
||||
stacked: true,
|
||||
horizontal: true
|
||||
},
|
||||
@ -1129,6 +1225,7 @@ include('parsedatachart.php');
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
borderRadius: 5,
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
}
|
||||
@ -1144,33 +1241,33 @@ include('parsedatachart.php');
|
||||
// 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>
|
||||
`;
|
||||
<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>
|
||||
`;
|
||||
<tr>
|
||||
<td>${names[i]}</td>
|
||||
<td>${failPercentages[i].toFixed(2)}%</td>
|
||||
<td>${failedReports[i]}</td>
|
||||
<td>${totalReports[i]}</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
tableHTML += `
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
|
||||
return tableHTML;
|
||||
}
|
||||
@ -1197,11 +1294,30 @@ include('parsedatachart.php');
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400
|
||||
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'
|
||||
}
|
||||
@ -1233,13 +1349,24 @@ include('parsedatachart.php');
|
||||
text: 'Suppliers'
|
||||
}
|
||||
},
|
||||
colors: ['#3368FF'],
|
||||
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 10 Suppliers with the Highest Failed Reports Percentage',
|
||||
text: 'Top Suppliers with the Highest Failed Reports Percentage',
|
||||
align: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#worstSuppliersChart"), options);
|
||||
chart.render();
|
||||
|
||||
@ -1318,6 +1445,7 @@ include('parsedatachart.php');
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
borderRadius: 5,
|
||||
columnWidth: '50%',
|
||||
dataLabels: {
|
||||
position: 'top'
|
||||
@ -1415,11 +1543,12 @@ include('parsedatachart.php');
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 500
|
||||
height: 550
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
borderRadius: 5,
|
||||
columnWidth: '100%',
|
||||
endingShape: 'rounded'
|
||||
}
|
||||
@ -1453,7 +1582,7 @@ include('parsedatachart.php');
|
||||
},
|
||||
fill: {
|
||||
opacity: 1,
|
||||
colors: ['#004d00']
|
||||
colors: ['green']
|
||||
},
|
||||
tooltip: {
|
||||
y: {
|
||||
@ -1488,29 +1617,29 @@ include('parsedatachart.php');
|
||||
// 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>
|
||||
`;
|
||||
<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>
|
||||
`;
|
||||
<tr>
|
||||
<td>${analyteNames[i]}</td>
|
||||
<td>${failCounts[i]}</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
tableHTML += `
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
|
||||
return tableHTML;
|
||||
}
|
||||
@ -1536,6 +1665,7 @@ include('parsedatachart.php');
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
borderRadius: 5,
|
||||
dataLabels: {
|
||||
position: 'center' // Etichette al centro delle barre
|
||||
}
|
||||
@ -1544,12 +1674,14 @@ include('parsedatachart.php');
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#fff'], // Colore del testo all'interno delle barre
|
||||
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
|
||||
@ -1656,7 +1788,19 @@ include('parsedatachart.php');
|
||||
series: values,
|
||||
chart: {
|
||||
type: 'pie',
|
||||
height: 350
|
||||
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: [{
|
||||
@ -1683,6 +1827,7 @@ include('parsedatachart.php');
|
||||
$('#tablePhasePie').html(generatePhasePieTable(labels, values));
|
||||
}
|
||||
|
||||
|
||||
function renderPhaseBarChart(phaseRatingsData) {
|
||||
const labels = phaseRatingsData.map(item => item.phase);
|
||||
const passCounts = phaseRatingsData.map(item => parseInt(item.passCount, 10));
|
||||
@ -1718,7 +1863,8 @@ include('parsedatachart.php');
|
||||
colors: ['#28A745', '#FF4D4D', '#FFA500'],
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
horizontal: false,
|
||||
borderRadius: 5,
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user