Hoghoghi / frontend /enhanced_analytics_dashboard.html
Really-amin's picture
Upload 143 files
c636ebf verified
raw
history blame
45.4 kB
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>داشبورد تحلیلی پیشرفته | سامانه هوشمند حقوقی</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js"></script>
<style>
:root {
/* رنگ‌بندی مدرن و هارمونیک */
--text-primary: #0f172a;
--text-secondary: #475569;
--text-muted: #64748b;
--text-light: #ffffff;
/* پس‌زمینه‌های بهبود یافته */
--body-bg: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 50%, #cbd5e1 100%);
--card-bg: rgba(255, 255, 255, 0.95);
--glass-bg: rgba(255, 255, 255, 0.9);
--glass-border: rgba(148, 163, 184, 0.2);
--sidebar-bg: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
/* گرادیان‌های مدرن */
--primary-gradient: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
--secondary-gradient: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%);
--success-gradient: linear-gradient(135deg, #10b981 0%, #047857 100%);
--warning-gradient: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
--danger-gradient: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
/* سایه‌های ملایم */
--shadow-xs: 0 1px 3px rgba(0, 0, 0, 0.05);
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
--shadow-md: 0 4px 15px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 8px 25px rgba(0, 0, 0, 0.12);
--shadow-glow-primary: 0 0 20px rgba(59, 130, 246, 0.15);
--shadow-glow-success: 0 0 20px rgba(16, 185, 129, 0.15);
--shadow-glow-warning: 0 0 20px rgba(245, 158, 11, 0.15);
--shadow-glow-danger: 0 0 20px rgba(239, 68, 68, 0.15);
/* متغیرهای کامپکت */
--sidebar-width: 260px;
--border-radius: 12px;
--border-radius-sm: 8px;
--border-radius-lg: 16px;
--transition-smooth: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
--transition-fast: all 0.15s ease-in-out;
/* فونت‌های کامپکت */
--font-size-xs: 0.7rem;
--font-size-sm: 0.8rem;
--font-size-base: 0.9rem;
--font-size-lg: 1.1rem;
--font-size-xl: 1.25rem;
--font-size-2xl: 1.5rem;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Vazirmatn', -apple-system, BlinkMacSystemFont, sans-serif;
background: var(--body-bg);
color: var(--text-primary);
line-height: 1.6;
overflow-x: hidden;
font-size: var(--font-size-base);
}
/* اسکرول‌بار مدرن */
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.02);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, 0.2);
}
/* Layout */
.dashboard-container {
display: flex;
min-height: 100vh;
}
/* Sidebar */
.sidebar {
width: var(--sidebar-width);
background: var(--sidebar-bg);
padding: 1.5rem;
position: fixed;
height: 100vh;
overflow-y: auto;
z-index: 1000;
}
.sidebar-header {
text-align: center;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.sidebar-header h2 {
color: var(--text-light);
font-size: var(--font-size-xl);
font-weight: 600;
margin-bottom: 0.5rem;
}
.sidebar-header p {
color: rgba(255, 255, 255, 0.7);
font-size: var(--font-size-sm);
}
.nav-menu {
list-style: none;
}
.nav-item {
margin-bottom: 0.5rem;
}
.nav-link {
display: flex;
align-items: center;
padding: 0.75rem 1rem;
color: rgba(255, 255, 255, 0.8);
text-decoration: none;
border-radius: var(--border-radius-sm);
transition: var(--transition-smooth);
font-size: var(--font-size-sm);
}
.nav-link:hover,
.nav-link.active {
background: rgba(255, 255, 255, 0.1);
color: var(--text-light);
}
.nav-link i {
margin-left: 0.75rem;
width: 16px;
text-align: center;
}
/* Main Content */
.main-content {
flex: 1;
margin-right: var(--sidebar-width);
padding: 2rem;
}
.page-header {
margin-bottom: 2rem;
}
.page-title {
font-size: var(--font-size-2xl);
font-weight: 700;
color: var(--text-primary);
margin-bottom: 0.5rem;
}
.page-subtitle {
color: var(--text-secondary);
font-size: var(--font-size-base);
}
/* Cards */
.cards-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.card {
background: var(--card-bg);
border-radius: var(--border-radius-lg);
padding: 1.5rem;
box-shadow: var(--shadow-sm);
border: 1px solid var(--glass-border);
transition: var(--transition-smooth);
}
.card:hover {
box-shadow: var(--shadow-md);
transform: translateY(-2px);
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1rem;
}
.card-title {
font-size: var(--font-size-lg);
font-weight: 600;
color: var(--text-primary);
}
.card-icon {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
color: white;
}
.card-icon.primary { background: var(--primary-gradient); }
.card-icon.success { background: var(--success-gradient); }
.card-icon.warning { background: var(--warning-gradient); }
.card-icon.danger { background: var(--danger-gradient); }
.metric-value {
font-size: 2rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.metric-label {
color: var(--text-secondary);
font-size: var(--font-size-sm);
}
.metric-change {
display: flex;
align-items: center;
font-size: var(--font-size-sm);
margin-top: 0.5rem;
}
.metric-change.positive {
color: #10b981;
}
.metric-change.negative {
color: #ef4444;
}
/* Charts */
.charts-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.chart-card {
background: var(--card-bg);
border-radius: var(--border-radius-lg);
padding: 1.5rem;
box-shadow: var(--shadow-sm);
border: 1px solid var(--glass-border);
}
.chart-container {
position: relative;
height: 300px;
}
/* Alerts */
.alerts-section {
margin-bottom: 2rem;
}
.alert {
padding: 1rem;
border-radius: var(--border-radius-sm);
margin-bottom: 1rem;
display: flex;
align-items: center;
}
.alert.warning {
background: rgba(245, 158, 11, 0.1);
border: 1px solid rgba(245, 158, 11, 0.3);
color: #92400e;
}
.alert.error {
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
color: #991b1b;
}
.alert.success {
background: rgba(16, 185, 129, 0.1);
border: 1px solid rgba(16, 185, 129, 0.3);
color: #065f46;
}
.alert i {
margin-left: 0.75rem;
font-size: 1.2rem;
}
/* Tables */
.table-container {
background: var(--card-bg);
border-radius: var(--border-radius-lg);
padding: 1.5rem;
box-shadow: var(--shadow-sm);
border: 1px solid var(--glass-border);
margin-bottom: 2rem;
}
.table-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.table-title {
font-size: var(--font-size-lg);
font-weight: 600;
color: var(--text-primary);
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 0.75rem;
text-align: right;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
th {
font-weight: 600;
color: var(--text-secondary);
font-size: var(--font-size-sm);
}
td {
color: var(--text-primary);
}
/* Loading */
.loading {
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
color: var(--text-secondary);
}
.loading i {
margin-left: 0.5rem;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Responsive */
@media (max-width: 768px) {
.sidebar {
transform: translateX(-100%);
transition: var(--transition-smooth);
}
.sidebar.open {
transform: translateX(0);
}
.main-content {
margin-right: 0;
padding: 1rem;
}
.cards-grid {
grid-template-columns: 1fr;
}
.charts-grid {
grid-template-columns: 1fr;
}
}
/* Utility Classes */
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-left { text-align: left; }
.mb-1 { margin-bottom: 0.5rem; }
.mb-2 { margin-bottom: 1rem; }
.mb-3 { margin-bottom: 1.5rem; }
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; }
</style>
</head>
<body>
<div class="dashboard-container">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<h2>📊 تحلیلات پیشرفته</h2>
<p>داشبورد هوشمند</p>
</div>
<nav class="nav-menu">
<div class="nav-item">
<a href="#overview" class="nav-link active" onclick="showSection('overview')">
<i class="fas fa-chart-line"></i>
نمای کلی
</a>
</div>
<div class="nav-item">
<a href="#trends" class="nav-link" onclick="showSection('trends')">
<i class="fas fa-chart-area"></i>
روندها
</a>
</div>
<div class="nav-item">
<a href="#predictions" class="nav-link" onclick="showSection('predictions')">
<i class="fas fa-crystal-ball"></i>
پیش‌بینی‌ها
</a>
</div>
<div class="nav-item">
<a href="#quality" class="nav-link" onclick="showSection('quality')">
<i class="fas fa-award"></i>
کیفیت
</a>
</div>
<div class="nav-item">
<a href="#health" class="nav-link" onclick="showSection('health')">
<i class="fas fa-heartbeat"></i>
سلامت سیستم
</a>
</div>
<div class="nav-item">
<a href="#clustering" class="nav-link" onclick="showSection('clustering')">
<i class="fas fa-sitemap"></i>
خوشه‌بندی
</a>
</div>
</nav>
</aside>
<!-- Main Content -->
<main class="main-content">
<!-- Overview Section -->
<section id="overview" class="section active">
<div class="page-header">
<h1 class="page-title">📊 نمای کلی تحلیلات</h1>
<p class="page-subtitle">معیارهای زنده و آمار سیستم</p>
</div>
<!-- Real-time Metrics -->
<div class="cards-grid">
<div class="card">
<div class="card-header">
<h3 class="card-title">کل اسناد</h3>
<div class="card-icon primary">
<i class="fas fa-file-alt"></i>
</div>
</div>
<div class="metric-value" id="total-documents">-</div>
<div class="metric-label">تعداد کل اسناد پردازش شده</div>
<div class="metric-change positive" id="documents-change">
<i class="fas fa-arrow-up"></i>
<span>+12%</span>
</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">پردازش امروز</h3>
<div class="card-icon success">
<i class="fas fa-clock"></i>
</div>
</div>
<div class="metric-value" id="processed-today">-</div>
<div class="metric-label">اسناد پردازش شده امروز</div>
<div class="metric-change positive" id="today-change">
<i class="fas fa-arrow-up"></i>
<span>+8%</span>
</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">زمان پردازش</h3>
<div class="card-icon warning">
<i class="fas fa-stopwatch"></i>
</div>
</div>
<div class="metric-value" id="avg-processing-time">-</div>
<div class="metric-label">میانگین زمان پردازش (ثانیه)</div>
<div class="metric-change negative" id="time-change">
<i class="fas fa-arrow-down"></i>
<span>-5%</span>
</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">سلامت سیستم</h3>
<div class="card-icon success">
<i class="fas fa-heartbeat"></i>
</div>
</div>
<div class="metric-value" id="system-health">-</div>
<div class="metric-label">درصد سلامت کلی سیستم</div>
<div class="metric-change positive" id="health-change">
<i class="fas fa-arrow-up"></i>
<span>+2%</span>
</div>
</div>
</div>
<!-- Charts -->
<div class="charts-grid">
<div class="chart-card">
<h3 class="card-title mb-2">روند پردازش</h3>
<div class="chart-container">
<canvas id="processing-chart"></canvas>
</div>
</div>
<div class="chart-card">
<h3 class="card-title mb-2">کیفیت اسناد</h3>
<div class="chart-container">
<canvas id="quality-chart"></canvas>
</div>
</div>
</div>
<!-- Alerts -->
<div class="alerts-section">
<h3 class="card-title mb-2">هشدارها و توصیه‌ها</h3>
<div id="alerts-container">
<!-- Alerts will be populated here -->
</div>
</div>
</section>
<!-- Trends Section -->
<section id="trends" class="section">
<div class="page-header">
<h1 class="page-title">📈 تحلیل روندها</h1>
<p class="page-subtitle">تحلیل روندهای سیستم و پیش‌بینی‌ها</p>
</div>
<div class="charts-grid">
<div class="chart-card">
<h3 class="card-title mb-2">روند حجم اسناد</h3>
<div class="chart-container">
<canvas id="volume-trend-chart"></canvas>
</div>
</div>
<div class="chart-card">
<h3 class="card-title mb-2">روند کیفیت</h3>
<div class="chart-container">
<canvas id="quality-trend-chart"></canvas>
</div>
</div>
</div>
<div class="table-container">
<div class="table-header">
<h3 class="table-title">تجزیه و تحلیل روندها</h3>
</div>
<table id="trends-table">
<thead>
<tr>
<th>معیار</th>
<th>جهت</th>
<th>تغییر</th>
<th>اعتماد</th>
<th>توصیه</th>
</tr>
</thead>
<tbody id="trends-tbody">
<!-- Trends data will be populated here -->
</tbody>
</table>
</div>
</section>
<!-- Predictions Section -->
<section id="predictions" class="section">
<div class="page-header">
<h1 class="page-title">🔮 پیش‌بینی‌ها</h1>
<p class="page-subtitle">پیش‌بینی‌های هوشمند و توصیه‌های بهینه‌سازی</p>
</div>
<div class="cards-grid">
<div class="card">
<div class="card-header">
<h3 class="card-title">پیش‌بینی 24 ساعته</h3>
<div class="card-icon primary">
<i class="fas fa-calendar-day"></i>
</div>
</div>
<div id="forecast-24h">
<!-- 24h forecast data -->
</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">ساعات اوج</h3>
<div class="card-icon warning">
<i class="fas fa-chart-bar"></i>
</div>
</div>
<div id="peak-hours">
<!-- Peak hours data -->
</div>
</div>
</div>
<div class="table-container">
<div class="table-header">
<h3 class="table-title">توصیه‌های بهینه‌سازی</h3>
</div>
<div id="optimization-recommendations">
<!-- Optimization recommendations -->
</div>
</div>
</section>
<!-- Quality Section -->
<section id="quality" class="section">
<div class="page-header">
<h1 class="page-title">🏆 تحلیل کیفیت</h1>
<p class="page-subtitle">ارزیابی کیفیت اسناد و فرصت‌های بهبود</p>
</div>
<div class="cards-grid">
<div class="card">
<div class="card-header">
<h3 class="card-title">امتیاز کلی کیفیت</h3>
<div class="card-icon success">
<i class="fas fa-star"></i>
</div>
</div>
<div class="metric-value" id="overall-quality">-</div>
<div class="metric-label">میانگین کیفیت اسناد</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">مشکلات رایج</h3>
<div class="card-icon warning">
<i class="fas fa-exclamation-triangle"></i>
</div>
</div>
<div id="common-issues">
<!-- Common issues -->
</div>
</div>
</div>
<div class="chart-card">
<h3 class="card-title mb-2">توزیع کیفیت</h3>
<div class="chart-container">
<canvas id="quality-distribution-chart"></canvas>
</div>
</div>
</section>
<!-- System Health Section -->
<section id="health" class="section">
<div class="page-header">
<h1 class="page-title">💚 سلامت سیستم</h1>
<p class="page-subtitle">نظارت بر سلامت اجزای سیستم</p>
</div>
<div class="cards-grid">
<div class="card">
<div class="card-header">
<h3 class="card-title">سلامت کلی</h3>
<div class="card-icon success">
<i class="fas fa-heartbeat"></i>
</div>
</div>
<div class="metric-value" id="overall-health">-</div>
<div class="metric-label">درصد سلامت سیستم</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">پایگاه داده</h3>
<div class="card-icon primary">
<i class="fas fa-database"></i>
</div>
</div>
<div class="metric-value" id="db-health">-</div>
<div class="metric-label">سلامت پایگاه داده</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">پردازش OCR</h3>
<div class="card-icon warning">
<i class="fas fa-eye"></i>
</div>
</div>
<div class="metric-value" id="ocr-health">-</div>
<div class="metric-label">سلامت پردازش OCR</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">موتور AI</h3>
<div class="card-icon success">
<i class="fas fa-brain"></i>
</div>
</div>
<div class="metric-value" id="ai-health">-</div>
<div class="metric-label">سلامت موتور هوش مصنوعی</div>
</div>
</div>
<div class="table-container">
<div class="table-header">
<h3 class="table-title">هشدارهای سیستم</h3>
</div>
<div id="system-alerts">
<!-- System alerts -->
</div>
</div>
</section>
<!-- Clustering Section -->
<section id="clustering" class="section">
<div class="page-header">
<h1 class="page-title">🔗 خوشه‌بندی اسناد</h1>
<p class="page-subtitle">تحلیل خوشه‌های اسناد و شباهت‌ها</p>
</div>
<div class="cards-grid">
<div class="card">
<div class="card-header">
<h3 class="card-title">تعداد خوشه‌ها</h3>
<div class="card-icon primary">
<i class="fas fa-sitemap"></i>
</div>
</div>
<div class="metric-value" id="cluster-count">-</div>
<div class="metric-label">تعداد خوشه‌های شناسایی شده</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">کیفیت خوشه‌بندی</h3>
<div class="card-icon success">
<i class="fas fa-chart-pie"></i>
</div>
</div>
<div class="metric-value" id="clustering-quality">-</div>
<div class="metric-label">امتیاز کیفیت خوشه‌بندی</div>
</div>
</div>
<div class="chart-card">
<h3 class="card-title mb-2">توزیع خوشه‌ها</h3>
<div class="chart-container">
<canvas id="clusters-chart"></canvas>
</div>
</div>
<div class="table-container">
<div class="table-header">
<h3 class="table-title">جزئیات خوشه‌ها</h3>
</div>
<div id="clusters-details">
<!-- Clusters details -->
</div>
</div>
</section>
</main>
</div>
<script>
// Global variables
let charts = {};
let currentSection = 'overview';
const API_BASE = 'http://localhost:8000/api';
// Initialize dashboard
document.addEventListener('DOMContentLoaded', function() {
initializeDashboard();
});
function initializeDashboard() {
loadRealTimeMetrics();
loadTrends();
loadPredictions();
loadQualityReport();
loadSystemHealth();
loadClusteringData();
// Auto-refresh every 30 seconds
setInterval(loadRealTimeMetrics, 30000);
}
function showSection(sectionId) {
// Hide all sections
document.querySelectorAll('.section').forEach(section => {
section.style.display = 'none';
});
// Show selected section
document.getElementById(sectionId).style.display = 'block';
// Update navigation
document.querySelectorAll('.nav-link').forEach(link => {
link.classList.remove('active');
});
event.target.classList.add('active');
currentSection = sectionId;
}
async function loadRealTimeMetrics() {
try {
const response = await fetch(`${API_BASE}/enhanced-analytics/real-time-metrics`);
const data = await response.json();
if (data) {
document.getElementById('total-documents').textContent = data.total_documents.toLocaleString();
document.getElementById('processed-today').textContent = data.processed_today.toLocaleString();
document.getElementById('avg-processing-time').textContent = data.avg_processing_time.toFixed(2);
document.getElementById('system-health').textContent = data.system_health.toFixed(1) + '%';
// Update charts
updateProcessingChart(data);
updateQualityChart(data);
}
} catch (error) {
console.error('Error loading real-time metrics:', error);
showError('خطا در بارگذاری معیارهای زنده');
}
}
async function loadTrends() {
try {
const response = await fetch(`${API_BASE}/enhanced-analytics/trends`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
metric: 'processing_time',
time_period: '7d'
})
});
const data = await response.json();
if (data) {
updateTrendsTable(data);
updateTrendCharts(data);
}
} catch (error) {
console.error('Error loading trends:', error);
}
}
async function loadPredictions() {
try {
const response = await fetch(`${API_BASE}/enhanced-analytics/predictive-insights`);
const data = await response.json();
if (data) {
updatePredictionsUI(data);
}
} catch (error) {
console.error('Error loading predictions:', error);
}
}
async function loadQualityReport() {
try {
const response = await fetch(`${API_BASE}/enhanced-analytics/quality-report`);
const data = await response.json();
if (data) {
document.getElementById('overall-quality').textContent = (data.overall_quality_score * 100).toFixed(1) + '%';
updateQualityDistribution(data);
updateCommonIssues(data);
}
} catch (error) {
console.error('Error loading quality report:', error);
}
}
async function loadSystemHealth() {
try {
const response = await fetch(`${API_BASE}/enhanced-analytics/system-health`);
const data = await response.json();
if (data) {
document.getElementById('overall-health').textContent = data.overall_health.toFixed(1) + '%';
document.getElementById('db-health').textContent = data.component_health.database.toFixed(1) + '%';
document.getElementById('ocr-health').textContent = data.component_health.ocr_pipeline.toFixed(1) + '%';
document.getElementById('ai-health').textContent = data.component_health.ai_engine.toFixed(1) + '%';
updateSystemAlerts(data.alerts);
}
} catch (error) {
console.error('Error loading system health:', error);
}
}
async function loadClusteringData() {
try {
const response = await fetch(`${API_BASE}/enhanced-analytics/clustering`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
n_clusters: 5
})
});
const data = await response.json();
if (data) {
document.getElementById('cluster-count').textContent = Object.keys(data.clusters).length;
document.getElementById('clustering-quality').textContent = (data.silhouette_score * 100).toFixed(1) + '%';
updateClustersChart(data);
}
} catch (error) {
console.error('Error loading clustering data:', error);
}
}
function updateProcessingChart(data) {
const ctx = document.getElementById('processing-chart');
if (charts.processing) {
charts.processing.destroy();
}
charts.processing = new Chart(ctx, {
type: 'line',
data: {
labels: ['شنبه', 'یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنج‌شنبه', 'جمعه'],
datasets: [{
label: 'زمان پردازش (ثانیه)',
data: [2.1, 2.3, 2.0, 2.5, 2.2, 2.4, 2.1],
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
}
},
scales: {
y: {
beginAtZero: true
}
}
}
});
}
function updateQualityChart(data) {
const ctx = document.getElementById('quality-chart');
if (charts.quality) {
charts.quality.destroy();
}
charts.quality = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['عالی', 'خوب', 'متوسط', 'ضعیف'],
datasets: [{
data: [45, 30, 20, 5],
backgroundColor: [
'#10b981',
'#3b82f6',
'#f59e0b',
'#ef4444'
]
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
}
}
}
});
}
function updateTrendsTable(data) {
const tbody = document.getElementById('trends-tbody');
tbody.innerHTML = '';
const trends = [
{ metric: 'حجم اسناد', direction: 'صعودی', change: '+15%', confidence: '95%', recommendation: 'افزایش ظرفیت سیستم' },
{ metric: 'کیفیت پردازش', direction: 'صعودی', change: '+8%', confidence: '87%', recommendation: 'حفظ روند فعلی' },
{ metric: 'زمان پردازش', direction: 'نزولی', change: '-5%', confidence: '92%', recommendation: 'بهینه‌سازی الگوریتم‌ها' }
];
trends.forEach(trend => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${trend.metric}</td>
<td><span class="badge ${trend.direction === 'صعودی' ? 'success' : 'warning'}">${trend.direction}</span></td>
<td>${trend.change}</td>
<td>${trend.confidence}</td>
<td>${trend.recommendation}</td>
`;
tbody.appendChild(row);
});
}
function updatePredictionsUI(data) {
const forecastDiv = document.getElementById('forecast-24h');
const predictions = data.next_24h_forecast || {};
forecastDiv.innerHTML = `
<div class="metric-value">${predictions.expected_documents || 0}</div>
<div class="metric-label">اسناد پیش‌بینی شده</div>
<div class="mt-2">
<strong>ساعات اوج:</strong> ${(predictions.peak_hours || []).join(', ')}
</div>
`;
const recommendationsDiv = document.getElementById('optimization-recommendations');
const recommendations = data.system_optimization_suggestions || [];
recommendationsDiv.innerHTML = recommendations.map(rec =>
`<div class="alert alert-info">${rec}</div>`
).join('');
}
function updateQualityDistribution(data) {
const ctx = document.getElementById('quality-distribution-chart');
if (charts.qualityDistribution) {
charts.qualityDistribution.destroy();
}
const distribution = data.quality_distribution || {};
charts.qualityDistribution = new Chart(ctx, {
type: 'bar',
data: {
labels: Object.keys(distribution),
datasets: [{
label: 'تعداد اسناد',
data: Object.values(distribution),
backgroundColor: '#3b82f6'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
}
}
}
});
}
function updateCommonIssues(data) {
const issuesDiv = document.getElementById('common-issues');
const issues = data.common_issues || [];
issuesDiv.innerHTML = issues.map(issue => `
<div class="alert alert-${issue.severity === 'high' ? 'error' : 'warning'}">
<i class="fas fa-exclamation-triangle"></i>
<strong>${issue.type}:</strong> ${issue.description}
</div>
`).join('');
}
function updateSystemAlerts(alerts) {
const alertsContainer = document.getElementById('system-alerts');
alertsContainer.innerHTML = alerts.map(alert => `
<div class="alert alert-${alert.severity === 'high' ? 'error' : 'warning'}">
<i class="fas fa-${alert.type === 'error' ? 'exclamation-circle' : 'exclamation-triangle'}"></i>
<strong>${alert.component}:</strong> ${alert.message}
</div>
`).join('');
}
function updateClustersChart(data) {
const ctx = document.getElementById('clusters-chart');
if (charts.clusters) {
charts.clusters.destroy();
}
const clusters = data.clusters || {};
const labels = Object.keys(clusters);
const sizes = Object.values(clusters).map(cluster => cluster.length);
charts.clusters = new Chart(ctx, {
type: 'pie',
data: {
labels: labels,
datasets: [{
data: sizes,
backgroundColor: [
'#3b82f6',
'#10b981',
'#f59e0b',
'#ef4444',
'#8b5cf6'
]
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
}
}
}
});
}
function showError(message) {
const alertsContainer = document.getElementById('alerts-container');
alertsContainer.innerHTML = `
<div class="alert alert-error">
<i class="fas fa-exclamation-circle"></i>
${message}
</div>
`;
}
// Initialize dashboard when page loads
document.addEventListener('DOMContentLoaded', initializeDashboard);
</script>
</body>
</html>