330 lines
12 KiB
PHP
330 lines
12 KiB
PHP
<?php $__env->startSection('title', 'Dasbor Mitigasi'); ?>
|
|
|
|
<?php $__env->startSection('content'); ?>
|
|
<div class="card shadow-sm" style="font-family: 'Inter', sans-serif;">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">Dasbor Mitigasi</h5>
|
|
<form
|
|
method="GET"
|
|
id="yearForm"
|
|
action="<?php echo e(route('dashboardMitigasi.index')); ?>"
|
|
class="d-inline"
|
|
>
|
|
<?php if (isset($component)) { $__componentOriginal3e3fea84a5c8bc5d124cd778c5bc56e5 = $component; } ?>
|
|
<?php if (isset($attributes)) { $__attributesOriginal3e3fea84a5c8bc5d124cd778c5bc56e5 = $attributes; } ?>
|
|
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'components.mitigation-year-select','data' => ['selectedYear' => $selectedYear,'name' => 'mitigationYear','onchange' => 'document.getElementById(\'yearForm\').submit()']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
|
<?php $component->withName('mitigation-year-select'); ?>
|
|
<?php if ($component->shouldRender()): ?>
|
|
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
|
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
|
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
|
<?php endif; ?>
|
|
<?php $component->withAttributes(['selectedYear' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($selectedYear),'name' => 'mitigationYear','onchange' => 'document.getElementById(\'yearForm\').submit()']); ?>
|
|
<?php echo $__env->renderComponent(); ?>
|
|
<?php endif; ?>
|
|
<?php if (isset($__attributesOriginal3e3fea84a5c8bc5d124cd778c5bc56e5)): ?>
|
|
<?php $attributes = $__attributesOriginal3e3fea84a5c8bc5d124cd778c5bc56e5; ?>
|
|
<?php unset($__attributesOriginal3e3fea84a5c8bc5d124cd778c5bc56e5); ?>
|
|
<?php endif; ?>
|
|
<?php if (isset($__componentOriginal3e3fea84a5c8bc5d124cd778c5bc56e5)): ?>
|
|
<?php $component = $__componentOriginal3e3fea84a5c8bc5d124cd778c5bc56e5; ?>
|
|
<?php unset($__componentOriginal3e3fea84a5c8bc5d124cd778c5bc56e5); ?>
|
|
<?php endif; ?>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="card-body">
|
|
<!-- Alerts -->
|
|
<?php if($errors->has('error')): ?>
|
|
<div class="alert alert-danger">
|
|
<?php echo e($errors->first('error')); ?>
|
|
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if(session('success')): ?>
|
|
<div class="alert alert-success">
|
|
<?php echo e(session('success')); ?>
|
|
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="row flex justify-content-end items-center ml-6 mb-4">
|
|
<div class="flex gap-2 mr-4">
|
|
<a href="<?php echo e(route('formMitigasi.create', ['reset' => 1])); ?>">
|
|
<button class="button-action px-4 py-2">
|
|
Aksi Baru
|
|
</button>
|
|
</a>
|
|
<a href="<?php echo e(route('mitigasi.aksi')); ?>">
|
|
<button class="button-action px-4 py-2 bg-green-600 text-white hover:bg-green-700">
|
|
Aksi Perubahan Iklim
|
|
</button>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<br/>
|
|
|
|
|
|
<div class="row mb-5">
|
|
<div class="col-lg-4">
|
|
<p class="h6">AKSI</p>
|
|
<canvas id="aksiChart" height="100"></canvas>
|
|
</div>
|
|
<div class="col-lg-4">
|
|
<p class="h6">ALOKASI (Miliar Rupiah)</p>
|
|
<canvas id="anggaranChart" height="100"></canvas>
|
|
</div>
|
|
<div class="col-lg-4">
|
|
<p class="h6">REALISASI (Miliar Rupiah)</p>
|
|
<canvas id="realisasiChart" height="100"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="table-responsive">
|
|
<table id="mitigasiTable" class="table table-bordered table-striped align-middle">
|
|
<thead class="bg-header text-white text-center">
|
|
<tr style="font-size:16px;font-weight:700">
|
|
<th>Tipe Kegiatan</th>
|
|
<th>Nama Kegiatan</th>
|
|
<th>Tahun</th>
|
|
<th>Sektor</th>
|
|
<th>Sub-Sektor</th>
|
|
<th>Kategori</th>
|
|
<th class="text-end">Penurunan Emisi</th>
|
|
<th class="text-center">Revisi</th>
|
|
<th style="width:80px;"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php $__currentLoopData = $tableData; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $m): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
|
<tr style="font-size:14px">
|
|
<td><?php echo e($m->tipe_kegiatan); ?></td>
|
|
<td><?php echo e(Str::limit($m->nama_kegiatan, 60)); ?></td>
|
|
<td class="text-center"><?php echo e($m->tahun_kegiatan); ?></td>
|
|
<td><?php echo e($m->sektor); ?></td>
|
|
<td><?php echo e($m->sub_sektor); ?></td>
|
|
<td><?php echo e($m->kategori_perhitungan); ?></td>
|
|
<td class="text-end">
|
|
<?php echo e($m->emission_factor); ?>
|
|
|
|
</td>
|
|
<td class="text-center"><?php echo e($m->revisi ?? '--'); ?></td>
|
|
<td class="text-center">
|
|
<a href="<?php echo e(route('mitigasi.view', $m->id)); ?>" class="text-secondary me-2">
|
|
<i class="ti ti-eye"></i>
|
|
</a>
|
|
<a href="<?php echo e(route('mitigasi.edit', $m->id)); ?>" class="text-secondary">
|
|
<i class="ti ti-pencil"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php $__env->stopSection(); ?>
|
|
|
|
<?php $__env->startPush('styles'); ?>
|
|
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css"/>
|
|
<?php $__env->stopPush(); ?>
|
|
|
|
<?php $__env->startPush('scripts'); ?>
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>
|
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
|
|
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// === DataTables (unchanged) ===
|
|
$('#mitigasiTable').DataTable({
|
|
pageLength: 10, ordering: true, searching: true, lengthChange: true,
|
|
columnDefs: [
|
|
{ targets: 6, className: 'text-end' },
|
|
{ targets: 7, className: 'text-center' },
|
|
{ targets: 8, className: 'text-center', orderable: false, searchable: false }
|
|
],
|
|
language: {
|
|
search: "Cari:", lengthMenu: "Tampilkan _MENU_ data per halaman",
|
|
zeroRecords: "Tidak ada data ditemukan", emptyTable: "Tidak ada data.",
|
|
info: "Menampilkan _START_ sampai _END_ dari _TOTAL_ data",
|
|
infoEmpty: "Tidak ada data tersedia",
|
|
infoFiltered: "(difilter dari _MAX_ total data)"
|
|
},
|
|
footerCallback: function () {
|
|
const api = this.api();
|
|
$(api.column(0).footer()).html('TOTAL (Semua Tahun <?php echo e($selectedYear); ?>)');
|
|
const parseIdNumber = (v) => {
|
|
if (typeof v === 'number') return v;
|
|
if (!v) return 0;
|
|
const s = String(v).replace(/\./g, '').replace(',', '.');
|
|
const n = parseFloat(s);
|
|
return isNaN(n) ? 0 : n;
|
|
};
|
|
const total = api.column(6, { search: 'applied' }).data().toArray()
|
|
.reduce((sum, val) => sum + parseIdNumber(val), 0);
|
|
const formatted = new Intl.NumberFormat('id-ID', { maximumFractionDigits: 6 }).format(total);
|
|
$(api.column(6).footer()).html(formatted);
|
|
}
|
|
});
|
|
|
|
// === Colors ===
|
|
function getColor(i) {
|
|
const p = [
|
|
'rgba(255,99,132,0.6)','rgba(54,162,235,0.6)','rgba(255,206,86,0.6)',
|
|
'rgba(75,192,192,0.6)','rgba(153,102,255,0.6)','rgba(255,159,64,0.6)',
|
|
'rgba(199,199,199,0.6)','rgba(100,181,246,0.6)','rgba(76,175,80,0.6)',
|
|
'rgba(121,85,72,0.6)'
|
|
];
|
|
return p[i % p.length];
|
|
}
|
|
|
|
// === Parser & Formatter (IDR → Miliar, desimal adaptif) ===
|
|
function parseIdrToNumber(v) {
|
|
if (typeof v === 'number') return v;
|
|
if (v == null) return 0;
|
|
const s = String(v).replace(/\s/g,'').replace(/\./g,'').replace(',', '.');
|
|
const n = Number(s);
|
|
return isNaN(n) ? 0 : n;
|
|
}
|
|
function toBillion(v) { return parseIdrToNumber(v) / 1_000_000_000; }
|
|
function pickDecimals(maxAbs) {
|
|
if (maxAbs >= 1) return 2;
|
|
if (maxAbs >= 0.1) return 3;
|
|
if (maxAbs >= 0.01) return 4;
|
|
if (maxAbs >= 0.001) return 5;
|
|
return 6;
|
|
}
|
|
function fmtMiliar(v, d) {
|
|
return new Intl.NumberFormat('id-ID', { maximumFractionDigits: d }).format(v) + ' M';
|
|
}
|
|
|
|
// === Chart AKSI (bukan rupiah) ===
|
|
const barData = <?php echo json_encode($barData, 15, 512) ?>;
|
|
const years = barData.map(d => d.year);
|
|
const sectors = barData.length ? Object.keys(barData[0].jumlah || {}) : [];
|
|
const aksiDatasets = sectors.map((sec, idx) => ({
|
|
label: sec,
|
|
data: years.map(y => {
|
|
const row = barData.find(d => d.year === y) || {};
|
|
return (row.jumlah && row.jumlah[sec]) ? row.jumlah[sec] : 0;
|
|
}),
|
|
backgroundColor: getColor(idx),
|
|
borderColor: getColor(idx).replace('0.6','1'),
|
|
borderWidth: 1
|
|
}));
|
|
|
|
new Chart(document.getElementById('aksiChart'), {
|
|
type: 'bar',
|
|
data: { labels: years, datasets: aksiDatasets },
|
|
options: {
|
|
plugins: {
|
|
legend: { position: 'top' },
|
|
tooltip: { callbacks: { label: ctx => `${ctx.dataset.label}: ${ctx.parsed.y}` } }
|
|
},
|
|
scales: {
|
|
x: { stacked: true },
|
|
y: { stacked: true, beginAtZero: true, title: { display: true, text: 'Jumlah Kegiatan' } }
|
|
}
|
|
}
|
|
});
|
|
|
|
// === Chart Anggaran & Realisasi (Rupiah → Miliar) ===
|
|
const budget = <?php echo json_encode($budgetData, 15, 512) ?>;
|
|
const realisasi = <?php echo json_encode($realisasiData, 15, 512) ?>;
|
|
const labels = ['APBN','APBD','Swasta','Lain-lain'];
|
|
|
|
const anggaranValuesB = [
|
|
toBillion(budget?.apbn), toBillion(budget?.apbd),
|
|
toBillion(budget?.swasta), toBillion(budget?.lainlain)
|
|
];
|
|
const realisasiValuesB = [
|
|
toBillion(realisasi?.apbn), toBillion(realisasi?.apbd),
|
|
toBillion(realisasi?.swasta), toBillion(realisasi?.lainlain)
|
|
];
|
|
|
|
// Tentukan jumlah desimal per chart berdasarkan nilai maksimum
|
|
const decAnggaran = pickDecimals(Math.max(...anggaranValuesB.map(Math.abs), 0));
|
|
const decRealisasi = pickDecimals(Math.max(...realisasiValuesB.map(Math.abs), 0));
|
|
|
|
const colors = ['#0575E6','#FFA500','#8A2BE2','#00BFA6'];
|
|
const realisasiColors = ['#7ed957','#ffd966','#bdb2ff','#80cbc4'];
|
|
|
|
function createBarChart(canvasId, datasetLabel, valuesB, colorsArr, decimals) {
|
|
const ctx = document.getElementById(canvasId).getContext('2d');
|
|
|
|
const datasets = labels.map((label, i) => ({
|
|
label: label,
|
|
data: [valuesB[i]], // satu nilai per kategori
|
|
backgroundColor: colorsArr[i],
|
|
datalabels: {
|
|
anchor: 'end',
|
|
align: 'right',
|
|
formatter: v => fmtMiliar(v, decimals),
|
|
clip: false
|
|
}
|
|
}));
|
|
|
|
new Chart(ctx, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: [datasetLabel], // cuma 1 kategori "Anggaran" atau "Realisasi"
|
|
datasets: datasets
|
|
},
|
|
options: {
|
|
indexAxis: 'y',
|
|
plugins: {
|
|
legend: { display: true, position: 'top' },
|
|
tooltip: {
|
|
callbacks: {
|
|
label: (ctx) => {
|
|
const v = ctx.parsed.x ?? ctx.parsed.y ?? 0;
|
|
return `${ctx.dataset.label}: ${fmtMiliar(v, decimals)}`;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
scales: {
|
|
x: {
|
|
beginAtZero: true,
|
|
suggestedMax: Math.max(...valuesB) * 1.1 || 1,
|
|
title: { display: true, text: 'Miliar Rupiah (M)' },
|
|
ticks: {
|
|
callback: (value) => fmtMiliar(value, decimals)
|
|
}
|
|
},
|
|
y: { ticks: { autoSkip: false } }
|
|
}
|
|
},
|
|
plugins: [ ChartDataLabels ]
|
|
});
|
|
}
|
|
|
|
|
|
createBarChart('anggaranChart', '', anggaranValuesB, colors, decAnggaran);
|
|
createBarChart('realisasiChart', '', realisasiValuesB, realisasiColors, decRealisasi);
|
|
});
|
|
</script>
|
|
<?php $__env->stopPush(); ?>
|
|
|
|
|
|
|
|
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH /var/www/sigd/resources/views/auth/dashboard-mitigation.blade.php ENDPATH**/ ?>
|