feat: tambahkan grafik produk terlaris & kestabilan harga di dashboard admin, hapus fitur verifikasi petani
This commit is contained in:
parent
f01c00fa87
commit
6097b439fc
|
|
@ -7,75 +7,63 @@
|
||||||
use App\Models\Petani;
|
use App\Models\Petani;
|
||||||
use App\Models\Produk;
|
use App\Models\Produk;
|
||||||
use App\Models\Transaksi;
|
use App\Models\Transaksi;
|
||||||
|
use App\Models\DetailTransaksi;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class AdminController extends Controller
|
class AdminController extends Controller
|
||||||
{
|
{
|
||||||
public function dashboard()
|
public function dashboard()
|
||||||
{
|
{
|
||||||
|
// STATISTIK
|
||||||
$totalPetani = Petani::where('status_akun', 'aktif')->count();
|
$totalPetani = Petani::where('status_akun', 'aktif')->count();
|
||||||
$petaniPending = Petani::where('status_akun', 'menunggu')->count();
|
|
||||||
$totalProduk = Produk::count();
|
$totalProduk = Produk::count();
|
||||||
$totalTransaksi = Transaksi::count();
|
$totalTransaksi = Transaksi::count();
|
||||||
|
$transaksiTerbaru = Transaksi::with(['pembeli', 'petani'])->latest()->take(5)->get();
|
||||||
|
|
||||||
$transaksiTerbaru = Transaksi::with(['pembeli', 'petani'])
|
// PRODUK TERLARIS
|
||||||
->latest()
|
$produkTerlaris = Produk::withSum(['detailTransaksis as total_terjual' => function ($query) {
|
||||||
|
$query->whereHas('transaksi', function ($q) {
|
||||||
|
$q->where('status', '!=', 'batal');
|
||||||
|
});
|
||||||
|
}], 'jumlah')
|
||||||
|
->orderByDesc('total_terjual')
|
||||||
->take(5)
|
->take(5)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
$labelTerlaris = $produkTerlaris->pluck('nama_produk');
|
||||||
|
$dataTerlaris = $produkTerlaris->pluck('total_terjual');
|
||||||
|
|
||||||
|
// Menghitung rata-rata harga jual harian selama 7 hari terakhir
|
||||||
|
$hargaStabil = DetailTransaksi::join('transaksis', 'detail_transaksis.transaksi_id', '=', 'transaksis.id')
|
||||||
|
->selectRaw('DATE(transaksis.tanggal_transaksi) as tanggal, AVG(detail_transaksis.harga_satuan) as rata_harga')
|
||||||
|
->where('transaksis.status', '!=', 'batal')
|
||||||
|
->groupBy('tanggal')
|
||||||
|
->orderBy('tanggal', 'asc')
|
||||||
|
->take(7)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$labelHarga = $hargaStabil->pluck('tanggal')->map(function($date) {
|
||||||
|
return \Carbon\Carbon::parse($date)->format('d M');
|
||||||
|
});
|
||||||
|
$dataHarga = $hargaStabil->pluck('rata_harga');
|
||||||
|
|
||||||
return view('admin.dashboard', compact(
|
return view('admin.dashboard', compact(
|
||||||
'totalPetani',
|
'totalPetani', 'totalProduk', 'totalTransaksi', 'transaksiTerbaru',
|
||||||
'petaniPending',
|
'labelTerlaris', 'dataTerlaris', 'labelHarga', 'dataHarga'
|
||||||
'totalProduk',
|
|
||||||
'totalTransaksi',
|
|
||||||
'transaksiTerbaru'
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function monitoring()
|
public function monitoring()
|
||||||
{
|
{
|
||||||
$produks = Produk::with('petani')->latest()->paginate(10);
|
$produks = Produk::with('petani')->latest()->paginate(10);
|
||||||
$transaksis = Transaksi::with(['pembeli', 'petani'])
|
$transaksis = Transaksi::with(['pembeli', 'petani'])->latest()->paginate(10);
|
||||||
->latest()
|
|
||||||
->paginate(10);
|
|
||||||
|
|
||||||
return view('admin.monitoring', compact('produks', 'transaksis'));
|
return view('admin.monitoring', compact('produks', 'transaksis'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transaksiDetail($id)
|
public function transaksiDetail($id)
|
||||||
{
|
{
|
||||||
$transaksi = Transaksi::with(['pembeli', 'petani', 'detailTransaksis.produk'])
|
$transaksi = Transaksi::with(['pembeli', 'petani', 'detailTransaksis.produk'])->findOrFail($id);
|
||||||
->findOrFail($id);
|
|
||||||
|
|
||||||
return view('admin.transaksi_detail', compact('transaksi'));
|
return view('admin.transaksi_detail', compact('transaksi'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function verifikasiIndex()
|
|
||||||
{
|
|
||||||
$petanis = Petani::orderBy('created_at', 'desc')->get();
|
|
||||||
return view('admin.verifikasi.index', compact('petanis'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function verifikasiShow($id)
|
|
||||||
{
|
|
||||||
$petani = Petani::findOrFail($id);
|
|
||||||
return view('admin.verifikasi.show', compact('petani'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function verifikasiApprove($id)
|
|
||||||
{
|
|
||||||
$petani = Petani::findOrFail($id);
|
|
||||||
$petani->status_akun = 'aktif';
|
|
||||||
$petani->save();
|
|
||||||
|
|
||||||
return redirect('admin/verifikasi')->with('success', 'Pendaftaran Petani BERHASIL diterima.');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function verifikasiReject($id)
|
|
||||||
{
|
|
||||||
$petani = Petani::findOrFail($id);
|
|
||||||
$petani->status_akun = 'ditolak';
|
|
||||||
$petani->save();
|
|
||||||
|
|
||||||
return redirect('admin/verifikasi')->with('success', 'Pendaftaran Petani DITOLAK.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ public function checkoutPage(Request $request)
|
||||||
// Mendefinisikan ID Pembeli agar tidak error 'Undefined Variable'
|
// Mendefinisikan ID Pembeli agar tidak error 'Undefined Variable'
|
||||||
$pembeli_id = Auth::guard('pembeli')->id();
|
$pembeli_id = Auth::guard('pembeli')->id();
|
||||||
|
|
||||||
// 1. LOGIKA BELI LANGSUNG (Buy Now)
|
// LOGIKA BELI LANGSUNG (Buy Now)
|
||||||
if ($request->has('produk_id')) {
|
if ($request->has('produk_id')) {
|
||||||
$produk = Produk::with('petani')->findOrFail($request->produk_id);
|
$produk = Produk::with('petani')->findOrFail($request->produk_id);
|
||||||
$items = collect([
|
$items = collect([
|
||||||
|
|
@ -41,7 +41,7 @@ public function checkoutPage(Request $request)
|
||||||
return view('landing.checkout', compact('items', 'total_belanja'));
|
return view('landing.checkout', compact('items', 'total_belanja'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. LOGIKA CHECKOUT DARI KERANJANG (Database)
|
// LOGIKA CHECKOUT DARI KERANJANG (Database)
|
||||||
$cartIds = $request->query('cart_ids');
|
$cartIds = $request->query('cart_ids');
|
||||||
|
|
||||||
if (!$cartIds) {
|
if (!$cartIds) {
|
||||||
|
|
@ -50,7 +50,6 @@ public function checkoutPage(Request $request)
|
||||||
|
|
||||||
$selectedIds = explode(',', $cartIds);
|
$selectedIds = explode(',', $cartIds);
|
||||||
|
|
||||||
// Ambil data dari Tabel Cart yang ID-nya dicentang oleh user
|
|
||||||
$cartItems = Cart::with('produk.petani')
|
$cartItems = Cart::with('produk.petani')
|
||||||
->where('pembeli_id', $pembeli_id)
|
->where('pembeli_id', $pembeli_id)
|
||||||
->whereIn('id', $selectedIds)
|
->whereIn('id', $selectedIds)
|
||||||
|
|
@ -132,7 +131,6 @@ public function prosesCheckout(Request $request)
|
||||||
->where('pembeli_id', $pembeli_id)
|
->where('pembeli_id', $pembeli_id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
// Kelompokkan produk berdasarkan Petani ID agar Invoice terpisah per toko
|
|
||||||
$groupedByPetani = [];
|
$groupedByPetani = [];
|
||||||
foreach ($cartItems as $item) {
|
foreach ($cartItems as $item) {
|
||||||
$groupedByPetani[$item->produk->petani_id][] = $item;
|
$groupedByPetani[$item->produk->petani_id][] = $item;
|
||||||
|
|
@ -144,7 +142,7 @@ public function prosesCheckout(Request $request)
|
||||||
'petani_id' => $petani_id,
|
'petani_id' => $petani_id,
|
||||||
'tanggal_transaksi' => now(),
|
'tanggal_transaksi' => now(),
|
||||||
'alamat_pengiriman' => $request->alamat_pengiriman,
|
'alamat_pengiriman' => $request->alamat_pengiriman,
|
||||||
'total_harga' => 0, // Diupdate setelah menghitung subtotal
|
'total_harga' => 0,
|
||||||
'status' => 'menunggu konfirmasi',
|
'status' => 'menunggu konfirmasi',
|
||||||
'kode_invoice' => 'INV/' . date('Ymd') . '/' . rand(1000, 9999),
|
'kode_invoice' => 'INV/' . date('Ymd') . '/' . rand(1000, 9999),
|
||||||
]);
|
]);
|
||||||
|
|
@ -169,7 +167,6 @@ public function prosesCheckout(Request $request)
|
||||||
$transaksi->update(['total_harga' => $subtotal_transaksi]);
|
$transaksi->update(['total_harga' => $subtotal_transaksi]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// OTOMATIS BERSIHKAN ITEM KERANJANG YANG SUDAH DIBELI
|
|
||||||
Cart::whereIn('id', $cartIds)->delete();
|
Cart::whereIn('id', $cartIds)->delete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,45 +6,27 @@
|
||||||
@section('content')
|
@section('content')
|
||||||
<section class="row">
|
<section class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
|
||||||
|
{{-- STATISTIK ATAS --}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{-- Statistik Petani Aktif --}}
|
<div class="col-6 col-lg-4 col-md-6">
|
||||||
<div class="col-6 col-lg-3 col-md-6">
|
<div class="card shadow-sm">
|
||||||
<div class="card">
|
<div class="card-body px-4 py-4-5">
|
||||||
<div class="card-body px-3 py-4-5">
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
||||||
<div class="stats-icon purple"><i class="bi bi-people-fill"></i></div>
|
<div class="stats-icon purple"><i class="bi bi-people-fill"></i></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<h6 class="text-muted font-semibold">Petani Aktif</h6>
|
<h6 class="text-muted font-semibold">Total Petani</h6>
|
||||||
<h6 class="font-extrabold mb-0">{{ $totalPetani }}</h6>
|
<h6 class="font-extrabold mb-0">{{ $totalPetani }}</h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-6 col-lg-4 col-md-6">
|
||||||
{{-- Statistik Menunggu Verifikasi --}}
|
<div class="card shadow-sm">
|
||||||
<div class="col-6 col-lg-3 col-md-6">
|
<div class="card-body px-4 py-4-5">
|
||||||
<div class="card">
|
|
||||||
<div class="card-body px-3 py-4-5">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
|
||||||
<div class="stats-icon red"><i class="bi bi-person-plus-fill"></i></div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-8">
|
|
||||||
<h6 class="text-muted font-semibold">Verifikasi Masuk</h6>
|
|
||||||
<h6 class="font-extrabold mb-0">{{ $petaniPending }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{-- Statistik Total Produk --}}
|
|
||||||
<div class="col-6 col-lg-3 col-md-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body px-3 py-4-5">
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
||||||
<div class="stats-icon green"><i class="bi bi-basket-fill"></i></div>
|
<div class="stats-icon green"><i class="bi bi-basket-fill"></i></div>
|
||||||
|
|
@ -57,11 +39,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-12 col-lg-4 col-md-12">
|
||||||
{{-- Statistik Total Transaksi --}}
|
<div class="card shadow-sm">
|
||||||
<div class="col-6 col-lg-3 col-md-6">
|
<div class="card-body px-4 py-4-5">
|
||||||
<div class="card">
|
|
||||||
<div class="card-body px-3 py-4-5">
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
||||||
<div class="stats-icon blue"><i class="bi bi-receipt"></i></div>
|
<div class="stats-icon blue"><i class="bi bi-receipt"></i></div>
|
||||||
|
|
@ -76,14 +56,41 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- Tabel Ringkasan Transaksi --}}
|
{{-- AREA GRAFIK BERSEBELAHAN --}}
|
||||||
|
<div class="row mb-4">
|
||||||
|
{{-- Kiri: Grafik Produk Terlaris --}}
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="card-title mb-0"><i class="bi bi-bar-chart-fill text-primary me-2"></i>Produk Terlaris</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body mt-3">
|
||||||
|
<canvas id="chartTerlaris" style="max-height: 300px;"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Kanan: Grafik Kestabilan Harga --}}
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="card-title mb-0"><i class="bi bi-graph-up text-success me-2"></i>Kestabilan Harga Jual Petani</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body mt-3">
|
||||||
|
<canvas id="chartHarga" style="max-height: 300px;"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- TABEL TRANSAKSI TERBARU (SAMA SEPERTI SEBELUMNYA) --}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card shadow-sm">
|
||||||
<div class="card-header">
|
<div class="card-header bg-white border-bottom">
|
||||||
<h4>Transaksi Terbaru di Platform</h4>
|
<h5 class="mb-0">Transaksi Terbaru di Platform</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body mt-3">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover align-middle">
|
<table class="table table-hover align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
@ -102,20 +109,12 @@
|
||||||
<td class="fw-bold text-primary">#{{ $trx->kode_invoice }}</td>
|
<td class="fw-bold text-primary">#{{ $trx->kode_invoice }}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex flex-column">
|
<div class="d-flex flex-column">
|
||||||
<span class="fw-bold text-dark">
|
<span class="fw-bold text-dark">{{ $trx->petani->nama_lengkap ?? 'Petani Tidak Ditemukan' }}</span>
|
||||||
{{ $trx->petani->nama_lengkap ?? 'Petani Tidak Ditemukan' }}
|
<small class="text-muted"><i class="bi bi-shop me-1"></i>{{ $trx->petani->nama_usaha ?? '-' }}</small>
|
||||||
</span>
|
|
||||||
<small class="text-muted" style="font-size: 0.85em;">
|
|
||||||
<i class="bi bi-shop me-1"></i>
|
|
||||||
{{ $trx->petani->nama_usaha ?? '-' }}
|
|
||||||
</small>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>{{ $trx->pembeli->nama_lengkap ?? 'Guest' }}</td>
|
<td>{{ $trx->pembeli->nama_lengkap ?? 'Guest' }}</td>
|
||||||
|
|
||||||
<td class="fw-bold">Rp {{ number_format($trx->total_harga, 0, ',', '.') }}</td>
|
<td class="fw-bold">Rp {{ number_format($trx->total_harga, 0, ',', '.') }}</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
@php
|
@php
|
||||||
$badgeClass = match ($trx->status) {
|
$badgeClass = match ($trx->status) {
|
||||||
|
|
@ -127,30 +126,18 @@
|
||||||
default => 'bg-secondary',
|
default => 'bg-secondary',
|
||||||
};
|
};
|
||||||
@endphp
|
@endphp
|
||||||
<span class="badge {{ $badgeClass }} rounded-pill px-3">
|
<span class="badge {{ $badgeClass }} rounded-pill px-3">{{ ucwords($trx->status) }}</span>
|
||||||
{{ ucwords($trx->status) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="text-muted small">{{ $trx->created_at->format('d M Y') }}</td>
|
<td class="text-muted small">{{ $trx->created_at->format('d M Y') }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr><td colspan="6" class="text-center py-4 text-muted">Belum ada transaksi baru.</td></tr>
|
||||||
<td colspan="6" class="text-center py-4 text-muted">
|
|
||||||
<div class="d-flex flex-column align-items-center">
|
|
||||||
<i class="bi bi-inbox fs-1 mb-2"></i>
|
|
||||||
Belum ada transaksi baru.
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mt-3">
|
<div class="text-center mt-3">
|
||||||
<a href="{{ route('admin.monitoring') }}" class="btn btn-sm btn-primary">
|
<a href="{{ route('admin.monitoring') }}" class="btn btn-sm btn-primary">Lihat Semua Data</a>
|
||||||
Lihat Semua Data
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -159,3 +146,128 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@section('js')
|
||||||
|
{{-- Load library Chart.js --}}
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const labelTerlarisAsli = {!! json_encode($labelTerlaris) !!};
|
||||||
|
const dataTerlaris = {!! json_encode($dataTerlaris) !!};
|
||||||
|
|
||||||
|
const labelMultiline = labelTerlarisAsli.map(function(label) {
|
||||||
|
const words = label.split(' ');
|
||||||
|
const lines = [];
|
||||||
|
let currentLine = '';
|
||||||
|
|
||||||
|
words.forEach(word => {
|
||||||
|
if ((currentLine + word).length > 15 && currentLine !== '') {
|
||||||
|
lines.push(currentLine.trim());
|
||||||
|
currentLine = word + ' ';
|
||||||
|
} else {
|
||||||
|
currentLine += word + ' ';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lines.push(currentLine.trim());
|
||||||
|
return lines;
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- GRAFIK PRODUK TERLARIS ---
|
||||||
|
const ctxTerlaris = document.getElementById('chartTerlaris').getContext('2d');
|
||||||
|
new Chart(ctxTerlaris, {
|
||||||
|
type: 'bar',
|
||||||
|
|
||||||
|
data: {
|
||||||
|
labels: labelMultiline,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Total Terjual',
|
||||||
|
data: dataTerlaris,
|
||||||
|
backgroundColor: 'rgba(129, 196, 8, 0.8)',
|
||||||
|
borderColor: '#81c408',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 4
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: { display: false },
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
title: function(context) {
|
||||||
|
return labelTerlarisAsli[context[0].dataIndex];
|
||||||
|
},
|
||||||
|
label: function(context) {
|
||||||
|
return context.raw + ' Kg';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
ticks: {
|
||||||
|
maxRotation: 0,
|
||||||
|
autoSkip: false,
|
||||||
|
font: { size: 12 }
|
||||||
|
},
|
||||||
|
grid: { display: false }
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
ticks: { stepSize: 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- GRAFIK KESTABILAN HARGA ---
|
||||||
|
const ctxHarga = document.getElementById('chartHarga').getContext('2d');
|
||||||
|
new Chart(ctxHarga, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: {!! json_encode($labelHarga) !!},
|
||||||
|
datasets: [{
|
||||||
|
label: 'Rata-rata Harga',
|
||||||
|
data: {!! json_encode($dataHarga) !!},
|
||||||
|
backgroundColor: 'rgba(54, 162, 235, 0.1)',
|
||||||
|
borderColor: '#36A2EB',
|
||||||
|
borderWidth: 2,
|
||||||
|
pointBackgroundColor: '#fff',
|
||||||
|
pointBorderColor: '#36A2EB',
|
||||||
|
pointBorderWidth: 2,
|
||||||
|
pointRadius: 4,
|
||||||
|
tension: 0.4,
|
||||||
|
fill: true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: { display: false },
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
label: function(context) {
|
||||||
|
return 'Rp ' + context.raw.toLocaleString('id-ID');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
grid: { display: false }
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
beginAtZero: false,
|
||||||
|
ticks: {
|
||||||
|
callback: function(value) { return 'Rp ' + value.toLocaleString('id-ID'); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endsection
|
||||||
Loading…
Reference in New Issue