update entra id

This commit is contained in:
2025-05-13 15:03:09 +02:00
parent 6752d3515f
commit 2a96d24de7
44 changed files with 3835 additions and 1856 deletions
@@ -0,0 +1,117 @@
import { generatePieTable } from "../utils/tableGenerator.js";
export function renderAnalysisDistributionChart(
chartData,
containerId,
tableContainerId,
) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Estrai i dati per il grafico a torta
const analysisDistribution = chartData || [];
const labels = analysisDistribution.map((item) => item.analysisName);
const series = analysisDistribution.map((item) => {
const value = parseInt(item.totalTests);
return isNaN(value) || value < 0 ? 0 : value;
});
// Verifica se ci sono dati validi da visualizzare
const hasValidData = series.some((value) => value > 0);
if (!hasValidData) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No valid data to display.</p>';
return;
}
// Configurazione del grafico a torta
const options = {
series: series,
chart: {
type: "pie",
height: 350,
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
labels: labels,
colors: [
"#FF4560",
"#008FFB",
"#00E396",
"#FEB019",
"#FF66FF",
"#775DD0",
"#546E7A",
"#26A69A",
"#D81B60",
"#F06292",
"#4FC3F7",
"#AED581",
"#FF8A65",
"#A1887F",
"#E0E0E0",
"#90A4AE",
"#FFCA28",
"#78909C",
"#D4E157",
"#F4FF81",
],
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 200,
},
legend: {
position: "bottom",
},
},
},
],
tooltip: {
y: {
formatter: function (val) {
return val + " tests";
},
},
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Forza un aggiornamento del grafico dopo un breve ritardo
setTimeout(() => {
chart.updateOptions({});
}, 100);
// Genera la tabella usando la funzione esistente
const tableHTML = generatePieTable(labels, series);
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
}
@@ -0,0 +1,143 @@
export function renderAnalytesFailChart(
analytesData,
containerId,
tableContainerId,
) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Validazione dei dati
if (!Array.isArray(analytesData) || analytesData.length === 0) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No failures to display.</p>';
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML =
'<p class="text-center text-muted">No failures to display.</p>';
}
return;
}
const labels = analytesData.map((item) => item.AnalyteName || "Unknown");
const data = analytesData.map((item) => parseInt(item.FailCount, 10) || 0);
// Verifica se ci sono dati validi da visualizzare
const hasValidData = analytesData.some((item) => item.FailCount > 0);
if (!hasValidData) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No failures to display.</p>';
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML =
'<p class="text-center text-muted">No failures to display.</p>';
}
return;
}
// Configurazione del grafico a barre orizzontali
const options = {
series: [
{
name: "Failures",
data: data,
},
],
chart: {
type: "bar",
height: 400,
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
plotOptions: {
bar: {
horizontal: true,
barHeight: "80%",
},
},
dataLabels: {
enabled: false,
},
xaxis: {
categories: labels,
title: {
text: "Number of Failures",
},
},
yaxis: {
title: {
text: "Analyte",
},
},
colors: ["#FF4D4D"],
fill: {
opacity: 1,
},
tooltip: {
y: {
formatter: function (val) {
return val + " failures";
},
},
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Genera una tabella per i dati
const tableHTML = `
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Analyte</th>
<th>Failures</th>
</tr>
</thead>
<tbody>
${analytesData
.map(
(item) => `
<tr>
<td>${item.AnalyteName || "Unknown"}</td>
<td>${parseInt(item.FailCount, 10) || 0}</td>
</tr>
`,
)
.join("")}
</tbody>
</table>
`;
// Riprova a trovare il contenitore della tabella con un ritardo
const renderTable = () => {
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
};
// Prova immediatamente e riprova dopo un breve ritardo
renderTable();
setTimeout(renderTable, 100);
}
@@ -0,0 +1,91 @@
import { generatePieTable } from "../utils/tableGenerator.js";
export function renderBarChart(data, containerId, tableContainerId) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Dati per il grafico a barre (usa gli stessi dati del grafico a torta)
const intFailReports = parseInt(data.failReportsPie) || 0;
const intPassReports = parseInt(data.passReportsPie) || 0;
const intOtherReports = parseInt(data.otherReportsPie) || 0;
const barLabels = ["Fail", "Pass", "Others"];
const barSeries = [intFailReports, intPassReports, intOtherReports];
// Configurazione del grafico a barre
const options = {
series: [
{
name: "Reports",
data: barSeries,
},
],
chart: {
height: 350,
type: "bar",
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: "55%",
endingShape: "rounded",
},
},
dataLabels: {
enabled: false,
},
stroke: {
show: true,
width: 2,
colors: ["transparent"],
},
xaxis: {
categories: barLabels,
},
colors: ["#FF4D4D", "#28A745", "#FFA500"],
fill: {
opacity: 1,
},
tooltip: {
y: {
formatter: function (val) {
return val + " reports";
},
},
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Genera la tabella e aggiungi un log
const tableHTML = generatePieTable(barLabels, barSeries);
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
}
@@ -0,0 +1,133 @@
export function renderHorizontalBarChart(
chartData,
containerId,
tableContainerId,
) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Estrai i dati per il grafico a barre orizzontali
const horizontalBarData = chartData || [];
const categories = horizontalBarData.map((item) => item.groupingValue);
const passData = horizontalBarData.map((item) => item.passCount);
const failData = horizontalBarData.map((item) => item.failCount);
const otherData = horizontalBarData.map((item) => item.otherCount);
// Configurazione del grafico a barre orizzontali
const options = {
series: [
{
name: "Pass",
data: passData,
},
{
name: "Fail",
data: failData,
},
{
name: "Others",
data: otherData,
},
],
chart: {
type: "bar",
height: 600,
stacked: true,
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
plotOptions: {
bar: {
horizontal: true,
barHeight: "80%",
},
},
dataLabels: {
enabled: false,
},
xaxis: {
categories: categories,
title: {
text: "Number of Reports",
},
},
yaxis: {
title: {
text: "Grouping Value",
},
},
colors: ["#28A745", "#FF4D4D", "#FFA500"],
fill: {
opacity: 1,
},
tooltip: {
y: {
formatter: function (val) {
return val + " reports";
},
},
},
legend: {
position: "top",
horizontalAlign: "left",
offsetX: 40,
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Genera una tabella per i dati
const tableHTML = `
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Grouping Value</th>
<th>Pass</th>
<th>Fail</th>
<th>Others</th>
</tr>
</thead>
<tbody>
${horizontalBarData
.map(
(item) => `
<tr>
<td>${item.groupingValue}</td>
<td>${item.passCount}</td>
<td>${item.failCount}</td>
<td>${item.otherCount}</td>
</tr>
`,
)
.join("")}
</tbody>
</table>
`;
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
}
@@ -0,0 +1,172 @@
export function renderPhaseBarChart(chartData, containerId, tableContainerId) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Estrai i dati per il grafico a barre
const phaseRatingsData = chartData || [];
// Validazione dei dati
if (!Array.isArray(phaseRatingsData) || phaseRatingsData.length === 0) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No data available for Phase Rating Distribution.</p>';
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML =
'<p class="text-center text-muted">No data available.</p>';
}
return;
}
const phases = phaseRatingsData.map((item) => item.phase || "Unknown");
const passData = phaseRatingsData.map(
(item) => parseInt(item.passCount) || 0,
);
const failData = phaseRatingsData.map(
(item) => parseInt(item.failCount) || 0,
);
const otherData = phaseRatingsData.map(
(item) => parseInt(item.otherCount) || 0,
);
// Verifica se ci sono dati validi da visualizzare
const hasValidData =
passData.some((value) => value > 0) ||
failData.some((value) => value > 0) ||
otherData.some((value) => value > 0);
if (!hasValidData) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No ratings to display.</p>';
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML =
'<p class="text-center text-muted">No ratings to display.</p>';
}
return;
}
// Configurazione del grafico a barre orizzontali
const options = {
series: [
{
name: "Pass",
data: passData,
},
{
name: "Fail",
data: failData,
},
{
name: "Others",
data: otherData,
},
],
chart: {
type: "bar",
height: 600,
stacked: true,
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
plotOptions: {
bar: {
horizontal: true,
barHeight: "80%",
},
},
dataLabels: {
enabled: false,
},
xaxis: {
categories: phases,
title: {
text: "Number of Reports",
},
},
yaxis: {
title: {
text: "Phase",
},
},
colors: ["#28A745", "#FF4D4D", "#FFA500"],
fill: {
opacity: 1,
},
tooltip: {
y: {
formatter: function (val) {
return val + " reports";
},
},
},
legend: {
position: "top",
horizontalAlign: "left",
offsetX: 40,
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Genera una tabella per i dati
const tableHTML = `
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Phase</th>
<th>Pass</th>
<th>Fail</th>
<th>Others</th>
</tr>
</thead>
<tbody>
${phaseRatingsData
.map(
(item) => `
<tr>
<td>${item.phase || "Unknown"}</td>
<td>${parseInt(item.passCount) || 0}</td>
<td>${parseInt(item.failCount) || 0}</td>
<td>${parseInt(item.otherCount) || 0}</td>
</tr>
`,
)
.join("")}
</tbody>
</table>
`;
// Riprova a trovare il contenitore della tabella con un ritardo
const renderTable = () => {
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
tableContainer.style.display = "block"; // Forza la visibilità
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
};
// Prova immediatamente e riprova dopo un breve ritardo
renderTable();
setTimeout(renderTable, 100);
}
@@ -0,0 +1,126 @@
import { generatePieTable } from "../utils/tableGenerator.js";
export function renderPhasePieChart(chartData, containerId, tableContainerId) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Estrai i dati per il grafico a torta
const phaseData = chartData || [];
// Validazione dei dati
if (!Array.isArray(phaseData) || phaseData.length === 0) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No data available for Products Distribution by Phase.</p>';
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML =
'<p class="text-center text-muted">No data available.</p>';
}
return;
}
const labels = phaseData.map((item) => item.phase || "Unknown");
const series = phaseData.map((item) => {
const count = parseInt(item.totalProducts, 10);
return isNaN(count) ? 0 : count;
});
// Verifica se ci sono dati validi da visualizzare
const hasValidData = series.some((value) => value > 0);
if (!hasValidData) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No valid data to display.</p>';
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML =
'<p class="text-center text-muted">No valid data to display.</p>';
}
return;
}
// Configurazione del grafico a torta
const options = {
series: series,
chart: {
type: "pie",
height: 350,
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
labels: labels,
colors: [
"#FF4560",
"#008FFB",
"#00E396",
"#FEB019",
"#FF66FF",
"#775DD0",
],
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 200,
},
legend: {
position: "bottom",
},
},
},
],
tooltip: {
y: {
formatter: function (val) {
return val + " products";
},
},
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Forza un aggiornamento del grafico dopo un breve ritardo
setTimeout(() => {
chart.updateOptions({});
}, 100);
// Genera la tabella usando la funzione esistente
const tableHTML = generatePieTable(labels, series);
// Riprova a trovare il contenitore della tabella con un ritardo
const renderTable = () => {
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
tableContainer.style.display = "block"; // Forza la visibilità
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
};
// Prova immediatamente e riprova dopo un breve ritardo
renderTable();
setTimeout(renderTable, 100);
}
@@ -0,0 +1,68 @@
import { generatePieTable } from "../utils/tableGenerator.js";
export function renderPieChart(data, containerId, tableContainerId) {
// Pulizia del contenitore
document.querySelector(`#${containerId}`).innerHTML = "";
// Dati per il grafico a torta
const intFailReports = parseInt(data.failReportsPie);
const intPassReports = parseInt(data.passReportsPie);
const intOtherReports = parseInt(data.otherReportsPie);
const pieLabels = ["Fail", "Pass", "Others"];
const pieSeries = [intFailReports, intPassReports, intOtherReports];
// Configurazione del grafico
const options = {
series: pieSeries,
chart: {
width: "100%",
type: "pie",
toolbar: {
show: true,
tools: {
download: true,
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,
},
};
// Render del grafico
const chart = new ApexCharts(
document.querySelector(`#${containerId}`),
options,
);
chart.render();
// Genera la tabella
document.querySelector(`#${tableContainerId}`).innerHTML = generatePieTable(
pieLabels,
pieSeries,
);
}
@@ -0,0 +1,113 @@
export function renderProductBySupplierChart(
chartData,
containerId,
tableContainerId,
) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Estrai i dati per il grafico
const productBySupplier = chartData || [];
const suppliers = productBySupplier.map((item) => item.supplier);
const totalProducts = productBySupplier.map((item) => item.totalProducts);
// Configurazione del grafico a barre orizzontali
const options = {
series: [
{
name: "Total Products",
data: totalProducts,
},
],
chart: {
type: "bar",
height: 600,
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
plotOptions: {
bar: {
horizontal: true,
barHeight: "80%",
},
},
dataLabels: {
enabled: true,
},
xaxis: {
categories: suppliers,
title: {
text: "Number of Products",
},
},
yaxis: {
title: {
text: "Supplier",
},
},
colors: ["#007BFF"],
fill: {
opacity: 1,
},
tooltip: {
y: {
formatter: function (val) {
return val + " products";
},
},
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Genera una tabella per i dati
const tableHTML = `
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Supplier</th>
<th>Total Products</th>
</tr>
</thead>
<tbody>
${productBySupplier
.map(
(item) => `
<tr>
<td>${item.supplier}</td>
<td>${item.totalProducts}</td>
</tr>
`,
)
.join("")}
</tbody>
</table>
`;
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
}
@@ -0,0 +1,120 @@
export function renderWorstSuppliersChart(
chartData,
containerId,
tableContainerId,
) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Estrai i dati per il grafico
const worstSuppliers = chartData || [];
const suppliers = worstSuppliers.map((item) => item.supplier);
const failPercentages = worstSuppliers.map((item) => item.failPercentage);
// Configurazione del grafico a barre orizzontali
const options = {
series: [
{
name: "Fail Percentage",
data: failPercentages,
},
],
chart: {
type: "bar",
height: 600,
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
plotOptions: {
bar: {
horizontal: true,
barHeight: "80%",
},
},
dataLabels: {
enabled: true,
formatter: function (val) {
return val.toFixed(2) + "%";
},
},
xaxis: {
categories: suppliers,
title: {
text: "Fail Percentage (%)",
},
},
yaxis: {
title: {
text: "Supplier",
},
},
colors: ["#FF4D4D"],
fill: {
opacity: 1,
},
tooltip: {
y: {
formatter: function (val) {
return val.toFixed(2) + "%";
},
},
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Genera una tabella per i dati
const tableHTML = `
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Supplier</th>
<th>Fail Percentage</th>
<th>Total Reports</th>
<th>Failed Reports</th>
</tr>
</thead>
<tbody>
${worstSuppliers
.map(
(item) => `
<tr>
<td>${item.supplier}</td>
<td>${item.failPercentage.toFixed(2)}%</td>
<td>${item.totalReports}</td>
<td>${item.failedReports}</td>
</tr>
`,
)
.join("")}
</tbody>
</table>
`;
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
}
@@ -0,0 +1,145 @@
export function renderWorstTenAnalysisChart(
analysisData,
containerId,
tableContainerId,
) {
// Pulizia del contenitore del grafico
const chartContainer = document.querySelector(`#${containerId}`);
if (chartContainer) {
chartContainer.innerHTML = "";
} else {
console.error(`Contenitore del grafico non trovato: #${containerId}`);
return;
}
// Validazione dei dati
if (!Array.isArray(analysisData) || analysisData.length === 0) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No failed tests to display.</p>';
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML =
'<p class="text-center text-muted">No failed tests to display.</p>';
}
return;
}
const labels = analysisData.map((item) => item.name || "Unknown");
const data = analysisData.map((item) => parseInt(item.failCount, 10) || 0);
console.log("Dati per il grafico Worst Analysis:", { labels, data });
// Verifica se ci sono dati validi da visualizzare
const hasValidData = analysisData.some((item) => item.failCount > 0);
if (!hasValidData) {
chartContainer.innerHTML =
'<p class="text-center text-muted">No failed tests to display.</p>';
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML =
'<p class="text-center text-muted">No failed tests to display.</p>';
}
return;
}
// Configurazione del grafico a barre orizzontali
const options = {
series: [
{
name: "Failed Tests",
data: data,
},
],
chart: {
type: "bar",
height: 400,
toolbar: {
show: true,
tools: {
download: true,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: false,
reset: false,
},
},
},
plotOptions: {
bar: {
horizontal: true,
barHeight: "80%",
},
},
dataLabels: {
enabled: false,
},
xaxis: {
categories: labels,
title: {
text: "Number of Failed Tests",
},
},
yaxis: {
title: {
text: "Analysis",
},
},
colors: ["#FF4D4D"],
fill: {
opacity: 1,
},
tooltip: {
y: {
formatter: function (val) {
return val + " failed tests";
},
},
},
};
// Render del grafico
const chart = new ApexCharts(chartContainer, options);
chart.render();
// Genera una tabella per i dati
const tableHTML = `
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Analysis</th>
<th>Failed Tests</th>
</tr>
</thead>
<tbody>
${analysisData
.map(
(item) => `
<tr>
<td>${item.name || "Unknown"}</td>
<td>${parseInt(item.failCount, 10) || 0}</td>
</tr>
`,
)
.join("")}
</tbody>
</table>
`;
// Riprova a trovare il contenitore della tabella con un ritardo
const renderTable = () => {
const tableContainer = document.querySelector(`#${tableContainerId}`);
if (tableContainer) {
tableContainer.innerHTML = tableHTML;
} else {
console.error(
`Contenitore della tabella non trovato: #${tableContainerId}`,
);
}
};
// Prova immediatamente e riprova dopo un breve ritardo
renderTable();
setTimeout(renderTable, 100);
}
+138
View File
@@ -0,0 +1,138 @@
import { fetchData } from "./utils/ajaxUtils.js";
import { renderPieChart } from "./charts/pieChart.js";
import { renderBarChart } from "./charts/barChart.js";
import { renderHorizontalBarChart } from "./charts/horizontalBarChart.js";
import { renderWorstSuppliersChart } from "./charts/worstSuppliersChart.js";
import { renderProductBySupplierChart } from "./charts/productBySupplierChart.js";
import { renderAnalysisDistributionChart } from "./charts/analysisDistributionChart.js";
import { renderWorstTenAnalysisChart } from "./charts/worsttenanalysis.js";
import { renderAnalytesFailChart } from "./charts/analytesFailChart.js";
import { renderPhasePieChart } from "./charts/phasePieChart.js";
import { renderPhaseBarChart } from "./charts/phaseBarChart.js";
$(document).ready(function () {
function getFilters() {
return {
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(),
groupingField: $("#groupingField").val(),
};
}
function updateCharts() {
const filters = getFilters();
// Aggiorna il titolo dinamicamente
const groupingText = $("#groupingField option:selected").text();
$("#dynamicChartTitle").text(
`Rating Distribution by Group: ${groupingText}`,
);
fetchData("parsedatachart.php", filters).then((data) => {
if (data) {
console.log("Dati ricevuti dal backend:", data); // Aggiungi log qui
console.log("topFailingAnalysis:", data.topFailingAnalysis);
console.log("failedAnalytes:", data.failedAnalytes);
// Aggiorna le card
$("#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)}%)`,
);
// Renderizza i grafici
renderPieChart(data, "reportPieChart", "tableChart2");
renderBarChart(data, "reportBarChart", "tableChart3");
renderHorizontalBarChart(
data.horizontalBarData,
"horizontalBarChart",
"tableHorizontalBarChart",
);
renderHorizontalBarChart(
data.horizontalBarAnalysisData,
"horizontalBarAnalysisChart",
"tableHorizontalBarAnalysisChart",
);
renderWorstSuppliersChart(
data.worstSuppliers,
"worstSuppliersChart",
"tableChartWorstSuppliers",
);
renderProductBySupplierChart(
data.productBySupplier,
"productBySupplierChart",
"tableChartProductsBySupplier",
);
renderAnalysisDistributionChart(
data.analysisDistribution,
"analysisDistributionChart",
"tableChartAnalysisDistribution",
);
renderWorstTenAnalysisChart(
data.topFailingAnalysis,
"worsttenanalysis",
"tableChartWorst",
);
renderAnalytesFailChart(
data.failedAnalytes,
"analytesFailChart",
"tableChartAnalytesFail",
);
renderPhasePieChart(
data.phaseData,
"phasePieChart",
"tableChartPhasePie",
);
renderPhaseBarChart(
data.phaseRatingsData,
"phaseBarChart",
"tableChartPhaseBar",
);
}
});
}
function setupEventListeners() {
$(
"#startDate, #endDate, #supplierFilter, #productsRefnumber, #productsSeason, #ageRange, #reportsLabName, #reportsTestType, #reportsNumberLab, #groupingField",
).on("change", updateCharts);
$("#clearFilters").on("click", () => {
$("#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");
updateCharts();
});
// Evento per togglare la tabella con delegazione
$(document).on("click", ".toggle-table", function () {
const target = $(this).data("target");
console.log("Toggle table clicked, target:", target);
setTimeout(() => {
$(target).toggleClass("hidden");
}, 200);
});
}
setupEventListeners();
updateCharts(); // Caricamento iniziale
});
@@ -0,0 +1,23 @@
export function fetchData(url, filters) {
return $.ajax({
url: url,
method: "POST",
data: filters,
})
.then((response) => {
if (!response) {
alert("No data found.");
return null;
}
try {
return JSON.parse(response);
} catch (e) {
alert("Invalid data format.");
return null;
}
})
.catch(() => {
alert("Error retrieving data.");
return null;
});
}
@@ -0,0 +1,24 @@
export function generatePieTable(labels, series) {
let tableHTML = `
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Category</th>
<th>Count</th>
</tr>
</thead>
<tbody>
${labels
.map(
(label, i) => `
<tr>
<td>${label}</td>
<td>${series[i]}</td>
</tr>
`,
)
.join("")}
</tbody>
</table>`;
return tableHTML;
}