feat: slicing laporan capaian bps rw per wilayah

main-dlh
shola 2025-12-01 17:15:01 +07:00
parent 913fcc0643
commit 01fd84c273
No known key found for this signature in database
GPG Key ID: FA9358FFDCCD05D9
4 changed files with 1642 additions and 4 deletions

View File

@ -0,0 +1,264 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
namespace BpsRwApp.Controllers
{
public class LaporanCapaianWilayahController : AppControllerBase
{
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult GetData(string bulanAwal, string bulanAkhir, string wilayah)
{
try
{
// Default date range
DateTime startDate = DateTime.Now.AddMonths(-2);
DateTime endDate = DateTime.Now;
if (!string.IsNullOrEmpty(bulanAwal))
{
if (!DateTime.TryParse(bulanAwal + "-01", out startDate))
{
startDate = DateTime.Now.AddMonths(-2);
}
}
if (!string.IsNullOrEmpty(bulanAkhir))
{
if (!DateTime.TryParse(bulanAkhir + "-01", out endDate))
{
endDate = DateTime.Now;
}
}
var periode = $"{startDate.ToString("MMMM", new System.Globalization.CultureInfo("id-ID"))} - {endDate.ToString("MMMM yyyy", new System.Globalization.CultureInfo("id-ID"))}";
// Labels bulan
var monthLabels = new List<string>();
var currentMonth = startDate;
while (currentMonth <= endDate)
{
monthLabels.Add(currentMonth.ToString("MMMM yyyy", new System.Globalization.CultureInfo("id-ID")));
currentMonth = currentMonth.AddMonths(1);
}
string locationText;
if (!string.IsNullOrEmpty(wilayah))
{
locationText = $"Kota Administrasi {wilayah}";
}
else
{
locationText = "DKI Jakarta";
}
var random = new Random();
var data = new
{
bulanAwal = startDate.ToString("yyyy-MM"),
bulanAkhir = endDate.ToString("yyyy-MM"),
periode,
countMonthLabels = monthLabels.Count,
wilayah = wilayah ?? "",
locationText,
// Tingkat Kepatuhan PJLP
tingkatKepatuhanPjlp = monthLabels.Select(m => new
{
bulan = m,
ceklis = random.Next(40, 80),
belumCeklis = random.Next(10, 30)
}).Select(x => new
{
x.bulan,
x.ceklis,
x.belumCeklis,
total = x.ceklis + x.belumCeklis,
}).ToList(),
// Status Validasi SATPEL
statusValidasiSatpel = monthLabels.Select(m => new
{
bulan = m,
sudah = random.Next(300, 600),
belum = random.Next(0, 150)
}).Select(x => new
{
x.bulan,
x.sudah,
x.belum,
total = x.sudah + x.belum,
}).ToList(),
// Status Validasi SUDIN
statusValidasiSudin = monthLabels.Select(m => new
{
bulan = m,
sudah = random.Next(300, 600),
belum = random.Next(0, 100)
}).Select(x => new
{
x.bulan,
x.sudah,
x.belum,
total = x.sudah + x.belum,
}).ToList(),
// Capaian Rumah Memilah
capaianRumahMemilah = monthLabels.Select(m => new
{
bulan = m,
konsisten = random.Next(2000, 5000),
tidakKonsisten = random.Next(500, 1500),
}).Select(x => new
{
x.bulan,
x.konsisten,
x.tidakKonsisten,
total = x.konsisten + x.tidakKonsisten,
}).ToList(),
// Volume Timbulan Sampah
volumeTimbulanSampah = monthLabels.Select(m => new
{
bulan = m,
terurai = Math.Round(random.NextDouble() * 0.3 + 0.1, 2),
tidakTerurai = Math.Round(random.NextDouble() * 0.2 + 0.05, 2),
}).Select(x => new
{
x.bulan,
x.terurai,
x.tidakTerurai,
total = Math.Round(x.terurai + x.tidakTerurai, 2)
}).ToList(),
// Realisasi Terhadap Target
realisasiTarget = monthLabels.Select(m => new
{
bulan = m,
rmKonsisten = random.Next(3000, 6000),
rmTidakKonsisten = random.Next(-4000, -1000),
target = random.Next(6000, 8000)
}).Select(x => new
{
x.bulan,
x.rmKonsisten,
x.rmTidakKonsisten,
x.target,
}).ToList(),
// volume sampah
volumeSampahInfo = new
{
jumlahRumah = random.Next(5000, 6000),
periode,
totalVolume = Math.Round(random.NextDouble() * 10000 + 20000, 2).ToString("N2")
}
};
return Json(data);
}
catch (Exception ex)
{
return StatusCode(500, new { error = ex.Message, stackTrace = ex.StackTrace });
}
}
[HttpGet]
public IActionResult GetDataKepatuhanPeriode(string bulan, string wilayah)
{
try
{
// default bulan
DateTime selectedDate = DateTime.Now;
if (!string.IsNullOrEmpty(bulan))
{
if (!DateTime.TryParse(bulan + "-01", out selectedDate))
{
selectedDate = DateTime.Now;
}
}
var periode = selectedDate.ToString("MMMM yyyy", new System.Globalization.CultureInfo("id-ID"));
// Data kecamatan
var kecamatanData = new Dictionary<string, string[]>
{
{ "Jakarta Pusat", new[] { "Gambir", "Tanah Abang", "Menteng", "Senen", "Cempaka Putih", "Johar Baru", "Kemayoran", "Sawah Besar" } },
{ "Jakarta Utara", new[] { "Penjaringan", "Pademangan", "Tanjung Priok", "Koja", "Kelapa Gading", "Cilincing" } },
{ "Jakarta Barat", new[] { "Cengkareng", "Grogol Petamburan", "Taman Sari", "Tambora", "Kebon Jeruk", "Kalideres", "Palmerah", "Kembangan" } },
{ "Jakarta Selatan", new[] { "Kebayoran Baru", "Kebayoran Lama", "Pesanggrahan", "Cilandak", "Pasar Minggu", "Jagakarsa", "Mampang Prapatan", "Pancoran", "Tebet", "Setiabudi" } },
{ "Jakarta Timur", new[] { "Matraman", "Pulo Gadung", "Jatinegara", "Kramat Jati", "Pasar Rebo", "Cakung", "Duren Sawit", "Makasar", "Ciracas", "Cipayung" } },
{ "Kepulauan Seribu", new[] { "Kepulauan Seribu Utara", "Kepulauan Seribu Selatan" } }
};
string[] kecamatanLabels;
string locationText;
if (!string.IsNullOrEmpty(wilayah) && kecamatanData.ContainsKey(wilayah))
{
kecamatanLabels = kecamatanData[wilayah];
locationText = $"Kota Administrasi {wilayah}";
}
else
{
kecamatanLabels = kecamatanData["Jakarta Barat"];
locationText = "DKI Jakarta";
}
var random = new Random();
// Tingkat Kepatuhan PJLP Periode
var tingkatKepatuhanPeriode = kecamatanLabels.Select(w => new
{
wilayah = w,
ceklis = random.Next(40, 60),
belumCeklis = random.Next(40, 60),
total = random.Next(90, 100)
}).ToList();
// Total Pjlp
var totalPjlp = tingkatKepatuhanPeriode.Sum(x => x.total);
var totalSudahCeklis = tingkatKepatuhanPeriode.Sum(x => x.ceklis);
var totalBelumCeklis = tingkatKepatuhanPeriode.Sum(x => x.belumCeklis);
var persentaseSudah = totalPjlp > 0 ? Math.Round((double)totalSudahCeklis / totalPjlp * 100, 0) : 0;
var persentaseBelum = totalPjlp > 0 ? Math.Round((double)totalBelumCeklis / totalPjlp * 100, 0) : 0;
var data = new
{
bulan = selectedDate.ToString("yyyy-MM"),
periode,
wilayah = wilayah ?? "",
locationText,
// Tingkat Kepatuhan PJLP Periode
tingkatKepatuhanPeriode,
// Data cards PJLP
pjlpStats = new
{
total = totalPjlp,
sudahCeklis = totalSudahCeklis,
belumCeklis = totalBelumCeklis,
persentaseSudah = (int)persentaseSudah,
persentaseBelum = (int)persentaseBelum
}
};
return Json(data);
}
catch (Exception ex)
{
return StatusCode(500, new { error = ex.Message, stackTrace = ex.StackTrace });
}
}
}
}

View File

@ -91,7 +91,11 @@
<script>
Chart.register(ChartDataLabels);
Chart.defaults.animation = { duration: 1500, easing: 'easeOutQuart' };
Chart.defaults.animation = { duration: 500, easing: 'easeOutQuart' };
Chart.defaults.animations = {
numbers: { duration: 500, easing: 'easeOutQuart' },
colors: { duration: 500, easing: 'easeOutQuart' }
};
let chartInstances = {
pieTotal: null,
@ -168,6 +172,11 @@
options: {
responsive: true,
maintainAspectRatio: false,
layout: {
padding: {
top: 20
}
},
scales: { y: { beginAtZero: true } },
plugins: {
legend: { position: 'bottom', labels: { usePointStyle: true, pointStyle: "circle" } },
@ -317,6 +326,11 @@
options: {
responsive: true,
maintainAspectRatio: false,
layout: {
padding: {
top: 20
}
},
scales: { y: { beginAtZero: true } },
plugins: {
legend: { position: 'bottom', labels: { usePointStyle: true, pointStyle: "circle" } },

View File

@ -93,10 +93,10 @@
<script>
Chart.register(ChartDataLabels);
Chart.defaults.animation = { duration: 1500, easing: 'easeOutQuart' };
Chart.defaults.animation = { duration: 500, easing: 'easeOutQuart' };
Chart.defaults.animations = {
numbers: { duration: 1500, easing: 'easeOutQuart' },
colors: { duration: 1500, easing: 'easeOutQuart' }
numbers: { duration: 500, easing: 'easeOutQuart' },
colors: { duration: 500, easing: 'easeOutQuart' }
};
const chartInstances = {

File diff suppressed because it is too large Load Diff