Semua artikel

Monitoring Pengumpulan Monev Bulanan Bidang



Grafik Laporan Monev (Realtime) /* CSS untuk membuat tampilan grafik lebih rapi dan modern */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #eef2f7;
color: #333;
}
.chart-wrapper {
width: 95%;
max-width: 900px;
padding: 25px;
background-color: #ffffff;
border-radius: 12px;
box-shadow: 0 8px 30px rgba(0,0,0,0.08);
box-sizing: border-box;
text-align: center;
}
.chart-header {
margin-bottom: 20px;
text-align: center;
}
.chart-header h1 {
margin: 0;
font-size: 1.5rem;
color: #1a202c;
}
.chart-header p {
margin: 5px 0 0;
font-size: 0.9rem;
color: #718096;
}
#clock {
font-size: 1rem;
font-weight: bold;
color: #4a5568;
margin-top: 10px;
padding: 8px 16px;
background-color: #f7fafc;
border-radius: 6px;
display: inline-block;
}
.chart-container {
position: relative;
height: 50vh;
min-height: 300px;
}
#status {
color: #718096;
font-style: italic;
padding-top: 20px;
}

Progres Laporan Monev

Data diperbarui secara otomatis setiap 1 menit

Memuat data...



// URL BARU dari Google Sheet Anda
const googleSheetUrl = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vSP5IjQLD0UGMjP_sPxeMtywCDCjBQsU8HnibqGeL57UeVydDKw27QWRkewMj9G14uqiwdGcRiRcZnO/pub?gid=0&single=true&output=csv';

let myChart = null;
const statusElement = document.getElementById('status');
const clockElement = document.getElementById('clock');

// Fungsi untuk jam digital
function updateClock() {
const now = new Date();
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', timeZone: 'Asia/Jakarta' };
const dateString = now.toLocaleDateString('id-ID', options);
const timeString = now.toLocaleTimeString('id-ID', { timeZone: 'Asia/Jakarta' });
clockElement.textContent = `${dateString}, ${timeString} WIB`;
}

// Fungsi untuk mengambil data dan memperbarui grafik
async function fetchDataAndUpdateChart() {
const urlWithCacheBuster = googleSheetUrl + '&t=' + new Date().getTime();
statusElement.textContent = 'Mengambil data dari Google Sheet...';

try {
const response = await fetch(urlWithCacheBuster);
if (!response.ok) throw new Error(`Gagal mengambil data: Status ${response.status}`);
const csvText = await response.text();
if (!csvText) {
statusElement.textContent = 'Data kosong diterima dari Google Sheet.';
return;
}

statusElement.textContent = 'Memproses data...';

Papa.parse(csvText, {
header: true,
skipEmptyLines: true,
complete: function(results) {
const sheetData = results.data;
if (!sheetData || sheetData.length === 0) {
statusElement.textContent = 'Gagal memproses data atau sheet kosong.';
return;
}

statusElement.style.display = 'none';

const labels = sheetData.map(row => row['Nama Bidang']);
const dataValues = sheetData.map(row => {
const value = row['Laporan Masuk'] || row['Jumlah Laporan'];
return parseInt(value) || 0;
});
const totalLaporan = parseInt(sheetData[0]['Total Laporan']) || 12;

if (!myChart) {
createChart(labels, dataValues, totalLaporan);
} else {
myChart.data.labels = labels;
myChart.data.datasets[0].data = dataValues;
myChart.options.scales.y.max = totalLaporan;
myChart.update();
}
},
error: (err) => {
statusElement.textContent = 'Terjadi kesalahan saat memproses data.';
console.error("Kesalahan parsing CSV:", err);
}
});

} catch (error) {
statusElement.textContent = `Terjadi kesalahan jaringan: ${error.message}. Periksa koneksi internet dan pastikan link Google Sheet dapat diakses.`;
console.error("Kesalahan fetch:", error);
}
}

// Fungsi untuk membuat grafik pertama kali
function createChart(labels, dataValues, totalLaporan) {
Chart.register(ChartDataLabels);
const ctx = document.getElementById('myChart').getContext('2d');
myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Laporan Masuk',
data: dataValues,
backgroundColor: '#4299e1',
borderColor: '#2b6cb0',
borderWidth: 1,
borderRadius: 4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: totalLaporan,
ticks: { stepSize: 1 }
}
},
plugins: {
legend: { display: false },
datalabels: {
anchor: 'end',
align: 'top',
color: '#1a202c',
font: { weight: 'bold', size: 14 }
}
}
}
});
}

// Jalankan fungsi pertama kali
fetchDataAndUpdateChart();
updateClock();

// Atur interval pembaruan
setInterval(fetchDataAndUpdateChart, 60000); // 1 menit untuk data grafik
setInterval(updateClock, 1000); // 1 detik untuk jam


Diskusi

No comments yet