Menambahkan Fitur Dashboard Analytics & Grafik Interaktif di Yii2
Setelah berhasil membangun fitur pengelolaan data dasar (CRUD), integrasi API eksternal via Guzzle, dan ekspor laporan PDF pada tahap sebelumnya, kebutuhan tingkat lanjut berikutnya adalah Dashboard Analytics.
Manajemen perusahaan biasanya memerlukan ringkasan visual untuk mengambil keputusan secara cepat tanpa harus membaca tabel data yang panjang.
Pada bagian lanjutan ini, kita akan menambahkan Dashboard Analistik Ringkas yang menampilkan:
-
Kartu Statistik Kunci (KPI Cards): Total Produk, Total Stok, dan Total Nilai Aset Inventaris (dalam IDR).
-
Grafik Interaktif (Chart): Visualisasi Top 5 Produk dengan Stok Terbanyak menggunakan modul Composer
kartik-v/yii2-widgetsatau pustaka ChartJS.
Susunan Judul Pengembangan Fitur Dashboard
-
Persiapan & Instalasi Modul Widget via Composer
-
Membuat Controller Khusus Dashboard (
DashboardController) -
Membangun Query Statistik di Model (
Produk.php) -
Membuat Tampilan Dashboard dengan Card & ChartJS
-
Menghubungkan Dashboard ke Menu Navigasi Utama
1. Persiapan & Instalasi Modul Widget via Composer
Kita akan memanfaatkan Chart.js (via CDN/Asset) serta ikon Bootstrap bawaan Yii2 untuk mempercantik tampilan ringkasan.
Pastikan dependensi utama sudah terpasang. Jika ingin menggunakan pustaka helper widget dari Kartik, kamu bisa menginstalnya via Composer:
Bash
composer require kartik-v/yii2-widgets
2. Membangun Query Statistik di Model (models/Produk.php)
Buka kembali berkas models/Produk.php dan tambahkan method-method pembantu (helper methods) untuk menghitung total statistik inventaris:
PHP
<?php
namespace app\models;
use Yii;
use yii\db\ActiveRecord;
class Produk extends ActiveRecord
{
// ... (kode method sebelumnya: getKursUsdToIdr, getHargaRupiah, dll) ...
/**
* Menghitung total varian produk yang terdaftar
*/
public static function getTotalProduk(): int
{
return (int) self::find()->count();
}
/**
* Menghitung jumlah akumulasi seluruh stok di gudang
*/
public static function getTotalStok(): int
{
return (int) self::find()->sum('stok');
}
/**
* Menghitung total nilai aset gudang dalam Rupiah
*/
public static function getTotalNilaiAsetRupiah(): float
{
$allProduk = self::find()->all();
$total = 0;
foreach ($allProduk as $item) {
$total += ($item->harga_usd * $item->stok);
}
return $total * self::getKursUsdToIdr();
}
/**
* Mengambil 5 produk dengan stok terbanyak untuk grafik
*/
public static function getTopStokProduk(int $limit = 5): array
{
return self::find()
->orderBy(['stok' => SORT_DESC])
->limit($limit)
->all();
}
}
3. Membuat Controller Khusus Dashboard (controllers/DashboardController.php)
Buat berkas baru bernama DashboardController.php di dalam folder controllers/:
PHP
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\Produk;
class DashboardController extends Controller
{
/**
* Menampilkan halaman utama Dashboard Analytics
*/
public function actionIndex()
{
// 1. Ambil data agregat statistik
$totalProduk = Produk::getTotalProduk();
$totalStok = Produk::getTotalStok();
$totalAset = Produk::getTotalNilaiAsetRupiah();
$kurs = Produk::getKursUsdToIdr();
// 2. Ambil data top 5 produk untuk chart
$topProduk = Produk::getTopStokProduk(5);
$chartLabels = [];
$chartData = [];
foreach ($topProduk as $p) {
$chartLabels[] = $p->nama_produk;
$chartData[] = $p->stok;
}
// 3. Render ke View
return $this->render('index', [
'totalProduk' => $totalProduk,
'totalStok' => $totalStok,
'totalAset' => $totalAset,
'kurs' => $kurs,
'chartLabels' => $chartLabels,
'chartData' => $chartData,
]);
}
}
4. Membuat Tampilan Dashboard (views/dashboard/index.php)
Buat folder baru views/dashboard/ dan buat berkas index.php di dalamnya. Kita akan menggunakan Chart.js via CDN untuk membuat grafik batang interaktif:
PHP
<?php
use yii\helpers\Html;
/* @var $this yii\web\View */
$this->title = 'Dashboard Analytics Inventaris';
$this->params['breadcrumbs'][] = $this->title;
// Load Chart.js CDN
$this->registerJsFile('https://cdn.jsdelivr.net/npm/chart.js', ['position' => \yii\web\View::POS_HEAD]);
?>
<div class="dashboard-index">
<h1><?= Html::encode($this->title) ?></h1>
<p class="text-muted">Ringkasan kondisi inventaris gudang dan estimasi nilai aset secara real-time.</p>
<hr>
<!-- BARIS 1: KARTU KPI STATISTIK -->
<div class="row style-cards" style="margin-bottom: 30px;">
<div class="col-md-4">
<div class="panel panel-primary" style="border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
<div class="panel-heading" style="border-top-left-radius: 8px; border-top-right-radius: 8px;">
<h3 class="panel-title">Total Jenis Produk</h3>
</div>
<div class="panel-body text-center">
<h2 style="font-size: 36px; margin: 0; font-weight: bold; color: #337ab7;"><?= number_format($totalProduk) ?></h2>
<span class="text-muted">Varian Item Terdaftar</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-success" style="border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
<div class="panel-heading" style="border-top-left-radius: 8px; border-top-right-radius: 8px;">
<h3 class="panel-title">Total Stok Fisik Gudang</h3>
</div>
<div class="panel-body text-center">
<h2 style="font-size: 36px; margin: 0; font-weight: bold; color: #3c763d;"><?= number_format($totalStok) ?></h2>
<span class="text-muted">Unit Barang Available</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-warning" style="border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
<div class="panel-heading" style="border-top-left-radius: 8px; border-top-right-radius: 8px;">
<h3 class="panel-title">Estimasi Nilai Aset (IDR)</h3>
</div>
<div class="panel-body text-center">
<h2 style="font-size: 24px; margin: 5px 0; font-weight: bold; color: #8a6d3b;">Rp <?= number_format($totalAset, 0, ',', '.') ?></h2>
<span class="text-muted">Kurs Real-time: 1 USD = Rp <?= number_format($kurs, 0, ',', '.') ?></span>
</div>
</div>
</div>
</div>
<!-- BARIS 2: GRAFIK INTERAKTIF CHART.JS -->
<div class="row">
<div class="col-md-12">
<div class="panel panel-default" style="border-radius: 8px; padding: 20px;">
<div class="panel-heading" style="background: none; border-bottom: 2px solid #eee;">
<h4 class="panel-title" style="font-weight: bold;">Top 5 Produk Stok Terbanyak</h4>
</div>
<div class="panel-body">
<canvas id="stokChart" height="100"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- SCRIPT UNTUK INSIALISASI CHART.JS -->
<?php
$labelsJson = json_encode($chartLabels);
$dataJson = json_encode($chartData);
$js = <<<JS
const ctx = document.getElementById('stokChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: $labelsJson,
datasets: [{
label: 'Jumlah Stok Unit',
data: $dataJson,
backgroundColor: 'rgba(54, 162, 235, 0.6)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
ticks: {
precision: 0
}
}
}
}
});
JS;
$this->registerJs($js);
?>
5. Menghubungkan Dashboard ke Menu Navigasi Utama
Buka berkas layout utama di views/layouts/main.php dan tambahkan menu navigasi Dashboard ke dalam daftar Nav::widget:
PHP
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => [
['label' => 'Dashboard', 'url' => ['/dashboard/index']], // Menu baru
['label' => 'Inventaris Produk', 'url' => ['/produk/index']],
['label' => 'Kontak', 'url' => ['/site/contact']],
Yii::$app->user->isGuest ? (
['label' => 'Login', 'url' => ['/site/login']]
) : (
'<li>'
. Html::beginForm(['/site/logout'], 'post')
. Html::submitButton(
'Logout (' . Yii::$app->user->identity->username . ')',
['class' => 'btn btn-link logout']
)
. Html::endForm()
. '</li>'
)
],
]);
Uji Coba Dashboard Analytics
-
Jalankan aplikasi Yii2 di server lokal:
Bashphp yii serve -
Buka URL:
http://localhost:8080/index.php?r=dashboard -
Kamu akan melihat tampilan dashboard visual yang berisi:
-
3 Kartu KPI: Jumlah Produk, Total Stok Unit, dan Total Nilai Aset IDR yang dihitung dinamis.
-
Grafik Batang Interaktif: Menampilkan 5 barang dengan persediaan stok tertinggi secara otomatis.
-
Kesimpulan
Aplikasi Sistem Inventaris Yii2 milik kita kini telah menjadi sebuah Sistem Aplikasi Web Enterprise Utuh yang memiliki:
-
CRUD & Search GridView (di-generate oleh Gii).
-
Integrasi API External Real-time (via Guzzle Composer).
-
Fitur Cetak Laporan PDF (via mPDF Composer).
-
Dashboard Analytics & Visualisasi Grafik (via Chart.js).



