MIF_HomsinNIME31231582/resources/views/dashboard.blade.php

620 lines
35 KiB
PHP

<x-app-layout>
<x-slot name="header">
<div class="bg-[#1e3a8a] rounded-2xl shadow-lg p-6">
<div class="flex flex-col md:flex-row md:items-center md:justify-between">
<div class="flex items-center space-x-4">
<div class="bg-white/10 p-3 rounded-xl">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg>
</div>
<div>
<h1 class="text-2xl font-bold text-white">Dashboard Analisis Sentimen S-Learn</h1>
<p class="text-white/70 text-sm mt-1">Memantau kepuasan dan masukan pengguna platform S-Learn</p>
</div>
</div>
<div class="mt-4 md:mt-0 flex items-center space-x-3">
<div class="bg-white/10 px-4 py-2 rounded-lg">
<span class="text-white text-sm font-medium">Terakhir update: {{ now()->format('d M Y H:i') }}</span>
</div>
</div>
</div>
</div>
</x-slot>
@php
$positif = $positif ?? 0;
$negatif = $negatif ?? 0;
$totalData = $totalData ?? ($positif + $negatif);
$score_0_20 = $score_0_20 ?? 0;
$score_21_40 = $score_21_40 ?? 0;
$score_41_60 = $score_41_60 ?? 0;
$score_61_80 = $score_61_80 ?? 0;
$score_81_100 = $score_81_100 ?? 0;
$formattedMetrics = $formattedMetrics ?? [];
$metricsNegatif = $formattedMetrics['negatif'] ?? ['precision'=>0,'recall'=>0,'f1'=>0];
$metricsPositif = $formattedMetrics['positif'] ?? ['precision'=>0,'recall'=>0,'f1'=>0];
$maintenance = $maintenance ?? [];
$maintenanceDetails = $maintenanceDetails ?? [];
// Hitung persentase untuk memudahkan pemahaman
$persentasePositif = $totalData > 0 ? round(($positif/$totalData)*100, 1) : 0;
$persentaseNegatif = $totalData > 0 ? round(($negatif/$totalData)*100, 1) : 0;
@endphp
<div class="py-8 bg-gray-50 min-h-screen"
x-data="{
openModal: false,
selectedCategory: '',
selectedData: [],
activeTab: 'ringkasan'
}">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
<!-- ========== TAB NAVIGASI ========== -->
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-1 flex flex-wrap">
<button @click="activeTab = 'ringkasan'"
class="flex-1 py-3 px-4 rounded-lg text-sm font-medium transition-all"
:class="activeTab === 'ringkasan' ? 'bg-white text-[#1e3a8a] shadow-md' : 'text-white/80 hover:bg-white/10 hover:text-white'">
📊 Ringkasan
</button>
<button @click="activeTab = 'sentimen'"
class="flex-1 py-3 px-4 rounded-lg text-sm font-medium transition-all"
:class="activeTab === 'sentimen' ? 'bg-white text-[#1e3a8a] shadow-md' : 'text-white/80 hover:bg-white/10 hover:text-white'">
😊 Analisis Sentimen
</button>
<button @click="activeTab = 'akurasi'"
class="flex-1 py-3 px-4 rounded-lg text-sm font-medium transition-all"
:class="activeTab === 'akurasi' ? 'bg-white text-[#1e3a8a] shadow-md' : 'text-white/80 hover:bg-white/10 hover:text-white'">
📈 Akurasi & Prediksi
</button>
<button @click="activeTab = 'masalah'"
class="flex-1 py-3 px-4 rounded-lg text-sm font-medium transition-all"
:class="activeTab === 'masalah' ? 'bg-white text-[#1e3a8a] shadow-md' : 'text-white/80 hover:bg-white/10 hover:text-white'">
⚠️ Masalah & Saran
</button>
</div>
<!-- ========== TAB RINGKASAN ========== -->
<div x-show="activeTab === 'ringkasan'" x-cloak>
<!-- Statistik Utama -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-5">
<p class="text-white/70 text-sm mb-1">Total Ulasan</p>
<p class="text-3xl font-bold text-white">{{ number_format($totalData) }}</p>
<p class="text-white/50 text-xs mt-1">Semua ulasan yang masuk</p>
</div>
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-5">
<p class="text-white/70 text-sm mb-1">Ulasan Positif</p>
<p class="text-3xl font-bold text-green-300">{{ number_format($positif) }}</p>
<p class="text-white/50 text-xs mt-1">{{ $persentasePositif }}% dari total</p>
</div>
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-5">
<p class="text-white/70 text-sm mb-1">Ulasan Negatif</p>
<p class="text-3xl font-bold text-red-300">{{ number_format($negatif) }}</p>
<p class="text-white/50 text-xs mt-1">{{ $persentaseNegatif }}% dari total</p>
</div>
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-5">
<p class="text-white/70 text-sm mb-1">Tingkat Kepuasan</p>
<p class="text-3xl font-bold text-yellow-300">{{ $persentasePositif }}%</p>
<p class="text-white/50 text-xs mt-1">Pengguna puas</p>
</div>
</div>
<!-- Grafik Ringkasan -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Grafik Batang -->
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="font-semibold text-white">Perbandingan Ulasan</h3>
<span class="text-xs bg-white/20 text-white px-2 py-1 rounded-full">Grafik Batang</span>
</div>
<p class="text-white/70 text-sm mb-4">Membandingkan jumlah ulasan positif dan negatif</p>
<div style="height:250px">
<canvas id="barChart"></canvas>
</div>
<div class="flex justify-center mt-4 space-x-6">
<div class="flex items-center">
<span class="w-3 h-3 bg-green-400 rounded-full mr-2"></span>
<span class="text-sm text-white">Positif: {{ number_format($positif) }}</span>
</div>
<div class="flex items-center">
<span class="w-3 h-3 bg-red-400 rounded-full mr-2"></span>
<span class="text-sm text-white">Negatif: {{ number_format($negatif) }}</span>
</div>
</div>
</div>
<!-- Grafik Lingkaran -->
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="font-semibold text-white">Proporsi Kepuasan</h3>
<span class="text-xs bg-white/20 text-white px-2 py-1 rounded-full">Grafik Lingkaran</span>
</div>
<p class="text-white/70 text-sm mb-4">Persentase perbandingan ulasan</p>
<div style="height:250px">
<canvas id="pieChart"></canvas>
</div>
<div class="text-center mt-4">
<p class="text-sm">
<span class="inline-block px-3 py-1 bg-green-500/20 text-green-300 rounded-full font-medium">{{ $persentasePositif }}% Puas</span>
<span class="mx-2 text-white/50">|</span>
<span class="inline-block px-3 py-1 bg-red-500/20 text-red-300 rounded-full font-medium">{{ $persentaseNegatif }}% Tidak Puas</span>
</p>
</div>
</div>
</div>
</div>
<!-- ========== TAB ANALISIS SENTIMEN ========== -->
<div x-show="activeTab === 'sentimen'" x-cloak>
<!-- Distribusi Tingkat Kepuasan -->
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-6 mb-6">
<h3 class="font-semibold text-white mb-2">Tingkat Kepuasan Pengguna</h3>
<p class="text-white/70 text-sm mb-4">Skor 0-100 (Semakin tinggi angkanya, semakin puas pengguna)</p>
<!-- Kategori Skor -->
<div class="grid grid-cols-5 gap-2 mb-6">
<div class="text-center p-3 bg-red-500/20 rounded-lg">
<span class="text-xs text-red-300 font-medium block">0-20</span>
<span class="text-lg font-bold text-white">{{ $score_0_20 }}</span>
<span class="text-xs text-white/60 block">Sangat Tidak Puas</span>
</div>
<div class="text-center p-3 bg-orange-500/20 rounded-lg">
<span class="text-xs text-orange-300 font-medium block">21-40</span>
<span class="text-lg font-bold text-white">{{ $score_21_40 }}</span>
<span class="text-xs text-white/60 block">Tidak Puas</span>
</div>
<div class="text-center p-3 bg-yellow-500/20 rounded-lg">
<span class="text-xs text-yellow-300 font-medium block">41-60</span>
<span class="text-lg font-bold text-white">{{ $score_41_60 }}</span>
<span class="text-xs text-white/60 block">Netral</span>
</div>
<div class="text-center p-3 bg-lime-500/20 rounded-lg">
<span class="text-xs text-lime-300 font-medium block">61-80</span>
<span class="text-lg font-bold text-white">{{ $score_61_80 }}</span>
<span class="text-xs text-white/60 block">Puas</span>
</div>
<div class="text-center p-3 bg-green-500/20 rounded-lg">
<span class="text-xs text-green-300 font-medium block">81-100</span>
<span class="text-lg font-bold text-white">{{ $score_81_100 }}</span>
<span class="text-xs text-white/60 block">Sangat Puas</span>
</div>
</div>
<!-- Grafik Garis -->
<div style="height:250px">
<canvas id="scoreChart"></canvas>
</div>
<!-- Info Box -->
<div class="mt-4 bg-white/10 p-4 rounded-lg">
<p class="text-sm text-white">
<span class="font-semibold">📊 Analisis:</span>
Grafik menunjukkan sebaran tingkat kepuasan.
@if($score_81_100 > $score_0_20)
Mayoritas pengguna merasa puas dengan layanan S-Learn (skor 81-100).
@else
Perlu perhatian pada area dengan skor rendah (0-40) untuk meningkatkan kepuasan.
@endif
</p>
</div>
</div>
</div>
<!-- ========== TAB AKURASI & PREDIKSI ========== -->
<div x-show="activeTab === 'akurasi'" x-cloak>
<!-- Metrik Akurasi -->
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-6 mb-6">
<h3 class="font-semibold text-white mb-2">Tingkat Akurasi Sistem</h3>
<p class="text-white/70 text-sm mb-4">Seberapa akurat sistem dalam memprediksi sentimen</p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<div class="bg-white/10 p-5 rounded-xl text-center">
<p class="text-sm text-blue-300 mb-1">Precision (Ketepatan)</p>
<p class="text-3xl font-bold text-white">{{ number_format($metricsPositif['precision'] * 100, 1) }}%</p>
<p class="text-xs text-white/50 mt-2">Seberapa tepat sistem memprediksi sentimen positif</p>
</div>
<div class="bg-white/10 p-5 rounded-xl text-center">
<p class="text-sm text-green-300 mb-1">Recall (Kelengkapan)</p>
<p class="text-3xl font-bold text-white">{{ number_format($metricsPositif['recall'] * 100, 1) }}%</p>
<p class="text-xs text-white/50 mt-2">Seberapa lengkap sistem menangkap sentimen positif</p>
</div>
<div class="bg-white/10 p-5 rounded-xl text-center">
<p class="text-sm text-purple-300 mb-1">F1-Score (Keseimbangan)</p>
<p class="text-3xl font-bold text-white">{{ number_format($metricsPositif['f1'] * 100, 1) }}%</p>
<p class="text-xs text-white/50 mt-2">Keseimbangan antara ketepatan dan kelengkapan</p>
</div>
</div>
<!-- Grafik Metrik -->
<div style="height:250px" class="mb-6">
<canvas id="metricsChart"></canvas>
</div>
<!-- Confusion Matrix (DIPERTAHANKAN) -->
<div class="mt-8">
<h4 class="font-semibold text-white mb-3">📊 Matriks Prediksi (Confusion Matrix)</h4>
<p class="text-white/70 text-sm mb-4">Tabel ini menunjukkan detail hasil prediksi sistem</p>
@if(isset($cm) && count($cm) > 1)
<div class="overflow-x-auto">
<table class="w-full max-w-2xl mx-auto border-collapse">
<!-- Header -->
<tr>
<td class="p-2"></td>
<td class="p-3 text-center font-semibold bg-white/20 text-white rounded-tl-lg" colspan="2">HASIL PREDIKSI SISTEM</td>
</tr>
<tr>
<td class="p-2"></td>
<td class="p-3 text-center bg-red-500/20 font-medium text-red-300 rounded-bl-lg">Diprediksi NEGATIF</td>
<td class="p-3 text-center bg-green-500/20 font-medium text-green-300 rounded-br-lg">Diprediksi POSITIF</td>
</tr>
<!-- Data -->
@foreach($cm as $i=>$row)
@if($i>0 && isset($row[1]) && isset($row[2]))
<tr>
<td class="p-3 font-medium bg-white/10 text-white rounded-l-lg">
{{ $i == 1 ? 'AKTUAL NEGATIF' : 'AKTUAL POSITIF' }}
<span class="block text-xs text-white/50">(Kenyataan sebenarnya)</span>
</td>
<td class="p-4 text-center bg-red-500/10 border-2 {{ $i==1 ? 'border-red-500/30' : 'border-orange-500/30' }}">
<span class="block text-2xl font-bold {{ $i==1 ? 'text-red-300' : 'text-orange-300' }}">{{ number_format($row[1]) }}</span>
<span class="text-xs text-white/70">
@if($i==1)
Benar Negatif
<span class="block text-xs text-white/50">(Sistem benar memprediksi NEGATIF)</span>
@else
Salah Negatif
<span class="block text-xs text-white/50">(Sistem salah memprediksi NEGATIF, padahal POSITIF)</span>
@endif
</span>
</td>
<td class="p-4 text-center bg-green-500/10 border-2 {{ $i==2 ? 'border-green-500/30' : 'border-yellow-500/30' }}">
<span class="block text-2xl font-bold {{ $i==2 ? 'text-green-300' : 'text-yellow-300' }}">{{ number_format($row[2]) }}</span>
<span class="text-xs text-white/70">
@if($i==2)
Benar Positif
<span class="block text-xs text-white/50">(Sistem benar memprediksi POSITIF)</span>
@else
Salah Positif
<span class="block text-xs text-white/50">(Sistem salah memprediksi POSITIF, padahal NEGATIF)</span>
@endif
</span>
</td>
</tr>
@endif
@endforeach
</table>
</div>
<!-- Penjelasan Sederhana -->
<div class="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-green-500/10 p-4 rounded-lg">
<p class="font-semibold text-green-300 mb-2"> Prediksi Benar</p>
<ul class="text-sm text-white/80 space-y-2">
<li> <span class="font-medium">Benar Positif ({{ number_format($cm[2][2] ?? 0) }})</span>: Sistem benar memprediksi POSITIF</li>
<li> <span class="font-medium">Benar Negatif ({{ number_format($cm[1][1] ?? 0) }})</span>: Sistem benar memprediksi NEGATIF</li>
</ul>
</div>
<div class="bg-red-500/10 p-4 rounded-lg">
<p class="font-semibold text-red-300 mb-2"> Prediksi Salah</p>
<ul class="text-sm text-white/80 space-y-2">
<li> <span class="font-medium">Salah Positif ({{ number_format($cm[1][2] ?? 0) }})</span>: Sistem salah prediksi POSITIF</li>
<li> <span class="font-medium">Salah Negatif ({{ number_format($cm[2][1] ?? 0) }})</span>: Sistem salah prediksi NEGATIF</li>
</ul>
</div>
</div>
<!-- Ringkasan -->
<div class="mt-4 bg-white/10 p-4 rounded-lg">
<p class="text-sm text-white">
<span class="font-semibold">📈 Ringkasan:</span><br>
Dari total {{ number_format($totalData) }} ulasan, sistem berhasil memprediksi dengan benar
<span class="font-bold text-green-300">{{ number_format(($cm[1][1] ?? 0) + ($cm[2][2] ?? 0)) }} data</span>
({{ $totalData > 0 ? round((($cm[1][1] ?? 0) + ($cm[2][2] ?? 0)) / $totalData * 100, 1) : 0 }}%)
dan salah memprediksi
<span class="font-bold text-red-300">{{ number_format(($cm[1][2] ?? 0) + ($cm[2][1] ?? 0)) }} data</span>.
</p>
</div>
@else
<div class="text-center py-8 bg-white/10 rounded-lg">
<p class="text-white/70">Data confusion matrix belum tersedia</p>
</div>
@endif
</div>
</div>
</div>
<!-- ========== TAB MASALAH & SARAN ========== -->
<div x-show="activeTab === 'masalah'" x-cloak>
<div class="bg-[#1e3a8a] rounded-xl shadow-lg p-6">
<h3 class="font-semibold text-white mb-2">Kategori Masalah & Saran Perbaikan</h3>
<p class="text-white/70 text-sm mb-6">Keluhan pengguna yang perlu mendapatkan perhatian</p>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
@forelse($maintenance as $kategori => $jumlah)
<div class="bg-white/10 rounded-lg p-5 hover:bg-white/20 transition-colors">
<div class="flex items-start justify-between mb-3">
<h4 class="font-semibold text-white">{{ $kategori }}</h4>
<span class="bg-red-500/30 text-red-300 px-2 py-1 rounded text-xs font-bold">{{ $jumlah }}</span>
</div>
<p class="text-sm text-white/70 mb-4">
{{ $jumlah }} pengguna melaporkan masalah ini
</p>
@if(!empty($maintenanceDetails[$kategori]))
<button
@click="
openModal = true;
selectedCategory = '{{ $kategori }}';
selectedData = {{ json_encode($maintenanceDetails[$kategori]) }};
"
class="w-full px-4 py-2 bg-white/20 text-white rounded-lg text-sm hover:bg-white/30 transition-colors flex items-center justify-center">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
</svg>
Lihat Detail Keluhan
</button>
@endif
</div>
@empty
<div class="col-span-full text-center py-12">
<div class="bg-white/10 rounded-lg p-8">
<svg class="w-16 h-16 mx-auto text-green-300 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<p class="text-white font-medium">Tidak ada masalah yang dilaporkan</p>
<p class="text-sm text-white/50 mt-1">Semua sistem berjalan dengan baik</p>
</div>
</div>
@endforelse
</div>
</div>
</div>
<!-- ========== MODAL DETAIL KELUHAN ========== -->
<div x-show="openModal"
x-cloak
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="fixed inset-0 z-50 overflow-y-auto"
style="display: none;">
<div class="fixed inset-0 bg-black/70" @click="openModal = false"></div>
<div class="relative min-h-screen flex items-center justify-center p-4">
<div class="relative bg-[#1e3a8a] rounded-xl shadow-xl w-full max-w-2xl max-h-[80vh] overflow-hidden">
<!-- Header Modal -->
<div class="bg-white/10 p-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="bg-white/20 p-2 rounded-lg">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-white">Detail Keluhan</h3>
<p class="text-white/70 text-sm" x-text="selectedCategory"></p>
</div>
</div>
<button @click="openModal = false" class="text-white/80 hover:text-white">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
</div>
<!-- Konten Modal -->
<div class="p-6 overflow-y-auto max-h-[calc(80vh-120px)]">
<div class="mb-4 flex items-center justify-between">
<span class="text-sm text-white/70">Total Keluhan:</span>
<span class="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium"
x-text="selectedData.length + ' ulasan'"></span>
</div>
<div class="space-y-3">
<template x-for="(item, index) in selectedData" :key="index">
<div class="bg-white/10 p-4 rounded-lg">
<div class="flex items-start space-x-3">
<span class="flex-shrink-0 w-6 h-6 bg-white/20 text-white rounded-full flex items-center justify-center text-xs font-bold"
x-text="index + 1"></span>
<p class="text-white/90 text-sm" x-text="item"></p>
</div>
</div>
</template>
</div>
</div>
<!-- Footer Modal -->
<div class="bg-white/10 px-6 py-3 flex justify-end">
<button @click="openModal = false"
class="px-4 py-2 bg-white/20 text-white rounded-lg hover:bg-white/30 transition-colors text-sm">
Tutup
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('alpine:init', () => {
setTimeout(() => {
initializeCharts();
}, 100);
});
function initializeCharts() {
// Data
const positif = {{ $positif }};
const negatif = {{ $negatif }};
const scoreData = [
{{ $score_0_20 }},
{{ $score_21_40 }},
{{ $score_41_60 }},
{{ $score_61_80 }},
{{ $score_81_100 }}
];
const metricsNegatif = [
{{ $metricsNegatif['precision'] }},
{{ $metricsNegatif['recall'] }},
{{ $metricsNegatif['f1'] }}
];
const metricsPositif = [
{{ $metricsPositif['precision'] }},
{{ $metricsPositif['recall'] }},
{{ $metricsPositif['f1'] }}
];
// Hapus chart lama
['barChart', 'pieChart', 'scoreChart', 'metricsChart'].forEach(chartId => {
const canvas = document.getElementById(chartId);
if (canvas) {
const existingChart = Chart.getChart(canvas);
if (existingChart) existingChart.destroy();
}
});
// Bar Chart
new Chart(document.getElementById('barChart'), {
type: 'bar',
data: {
labels: ['Positif', 'Negatif'],
datasets: [{
data: [positif, negatif],
backgroundColor: ['#10b981', '#ef4444'],
borderRadius: 5,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: {
y: {
beginAtZero: true,
grid: { color: 'rgba(255,255,255,0.1)' },
ticks: { color: 'white' }
},
x: { ticks: { color: 'white' } }
}
}
});
// Pie Chart
new Chart(document.getElementById('pieChart'), {
type: 'doughnut',
data: {
labels: ['Positif', 'Negatif'],
datasets: [{
data: [positif, negatif],
backgroundColor: ['#10b981', '#ef4444'],
borderWidth: 0,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
}
},
cutout: '60%',
}
});
// Score Chart
new Chart(document.getElementById('scoreChart'), {
type: 'line',
data: {
labels: ['0-20', '21-40', '41-60', '61-80', '81-100'],
datasets: [{
data: scoreData,
borderColor: '#60a5fa',
backgroundColor: 'rgba(96, 165, 250, 0.2)',
borderWidth: 2,
fill: true,
tension: 0.4,
pointBackgroundColor: '#60a5fa',
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: {
y: {
beginAtZero: true,
grid: { color: 'rgba(255,255,255,0.1)' },
ticks: { color: 'white' }
},
x: { ticks: { color: 'white' } }
}
}
});
// Metrics Chart
new Chart(document.getElementById('metricsChart'), {
type: 'bar',
data: {
labels: ['Precision', 'Recall', 'F1-Score'],
datasets: [
{ label: 'Negatif', data: metricsNegatif, backgroundColor: '#ef4444' },
{ label: 'Positif', data: metricsPositif, backgroundColor: '#10b981' }
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: 'white' }
}
},
scales: {
y: {
min: 0,
max: 1,
ticks: {
callback: v => (v * 100) + '%',
color: 'white'
},
grid: { color: 'rgba(255,255,255,0.1)' }
},
x: { ticks: { color: 'white' } }
}
}
});
}
</script>
<style>
[x-cloak] { display: none !important; }
</style>
</x-app-layout>