Spaces:
Paused
Paused
<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> |