penambahan tampilan pcpd_pajak tambahan gauge

1 parent d8e4d127
......@@ -3,6 +3,9 @@ eis-pcpd,PCPD,/eis/pcpd,1,0,0
eis-pcpd-act,PCPD Act,/eis/pcpd/{act}/act,1,0
eis-pajak,Pajak,#,1,0,1
eis-pajak-kumulatif,Pajak,/eis/pajak,1,0,1,eis-pajak,pcpd,Views,view_pajak,,pcpd_pajak.pt
eis-pajak-kumulatif2,Pajak,/eis/pajak2,1,0,1,eis-pajak,pcpd,Views,view_pajak,,pcpd_pajak2.pt
eis-pajak-kumulatif3,Pajak,/eis/pajak3,1,0,1,eis-pajak,pcpd,Views,view_pajak,,pcpd_pajak3.pt
eis-pajak-kumulatif4,Pajak,/eis/pajak4,1,0,1,eis-pajak,pcpd,Views,view_pajak,,pcpd_pajak4.pt
eis-pbb,PBB,/eis/pbb,1,0,1,eis-pajak,pcpd,Views,view_pbb,,pbb.pt
eis-bphtb,BPHTB,/eis/bphtb,1,0,1,eis-pajak,pcpd,Views,view_bphtb,eis,pcpd.pt
eis-pbjt,PBJT,#,1,0,1,eis-pajak
......
......@@ -30,94 +30,63 @@ PAD_TYP = {
}
jenis_pajak = {
"opsen": {
"kode": "41012",
"nama": "Opsen",
"subs": [
{"kode": "410120010001",
{"kode": "4.1.1.10",
"nama": "Opsen PKB"},
{"kode": "410121010001",
{"kode": "4.1.1.11",
"nama": "Opsen BBNKB"},
]},
"pbb": {
"kode": "410115",
"nama": "PBBP2"},
"kode": "4.1.1.0",
"nama": "Pajak Bumi & Bangunan",
"subs": []
},
"bphtb": {
"kode": "410116",
"nama": "BPHTB-Pemindahan Hak"},
"kode": "4.1.0.0",
"nama": "Bea Perolehan Hak atas Tanah dan Bangunan",
"subs": []
},
"resto": {
"kode": "41011901",
"nama": "PBJT Restoran",
"subs": [
{"kode": "410119010001",
"nama": "PBJT-Restoran"},
{"kode": "410119010002",
"nama": "PBJT-Penyedia Jasa Boga atau Katering"},
{"kode": "410119020001",
"nama": "PBJT-Konsumsi Tenaga Listrik dari Sumber Lain"},
]},
"kode": "4.1.1.02",
"nama": "PBJT - Makanan dan Minuman",
"subs": []
},
"ppju": {
"kode": "41011902",
"kode": "4.1.1.05",
"nama": "PBJT-Tenaga Listrik",
"subs": []},
"hotel": {
"kode": "41011903",
"kode": "4.1.1.01",
"nama": "PBJT Jasa Perhotelan",
"subs": [
{"kode": "410119030001", "nama": "PBJT-Hotel"},
{"kode": "410119030003", "nama": "PBJT-Vila"},
{"kode": "410119030007", "nama": "PBJT-Wisma Pariwisata"},
]},
"subs": []
},
"parkir": {
"kode": "41011904",
"nama": "PBJT-Penyediaan atau Penyelenggaraan Tempat Parkir"},
"kode": "4.1.1.07",
"nama": "Pajak Parkir"},
"hiburan": {
"kode": "41011905",
"nama": "PBJT-Jasa Kesenian dan Hiburan",
"subs": [
{"kode": "410119050001",
"nama": "PBJT-Tontonan Film atau Bentuk Tontonan Audio Visual Lainnya yang Dipertontonkan secara Langsung di Suatu Lokasi Tertentu"},
{"kode": "410119050002",
"nama": "PBJT-Pergelaran Kesenian, Musik, Tari, dan/atau Busana"},
{"kode": "410119050007",
"nama": "PBJT-Pacuan Kuda dan Perlombaan Kendaraan Bermotor"},
{"kode": "410119050008",
"nama": "PBJT-Permainan Ketangkasan"},
{"kode": "410119050009",
"nama": "PBJT-Olahraga Permainan dengan Menggunakan Tempat/Ruang dan/atau Peralatan dan Perlengkapan untuk Olahraga dan Kebugaran"},
{"kode": "410119050010",
"nama": "PBJT-Rekreasi Wahana Air, Wahana Ekologi, Wahana Pendidikan, Wahana Budaya, Wahana Salju, Wahana Permainan, Pemancingan, Agrowisata, dan Kebun Binatang"},
{"kode": "410119050012",
"nama": "PBJT-Distkotek, Karaoke, Kelab Malam, Bar, dan Mandi Uap/Spa"},
]},
"kode": "4.1.1.03",
"nama": "PBJT - Jasa Kesenian dan Hiburan",
"subs": []
},
"reklame": {
"kode": "410109",
"nama": "Pajak Reklame",
"subs": [
{"kode": "410109010001",
"nama": "Pajak Reklame Papan/Billboard/Videotron/Megatron"},
{"kode": "410109020001", "nama": "Pajak Reklame Kain"},
{"kode": "410109030001",
"nama": "Pajak Reklame Melekat/Stiker"},
{"kode": "410109050001", "nama": "Pajak Reklame Berjalan"},
]},
"kode": "4.1.1.04",
"nama": "Pajak Rekalme",
"subs": []
},
"atd": {
"kode": "410112",
"kode": "4.1.1.08",
"nama": "Pajak Air Tanah"},
"walet": {
"kode": "410113",
"nama": "Pajak Sarang Burung Walet "},
"kode": "4.1.1.09",
"nama": "Pajak Sarang Burung Walet"},
"minerba": {
"kode": "410114",
"kode": "4.1.1.06",
"nama": "Pajak Mineral Bukan Logam dan Batuan",
"subs": [
{"kode": "410114230001", "nama": "Pajak Pasir dan Kerikil"},
{"kode": "410114300001", "nama": "Pajak Tanah Liat"},
]}
"subs": []
}
}
......
......@@ -10,7 +10,22 @@
</style>
<div metal:fill-slot="content">
<!-- Main Title -->
<div class="row">
<div class="col-md-12">
<div class="text-center" style="margin-bottom: 20px; padding: 15px 0;">
<h2 style="margin: 0; font-weight: bold; color: #333; text-transform: uppercase; letter-spacing: 1px;">
LAPORAN REALTIME REALISASI PAJAK DAERAH
</h2>
<h3 style="margin: 5px 0 0; font-weight: bold; color: #cc5200; text-transform: uppercase; letter-spacing: 1px;">
DATA DAN INFORMASI
</h3>
<h4 id="tanggalHariIni" style="margin: 5px 0 0; color: #003399; font-weight: bold;"></h4>
</div>
</div>
</div>
<div class="row hide">
<div class="col-md-3 col1">
<img src="${home}/eis/static/pcpd-logo.png" class="img-responsive logo-pcpd" alt="PCPD Logo">
</div>
......@@ -29,7 +44,7 @@
</div>
</div>
</div>
<div class="row">
<div class="row hide">
<div class="col-md-6">
<div class="panel panel-default text-center">
<div class="panel-heading">
......@@ -70,10 +85,10 @@
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-heading">
<img src="${home}/eis/static/42x42-statistics.png" class="icon-rounded" alt="" align="left">
<img src="${home}/eis/static/bapend.png" class="icon-rounded" alt="" align="left">
<h5 class="text-left bold">Target dan Realisasi per Pajak
<i class="fa fa-info-circle pull-right icon-color"></i>
</h5>
......@@ -111,10 +126,28 @@
</div>
</div>
</div>
<hr>
<!-- Gauge Chart Section -->
<div class="col-md-4">
<div class="panel panel-default" id="gaugePanel" style="min-height: 500px;">
<div class="panel-heading" style="padding: 10px 15px;">
<h5 class="text-center bold" style="margin: 0;">REALISASI PAJAK DAERAH</h5>
</div>
<div class="panel-body" style="padding: 0; height: calc(100% - 50px); overflow: hidden; display: flex; flex-direction: column;">
<div id="chartContainer" style="flex: 1; display: flex; align-items: center; justify-content: center; margin: 0; padding: 0;">
<canvas id="gaugeChart" width="100%" height="100%"></canvas>
</div>
<div class="text-center" style="padding: 10px; background: rgba(0,0,0,0.02); border-top: 1px solid #ddd;">
<h4 id="gaugePercentage" style="margin: 2px 0; font-weight: bold; color: #333; font-size: 16px;">63.70%</h4>
<p style="margin: 1px 0; font-size: 11px; color: #666;">Realisasi: Rp.<span id="gaugeRealisasi">2.343.460.022.116</span></p>
<p style="margin: 1px 0; font-size: 11px; color: #666;">Target: Rp.<span id="gaugeTarget">3.679.068.431.493</span></p>
</div>
</div>
</div>
</div>
</div>
<hr>
<div class="row ">
<div class="row hide">
<div class="col-md-2">
<select class="form-control rounded" id="rangeType">
<option value="3">Bulanan</option>
......@@ -124,7 +157,7 @@
</div>
<hr>
</div>
<div class="row">
<div class="row hide">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
......@@ -156,7 +189,7 @@
</div>
</div>
</div>
<div class="row">
<div class="row hide">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
......@@ -200,11 +233,21 @@
<script metal:fill-slot="scripts">
const today = new Date();
const options = { day: 'numeric', month: 'long', year: 'numeric' };
const tanggalFormat = today.toLocaleDateString('id-ID', options);
document.addEventListener("DOMContentLoaded", function () {
document.getElementById("tanggalHariIni").innerText = "Tanggal, " + tanggalFormat;
});
var pieChart;
var amtTrendChart;
var trxTrendChart;
var amtKumulatifChart;
var trxKumulatifChart;
var gaugeChart;
var newData;
$(document).ready(function () {
......@@ -342,9 +385,154 @@
$("#rangeType").change(function () {
trendChart();
});
// Initialize Gauge Chart
initializeGauge();
$().datarefresh();
});
// Function to match gauge panel height with table panel
function matchPanelHeights() {
var tablePanel = document.querySelector('.col-md-8 .panel');
var gaugePanel = document.getElementById('gaugePanel');
if (tablePanel && gaugePanel) {
var tablePanelHeight = tablePanel.offsetHeight;
gaugePanel.style.height = tablePanelHeight + 'px';
}
}
function initializeGauge() {
var canvas = document.getElementById('gaugeChart');
var ctx = canvas.getContext('2d');
var container = document.getElementById('chartContainer');
// Set canvas size to fill container
function resizeCanvas() {
var containerRect = container.getBoundingClientRect();
var size = Math.min(containerRect.width, containerRect.height);
canvas.width = containerRect.width;
canvas.height = size * 0.7; // Semi-circle height ratio
// Update gauge properties
if (gaugeChart) {
gaugeChart.centerX = canvas.width / 2;
gaugeChart.centerY = canvas.height - 20;
gaugeChart.radius = Math.min(canvas.width * 0.45, canvas.height * 0.65);
gaugeChart.draw();
}
}
// Match panel heights and resize canvas
matchPanelHeights();
setTimeout(resizeCanvas, 100); // Allow DOM to update
gaugeChart = {
canvas: canvas,
ctx: ctx,
centerX: canvas.width / 2,
centerY: canvas.height - 20,
radius: Math.min(canvas.width * 0.45, canvas.height * 0.65),
value: 63.70,
draw: function() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Draw gauge background segments
this.drawSegments();
// Draw scale numbers
this.drawScale();
// Draw needle
this.drawNeedle();
},
drawSegments: function() {
var ctx = this.ctx;
var segments = [
{ start: 0, end: 40, color: '#ff0000' }, // Red (0-40)
{ start: 40, end: 70, color: '#ffff00' }, // Yellow (40-70)
{ start: 70, end: 100, color: '#00ff00' } // Green (70-100)
];
segments.forEach(segment => {
var startAngle = Math.PI + (segment.start / 100) * Math.PI;
var endAngle = Math.PI + (segment.end / 100) * Math.PI;
ctx.beginPath();
ctx.arc(this.centerX, this.centerY, this.radius, startAngle, endAngle);
ctx.lineWidth = Math.max(12, this.radius * 0.08);
ctx.strokeStyle = segment.color;
ctx.stroke();
});
},
drawScale: function() {
var ctx = this.ctx;
ctx.fillStyle = '#000';
ctx.font = Math.max(10, this.radius * 0.08) + 'px Arial';
ctx.textAlign = 'center';
// Draw scale numbers (0, 10, 20, ..., 100)
for (var i = 0; i <= 100; i += 10) {
var angle = Math.PI + (i / 100) * Math.PI;
var labelRadius = this.radius + Math.max(20, this.radius * 0.15);
var x = this.centerX + Math.cos(angle) * labelRadius;
var y = this.centerY + Math.sin(angle) * labelRadius + 5;
ctx.fillText(i.toString(), x, y);
}
},
drawNeedle: function() {
var ctx = this.ctx;
var angle = Math.PI + (this.value / 100) * Math.PI;
ctx.save();
// Draw needle line
ctx.beginPath();
ctx.moveTo(this.centerX, this.centerY);
var needleLength = this.radius - Math.max(8, this.radius * 0.05);
var needleX = this.centerX + Math.cos(angle) * needleLength;
var needleY = this.centerY + Math.sin(angle) * needleLength;
ctx.lineTo(needleX, needleY);
ctx.strokeStyle = '#000';
ctx.lineWidth = Math.max(3, this.radius * 0.02);
ctx.lineCap = 'round';
ctx.stroke();
ctx.restore();
// Draw center circle
ctx.beginPath();
ctx.arc(this.centerX, this.centerY, Math.max(5, this.radius * 0.04), 0, 2 * Math.PI);
ctx.fillStyle = '#000';
ctx.fill();
},
update: function(value) {
this.value = Math.max(0, Math.min(100, value));
this.draw();
}
};
// Initial draw
gaugeChart.draw();
}
function updateGauge(percentage, realisasi, target) {
if (gaugeChart) {
gaugeChart.update(percentage);
}
document.getElementById('gaugePercentage').textContent = percentage.toFixed(2) + '%';
document.getElementById('gaugeRealisasi').textContent = parseInt(realisasi).toLocaleString('id-ID');
document.getElementById('gaugeTarget').textContent = parseInt(target).toLocaleString('id-ID');
}
function addData(chart, data) {
labels = [];
aData = [];
......@@ -460,6 +648,13 @@
$('#sum_sisa').html(sum_sisa.toLocaleString("id-ID"));
$('#sum_persen').html((sum_realisasi / sum_target * 100).toFixed(2));
// Update gauge with total values
var gaugePercentage = (sum_realisasi / sum_target * 100);
updateGauge(gaugePercentage, sum_realisasi, sum_target);
// Match panel heights after data load
matchPanelHeights();
table.draw();
} else {
console.log("Request failed.");
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!