<!
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Shuttle Attendance IN/OUT Pie Chart</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- [Link] CDN -->
<script src="[Link]
<!-- Google Fonts for modern look -->
<link
href="[Link]
rel="stylesheet">
<style>
:root {
--primary: #2563eb;
--present: #22c55e;
--late: #f59e42;
--out: #38bdf8;
--absent: #f43f5e;
--card-bg: #fff;
--text-main: #22223b;
--text-muted: #70708f;
--shadow: 0 2px 12px 0 rgba(34,34,59,0.10);
--radius: 16px;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
font-family: 'Inter', Arial, sans-serif;
background: linear-gradient(135deg, #f3f7fa 0%, #e6e9f0 100%);
color: var(--text-main);
min-height: 100vh;
}
.container {
max-width: 440px;
margin: 48px auto;
padding: 24px 18px 32px 18px;
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
transition: box-shadow 0.2s;
}
h2 {
font-weight: 600;
text-align: center;
font-size: 1.5rem;
margin-top: 0;
margin-bottom: 10px;
letter-spacing: -0.5px;
}
#chart-container {
position: relative;
min-height: 300px;
width: 100%;
max-width: 370px;
margin: 0 auto 16px auto;
display: flex;
align-items: center;
justify-content: center;
}
.legend {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 16px;
margin: 16px 0 0 0;
padding: 0;
list-style: none;
}
.legend li {
display: flex;
align-items: center;
font-size: 1rem;
color: var(--text-muted);
gap: 8px;
margin-bottom: 0;
}
.legend .dot {
width: 16px;
height: 16px;
border-radius: 50%;
display: inline-block;
margin-right: 4px;
border: 2px solid #e0e1e5;
}
/* Responsive */
@media (max-width: 600px) {
.container {
margin: 0;
border-radius: 0;
width: 100vw;
max-width: 100vw;
min-height: 100vh;
box-shadow: none;
}
#chart-container {
min-height: 220px;
max-width: 95vw;
}
}
</style>
</head>
<body>
<div class="container">
<h2>Shuttle Attendance IN/OUT Pie Chart</h2>
<div id="chart-container">
<canvas id="attendancePie"></canvas>
</div>
<ul class="legend" id="chartLegend"></ul>
<div id="last-updated" style="text-align:center;color:var(--text-
muted);font-size:0.95em;margin-top:12px;"></div>
</div>
<script>
// Adjust this if fetch_attendance.php is in another folder
const DATA_URL = "[Link]"; // or "./fetch_attendance.php"
const REFRESH_INTERVAL = 5 * 1000; // 5 seconds
let chartInstance = null;
function fetchAndRender() {
fetch(DATA_URL)
.then(res => [Link]())
.then(data => {
if() {
[Link]('chart-container').innerHTML =
'<p style="color:red;">Failed to load attendance
data.</p>';
[Link]('last-updated').textContent = '';
return;
}
// Tally status counts
const counts = { 'Present': 0, 'Late': 0, 'OUT': 0, 'Absent':
0 };
[Link](emp => {
if ([Link]([Link])) {
counts[[Link]]++;
}
});
// Prepare chart data
const labels = [Link](counts);
const values = [Link](l => counts[l]);
const colors = [Link](l =>
getComputedStyle([Link])
.getPropertyValue(`--${[Link]()}`).trim());
// Render or update pie chart
const ctx =
[Link]('attendancePie').getContext('2d');
if (chartInstance) {
[Link] = labels;
[Link][0].data = values;
[Link][0].backgroundColor = colors;
[Link]();
} else {
chartInstance = new Chart(ctx, {
type: 'pie',
data: {
labels: labels,
datasets: [{
data: values,
backgroundColor: colors
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false }, // We use custom
legend
title: { display: false },
tooltip: {
callbacks: {
label: function(context) {
const label = [Link] || '';
const value = [Link] || 0;
const total = [Link]((a,b)
=> a+b, 0);
const pct = total ?
((value/total)*100).toFixed(1) : 0;
return `${label}: ${value}
(${pct}%)`;
}
}
}
}
}
});
}
// Custom Legend
const legend = [Link]('chartLegend');
[Link] = [Link]((label, i) => `
<li>
<span class="dot" style="background:${colors[i]}"></span>
${label} <b style="margin-left:2px; color:var(--text-
main)">${values[i]}</b>
</li>
`).join('');
// Last updated time
const now = new Date();
[Link]('last-updated').textContent =
"Last updated: " + [Link]();
})
.catch(err => {
[Link]('chart-container').innerHTML =
'<p style="color:red;">Failed to load attendance data.</p>';
[Link]('last-updated').textContent = '';
[Link](err);
});
}
fetchAndRender();
setInterval(fetchAndRender, REFRESH_INTERVAL);
</script>
</body>
</html>