From 8b21fab8b8a7842da7f700b6adbb034f1daba9c8 Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Fri, 7 Aug 2026 12:59:25 +0700 Subject: [PATCH 1/3] dashboard indeks petani --- .../Web/Dashboard/IndeksPetaniController.php | 59 ++++- app/Models/Pertanian/Petani.php | 6 +- .../views/dashboard/indeks-petani.blade.php | 232 +++++++++++++++++- 3 files changed, 288 insertions(+), 9 deletions(-) diff --git a/app/Http/Controllers/Web/Dashboard/IndeksPetaniController.php b/app/Http/Controllers/Web/Dashboard/IndeksPetaniController.php index 4918838..fcf0889 100644 --- a/app/Http/Controllers/Web/Dashboard/IndeksPetaniController.php +++ b/app/Http/Controllers/Web/Dashboard/IndeksPetaniController.php @@ -106,6 +106,59 @@ class IndeksPetaniController extends Controller avg(skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar) as skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar") ->first(); + $desaKelurahan = Petani::query() + ->join('master_desa_kelurahan', 'petani.desa_kelurahan_id', '=', 'master_desa_kelurahan.id') + ->join('master_kecamatan', 'master_desa_kelurahan.kecamatan_id', '=', 'master_kecamatan.id') + ->join('master_kabupaten_kota', 'master_kecamatan.kabupaten_kota_id', '=', 'master_kabupaten_kota.id') + ->join('master_provinsi', 'master_kabupaten_kota.provinsi_id', '=', 'master_provinsi.id') + ->selectRaw(" + master_desa_kelurahan.id as desa_kelurahan_id, + master_desa_kelurahan.nama as desa_kelurahan, + master_desa_kelurahan.path as path, + master_kecamatan.id as kecamatan_id, + master_kecamatan.nama as kecamatan, + master_kabupaten_kota.id as kabupaten_id, + master_kabupaten_kota.nama as kabupaten, + master_provinsi.id as provinsi_id, + master_provinsi.nama as provinsi + ") + ->whereIn('petani.id', $petani) + ->distinct() + ->get(); + + $mapSegmentasi = SkorPetani::query() + ->join('petani', 'petani_skor.petani_id', '=', 'petani.id') + ->selectRaw("petani.desa_kelurahan_id, + $case AS segmen, + COUNT(petani.id) AS total + ") + ->whereIn('petani_skor.petani_id', $petani) + ->groupBy('petani.desa_kelurahan_id') + ->groupByRaw($case) + ->get(); + + $mapAvgSkorSegmentasi = SkorPetani::query() + ->join('petani', 'petani_skor.petani_id', '=', 'petani.id') + ->selectRaw("petani.desa_kelurahan_id, + COUNT(petani.id) AS jumlah_petani, + avg(skor_kesiapan_adopsi) AS skor, + CASE + WHEN AVG(skor_kesiapan_adopsi) >= 4 THEN 'Penggerak' + WHEN AVG(skor_kesiapan_adopsi) >= 3 THEN 'Perintis' + WHEN AVG(skor_kesiapan_adopsi) >= 2 THEN 'Pemerhati' + WHEN AVG(skor_kesiapan_adopsi) >= 1 THEN 'Pemula' + ELSE 'Belum Lengkap' + END AS segmen + ") + ->whereIn('petani_skor.petani_id', $petani) + ->groupBy('petani.desa_kelurahan_id') + ->get(); + + $daftarPetani = Petani::query() + ->whereIn('id', $petani) + ->whereIn('komoditas_id', $komoditas->pluck('id')) + ->get(); + return view('dashboard.indeks-petani', compact( 'komoditas', 'countPetani', @@ -119,7 +172,11 @@ class IndeksPetaniController extends Controller 'countSegmentasi', 'countSegmentasiByKomoditas', 'avgDimensi', - 'avgKomponen' + 'avgKomponen', + 'desaKelurahan', + 'mapSegmentasi', + 'mapAvgSkorSegmentasi', + 'daftarPetani', )); } } \ No newline at end of file diff --git a/app/Models/Pertanian/Petani.php b/app/Models/Pertanian/Petani.php index a44bb2e..e7053e0 100644 --- a/app/Models/Pertanian/Petani.php +++ b/app/Models/Pertanian/Petani.php @@ -339,7 +339,7 @@ class Petani extends Model $skor >= 3.0 => 'Perintis', $skor >= 2.0 => 'Pemerhati', $skor >= 1.0 => 'Pemula', - default => 'Belum tersegmentasi', + default => 'Belum lengkap', }; } @@ -365,10 +365,10 @@ class Petani extends Model } elseif ($skor->skor_kesiapan_adopsi >= 1.0) { return 'Pemula'; } else { - return 'Belum tersegmentasi'; + return 'Belum lengkap'; } - return 'Belum tersegmentasi'; + return 'Belum lengkap'; } public function keteranganSegmen(): ?string diff --git a/resources/views/dashboard/indeks-petani.blade.php b/resources/views/dashboard/indeks-petani.blade.php index edb5c88..5d7bbf0 100644 --- a/resources/views/dashboard/indeks-petani.blade.php +++ b/resources/views/dashboard/indeks-petani.blade.php @@ -1,5 +1,11 @@ @extends('layout.main') +@push('style') + +@endpush + @section('content') @php $segments = [ @@ -33,6 +39,7 @@ $colors = collect($segments) ->pluck('color') ->map(fn($c) => "var(--bs-{$c})") ->values(); +$segmentStyles = collect($segments)->keyBy('name'); $countSegmentasi = $countSegmentasi->keyBy('segmen'); $seriesSegmentasi = collect($segments)->map(function ($segment) use ($countSegmentasi) { @@ -55,6 +62,34 @@ $seriesSegmentasiKomoditas = collect($segments)->map(function ($segment) use ($c ]; })->values(); + +$segmenDominan = $mapSegmentasi + ->groupBy('desa_kelurahan_id') + ->map(function ($items) { + return $items->sortByDesc('total')->first(); + }); + +$mapAvgSkorSegmentasi->each(function ($item) use ($segmenDominan) { + $dominan = $segmenDominan->get($item->desa_kelurahan_id); + + $item->segmen_dominan = $dominan?->segmen; + $item->jumlah_dominan = $dominan?->total; +}); + +$segmentasiByDesa = $mapAvgSkorSegmentasi->keyBy('desa_kelurahan_id'); +$desaLookup = $desaKelurahan->keyBy('desa_kelurahan_id'); + +$mapDesaSegmentasi = $segmentasiByDesa->map(function ($segmentasi, $desaId) use ($desaLookup) { + $desa = $desaLookup->get($desaId); + + if (!$desa) { + return null; + } + + $desa->segmentasi = $segmentasi; + + return $desa; +})->filter()->values(); @endphp
@@ -203,7 +238,7 @@ $seriesSegmentasiKomoditas = collect($segments)->map(function ($segment) use ($c
-
+
Rata-rata Dimensi Kesiapan Adopsi
@@ -227,7 +262,7 @@ $seriesSegmentasiKomoditas = collect($segments)->map(function ($segment) use ($c
-
+
Rata-rata Komponen Kesiapan Adopsi
@@ -260,12 +295,124 @@ $seriesSegmentasiKomoditas = collect($segments)->map(function ($segment) use ($c
+ +
+
+
+
+
+
Sebaran Segmentasi Petani
+

berdasarkan sebaran wilayah untuk semua komoditas

+
+
+
+
+ *klik pada desa untuk menampilkan detail informasi dan menyaring daftar petani +
+
+
+
+
+
+
+
Distribusi Segmentasi Petani
+

berdasarkan sebaran wilayah untuk semua komoditas

+
+
+
+ + + + + + + + + + + @foreach ($mapDesaSegmentasi as $desa) + @php + $style = $segmentStyles[$desa->segmentasi->segmen] ?? null; + $styleDominan = $segmentStyles[$desa->segmentasi->segmen_dominan] ?? null; + @endphp + + + + + + + @endforeach + +
Desa/KelurahanPetaniSegmen Rata-rataSegmen Dominan
{{ $desa->desa_kelurahan }}{{ number_format($desa->segmentasi->jumlah_petani) }} + + {{ $desa->segmentasi->segmen }} + + ({{ number_format($desa->segmentasi->skor, 2, ',', '.') }}) + + + {{ $desa->segmentasi->segmen_dominan }} + + ({{ number_format($desa->segmentasi->jumlah_dominan) }} petani) +
+
+
+
+
+ +
+
+
+
+
+
Daftar Petani
+

untuk semua komoditas

+
+
+
+ + + + + + + + + + + + @foreach ($daftarPetani as $item) + @php + $style = $segmentStyles[$item->segmen()] ?? null; + @endphp + + + + + + + + @endforeach + +
Nama PetaniKomoditasLuas Lahan (ha)Indeks Kesiapan AdopsiSegmen
{{ $item->nama }}{{ $item->komoditas?->nama }}{{ number_format($item->lahans?->sum('luas_lahan'), 2, ',', '.') }}{{ $item->skor ? number_format($item->skor?->skor_kesiapan_adopsi, 2, ',', '.') : '' }} + @if ($item->skor) + + {{ $item->segmen() }} + + @endif +
+
+
+
+
@endsection @push('scripts') + @endpush \ No newline at end of file From 946fabb9a51f6858b09da3e22449359d0e6e7b70 Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Fri, 7 Aug 2026 14:17:06 +0700 Subject: [PATCH 2/3] lahan skor has petani --- .../Web/Dashboard/IndeksPetaniController.php | 22 ++++++------------- app/Models/Pertanian/Lahan.php | 3 ++- app/Models/Pertanian/SkorPetani.php | 8 +++++++ 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/Web/Dashboard/IndeksPetaniController.php b/app/Http/Controllers/Web/Dashboard/IndeksPetaniController.php index fcf0889..798f856 100644 --- a/app/Http/Controllers/Web/Dashboard/IndeksPetaniController.php +++ b/app/Http/Controllers/Web/Dashboard/IndeksPetaniController.php @@ -26,7 +26,7 @@ class IndeksPetaniController extends Controller $komoditas = Komoditas::where('is_utama', true)->get(); $petani = Petani::pluck('id'); - $lahan = Lahan::whereIn('petani_id', $petani)->get(); + $lahan = Lahan::has('petani')->get(); $case = " CASE @@ -38,14 +38,13 @@ class IndeksPetaniController extends Controller END "; - $countPetani = Petani::whereIn('id', $petani)->count(); - $countKomoditas = Petani::whereIn('id', $petani)->whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('komoditas_id'); - $sumLahan = Lahan::whereIn('petani_id', $petani)->whereIn('komoditas_id', $komoditas->pluck('id'))->sum('luas_lahan'); - $avgLahan = Lahan::whereIn('petani_id', $petani)->whereIn('komoditas_id', $komoditas->pluck('id'))->avg('luas_lahan'); + $countPetani = Petani::count(); + $countKomoditas = Petani::whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('komoditas_id'); + $sumLahan = Lahan::has('petani')->whereIn('komoditas_id', $komoditas->pluck('id'))->sum('luas_lahan'); + $avgLahan = Lahan::has('petani')->whereIn('komoditas_id', $komoditas->pluck('id'))->avg('luas_lahan'); $avgSkor = SkorPetani::query() ->join('petani', 'petani_skor.petani_id', '=', 'petani.id') - ->whereIn('petani_id', $petani) ->whereIn('petani.komoditas_id', $komoditas->pluck('id')) ->avg('skor_kesiapan_adopsi'); @@ -61,14 +60,13 @@ class IndeksPetaniController extends Controller $avgSegmen = 'Belum Lengkap'; } - $countDesa = Petani::whereIn('id', $petani)->whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('desa_kelurahan_id'); - $countKecamatan = Petani::whereIn('petani.id', $petani) + $countDesa = Petani::whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('desa_kelurahan_id'); + $countKecamatan = Petani::query() ->join('master_desa_kelurahan', 'petani.desa_kelurahan_id', '=', 'master_desa_kelurahan.id') ->join('master_kecamatan', 'master_desa_kelurahan.kecamatan_id', '=', 'master_kecamatan.id') ->whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('master_kecamatan.id'); $countSegmentasi = SkorPetani::selectRaw("$case AS segmen, COUNT(*) AS total") - ->whereIn('petani_id', $petani) ->groupByRaw($case) ->get(); @@ -79,14 +77,12 @@ class IndeksPetaniController extends Controller $case AS segmen, COUNT(petani.id) AS total ") - ->whereIn('petani_skor.petani_id', $petani) ->groupBy('petani.komoditas_id') ->groupByRaw($case) ->get(); $avgDimensi = SkorPetani::query() ->join('petani', 'petani_skor.petani_id', '=', 'petani.id') - ->whereIn('petani_id', $petani) ->whereIn('petani.komoditas_id', $komoditas->pluck('id')) ->selectRaw(" avg(skor_d2_sistem_praktik_budidaya) as skor_d2_sistem_praktik_budidaya, @@ -96,7 +92,6 @@ class IndeksPetaniController extends Controller $avgKomponen = SkorPetani::query() ->join('petani', 'petani_skor.petani_id', '=', 'petani.id') - ->whereIn('petani_id', $petani) ->whereIn('petani.komoditas_id', $komoditas->pluck('id')) ->selectRaw("avg(skor_komp_1_d4_k3_motivasi_kapasitas_adopsi) as skor_komp_1_d4_k3_motivasi_kapasitas_adopsi, avg(skor_komp_2_d4_k2_ekonomi_rumah_tangga) as skor_komp_2_d4_k2_ekonomi_rumah_tangga, @@ -132,7 +127,6 @@ class IndeksPetaniController extends Controller $case AS segmen, COUNT(petani.id) AS total ") - ->whereIn('petani_skor.petani_id', $petani) ->groupBy('petani.desa_kelurahan_id') ->groupByRaw($case) ->get(); @@ -150,12 +144,10 @@ class IndeksPetaniController extends Controller ELSE 'Belum Lengkap' END AS segmen ") - ->whereIn('petani_skor.petani_id', $petani) ->groupBy('petani.desa_kelurahan_id') ->get(); $daftarPetani = Petani::query() - ->whereIn('id', $petani) ->whereIn('komoditas_id', $komoditas->pluck('id')) ->get(); diff --git a/app/Models/Pertanian/Lahan.php b/app/Models/Pertanian/Lahan.php index 8021c23..fc18aca 100644 --- a/app/Models/Pertanian/Lahan.php +++ b/app/Models/Pertanian/Lahan.php @@ -18,6 +18,7 @@ use App\Enums\KondisiTanaman; use App\Enums\SeranganHama; use App\Enums\PenyakitTanaman; use App\Enums\KeparahanSerangan; +use App\Models\Pertanian\Petani; class Lahan extends Model { @@ -98,7 +99,7 @@ class Lahan extends Model public function petani(): BelongsTo { - return $this->belongsTo(Profile::class, 'petani_id'); + return $this->belongsTo(Petani::class, 'petani_id'); } public function komoditas(): BelongsTo diff --git a/app/Models/Pertanian/SkorPetani.php b/app/Models/Pertanian/SkorPetani.php index b1482bc..3d2fb0a 100644 --- a/app/Models/Pertanian/SkorPetani.php +++ b/app/Models/Pertanian/SkorPetani.php @@ -4,6 +4,9 @@ namespace App\Models\Pertanian; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Database\Eloquent\Relations\BelongsTo; + +use App\Models\Pertanian\Petani; class SkorPetani extends Model { @@ -139,4 +142,9 @@ class SkorPetani extends Model ); }); } + + public function petani(): BelongsTo + { + return $this->belongsTo(Petani::class, 'petani_id'); + } } From 04387268cdaac751b393cd3c89d1bdcb8654152d Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Fri, 7 Aug 2026 14:31:16 +0700 Subject: [PATCH 3/3] indeks petani --- resources/views/dashboard/indeks-petani.blade.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/resources/views/dashboard/indeks-petani.blade.php b/resources/views/dashboard/indeks-petani.blade.php index 5d7bbf0..36e4688 100644 --- a/resources/views/dashboard/indeks-petani.blade.php +++ b/resources/views/dashboard/indeks-petani.blade.php @@ -373,6 +373,7 @@ $mapDesaSegmentasi = $segmentasiByDesa->map(function ($segmentasi, $desaId) use Nama Petani + Desa/Kelurahan Komoditas Luas Lahan (ha) Indeks Kesiapan Adopsi @@ -386,6 +387,7 @@ $mapDesaSegmentasi = $segmentasiByDesa->map(function ($segmentasi, $desaId) use @endphp {{ $item->nama }} + {{ $item->desaKelurahan?->nama }} {{ $item->komoditas?->nama }} {{ number_format($item->lahans?->sum('luas_lahan'), 2, ',', '.') }} {{ $item->skor ? number_format($item->skor?->skor_kesiapan_adopsi, 2, ',', '.') : '' }} @@ -426,6 +428,18 @@ $mapDesaSegmentasi = $segmentasiByDesa->map(function ($segmentasi, $desaId) use "scrollX": true }); + var tableDesa = $('#table-desa').DataTable({ + "paging": true, + "lengthChange": false, + "searching": false, + "ordering": true, + "info": false, + "autoWidth": false, + "responsive": false, + "scrollX": true, + "pageLength": 5, + }); + var tablePetani = $('#table-petani').DataTable({ "paging": true, "lengthChange": true,