From 6f6eabcaeff2fe159f13526c7cc57cb75188f94b Mon Sep 17 00:00:00 2001 From: MufridaFaraDiani27 Date: Fri, 29 May 2026 13:23:40 +0700 Subject: [PATCH] laporan tahunan --- app/Http/Controllers/LaporanController.php | 429 ++++++++++-- resources/views/laporan/tahunan.blade.php | 647 ++++++++++++++++-- .../10ee49aecb46b4eac9b0217a359f795e.php | 5 + .../5fd932f7a53f435288301570d161158b.php | 377 ---------- .../7ac7144038b7ed595f7947eb2e474209.php | 605 ++++++++++++++++ .../83200b6ca19a8da36ba75ad680d43e19.php | 222 ------ .../ab3ba8940f81b3715d18ea258bfa635c.php | 340 +++++++++ .../da4c8b215347ddbbfe979485d71927be.php | 354 ---------- .../fb843eb1366f55ecbc0d64d0bcaf77ad.php | 229 ------- .../fe5b23b6d58765df42d452d1a22bfa55.php | 35 + 10 files changed, 1939 insertions(+), 1304 deletions(-) create mode 100644 storage/framework/views/10ee49aecb46b4eac9b0217a359f795e.php delete mode 100644 storage/framework/views/5fd932f7a53f435288301570d161158b.php create mode 100644 storage/framework/views/7ac7144038b7ed595f7947eb2e474209.php delete mode 100644 storage/framework/views/83200b6ca19a8da36ba75ad680d43e19.php create mode 100644 storage/framework/views/ab3ba8940f81b3715d18ea258bfa635c.php delete mode 100644 storage/framework/views/da4c8b215347ddbbfe979485d71927be.php delete mode 100644 storage/framework/views/fb843eb1366f55ecbc0d64d0bcaf77ad.php create mode 100644 storage/framework/views/fe5b23b6d58765df42d452d1a22bfa55.php diff --git a/app/Http/Controllers/LaporanController.php b/app/Http/Controllers/LaporanController.php index 5666d2e..7ba8316 100644 --- a/app/Http/Controllers/LaporanController.php +++ b/app/Http/Controllers/LaporanController.php @@ -19,95 +19,432 @@ public function downloadBulanan($periode) $data = $this->collectData($periode); - $data['periode'] = $periodeData; - $data['judulLaporan'] = 'Laporan Analisis Sentimen - ' . ($periodeData->nama ?? '-'); - $data['evaluasi'] = DB::table('evaluasi_model')->orderByDesc('id')->first() - ?? (object)['accuracy' => 0]; + $data['periode'] = $periodeData; - // Ulasan KOTOR — dari tabel ulasan mentah - $data['totalUlasanKotor'] = DB::table('ulasan') + $data['judulLaporan'] = + 'Laporan Analisis Sentimen - ' . + ($periodeData->nama ?? '-'); + + $data['evaluasi'] = + DB::table('evaluasi_model') + ->orderByDesc('id') + ->first() + ?? (object)['accuracy' => 0]; + + // TOTAL ULASAN KOTOR + $data['totalUlasanKotor'] = + DB::table('ulasan') ->where('periode_id', $periode) ->count(); - // Trend by tanggal ULASAN (bukan created_at analisis) - $data['trendHarian'] = DB::table('hasil_analisis') + // TREND HARIAN + $data['trendHarian'] = + DB::table('hasil_analisis') ->select( - DB::raw('DATE(created_at) as tanggal'), // ✅ ganti tanggal → created_at - DB::raw("SUM(CASE WHEN sentimen='positif' THEN 1 ELSE 0 END) as positif"), - DB::raw("SUM(CASE WHEN sentimen='netral' THEN 1 ELSE 0 END) as netral"), - DB::raw("SUM(CASE WHEN sentimen='negatif' THEN 1 ELSE 0 END) as negatif") + DB::raw('DATE(created_at) as tanggal'), + + DB::raw(" + SUM( + CASE + WHEN sentimen='positif' + THEN 1 ELSE 0 END + ) as positif + "), + + DB::raw(" + SUM( + CASE + WHEN sentimen='netral' + THEN 1 ELSE 0 END + ) as netral + "), + + DB::raw(" + SUM( + CASE + WHEN sentimen='negatif' + THEN 1 ELSE 0 END + ) as negatif + ") ) ->where('periode_id', $periode) - ->groupBy(DB::raw('DATE(created_at)')) // ✅ ganti tanggal → created_at - ->orderBy(DB::raw('DATE(created_at)')) // ✅ ganti tanggal → created_at + ->groupBy(DB::raw('DATE(created_at)')) + ->orderBy(DB::raw('DATE(created_at)')) ->get(); - return view('laporan.bulanan', $data); + return view( + 'laporan.bulanan', + $data + ); } + public function downloadTahunan(Request $request) { $tahun = $request->tahun; - $periodeList = DB::table('periode_analisis') + $periodeList = + DB::table('periode_analisis') ->where('tahun', $tahun) ->orderBy('bulan') ->get(); if ($periodeList->isEmpty()) { - return back()->with('error', 'Tidak ada data tahun tersebut'); + + return back()->with( + 'error', + 'Tidak ada data tahun tersebut' + ); } - return view('laporan.tahunan', compact('tahun', 'periodeList')); + $periodeIds = + $periodeList->pluck('id'); + + // TOTAL ULASAN + $totalUlasan = + DB::table('hasil_analisis') + ->whereIn( + 'periode_id', + $periodeIds + ) + ->count(); + + // TOTAL SENTIMEN + $positif = + DB::table('hasil_analisis') + ->whereIn( + 'periode_id', + $periodeIds + ) + ->where( + 'sentimen', + 'positif' + ) + ->count(); + + $netral = + DB::table('hasil_analisis') + ->whereIn( + 'periode_id', + $periodeIds + ) + ->where( + 'sentimen', + 'netral' + ) + ->count(); + + $negatif = + DB::table('hasil_analisis') + ->whereIn( + 'periode_id', + $periodeIds + ) + ->where( + 'sentimen', + 'negatif' + ) + ->count(); + + // PERSEN POSITIF + $persenPositif = + $totalUlasan > 0 + ? round( + ($positif / $totalUlasan) * 100, + 2 + ) + : 0; + + // AKURASI + $akurasi = + DB::table('evaluasi_model') + ->latest('id') + ->value('accuracy') + ?? 0; + + // TOTAL WISATA + $totalWisata = + DB::table('hasil_analisis') + ->whereIn( + 'periode_id', + $periodeIds + ) + ->distinct() + ->count('wisata'); + + // REKAP BULANAN + $rekapBulanan = + DB::table('hasil_analisis as h') + ->join( + 'periode_analisis as p', + 'h.periode_id', + '=', + 'p.id' + ) + + ->select( + + 'p.nama as bulan', + + DB::raw( + 'COUNT(*) as total' + ), + + DB::raw(" + SUM( + CASE + WHEN sentimen='positif' + THEN 1 ELSE 0 END + ) as positif + "), + + DB::raw(" + SUM( + CASE + WHEN sentimen='netral' + THEN 1 ELSE 0 END + ) as netral + "), + + DB::raw(" + SUM( + CASE + WHEN sentimen='negatif' + THEN 1 ELSE 0 END + ) as negatif + ") + ) + + ->whereIn( + 'periode_id', + $periodeIds + ) + + ->groupBy( + 'p.nama', + 'p.bulan' + ) + + ->orderBy( + 'p.bulan' + ) + + ->get(); + + // WISATA POPULER + $wisataPopuler = + DB::table('hasil_analisis') + + ->select( + + 'wisata', + + DB::raw( + 'COUNT(*) as jumlah' + ), + + DB::raw(" + ROUND( + ( + SUM( + CASE + WHEN sentimen='positif' + THEN 1 ELSE 0 END + ) + / + COUNT(*) + ) * 100 + ,2) + as persen + ") + ) + + ->whereIn( + 'periode_id', + $periodeIds + ) + + ->groupBy( + 'wisata' + ) + + ->orderByDesc( + 'persen' + ) + + ->limit(5) + + ->get(); + + return view( + + 'laporan.tahunan', + + compact( + + 'tahun', + 'periodeList', + 'totalUlasan', + 'akurasi', + 'totalWisata', + 'rekapBulanan', + 'wisataPopuler', + 'positif', + 'netral', + 'negatif', + 'persenPositif' + + ) + ); } + private function collectData($periodeId) { - $totalUlasan = DB::table('hasil_analisis') - ->where('periode_id', $periodeId) + $totalUlasan = + DB::table('hasil_analisis') + ->where( + 'periode_id', + $periodeId + ) ->count(); - $totalPositif = DB::table('hasil_analisis') - ->where('periode_id', $periodeId) - ->where('sentimen', 'positif') + $totalPositif = + DB::table('hasil_analisis') + ->where( + 'periode_id', + $periodeId + ) + ->where( + 'sentimen', + 'positif' + ) ->count(); - $totalNetral = DB::table('hasil_analisis') - ->where('periode_id', $periodeId) - ->where('sentimen', 'netral') + $totalNetral = + DB::table('hasil_analisis') + ->where( + 'periode_id', + $periodeId + ) + ->where( + 'sentimen', + 'netral' + ) ->count(); - $totalNegatif = DB::table('hasil_analisis') - ->where('periode_id', $periodeId) - ->where('sentimen', 'negatif') + $totalNegatif = + DB::table('hasil_analisis') + ->where( + 'periode_id', + $periodeId + ) + ->where( + 'sentimen', + 'negatif' + ) ->count(); $persen = [ - 'positif' => $totalUlasan ? round(($totalPositif / $totalUlasan) * 100, 2) : 0, - 'netral' => $totalUlasan ? round(($totalNetral / $totalUlasan) * 100, 2) : 0, - 'negatif' => $totalUlasan ? round(($totalNegatif / $totalUlasan) * 100, 2) : 0, + + 'positif' => + $totalUlasan + ? round( + ($totalPositif / + $totalUlasan) * 100, + 2 + ) + : 0, + + 'netral' => + $totalUlasan + ? round( + ($totalNetral / + $totalUlasan) * 100, + 2 + ) + : 0, + + 'negatif' => + $totalUlasan + ? round( + ($totalNegatif / + $totalUlasan) * 100, + 2 + ) + : 0, ]; - $perWisata = DB::table('hasil_analisis') + $perWisata = + DB::table('hasil_analisis') + ->select( + 'wisata', - DB::raw('COUNT(*) as total'), - DB::raw("SUM(CASE WHEN sentimen='positif' THEN 1 ELSE 0 END) as positif"), - DB::raw("SUM(CASE WHEN sentimen='netral' THEN 1 ELSE 0 END) as netral"), - DB::raw("SUM(CASE WHEN sentimen='negatif' THEN 1 ELSE 0 END) as negatif") + + DB::raw( + 'COUNT(*) as total' + ), + + DB::raw(" + SUM( + CASE + WHEN sentimen='positif' + THEN 1 ELSE 0 END + ) as positif + "), + + DB::raw(" + SUM( + CASE + WHEN sentimen='netral' + THEN 1 ELSE 0 END + ) as netral + "), + + DB::raw(" + SUM( + CASE + WHEN sentimen='negatif' + THEN 1 ELSE 0 END + ) as negatif + ") ) - ->where('periode_id', $periodeId) - ->groupBy('wisata') - ->orderByDesc('positif') + + ->where( + 'periode_id', + $periodeId + ) + + ->groupBy( + 'wisata' + ) + + ->orderByDesc( + 'positif' + ) + ->get(); return [ - 'totalUlasan' => $totalUlasan, - 'totalPositif' => $totalPositif, - 'totalNetral' => $totalNetral, - 'totalNegatif' => $totalNegatif, - 'persen' => $persen, - 'perWisata' => $perWisata, + + 'totalUlasan' => + $totalUlasan, + + 'totalPositif' => + $totalPositif, + + 'totalNetral' => + $totalNetral, + + 'totalNegatif' => + $totalNegatif, + + 'persen' => + $persen, + + 'perWisata' => + $perWisata, ]; } } \ No newline at end of file diff --git a/resources/views/laporan/tahunan.blade.php b/resources/views/laporan/tahunan.blade.php index 2fe69bf..a0846a8 100644 --- a/resources/views/laporan/tahunan.blade.php +++ b/resources/views/laporan/tahunan.blade.php @@ -1,110 +1,605 @@ - + +Laporan Tahunan + + + +.hero-icon { + width: 52px; + height: 52px; + background: #1d4ed8; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} +.hero-icon svg { width: 28px; height: 28px; fill: white; } + +.hero-title { font-size: 18px; font-weight: 900; color: #132b70; line-height: 1.3; } +.hero-sub { font-size: 11px; color: #6b7280; margin-top: 4px; } + +.hero-right { font-size: 12px; text-align: right; line-height: 1.8; } +.hero-right .year { font-size: 22px; font-weight: 800; color: #1e3a8a; } + +/* SECTION TITLE */ +.section-title { + font-size: 12px; + font-weight: 700; + color: #1e3a8a; + text-transform: uppercase; + letter-spacing: .6px; + margin: 20px 0 10px; + display: flex; + align-items: center; + gap: 8px; +} +.section-title::before { + content: ''; + display: inline-block; + width: 4px; + height: 14px; + background: #1d4ed8; + border-radius: 2px; +} + +/* CARDS */ +.cards { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 12px; + margin-bottom: 20px; +} + +.card { + border: 1px solid #e5e7eb; + border-radius: 12px; + padding: 14px 16px; + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +.card-info .card-label { font-size: 11px; color: #6b7280; margin-bottom: 4px; } +.card-info .card-value { font-size: 28px; font-weight: 800; line-height: 1; } +.card-info .card-unit { font-size: 11px; color: #9ca3af; margin-top: 4px; } +.card-icon { + width: 36px; height: 36px; + border-radius: 8px; + display: flex; align-items: center; justify-content: center; + font-size: 18px; + flex-shrink: 0; +} + +.blue { background: #eff6ff; border-color: #bfdbfe; } +.green { background: #f0fdf4; border-color: #bbf7d0; } +.yellow { background: #fffbeb; border-color: #fde68a; } +.purple { background: #faf5ff; border-color: #e9d5ff; } + +.blue .card-icon { background: #dbeafe; } +.green .card-icon { background: #dcfce7; } +.yellow .card-icon { background: #fef3c7; } +.purple .card-icon { background: #ede9fe; } + +/* REKAP + DONUT ROW */ +.grid2 { + display: grid; + grid-template-columns: 1.4fr 1fr; + gap: 16px; + margin-bottom: 16px; +} + +/* TABLE */ +.table-box { + border: 1px solid #e5e7eb; + border-radius: 12px; + overflow: hidden; +} + +table { width: 100%; border-collapse: collapse; } +table thead tr { background: #f8fafc; } +table th { padding: 10px 12px; font-size: 11px; font-weight: 700; color: #374151; text-align: left; } +table td { padding: 9px 12px; font-size: 11px; border-top: 1px solid #f1f5f9; } +table tbody tr:hover { background: #fafafa; } + +.tfoot-row td { background: #f8fafc; font-weight: 700; border-top: 2px solid #e5e7eb; } + +.pos { color: #16a34a; font-weight: 600; } +.net { color: #d97706; font-weight: 600; } +.neg { color: #dc2626; font-weight: 600; } + +.badge-green { + background: #dcfce7; + color: #15803d; + border-radius: 20px; + padding: 2px 8px; + font-weight: 700; + font-size: 11px; +} + +/* DONUT BOX */ +.donut-box { + border: 1px solid #e5e7eb; + border-radius: 12px; + padding: 16px; + display: flex; + flex-direction: column; +} +.donut-box h4 { + font-size: 11px; + font-weight: 700; + color: #1e3a8a; + text-transform: uppercase; + letter-spacing: .4px; + margin-bottom: 10px; +} +.donut-wrap { + position: relative; + flex: 1; + display: flex; + align-items: center; + justify-content: center; +} +.donut-center { + position: absolute; + text-align: center; + pointer-events: none; +} +.donut-center .dc-num { font-size: 20px; font-weight: 800; color: #1e3a8a; } +.donut-center .dc-label { font-size: 9px; color: #6b7280; } + +/* TREND BOX */ +.trend-box { + border: 1px solid #e5e7eb; + border-radius: 12px; + padding: 16px; + margin-bottom: 16px; +} +.trend-box h4 { + font-size: 11px; + font-weight: 700; + color: #1e3a8a; + text-transform: uppercase; + letter-spacing: .4px; + margin-bottom: 10px; +} + +/* BOTTOM GRID */ +.bottom-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + margin-bottom: 20px; +} + +/* KESIMPULAN */ +.kesimpulan-box { + border: 1px solid #dbeafe; + background: #eff6ff; + border-radius: 12px; + padding: 16px 18px; + font-size: 12px; + line-height: 1.7; +} +.kesimpulan-box h4 { + font-size: 12px; + font-weight: 700; + color: #1e3a8a; + margin-bottom: 8px; + text-transform: uppercase; +} + +/* FOOTER */ +.footer { + display: flex; + justify-content: space-between; + font-size: 11px; + color: #9ca3af; + padding-top: 14px; + border-top: 1px solid #f1f5f9; +} + +@media print { + body { background: white; padding: 0; } + .action-bar { display: none !important; } + .container { box-shadow: none; } +} + - -
+{{-- ACTION BAR --}} +
+
+
+ +
+
-

- LAPORAN TAHUNAN ANALISIS SENTIMEN -

- -

- Wisata Kabupaten Jember -

- -

- Tahun: - - {{ $tahun }} - -

+
+ {{-- HERO --}} +
+
+
+ +
+
+ {{-- Logo kecil di atas judul --}} +
+ -SENTARA- + JEMBER +
+
LAPORAN ANALISIS SENTIMEN
PER TAHUN
+
SISTEM ANALISIS SENTIMEN WISATA JEMBER
+
+
+
+
Tahun
+
{{ $tahun }}
+
Tanggal Cetak
+
{{ now()->format('d M Y H:i') }}
+
- + {{-- RINGKASAN --}} +
Ringkasan Tahunan
- - - - +
+
+
+
Total Ulasan
+
{{ $totalUlasan }}
+
Ulasan
+
+
💬
+
+
+
+
Rata-rata Akurasi
+
{{ $akurasi }}%
+
Akurasi
+
+
+
+
+
+
Total Wisata Dibahas
+
{{ $totalWisata }}
+
Wisata
+
+
📍
+
+
+
+
Bulan Dianalisis
+
{{ count($rekapBulanan) }}
+
Bulan
+
+
📅
+
+
- - - - + {{-- REKAP + DONUT --}} +
Rekap Sentimen per Bulan
- - - - +
+
+
Total Ulasan{{ $totalUlasan ?? 0 }}
Positif{{ $positif ?? 0 }}
Negatif{{ $negatif ?? 0 }}
+ + + + + + + + + + + + @php $totP=0; $totN=0; $totNt=0; $totAll=0; @endphp + @foreach($rekapBulanan as $r) + @php $totP+=$r->positif; $totN+=$r->negatif; $totNt+=$r->netral; $totAll+=$r->total; @endphp + + + + + + + + + @endforeach + + + + + + + + + + + +
BulanTotal UlasanPositifNetralNegatifPersentase Positif
{{ $r->bulan }}{{ $r->total }}{{ $r->positif }}{{ $r->netral }}{{ $r->negatif }}{{ number_format(($r->positif/max($r->total,1))*100,2) }}%
TOTAL / RATA-RATA{{ $totAll }}{{ $totP }}{{ $totNt }}{{ $totN }}{{ $totAll > 0 ? number_format(($totP/$totAll)*100,2) : 0 }}%
+
- - Netral - {{ $netral ?? 0 }} - +
+

Distribusi Sentimen Tahun {{ $tahun }}

+
+ +
+
+
- + {{-- TREND --}} +
Trend Sentimen per Bulan ({{ $tahun }})
-
+
+ +
-

Rekomendasi Tahunan

+ {{-- WISATA + KESIMPULAN --}} +
Wisata Serpopuler & Kesimpulan
- @forelse(($rekomendasi ?? []) as $item) +
+
+ + + + + + + + + + + @foreach($wisataPopuler as $i => $w) + + + + + + + @endforeach + +
NoWisataTotal UlasanPersentase Positif
{{ $i+1 }}{{ $w->wisata }}{{ $w->jumlah }}{{ $w->persen }}%
+
-

- • {{ $item->rekomendasi }} -

+
+

Kesimpulan Tahunan

+

+ Secara umum, sentimen positif mendominasi tahun {{ $tahun }} + dengan rata-rata {{ $persenPositif }}%. + @if(isset($wisataPopuler[0])) + {{ $wisataPopuler[0]->wisata }} menjadi destinasi paling populer + dengan sentimen positif tertinggi. + @endif + Diperlukan peningkatan pada aspek fasilitas, kebersihan, dan pelayanan + untuk menekan sentimen negatif. +

+
+
- @empty + {{-- FOOTER --}} + -

- Tidak ada rekomendasi. -

+ - @endforelse + \ No newline at end of file diff --git a/storage/framework/views/10ee49aecb46b4eac9b0217a359f795e.php b/storage/framework/views/10ee49aecb46b4eac9b0217a359f795e.php new file mode 100644 index 0000000..965c0f3 --- /dev/null +++ b/storage/framework/views/10ee49aecb46b4eac9b0217a359f795e.php @@ -0,0 +1,5 @@ +startSection('title', __('Not Found')); ?> +startSection('code', '404'); ?> +startSection('message', __('Not Found')); ?> + +make('errors::minimal', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?> \ No newline at end of file diff --git a/storage/framework/views/5fd932f7a53f435288301570d161158b.php b/storage/framework/views/5fd932f7a53f435288301570d161158b.php deleted file mode 100644 index 6f7c9f0..0000000 --- a/storage/framework/views/5fd932f7a53f435288301570d161158b.php +++ /dev/null @@ -1,377 +0,0 @@ - - - - -<?php echo e($judulLaporan); ?> - - - - - - - - -
- -
- -
- - - - - -
-
-
LAPORAN ANALISIS SENTIMEN
PER BULAN
-
SISTEM ANALISIS SENTIMEN WISATA JEMBER
-
-
- Periode
- nama ?? '-'); ?>

- Tanggal Cetak
- format('d M Y H:i')); ?> - -
-
- - -
Ringkasan
- -
-
-
Total Ulasan
-

-
Ulasan Masuk
-
-
-
Hasil Analisis
-

-
Data Bersih
-
-
-
Wisata Dibahas
-

-
Destinasi
-
-
-
Akurasi Analisis
-

accuracy ?? 0) * 100, 2)); ?>%

-
Model
-
-
- - -
Visualisasi
- -
-
-

Distribusi Sentimen

- -
-
-

Sentimen per Destinasi

- -
-
- - -
Top Wisata Berdasarkan Sentimen Positif
- - - - - - - - - - - - addLoop($__currentLoopData); foreach($__currentLoopData as $i => $w): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> - - - - - - - - - - popLoop(); $loop = $__env->getLastLoop(); ?> -
NoWisataTotalPositifNetralNegatif% Positif
wisata); ?>total); ?>positif); ?>netral); ?>negatif); ?>total > 0 ? round(($w->positif / $w->total) * 100, 2) : 0); ?>%
- - -
- KESIMPULAN -

- Pada periode nama ?? ''); ?>, - terdapat ulasan masuk dengan - data berhasil dianalisis. - Sentimen positif mendominasi dengan persentase %, - diikuti netral % - dan negatif %. -

-
- - - - -
- - - - - \ No newline at end of file diff --git a/storage/framework/views/7ac7144038b7ed595f7947eb2e474209.php b/storage/framework/views/7ac7144038b7ed595f7947eb2e474209.php new file mode 100644 index 0000000..0953476 --- /dev/null +++ b/storage/framework/views/7ac7144038b7ed595f7947eb2e474209.php @@ -0,0 +1,605 @@ + + + + +Laporan Tahunan + + + + + + + +
+
+
+ +
+
+ +
+ + +
+
+
+ +
+
+ +
+ -SENTARA- + JEMBER +
+
LAPORAN ANALISIS SENTIMEN
PER TAHUN
+
SISTEM ANALISIS SENTIMEN WISATA JEMBER
+
+
+
+
Tahun
+
+
Tanggal Cetak
+
format('d M Y H:i')); ?>
+
+
+ + +
Ringkasan Tahunan
+ +
+
+
+
Total Ulasan
+
+
Ulasan
+
+
💬
+
+
+
+
Rata-rata Akurasi
+
%
+
Akurasi
+
+
+
+
+
+
Total Wisata Dibahas
+
+
Wisata
+
+
📍
+
+
+
+
Bulan Dianalisis
+
+
Bulan
+
+
📅
+
+
+ + +
Rekap Sentimen per Bulan
+ +
+
+ + + + + + + + + + + + + + addLoop($__currentLoopData); foreach($__currentLoopData as $r): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> + positif; $totN+=$r->negatif; $totNt+=$r->netral; $totAll+=$r->total; ?> + + + + + + + + + popLoop(); $loop = $__env->getLastLoop(); ?> + + + + + + + + + + + +
BulanTotal UlasanPositifNetralNegatifPersentase Positif
bulan); ?>total); ?>positif); ?>netral); ?>negatif); ?>positif/max($r->total,1))*100,2)); ?>%
TOTAL / RATA-RATA 0 ? number_format(($totP/$totAll)*100,2) : 0); ?>%
+
+ +
+

Distribusi Sentimen Tahun

+
+ +
+
+
+ + +
Trend Sentimen per Bulan ()
+ +
+ +
+ + +
Wisata Serpopuler & Kesimpulan
+ +
+
+ + + + + + + + + + + addLoop($__currentLoopData); foreach($__currentLoopData as $i => $w): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> + + + + + + + popLoop(); $loop = $__env->getLastLoop(); ?> + +
NoWisataTotal UlasanPersentase Positif
wisata); ?>jumlah); ?>persen); ?>%
+
+ +
+

Kesimpulan Tahunan

+

+ Secara umum, sentimen positif mendominasi tahun + dengan rata-rata %. + + wisata); ?> menjadi destinasi paling populer + dengan sentimen positif tertinggi. + + Diperlukan peningkatan pada aspek fasilitas, kebersihan, dan pelayanan + untuk menekan sentimen negatif. +

+
+
+ + + + +
+ + + + + \ No newline at end of file diff --git a/storage/framework/views/83200b6ca19a8da36ba75ad680d43e19.php b/storage/framework/views/83200b6ca19a8da36ba75ad680d43e19.php deleted file mode 100644 index c0c66fa..0000000 --- a/storage/framework/views/83200b6ca19a8da36ba75ad680d43e19.php +++ /dev/null @@ -1,222 +0,0 @@ - - -
- - -
-
-

Rekomendasi Layanan

-

- Rekomendasi dibuat dari ulasan negatif agar saran perbaikan fokus pada keluhan pengunjung. -

-

- destinasi dianalisis, destinasi memiliki ulasan negatif. -

-
- - -
- - - -
-
- - -
- -
-
📍
-
-

Destinasi Dianalisis

-

-

punya keluhan

-
-
- -
-
😟
-
-

Total Ulasan Negatif

-

-

% dari total

-
-
- -
-
😊
-
-

Tingkat Kepuasan

-

%

- - - - -
-
- -
-
-
-

Isu Dominan

-

-

% dari total isu

-
-
- -
- - -
- - -
-

Isu Utama (Top 5)

- - addLoop($__currentLoopData); foreach($__currentLoopData as $i => $isu): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?> - 'bg-red-500', - 'orange' => 'bg-orange-500', - 'yellow' => 'bg-yellow-400', - 'green' => 'bg-green-500', - default => 'bg-blue-500', - }; - ?> -
-
- . - % -
-
-
-
-
- popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?> -

Belum ada data isu.

- -
- - -
-

Kata Kunci Dominan

- - - - addLoop($__currentLoopData); foreach($__currentLoopData as $kata => $jumlah): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?> -
-
- - x -
-
-
-
-
- popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?> -

Belum ada kata kunci.

- -
- - -
-

Saran Perbaikan

- -
- addLoop($__currentLoopData); foreach($__currentLoopData as $saran): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?> -
-
-
-

-

-
-
- popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?> -

Belum ada saran.

- -
-
- -
- - -
- - addLoop($__currentLoopData); foreach($__currentLoopData as $p): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?> - 'border-red-300', - 'orange' => 'border-orange-300', - 'yellow' => 'border-yellow-300', - 'green' => 'border-green-300', - default => 'border-blue-300', - }; - $title = match($p['color']) { - 'red' => 'text-red-600', - 'orange' => 'text-orange-500', - 'yellow' => 'text-yellow-600', - 'green' => 'text-green-600', - default => 'text-blue-600', - }; - $dampak = match($p['color']) { - 'red' => 'bg-red-100 text-red-600', - 'orange' => 'bg-orange-100 text-orange-600', - 'yellow' => 'bg-yellow-100 text-yellow-600', - 'green' => 'bg-green-100 text-green-700', - default => 'bg-blue-100 text-blue-600', - }; - ?> -
-

Prioritas

-

- -
    - addLoop($__currentLoopData); foreach($__currentLoopData as $action): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> -
  • - - -
  • - popLoop(); $loop = $__env->getLastLoop(); ?> -
- -
- Dampak: - -
-
- popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?> -
- Belum ada data rekomendasi. Pastikan analisis sentimen sudah dijalankan. -
- - -
- -
\ No newline at end of file diff --git a/storage/framework/views/ab3ba8940f81b3715d18ea258bfa635c.php b/storage/framework/views/ab3ba8940f81b3715d18ea258bfa635c.php new file mode 100644 index 0000000..4aaf0ed --- /dev/null +++ b/storage/framework/views/ab3ba8940f81b3715d18ea258bfa635c.php @@ -0,0 +1,340 @@ +startSection('content'); ?> + +
+ +
+ +
+

+ Riwayat Analisis +

+ +

+ Periode tersimpan otomatis setiap kali Ambil Data dijalankan. +

+
+ + + +
+ +
+ + + +
+ + + +
+ +
+ + +
+ + +
+ + + +
+ + +
+ + +
+ +

+ Import Data Lama dari CSV +

+ +

+ Gunakan untuk memasukkan ulasan historis. Kolom wajib: + wisata, rating, ulasan, tanggal. + Kolom reviewer boleh ada. +

+ +
+ + + + + + + + + +
+ + any()): ?> +
+ first()); ?> + +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?> + + + + + + + + + + + + + + + + + + popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?> + + + + + + + + + + + +
+ Periode + + Total Ulasan + + Hasil Analisis + + Wisata + + Terakhir Analisis + + Aksi +
+ nama); ?> + + + total_ulasan); ?> + + + total_hasil); ?> + + + total_wisata); ?> + + + + terakhir_analisis + ? \Carbon\Carbon::parse( + $item->terakhir_analisis + )->format('d M Y H:i') + : '-'); ?> + + + + + + +
+ + Belum ada riwayat analisis. + Jalankan Ambil Data terlebih dahulu. + +
+ +
+ + + + hasPages()): ?> + currentPage(); + $last = $riwayat->lastPage(); + $query = http_build_query(request()->except('page')); + $window = collect(range(max(1, $current - 2), min($last, $current + 2))); + ?> + +
+ + +

Menampilkan firstItem()); ?> – lastItem()); ?> dari total()); ?> data

+ + +
+ + + onFirstPage()): ?> + « + + « + + + + contains(1)): ?> + 1 + min() > 2): ?> + ... + + + + + addLoop($__currentLoopData); foreach($__currentLoopData as $page): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> + + + + + + popLoop(); $loop = $__env->getLastLoop(); ?> + + + contains($last)): ?> + max() < $last - 1): ?> + ... + + + + + + hasMorePages()): ?> + » + + » + + +
+
+ + +
+ +
+ +stopSection(); ?> +make('layouts.sentara', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?> \ No newline at end of file diff --git a/storage/framework/views/da4c8b215347ddbbfe979485d71927be.php b/storage/framework/views/da4c8b215347ddbbfe979485d71927be.php deleted file mode 100644 index 1889e17..0000000 --- a/storage/framework/views/da4c8b215347ddbbfe979485d71927be.php +++ /dev/null @@ -1,354 +0,0 @@ -startSection('content'); ?> - -
- - - -
- - -
- - -
- - -
- - - - -
- 📅 -
- - - -
- Data ulasan sudah tersedia, tetapi belum dilakukan analisis sentimen. -
- - -
-
- - Periode aktif: nama ?? 'Belum ada data'); ?> - - - - Lihat riwayat - -
-
- - - Terakhir update: format('d M Y H:i') : '-'); ?> - - - -
- - - - - - - -
-
-
- - -
- - -
- - - -
- - -
- - -
-
-

Total Ulasan

-

-
-
-

Sentimen Positif

-

%

-
-
-

Sentimen Negatif

-

%

-
-
-

Sentimen Netral

-

%

-
-
- - -
- - -
-

Distribusi Sentimen

-
- -
-
- - -
-

Sentimen per Destinasi

-
- -
-
- -
- - -
-
-

Total Data per Destinasi

-
- addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> -
- wisata); ?> - total); ?> ulasan -
- popLoop(); $loop = $__env->getLastLoop(); ?> -
-
-
-

Word Cloud

-
-

Belum ada kata dominan.

-
-
-
- -
- - -
- make('analisis.index', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?> -
- - -
- make('rekomendasi.index', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?> -
- -
-
- - - - - - - - - - -stopSection(); ?> -make('layouts.sentara', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?> \ No newline at end of file diff --git a/storage/framework/views/fb843eb1366f55ecbc0d64d0bcaf77ad.php b/storage/framework/views/fb843eb1366f55ecbc0d64d0bcaf77ad.php deleted file mode 100644 index 8bf74ac..0000000 --- a/storage/framework/views/fb843eb1366f55ecbc0d64d0bcaf77ad.php +++ /dev/null @@ -1,229 +0,0 @@ - - - startSection('content'); ?> - - -total() ?? 0; - $jumlahKelasAnalisis ??= 0; - $evaluasiTersedia = $evaluasi && $jumlahKelasAnalisis >= 2; -?> - -
- - -
-
-

Hasil Analisis Sentimen

-

- Evaluasi memakai pseudo-label dari rating/rule otomatis, bukan anotasi manual. -

- 0 && !$evaluasiTersedia): ?> -

- Semua hasil hanya memiliki kelas sentimen. Precision, recall, F1, dan akurasi tidak dihitung karena evaluasi klasifikasi membutuhkan minimal 2 kelas. Detail hasil analisis tetap ditampilkan di bawah. -

- -
-
- - -
- -
-

Precision

-

- precision ?? 0, 2) : '-'); ?> - -

-
- -
-

Recall

-

- recall ?? 0, 2) : '-'); ?> - -

-
- -
-

F1 Score

-

- f1_score ?? 0, 2) : '-'); ?> - -

-
- -
-

Akurasi

-

- accuracy ?? 0, 2) : '-'); ?> - -

-
- -
- - - - -
- -
- - - - - - - - -
- - - - - Lihat Riwayat - - -
- - -
- -

Detail Hasil Analisis Sentimen

- - - - - - - - - - - - - - - addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?> - - - - - - - - - popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?> - - - - - -
NoWisataUlasan AsliUlasan BersihSentimenProbabilitas
currentPage() - 1) * $hasil->perPage() + $loop->iteration); ?>wisata); ?>ulasan_asli ?? '-', 80)); ?>hasil_preprocessing ?? '-', 80)); ?> - - sentimen)); ?> - - - probabilitas ?? 0, 2)); ?>
Tidak ada data
- - - hasPages()): ?> - currentPage(); - $last = $hasil->lastPage(); - $query = http_build_query(request()->except('page')); - // Window 2 halaman kiri & kanan dari current - $window = collect(range(max(1, $current - 2), min($last, $current + 2))); - ?> - -
- - -

Menampilkan firstItem()); ?> - lastItem()); ?> dari total()); ?> data

- - -
- - - onFirstPage()): ?> - « - - « - - - - contains(1)): ?> - 1 - min() > 2): ?> - ... - - - - - addLoop($__currentLoopData); foreach($__currentLoopData as $page): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> - - - - - - popLoop(); $loop = $__env->getLastLoop(); ?> - - - contains($last)): ?> - max() < $last - 1): ?> - ... - - - - - - hasMorePages()): ?> - » - - » - - -
-
- - -
- -
- - - stopSection(); ?> - - -make('layouts.sentara', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?> \ No newline at end of file diff --git a/storage/framework/views/fe5b23b6d58765df42d452d1a22bfa55.php b/storage/framework/views/fe5b23b6d58765df42d452d1a22bfa55.php new file mode 100644 index 0000000..ccb0662 --- /dev/null +++ b/storage/framework/views/fe5b23b6d58765df42d452d1a22bfa55.php @@ -0,0 +1,35 @@ + + + + + + + <?php echo $__env->yieldContent('title'); ?> + + + + + + +
+
+
+
+ yieldContent('code'); ?> +
+ +
+ yieldContent('message'); ?> +
+
+
+
+ + + \ No newline at end of file