544 lines
17 KiB
JavaScript
544 lines
17 KiB
JavaScript
import Big from "big.js";
|
|
import GlobalConfig, { addThousandSeparators } from "../global-config.js";
|
|
import ApexCharts from "apexcharts";
|
|
import "gridjs/dist/gridjs.umd.js";
|
|
import GeneralTable from "../table-generator.js";
|
|
|
|
var chart;
|
|
document.addEventListener("DOMContentLoaded", async function () {
|
|
await initChart();
|
|
const yearPicker = document.getElementById("yearPicker");
|
|
|
|
async function updateDataByYear(selectedYear) {
|
|
// Target PAD Element
|
|
const targetPadElement = document.getElementById("target-pad");
|
|
if (!targetPadElement) return;
|
|
const targetPadValue = await getDataSettings("TARGET_PAD");
|
|
targetPadElement.textContent = formatCurrency(targetPadValue);
|
|
|
|
// Total Potensi Berkas
|
|
const totalPotensiBerkas = document.getElementById(
|
|
"total-potensi-berkas"
|
|
);
|
|
if (!totalPotensiBerkas) return;
|
|
const totalPotensiBerkasValue = await getDataTotalPotensi(selectedYear);
|
|
totalPotensiBerkas.textContent = formatCurrency(
|
|
totalPotensiBerkasValue.totalData
|
|
);
|
|
|
|
// Total Berkas Terverifikasi
|
|
const totalBerkasTerverifikasi = document.getElementById(
|
|
"total-berkas-terverifikasi"
|
|
);
|
|
if (!totalBerkasTerverifikasi) return;
|
|
const totalBerkasTerverifikasiValue = await getDataVerification(
|
|
selectedYear
|
|
);
|
|
totalBerkasTerverifikasi.textContent = formatCurrency(
|
|
totalBerkasTerverifikasiValue.totalData
|
|
);
|
|
|
|
// Total Kekurangan potensi
|
|
const totalKekuranganPotensi = document.getElementById(
|
|
"total-kekurangan-potensi"
|
|
);
|
|
if (!totalKekuranganPotensi) return;
|
|
const totalKekuranganPotensiValue =
|
|
new Big(targetPadValue) -
|
|
new Big(totalPotensiBerkasValue.totalData);
|
|
totalKekuranganPotensi.textContent = formatCurrency(
|
|
totalKekuranganPotensiValue
|
|
);
|
|
|
|
// Total Potensi PBG dari tata ruang
|
|
const totalPotensiPBGTataRuang = document.getElementById(
|
|
"total-potensi-pbd-tata-ruang"
|
|
);
|
|
if (!totalPotensiPBGTataRuang) return;
|
|
const totalPotensiPBGTataRuangValue = await getDataSettings(
|
|
"TATA_RUANG"
|
|
);
|
|
totalPotensiPBGTataRuang.textContent = formatCurrency(
|
|
totalPotensiPBGTataRuangValue
|
|
);
|
|
|
|
// Total Berkas Belum terverifikasi
|
|
const totalBerkasBelumTerverifikasi = document.getElementById(
|
|
"total-berkas-belum-terverifikasi"
|
|
);
|
|
if (!totalBerkasBelumTerverifikasi) return;
|
|
const totalBerkasBelumTerverifikasiValue = await getDataNonVerification(
|
|
selectedYear
|
|
);
|
|
const totalBerkasBelumTerverifikasiCount =
|
|
totalBerkasBelumTerverifikasiValue.countData;
|
|
totalBerkasBelumTerverifikasi.textContent = formatCurrency(
|
|
totalBerkasBelumTerverifikasiValue.totalData
|
|
);
|
|
|
|
// Total Berkas Usaha
|
|
const totalBerkasUsahaValue = await getDataBusiness(selectedYear);
|
|
const totalBerkasUsahaCount = totalBerkasUsahaValue.countData;
|
|
const totalBerkasUsahaTotalData = totalBerkasUsahaValue.totalData;
|
|
|
|
// Total Berkas Non Usaha
|
|
const totalBerkasNonUsahaValue = await getDataNonBusiness(selectedYear);
|
|
const totalBerkasNonUsahaCount = totalBerkasNonUsahaValue.countData;
|
|
const totalBerkasNonUsahaTotalData = totalBerkasNonUsahaValue.totalData;
|
|
|
|
// Pie Chart Section
|
|
let persenUsaha =
|
|
totalBerkasBelumTerverifikasiCount > 0
|
|
? (
|
|
(totalBerkasUsahaCount /
|
|
totalBerkasBelumTerverifikasiCount) *
|
|
100
|
|
).toFixed(2)
|
|
: "0";
|
|
|
|
let persenNonUsaha =
|
|
totalBerkasBelumTerverifikasiCount > 0
|
|
? (
|
|
(totalBerkasNonUsahaCount /
|
|
totalBerkasBelumTerverifikasiCount) *
|
|
100
|
|
).toFixed(2)
|
|
: "0";
|
|
|
|
const dataSeriesPieChart = [
|
|
Number(persenUsaha),
|
|
Number(persenNonUsaha),
|
|
];
|
|
const labelsPieChart = ["Berkas Usaha", "Berkas Non Usaha"];
|
|
document.querySelector("td[data-category='non-usaha']").textContent =
|
|
formatCurrency(totalBerkasNonUsahaTotalData).toLocaleString();
|
|
document.querySelector(
|
|
"td[data-category='non-usaha-percentage']"
|
|
).textContent = persenNonUsaha + "%";
|
|
|
|
document.querySelector("td[data-category='usaha']").textContent =
|
|
formatCurrency(totalBerkasUsahaTotalData).toLocaleString();
|
|
document.querySelector(
|
|
"td[data-category='usaha-percentage']"
|
|
).textContent = persenUsaha + "%";
|
|
|
|
updatePieChart(dataSeriesPieChart, labelsPieChart);
|
|
|
|
// Load all Tourism location
|
|
const allLocation = await getAllLocation();
|
|
console.log(allLocation);
|
|
|
|
// Filter hanya data yang memiliki angka valid
|
|
let validLocations = allLocation.dataLocation.filter((loc) => {
|
|
return (
|
|
!isNaN(parseFloat(loc.longitude)) &&
|
|
!isNaN(parseFloat(loc.latitude))
|
|
);
|
|
});
|
|
|
|
// Ubah string ke float
|
|
validLocations = validLocations.map((loc) => ({
|
|
name: loc.project_name,
|
|
longitude: parseFloat(loc.longitude),
|
|
latitude: parseFloat(loc.latitude),
|
|
}));
|
|
|
|
console.log(validLocations.name);
|
|
|
|
// Inisialisasi peta
|
|
var map = L.map("map").setView([-7.023, 107.5275], 10);
|
|
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
attribution: "© OpenStreetMap contributors",
|
|
}).addTo(map);
|
|
|
|
// Tambahkan marker ke peta
|
|
validLocations.forEach(function (loc) {
|
|
L.marker([loc.latitude, loc.longitude])
|
|
.addTo(map)
|
|
.bindPopup(`<b>${loc.name}</b>`) // Popup saat diklik
|
|
.bindTooltip(loc.name, { permanent: false, direction: "top" }); // Tooltip saat di-hover
|
|
});
|
|
|
|
// Realisasi terbit PBG
|
|
const totalRealisasiTerbitPBG = document.getElementById(
|
|
"realisasi-terbit-pbg"
|
|
);
|
|
if (!totalRealisasiTerbitPBG) return;
|
|
const totalRealisasiTerbitPBGValue = await getDataSettings(
|
|
"REALISASI_TERBIT_PBG_SUM"
|
|
);
|
|
totalRealisasiTerbitPBG.textContent = formatCurrency(
|
|
totalRealisasiTerbitPBGValue
|
|
);
|
|
|
|
// Menunggu Klik DPMPTSP
|
|
const totalMenungguKlikDpmptsp = document.getElementById(
|
|
"waiting-click-dpmptsp"
|
|
);
|
|
if (!totalMenungguKlikDpmptsp) return;
|
|
const totalMenungguKlikDpmptspValue = await getDataSettings(
|
|
"MENUNGGU_KLIK_DPMPTSP_SUM"
|
|
);
|
|
totalMenungguKlikDpmptsp.textContent = formatCurrency(
|
|
totalMenungguKlikDpmptspValue
|
|
);
|
|
|
|
// Proses Dinas Teknis
|
|
const totalProsesDinasTeknis = document.getElementById(
|
|
"processing-technical-services"
|
|
);
|
|
if (!totalProsesDinasTeknis) return;
|
|
const totalProsesDinasTeknisValue = await getDataSettings(
|
|
"PROSES_DINAS_TEKNIS_SUM"
|
|
);
|
|
totalProsesDinasTeknis.textContent = formatCurrency(
|
|
totalProsesDinasTeknisValue
|
|
);
|
|
|
|
// Load Tabel Baru di Update
|
|
const tableLastUpdated = new GeneralTable(
|
|
"pbg-filter-by-updated-at",
|
|
`${GlobalConfig.apiHost}/api/api-pbg-task?isLastUpdated=true`,
|
|
`${GlobalConfig.apiHost}`,
|
|
pbgTaskColumns
|
|
);
|
|
|
|
tableLastUpdated.processData = function (data) {
|
|
console.log("Response Data:", data);
|
|
return data.data.map((item) => {
|
|
return [
|
|
item.no,
|
|
item.name,
|
|
item.registration_number,
|
|
item.document_number,
|
|
item.address,
|
|
];
|
|
});
|
|
};
|
|
|
|
tableLastUpdated.init();
|
|
|
|
// Load Tabel Status SK Terbit
|
|
const tableSKPBGTerbit = new GeneralTable(
|
|
"pbg-filter-by-status",
|
|
`${GlobalConfig.apiHost}/api/api-pbg-task?isLastUpdated=false`,
|
|
`${GlobalConfig.apiHost}`,
|
|
pbgTaskColumns
|
|
);
|
|
|
|
tableSKPBGTerbit.processData = function (data) {
|
|
console.log("Response Data:", data);
|
|
return data.data.map((item) => {
|
|
return [
|
|
item.no,
|
|
item.name,
|
|
item.registration_number,
|
|
item.document_number,
|
|
item.address,
|
|
];
|
|
});
|
|
};
|
|
|
|
tableSKPBGTerbit.init();
|
|
|
|
document.querySelector(
|
|
"#pbg-filter-by-updated-at .gridjs-search"
|
|
).hidden = true;
|
|
document.querySelector(
|
|
"#pbg-filter-by-updated-at .gridjs-footer"
|
|
).hidden = true;
|
|
document.querySelector(
|
|
"#pbg-filter-by-status .gridjs-search"
|
|
).hidden = true;
|
|
document.querySelector(
|
|
"#pbg-filter-by-status .gridjs-footer"
|
|
).hidden = true;
|
|
}
|
|
|
|
await updateDataByYear(yearPicker.value);
|
|
|
|
yearPicker.addEventListener("change", async function () {
|
|
console.log("event change dropdown");
|
|
await updateDataByYear(yearPicker.value);
|
|
});
|
|
});
|
|
|
|
async function getDataSettings(string_key) {
|
|
try {
|
|
const response = await fetch(
|
|
`${GlobalConfig.apiHost}/api/data-settings?search=${string_key}`,
|
|
{
|
|
credentials: "include",
|
|
headers: {
|
|
Authorization: `Bearer ${
|
|
document.querySelector("meta[name='api-token']").content
|
|
}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
console.error("Network response was not ok", response);
|
|
}
|
|
|
|
const data = await response.json();
|
|
return data.data?.[0]?.value ?? 0; // Pastikan tidak error jika data kosong
|
|
} catch (error) {
|
|
console.error("Error fetching data:", error);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async function getDataTotalPotensi(year) {
|
|
try {
|
|
const response = await fetch(
|
|
`${GlobalConfig.apiHost}/api/all-task-documents?year=${year}`,
|
|
{
|
|
credentials: "include",
|
|
headers: {
|
|
Authorization: `Bearer ${
|
|
document.querySelector("meta[name='api-token']").content
|
|
}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
console.error("Network response was not ok", response);
|
|
}
|
|
|
|
const data = await response.json();
|
|
return {
|
|
totalData: data.data.total,
|
|
};
|
|
} catch (error) {
|
|
console.error("Error fetching chart data:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function getDataVerification(year) {
|
|
try {
|
|
const response = await fetch(
|
|
`${GlobalConfig.apiHost}/api/verification-documents?year=${year}`,
|
|
{
|
|
credentials: "include",
|
|
headers: {
|
|
Authorization: `Bearer ${
|
|
document.querySelector("meta[name='api-token']").content
|
|
}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
console.error("Network response was not ok", response);
|
|
}
|
|
|
|
const data = await response.json();
|
|
return {
|
|
totalData: data.data.total,
|
|
};
|
|
} catch (error) {
|
|
console.error("Error fetching chart data:", error);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async function getDataNonVerification(year) {
|
|
try {
|
|
const response = await fetch(
|
|
`${GlobalConfig.apiHost}/api/non-verification-documents?year=${year}`,
|
|
{
|
|
credentials: "include",
|
|
headers: {
|
|
Authorization: `Bearer ${
|
|
document.querySelector("meta[name='api-token']").content
|
|
}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
console.error("Network response was not ok", response);
|
|
}
|
|
|
|
const data = await response.json();
|
|
return {
|
|
countData: data.data.count,
|
|
totalData: data.data.total,
|
|
};
|
|
} catch (error) {
|
|
console.error("Error fetching chart data:", error);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async function getDataBusiness(year) {
|
|
try {
|
|
const response = await fetch(
|
|
`${GlobalConfig.apiHost}/api/business-documents?year=${year}`,
|
|
{
|
|
credentials: "include",
|
|
headers: {
|
|
Authorization: `Bearer ${
|
|
document.querySelector("meta[name='api-token']").content
|
|
}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
console.error("Network response was not ok", response);
|
|
}
|
|
|
|
const data = await response.json();
|
|
return {
|
|
countData: data.data.count,
|
|
totalData: data.data.total,
|
|
};
|
|
} catch (error) {
|
|
console.error("Error fetching chart data:", error);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async function getDataNonBusiness(year) {
|
|
try {
|
|
const response = await fetch(
|
|
`${GlobalConfig.apiHost}/api/non-business-documents?year=${year}`,
|
|
{
|
|
credentials: "include",
|
|
headers: {
|
|
Authorization: `Bearer ${
|
|
document.querySelector("meta[name='api-token']").content
|
|
}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
console.error("Network response was not ok", response);
|
|
}
|
|
const data = await response.json();
|
|
return {
|
|
countData: data.data.count,
|
|
totalData: data.data.total,
|
|
};
|
|
} catch (error) {
|
|
console.error("Error fetching chart data:", error);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async function getAllLocation() {
|
|
try {
|
|
const response = await fetch(
|
|
`${GlobalConfig.apiHost}/api/get-all-location`,
|
|
{
|
|
credentials: "include",
|
|
headers: {
|
|
Authorization: `Bearer ${
|
|
document.querySelector("meta[name='api-token']").content
|
|
}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
}
|
|
);
|
|
if (!response.ok) {
|
|
console.error("Network response was not ok", response);
|
|
}
|
|
const data = await response.json();
|
|
return {
|
|
dataLocation: data.data,
|
|
};
|
|
} catch (error) {
|
|
console.error("Error fetching chart data:", error);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async function initChart() {
|
|
var options = {
|
|
chart: {
|
|
height: 180,
|
|
type: "donut",
|
|
},
|
|
series: [0, 0], // Inisialisasi dengan nilai awal
|
|
labels: ["Berkas Usaha", "Berkas Non Usaha"],
|
|
legend: {
|
|
show: false,
|
|
},
|
|
stroke: {
|
|
width: 0,
|
|
},
|
|
plotOptions: {
|
|
pie: {
|
|
donut: {
|
|
size: "60%",
|
|
},
|
|
},
|
|
},
|
|
colors: ["#7e67fe", "#17c553"],
|
|
dataLabels: {
|
|
enabled: false,
|
|
},
|
|
responsive: [
|
|
{
|
|
breakpoint: 480,
|
|
options: {
|
|
chart: {
|
|
width: 200,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
fill: {
|
|
type: "gradient",
|
|
},
|
|
};
|
|
|
|
chart = new ApexCharts(document.querySelector("#conversions"), options);
|
|
chart.render();
|
|
}
|
|
|
|
async function updatePieChart(dataSeries, labels) {
|
|
if (!Array.isArray(dataSeries) || dataSeries.length === 0) {
|
|
console.error("Data series tidak valid:", dataSeries);
|
|
return;
|
|
}
|
|
|
|
// Perbarui data series chart
|
|
chart.updateSeries(dataSeries);
|
|
|
|
// Perbarui label jika diperlukan
|
|
if (Array.isArray(labels) && labels.length === dataSeries.length) {
|
|
chart.updateOptions({
|
|
labels: labels,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Fungsi untuk format angka ke Rupiah
|
|
function formatCurrency(number) {
|
|
return new Intl.NumberFormat("id-ID", {
|
|
style: "currency",
|
|
currency: "IDR",
|
|
minimumFractionDigits: 0,
|
|
}).format(number);
|
|
}
|
|
|
|
const pbgTaskColumns = [
|
|
"No",
|
|
"Name",
|
|
"Nomor Registrasi",
|
|
"Nomor Dokumen",
|
|
"Alamat",
|
|
];
|