<style> #wpBayar { min-width: 600px; max-width: auto; height: 600px; margin: 0 auto; } </style> <?php ini_set('memory_limit', '4096M'); echo 'Initial memory usage: ' . memory_get_usage() . ' bytes' . PHP_EOL; $tahun2 = date('Y'); $rentang_tahun = range($tahun2, 2022); $totalWPBYR = 0; $totalWPBYRTERATUR = 0; $totalJMLWP = 0; foreach ($raporbyr as $row) { $totalWPBYR += $row->WPBYR; $totalWPBYRTERATUR += $row->WPBYRTERATUR; $totalJMLWP += $row->JMLWP; } $nasionalX = ($totalWPBYR / ($totalJMLWP ?: 1)) * 100; $nasionalY = ($totalWPBYRTERATUR / ($totalWPBYR ?: 1)) * 100; $area1Count = 0; // Top right $area2Count = 0; // Top left $area3Count = 0; // Bottom right $area4Count = 0; // Bottom left foreach ($raporbyr as $row) { $x = ($row->WPBYR / ($row->JMLWP ?: 1)) * 100; $y = ($row->WPBYRTERATUR / ($row->WPBYR ?: 1)) * 100; if ($x > $nasionalX && $y > $nasionalY) { $area1Count++; } elseif ($x <= $nasionalX && $y > $nasionalY) { $area2Count++; } elseif ($x > $nasionalX && $y <= $nasionalY) { $area3Count++; } else { $area4Count++; } } $dataraporkwl = "["; $dataraporkwl .= "{x: " . $nasionalX . ", y: " . $nasionalY . ", z: 2, name: 'Nasional', color: '#000000', jmlwp: " . $totalJMLWP . ", wpbyr: " . $totalWPBYR . ", wpbyrteratur: " . $totalWPBYRTERATUR . "},"; foreach ($raporbyr as $row) { $x = (($row->WPBYR / $row->JMLWP ?: 1)) * 100; $y = (($row->WPBYRTERATUR / $row->WPBYR ?: 1)) * 100; $dd = $row->KWLADM; $dataraporkwl .= "{x: " . $x . ", y: " . $y . ", z: 1, name: '" . addslashes($row->NAMA) . "', drilldown: \"" . $dd . "\", jmlwp: " . $row->JMLWP . ", wpbyr: " . $row->WPBYR . ", wpbyrteratur: " . $row->WPBYRTERATUR . "},"; } $dataraporkwl = rtrim($dataraporkwl, ',') . "]"; $nasionalX = ($totalWPBYR / ($totalJMLWP ?: 1)) * 100; $nasionalY = ($totalWPBYRTERATUR / ($totalWPBYR ?: 1)) * 100; $drilldownSeries = []; // per KPP foreach ($drilldownData['kpp'] as $kwladm => $kpps) { $parentPoint = null; $data = []; foreach ($raporbyr as $row) { if ($row->KWLADM == $kwladm) { $parentPoint = [ 'name' => $row->NAMA, 'x' => ($row->WPBYR / ($row->JMLWP ?: 1)) * 100, 'y' => ($row->WPBYRTERATUR / ($row->WPBYR ?: 1)) * 100, 'color' => '#FF0000', 'dataLabels' => [ 'enabled' => true, 'format' => '{point.name}', 'style' => ['fontWeight' => 'bold'] ], 'jmlwp' => $row->JMLWP, 'wpbyr' => $row->WPBYR, 'wpbyrteratur' => $row->WPBYRTERATUR ]; break; } } if ($parentPoint) { $data[] = $parentPoint; } foreach ($kpps as $kpp) { $data[] = [ 'name' => $kpp['name'], 'x' => $kpp['x'], 'y' => $kpp['y'], 'z' => $kpp['z'], 'drilldown' => (string)$kpp['drilldown'], 'jmlwp' => $kpp['jmlwp'], 'wpbyr' => $kpp['wpbyr'], 'wpbyrteratur' => $kpp['wpbyrteratur'] ]; } $drilldownSeries[] = [ 'id' => (string)$kwladm, 'name' => "KPP in " . $kwladm, 'data' => $data ]; } // per Seksi foreach ($drilldownData['sie'] as $kppadm => $sies) { $parentPoint = null; $data = []; foreach ($raporbyrkpp as $row) { if ($row->KPPADM == $kppadm) { $parentPoint = [ 'name' => $row->NAMA, 'x' => ($row->WPBYR / ($row->JMLWP ?: 1)) * 100, 'y' => ($row->WPBYRTERATUR / ($row->WPBYR ?: 1)) * 100, 'color' => '#00FF00', 'dataLabels' => [ 'enabled' => true, 'format' => '{point.name}', 'style' => ['fontWeight' => 'bold'] ], 'jmlwp' => $row->JMLWP, 'wpbyr' => $row->WPBYR, 'wpbyrteratur' => $row->WPBYRTERATUR ]; break; } } if ($parentPoint) { $data[] = $parentPoint; } foreach ($sies as $sie) { $data[] = [ 'name' => $sie['name'], 'x' => $sie['x'], 'y' => $sie['y'], 'z' => $sie['z'], 'drilldown' => (string)($kppadm . '_' . $sie['drilldown']), 'jmlwp' => $sie['jmlwp'], 'wpbyr' => $sie['wpbyr'], 'wpbyrteratur' => $sie['wpbyrteratur'] ]; } $drilldownSeries[] = [ 'id' => (string)$kppadm, 'name' => "SIE in " . $kppadm, 'data' => $data ]; } // per Pegawai foreach ($drilldownData['peg'] as $key => $pegs) { $parentPoint = null; $data = []; list($kppadm, $kodesie) = explode('_', $key); foreach ($raporbyrsie as $row) { if ($row->KPPADM == $kppadm && $row->KODESIE == $kodesie) { $parentPoint = [ 'name' => $row->NAMA, 'x' => ($row->WPBYR / ($row->JMLWP ?: 1)) * 100, 'y' => ($row->WPBYRTERATUR / ($row->WPBYR ?: 1)) * 100, 'color' => '#0000FF', 'dataLabels' => [ 'enabled' => true, 'format' => '{point.name}', 'style' => ['fontWeight' => 'bold'] ], 'jmlwp' => $row->JMLWP, 'wpbyr' => $row->WPBYR, 'wpbyrteratur' => $row->WPBYRTERATUR ]; break; } } if ($parentPoint) { $data[] = $parentPoint; } foreach ($pegs as $peg) { $data[] = [ 'name' => $peg['name'], 'x' => $peg['x'], 'y' => $peg['y'], 'z' => $peg['z'], 'drilldown' => null, 'jmlwp' => $peg['jmlwp'], 'wpbyr' => $peg['wpbyr'], 'wpbyrteratur' => $peg['wpbyrteratur'] ]; } $drilldownSeries[] = [ 'id' => (string)$key, 'name' => "PEG in " . $key, 'data' => $data ]; } $d['drilldownSeries'] = $drilldownSeries; ?> <div class="main-content"> <div class="container-fluid"> <div class="row"> <div class="col-sm-12 mb-2"> <form class="form-inline" action="<?php base_url('rapor/wpbyr') ?>" method="post"> <label class="my-1 mr-2">Tahun :</label> <select class="custom-select my-1 mr-sm-2" id="tahun" name="tahun"> <?php foreach ($rentang_tahun as $tahun) { if ($tahun == $tahunx) { $sel = "selected"; } else { $sel = ""; } echo "<option value=\"" . $tahun . "\" " . $sel . ">" . $tahun . "</option>"; } ?> </select> <label class="my-1 mr-2">s.d. Bulan :</label> <select class="custom-select my-1 mr-sm-2" id="bulan" name="bulan"> <?php foreach ($refbulan as $rowb) { if ($rowb->KODE == $bulanx) { $isSelected = ' selected="selected"'; } else { $isSelected = ''; } echo "<option value='" . $rowb->KODE . "'" . $isSelected . ">" . ucfirst(strtolower($rowb->NM_PANJANG)) . "</option>"; } ?> </select> <button type="submit" class="btn btn-primary my-1">Proses</button> </form> </div> </div> <div class="row clearfix"> <div class="col-md-12"> <div class="card"> <div class="card-header"> <h3 class="text-center">WP Bayar dan WP Bayar Teratur</h3> <div class="card-header-right"> <ul class="list-unstyled card-option"> <li><i class="ik ik-chevron-left action-toggle"></i></li> <li><i class="ik ik-minus minimize-card"></i></li> <li><i class="ik ik-x close-card"></i></li> </ul> </div> </div> <div class="card-body"> <div id="wpBayar" style="height:600px"></div> </div> </div> </div> </div> <div class="row clearfix"> <div class="col-md-12"> <div class="card"> <div class="card-header"> <h3 class="text-center">Data</h3> <div class="card-header-right"> <ul class="list-unstyled card-option"> <li><i class="ik ik-chevron-left action-toggle"></i></li> <li><i class="ik ik-minus minimize-card"></i></li> <li><i class="ik ik-x close-card"></i></li> </ul> </div> </div> <div class="card-body"> <table class="table table-hover table-striped table-bordered tablesorter" id="wpBayarTable"> <thead class='thead-dark'> <tr class="table-active"> <th class="text-center">No</th> <th class="text-center">Unit</th> <th class="text-center">%WP Bayar</th> <th class="text-center">%WP Bayar Teratur</th> <th class="text-center">Jumlah WP</th> <th class="text-center">WP Bayar <?= $tahunx ?></th> <th class="text-center">WP Bayar Teratur <?= $tahunx ?></th> </tr> </thead> <tbody> <?php $no = 1; $totalJmlWP = 0; $totalWPBayar = 0; $totalWPBayarTeratur = 0; foreach ($raporbyr as $row) { $wpBayarPercentage = ($row->WPBYR / ($row->JMLWP ?: 1)) * 100; $wpBayarTeraturPercentage = ($row->WPBYRTERATUR / ($row->WPBYR ?: 1)) * 100; $totalJmlWP += $row->JMLWP; $totalWPBayar += $row->WPBYR; $totalWPBayarTeratur += $row->WPBYRTERATUR; ?> <tr> <td><?= $no++ ?></td> <td><?= $row->KWLADM ?>-<?= $row->NM_PANJANG ?></td> <td class="text-right"><?= number_format($wpBayarPercentage, 2) ?>%</td> <td class="text-right"><?= number_format($wpBayarTeraturPercentage, 2) ?>%</td> <td class="text-right"><?= number_format($row->JMLWP, 0, ',', '.') ?></td> <td class="text-right"><?= number_format($row->WPBYR, 0, ',', '.') ?></td> <td class="text-right"><?= number_format($row->WPBYRTERATUR, 0, ',', '.') ?></td> </tr> <?php } ?> </tbody> <tfoot class='thead-dark'> <tr> <th colspan="2" class="text-center">Total</th> <th class="text-right"><?= number_format(($totalWPBayar / ($totalJmlWP ?: 1)) * 100, 2) ?> % </th> <th class="text-right"><?= number_format(($totalWPBayarTeratur / ($totalWPBayar ?: 1)) * 100, 2) ?> % </th> <th class="text-right"><?= number_format($totalJmlWP, 0, ',', '.') ?></th> <th class="text-right"><?= number_format($totalWPBayar, 0, ',', '.') ?></th> <th class="text-right"><?= number_format($totalWPBayarTeratur, 0, ',', '.') ?></th> </tr> </tfoot> </table> </div> </div> </div> </div> </div> </div> <?php echo view('inc/js.php') ?> <script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script> <link rel="stylesheet" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css"> <script> function addAreaLabels(chart) { var renderer = chart.renderer; var plotLeft = chart.plotLeft; var plotTop = chart.plotTop; var plotWidth = chart.plotWidth; var plotHeight = chart.plotHeight; // Remove existing labels if any if (chart.areaLabels) { chart.areaLabels.forEach(function (label) { label.destroy(); }); } chart.areaLabels = []; // Create and add new labels var labelStyle = { color: '#FFFFFF', // White text for better contrast fontWeight: 'bold', fontSize: '12px', padding: 5, borderRadius: 5 }; var labels = [ { text: 'Kuadran 1<br><?php echo $area1Count; ?> Kanwil', x: plotLeft + plotWidth - 10, y: plotTop + 10, align: 'right', verticalAlign: 'top', color: 'rgba(0, 128, 0, 0.7)' // Green with 70% opacity }, { text: 'Kuadran 2<br><?php echo $area2Count; ?> Kanwil', x: plotLeft - 65, y: plotTop + 10, align: 'left', verticalAlign: 'top', color: 'rgba(255, 165, 0, 0.7)' // Orange with 70% opacity }, { text: 'Kuadran 3<br><?php echo $area3Count; ?> Kanwil', x: plotLeft + plotWidth - 10, y: plotTop + plotHeight - 40, align: 'right', verticalAlign: 'bottom', color: 'rgba(255, 165, 0, 0.7)' // Orange with 70% opacity }, { text: 'Kuadran 4<br><?php echo $area4Count; ?> Kanwil', x: plotLeft - 65, y: plotTop + plotHeight - 40, align: 'left', verticalAlign: 'bottom', color: 'rgba(255, 0, 0, 0.7)' // Red with 70% opacity } ]; labels.forEach(function (labelConfig) { var label = renderer.label(labelConfig.text, labelConfig.x, labelConfig.y) .css(labelStyle) .attr({ align: labelConfig.align, zIndex: 6, padding: 5, r: 5, // Border radius fill: labelConfig.color, stroke: '#000000', 'stroke-width': 1 }) .add(); chart.areaLabels.push(label); }); } Highcharts.chart('wpBayar', { chart: { type: 'scatter', plotBorderWidth: 1, zoomType: 'xy', panning: true, panKey: 'shift', events: { load: function () { addAreaLabels(this); }, redraw: function () { addAreaLabels(this); } } }, legend: { enabled: false }, title: { text: '' }, credits: { enabled: false }, accessibility: { point: { valueDescriptionFormat: '{index}. {point.name}, WPbayar: {point.x}%, WPBayarT: {point.y}%, index: {point.z}%.' } }, xAxis: { gridLineWidth: 1, type: 'logarithmic', title: { text: 'WP Bayar' }, labels: { format: '{value:.2f}%' }, accessibility: { rangeDescription: 'Range: 0 to 100 %.' }, plotLines: [{ color: 'red', dashStyle: 'dash', value: <?php echo $nasionalX; ?>, width: 2, zIndex: 3, label: { text: 'WP Bayar - Nasional', align: 'left', style: { color: 'gray' } } }], crosshair: { snap: false } }, yAxis: { startOnTick: false, endOnTick: false, type: 'logarithmic', title: { text: 'WP Bayar Teratur' }, labels: { format: '{value:.2f}%' }, maxPadding: 0.2, accessibility: { rangeDescription: 'Range: 0 to 100 persen.' }, plotLines: [{ color: 'red', dashStyle: 'dash', value: <?php echo $nasionalY; ?>, // Y-value of the Nasional point width: 2, zIndex: 3, label: { text: 'WP Bayar Teratur - Nasional', align: 'right', style: { color: 'gray' } } }], crosshair: { snap: false } }, tooltip: { useHTML: true, headerFormat: '<table style="width:100%; text-align:justify;">', pointFormatter: function () { return '<tr><th colspan="2" style="text-align:center; font-size: 20px; padding-bottom: 5px;">' + this.name + '</th></tr>' + '<tr><td style="font-size: 14px; padding-right: 10px;">%WP Bayar:</td><td style="font-size: 14px; text-align: right;">' + Highcharts.numberFormat(this.x, 2) + '%</td></tr>' + '<tr><td style="font-size: 14px; padding-right: 10px;">%WP Bayar Teratur:</td><td style="font-size: 14px; text-align: right;">' + Highcharts.numberFormat(this.y, 2) + '%</td></tr>' + '<tr><td style="font-size: 14px; padding-right: 10px;">Jumlah WP:</td><td style="font-size: 14px; text-align: right;">' + Highcharts.numberFormat(this.jmlwp, 0, '.', ',') + '</td></tr>' + '<tr><td style="font-size: 14px; padding-right: 10px;">WP Bayar:</td><td style="font-size: 14px; text-align: right;">' + Highcharts.numberFormat(this.wpbyr, 0, '.', ',') + '</td></tr>' + '<tr><td style="font-size: 14px; padding-right: 10px;">WP Bayar Teratur:</td><td style="font-size: 14px; text-align: right;">' + Highcharts.numberFormat(this.wpbyrteratur, 0, '.', ',') + '</td></tr>'; }, footerFormat: '</table>', followPointer: true, style: { fontSize: '14px' }, backgroundColor: 'rgba(255, 255, 255, 0.9)', borderWidth: 1, borderColor: '#AAA', borderRadius: 5, padding: 10 }, plotOptions: { series: { dataLabels: { enabled: true, format: '{point.name}', allowOverlap: true } } }, series: [{ data: <?php echo $dataraporkwl; ?>, colorByPoint: true, point: { events: { click: function () { if (this.name === 'Nasional') { return false; } } } } }], drilldown: { activeDataLabelStyle: { color: '#FFFFFF', textDecoration: 'none', textOutline: '1px #000000' }, breadcrumbs: { position: { align: 'right' }, }, series: <?php echo json_encode($drilldownSeries); ?>, drillUpButton: { position: { align: 'right', y: -10 } } }, }); console.log('Main series data:', <?php echo $dataraporkwl; ?>); console.log('Drilldown series:', <?php echo json_encode($drilldownSeries, JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT); ?>); $(document).ready(function () { $.fn.dataTable.ext.type.order['formatted-num-pre'] = function (data) { var x = data.replace(/[\.%,]/g, ''); return parseFloat(x); }; $('#wpBayarTable').DataTable({ "order": [[2, "desc"]], "columnDefs": [ { "type": "formatted-num", "targets": [2, 3, 4, 5, 6], "render": function (data, type, row) { if (type === 'sort') { return data.replace(/[\.%,]/g, ''); } return data; } } ], "language": { "decimal": ",", "thousands": "." }, "lengthChange": false, "pageLength": -1, "searching": false, "info": false }); }); </script>