917 lines
36 KiB
HTML
917 lines
36 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fa" dir="rtl">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>مستند فنی پروژه | ابزار رسم نمودارهای UML</title>
|
||
<style>
|
||
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700;800&display=swap');
|
||
:root {
|
||
--primary: #1a365d;
|
||
--primary-light: #2c5282;
|
||
--accent: #c9a961;
|
||
--accent-dark: #a8893f;
|
||
--bg: #faf9f6;
|
||
--card-bg: #ffffff;
|
||
--text: #1a202c;
|
||
--text-muted: #4a5568;
|
||
--border: #e2e8f0;
|
||
--success: #38a169;
|
||
--danger: #e53e3e;
|
||
--warning: #dd6b20;
|
||
--shadow: 0 4px 6px rgba(0,0,0,0.05), 0 10px 30px rgba(26,54,93,0.08);
|
||
}
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
body {
|
||
font-family: 'Vazirmatn', Tahoma, sans-serif;
|
||
background: var(--bg);
|
||
color: var(--text);
|
||
line-height: 1.9;
|
||
font-size: 15px;
|
||
padding: 30px 15px;
|
||
}
|
||
.document-container {
|
||
max-width: 950px;
|
||
margin: 0 auto;
|
||
background: var(--card-bg);
|
||
box-shadow: var(--shadow);
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
}
|
||
.document-header {
|
||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
|
||
color: white;
|
||
padding: 50px 40px 40px;
|
||
position: relative;
|
||
border-bottom: 4px solid var(--accent);
|
||
}
|
||
.document-header::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0; right: 0;
|
||
width: 200px; height: 200px;
|
||
background: radial-gradient(circle, rgba(201,169,97,0.15) 0%, transparent 70%);
|
||
border-radius: 50%;
|
||
transform: translate(50%, -50%);
|
||
}
|
||
.header-top {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 30px;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
.company-badge {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
.company-logo {
|
||
width: 60px; height: 60px;
|
||
background: var(--accent);
|
||
border-radius: 12px;
|
||
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
|
||
}
|
||
.doc-meta {
|
||
text-align: left;
|
||
font-size: 12px;
|
||
opacity: 0.9;
|
||
}
|
||
.doc-meta div { margin-bottom: 3px; }
|
||
.document-title {
|
||
text-align: center;
|
||
position: relative;
|
||
z-index: 1;
|
||
padding: 20px 0;
|
||
}
|
||
.document-title .label {
|
||
display: inline-block;
|
||
background: rgba(201,169,97,0.2);
|
||
color: var(--accent);
|
||
padding: 4px 16px;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
margin-bottom: 15px;
|
||
border: 1px solid rgba(201,169,97,0.4);
|
||
}
|
||
.document-title h1 {
|
||
font-size: 28px;
|
||
font-weight: 800;
|
||
margin-bottom: 10px;
|
||
letter-spacing: -0.5px;
|
||
}
|
||
.document-title h2 {
|
||
font-size: 16px;
|
||
font-weight: 400;
|
||
opacity: 0.9;
|
||
}
|
||
.document-body {
|
||
padding: 40px;
|
||
}
|
||
.intro-text {
|
||
background: linear-gradient(to left, #f7fafc, #edf2f7);
|
||
border-right: 4px solid var(--accent);
|
||
padding: 20px 25px;
|
||
border-radius: 8px;
|
||
margin-bottom: 35px;
|
||
font-size: 14px;
|
||
color: var(--text-muted);
|
||
}
|
||
.section {
|
||
margin-bottom: 40px;
|
||
page-break-inside: avoid;
|
||
}
|
||
.section-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 15px;
|
||
padding-bottom: 12px;
|
||
border-bottom: 2px solid var(--border);
|
||
margin-bottom: 20px;
|
||
}
|
||
.section-number {
|
||
width: 50px; height: 50px;
|
||
background: linear-gradient(135deg, var(--primary), var(--primary-light));
|
||
color: white;
|
||
border-radius: 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-weight: 800;
|
||
font-size: 20px;
|
||
flex-shrink: 0;
|
||
box-shadow: 0 4px 10px rgba(26,54,93,0.2);
|
||
}
|
||
.section-title { flex: 1; }
|
||
.section-title h3 {
|
||
font-size: 19px;
|
||
font-weight: 700;
|
||
color: var(--primary);
|
||
margin-bottom: 2px;
|
||
}
|
||
.section-title .subtitle {
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
}
|
||
.section-content {
|
||
padding-right: 10px;
|
||
}
|
||
.section-content p {
|
||
margin-bottom: 12px;
|
||
text-align: justify;
|
||
text-indent: 20px;
|
||
}
|
||
.section-content p.no-indent { text-indent: 0; }
|
||
.highlight-box {
|
||
background: linear-gradient(to left, #fffaf0, #fef5e7);
|
||
border: 1px solid #f6e05e;
|
||
border-right: 4px solid var(--accent);
|
||
padding: 18px 22px;
|
||
border-radius: 8px;
|
||
margin: 20px 0;
|
||
font-size: 14px;
|
||
}
|
||
.highlight-box strong {
|
||
color: var(--accent-dark);
|
||
}
|
||
.info-box {
|
||
background: linear-gradient(to left, #ebf8ff, #e6f6ff);
|
||
border: 1px solid #90cdf4;
|
||
border-right: 4px solid var(--primary-light);
|
||
padding: 18px 22px;
|
||
border-radius: 8px;
|
||
margin: 20px 0;
|
||
font-size: 14px;
|
||
}
|
||
.success-box {
|
||
background: linear-gradient(to left, #f0fff4, #e6fffa);
|
||
border: 1px solid #9ae6b4;
|
||
border-right: 4px solid var(--success);
|
||
padding: 18px 22px;
|
||
border-radius: 8px;
|
||
margin: 20px 0;
|
||
font-size: 14px;
|
||
}
|
||
.warning-box {
|
||
background: linear-gradient(to left, #fffaf0, #fef5e7);
|
||
border: 1px solid #fbd38d;
|
||
border-right: 4px solid var(--warning);
|
||
padding: 18px 22px;
|
||
border-radius: 8px;
|
||
margin: 20px 0;
|
||
font-size: 14px;
|
||
}
|
||
.styled-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin: 20px 0;
|
||
background: white;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
||
}
|
||
.styled-table thead {
|
||
background: linear-gradient(135deg, var(--primary), var(--primary-light));
|
||
color: white;
|
||
}
|
||
.styled-table th {
|
||
padding: 14px 16px;
|
||
text-align: right;
|
||
font-weight: 600;
|
||
font-size: 13px;
|
||
}
|
||
.styled-table td {
|
||
padding: 13px 16px;
|
||
border-bottom: 1px solid var(--border);
|
||
font-size: 13px;
|
||
}
|
||
.styled-table tbody tr:last-child td { border-bottom: none; }
|
||
.styled-table tbody tr:nth-child(even) { background: #f8fafc; }
|
||
.styled-table .highlight-row {
|
||
background: #fffaf0 !important;
|
||
font-weight: 600;
|
||
}
|
||
.code-block {
|
||
background: #1a202c;
|
||
color: #e2e8f0;
|
||
padding: 18px 22px;
|
||
border-radius: 8px;
|
||
margin: 15px 0;
|
||
font-family: 'Consolas', 'Courier New', monospace;
|
||
font-size: 13px;
|
||
line-height: 1.7;
|
||
direction: ltr;
|
||
text-align: left;
|
||
overflow-x: auto;
|
||
border-right: 4px solid var(--accent);
|
||
}
|
||
.code-block .keyword { color: #f6ad55; }
|
||
.code-block .string { color: #9ae6b4; }
|
||
.code-block .comment { color: #718096; font-style: italic; }
|
||
.code-block .func { color: #90cdf4; }
|
||
.stats-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 15px;
|
||
margin: 25px 0;
|
||
}
|
||
.stat-card {
|
||
background: linear-gradient(135deg, var(--primary), var(--primary-light));
|
||
color: white;
|
||
padding: 20px;
|
||
border-radius: 10px;
|
||
text-align: center;
|
||
box-shadow: 0 4px 12px rgba(26,54,93,0.2);
|
||
}
|
||
.stat-card .stat-value {
|
||
font-size: 24px;
|
||
font-weight: 800;
|
||
margin-bottom: 5px;
|
||
color: var(--accent);
|
||
line-height: 1.3;
|
||
}
|
||
.stat-card .stat-label {
|
||
font-size: 12px;
|
||
opacity: 0.9;
|
||
}
|
||
.diagram-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 15px;
|
||
margin: 25px 0;
|
||
}
|
||
.diagram-card {
|
||
background: #f8fafc;
|
||
border: 2px solid var(--border);
|
||
border-radius: 10px;
|
||
padding: 18px;
|
||
transition: all 0.2s;
|
||
}
|
||
.diagram-card:hover {
|
||
border-color: var(--primary-light);
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 12px rgba(26,54,93,0.1);
|
||
}
|
||
.diagram-card .icon {
|
||
font-size: 28px;
|
||
margin-bottom: 8px;
|
||
}
|
||
.diagram-card h4 {
|
||
font-size: 15px;
|
||
font-weight: 700;
|
||
color: var(--primary);
|
||
margin-bottom: 6px;
|
||
}
|
||
.diagram-card p {
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
text-indent: 0 !important;
|
||
margin-bottom: 0 !important;
|
||
}
|
||
.module-list {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 15px 0;
|
||
}
|
||
.module-list li {
|
||
background: #f8fafc;
|
||
border-right: 3px solid var(--primary-light);
|
||
padding: 12px 18px;
|
||
margin-bottom: 10px;
|
||
border-radius: 6px;
|
||
font-size: 13px;
|
||
}
|
||
.module-list li strong {
|
||
color: var(--primary);
|
||
display: inline-block;
|
||
margin-left: 8px;
|
||
}
|
||
.conclusion-box {
|
||
background: linear-gradient(135deg, var(--primary), var(--primary-light));
|
||
color: white;
|
||
padding: 30px;
|
||
border-radius: 12px;
|
||
margin: 30px 0;
|
||
text-align: center;
|
||
box-shadow: 0 8px 20px rgba(26,54,93,0.3);
|
||
}
|
||
.conclusion-box h3 {
|
||
font-size: 22px;
|
||
font-weight: 800;
|
||
margin-bottom: 15px;
|
||
color: var(--accent);
|
||
}
|
||
.conclusion-box p {
|
||
font-size: 14px;
|
||
line-height: 1.8;
|
||
text-indent: 0 !important;
|
||
margin-bottom: 15px;
|
||
}
|
||
.conclusion-box .highlight {
|
||
background: rgba(201,169,97,0.2);
|
||
padding: 15px 20px;
|
||
border-radius: 8px;
|
||
margin-top: 20px;
|
||
border: 1px solid rgba(201,169,97,0.4);
|
||
}
|
||
.document-footer {
|
||
background: var(--primary);
|
||
color: white;
|
||
padding: 25px 40px;
|
||
text-align: center;
|
||
font-size: 12px;
|
||
margin-top: 40px;
|
||
}
|
||
.document-footer .footer-brand {
|
||
font-weight: 700;
|
||
color: var(--accent);
|
||
margin-bottom: 5px;
|
||
font-size: 14px;
|
||
}
|
||
.footer-divider {
|
||
width: 60px;
|
||
height: 2px;
|
||
background: var(--accent);
|
||
margin: 10px auto;
|
||
}
|
||
.page-info {
|
||
text-align: center;
|
||
padding: 15px;
|
||
font-size: 11px;
|
||
color: var(--text-muted);
|
||
border-top: 1px solid var(--border);
|
||
margin-top: 30px;
|
||
}
|
||
@media print {
|
||
body { background: white; padding: 0; }
|
||
.document-container { box-shadow: none; border-radius: 0; }
|
||
.section { page-break-inside: avoid; }
|
||
}
|
||
@media (max-width: 768px) {
|
||
.document-body { padding: 25px 20px; }
|
||
.document-header { padding: 30px 20px; }
|
||
.diagram-grid { grid-template-columns: 1fr; }
|
||
.stats-grid { grid-template-columns: 1fr; }
|
||
.header-top { flex-direction: column; gap: 15px; }
|
||
.doc-meta { text-align: center; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="document-container">
|
||
<header class="document-header">
|
||
<div class="header-top">
|
||
<div class="company-badge">
|
||
<div class="company-logo"></div>
|
||
</div>
|
||
<div class="doc-meta">
|
||
<div>شماره مستند: UML-TOOL-DOC-1405-001</div>
|
||
<div>نسخه: ۱.۰</div>
|
||
<div>تاریخ تهیه: ۱۶ شهریور ۱۴۰۵ — ساعت ۱۰:۳۰</div>
|
||
<div>طبقهبندی: محرمانه / فنی</div>
|
||
</div>
|
||
</div>
|
||
<div class="document-title">
|
||
<span class="label">TECHNICAL DOCUMENTATION</span>
|
||
<h1>مستند فنی پروژه ابزار رسم نمودارهای UML</h1>
|
||
<h2>تحلیل معماری، ماژولها، موتور رسم و ساختار داده</h2>
|
||
</div>
|
||
</header>
|
||
<div class="document-body">
|
||
<div class="intro-text">
|
||
<strong>همکاران فنی و ذینفعان گرامی،</strong><br>
|
||
این مستند بهعنوان مرجع فنی جامع پروژه «ابزار رسم نمودارهای UML» تهیه شده است. هدف از این مستند، تشریح دقیق معماری، ساختار کد، ماژولهای کلیدی، الگوهای طراحی بهکار رفته و قابلیتهای فنی این ابزار میباشد تا تیمهای توسعه و نگهداری بتوانند با دیدی کامل و یکپارچه، به تحلیل، توسعه و گسترش آن بپردازند.
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۱</div>
|
||
<div class="section-title">
|
||
<h3>خلاصه اجرایی پروژه</h3>
|
||
<div class="subtitle">Executive Summary</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>پروژه «ابزار رسم نمودارهای UML» یک اپلیکیشن تحت وب کاملاً سمت کلاینت (Client-Side) است که با استفاده از تکنولوژیهای HTML5، CSS3 و JavaScript خالص (Vanilla JS) توسعه یافته است. این ابزار بدون نیاز به هیچگونه Backend یا فریمورک خارجی، امکان رسم، ویرایش، ذخیره و بازیابی هشت نوع نمودار استاندارد UML را در محیطی تعاملی و حرفهای فراهم میآورد.</p>
|
||
<div class="stats-grid">
|
||
<div class="stat-card">
|
||
<div class="stat-value">۸</div>
|
||
<div class="stat-label">نوع نمودار UML پشتیبانی شده</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-value">۵۰+</div>
|
||
<div class="stat-label">المان و رابطه قابل رسم</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-value">۱۰۰٪</div>
|
||
<div class="stat-label">اجرا در سمت مرورگر (بدون Backend)</div>
|
||
</div>
|
||
</div>
|
||
<div class="highlight-box">
|
||
<strong>💎 ارزش کلیدی:</strong> این ابزار با تکیه بر HTML5 Canvas API و معماری ماژولار، یک محیط حرفهای، سبک و کاملاً آفلاین برای مدلسازی سیستمهای نرمافزاری در اختیار معماران و تحلیلگران قرار میدهد.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۲</div>
|
||
<div class="section-title">
|
||
<h3>معماری کلی سیستم</h3>
|
||
<div class="subtitle">System Architecture Overview</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>معماری این پروژه بر پایه الگوی <strong>Single-Page Application (SPA)</strong> و با رویکرد <strong>State-Centric</strong> طراحی شده است. تمامی وضعیتهای برنامه در یک آبجکت مرکزی <code>state</code> نگهداری میشوند و هر تغییر در state منجر به بازترسیم کامل (Redraw) بوم میگردد.</p>
|
||
<ul class="module-list">
|
||
<li><strong>🎨 Rendering Layer:</strong> موتور رسم مبتنی بر HTML5 Canvas 2D Context با قابلیت پشتیبانی از تم روشن و تاریک.</li>
|
||
<li><strong>🧠 State Management:</strong> یک آبجکت سراسری <code>state</code> که شامل لیست نمودارها، نمودار فعال، ابزار جاری، وضعیت Drag & Draw و تنظیمات UI است.</li>
|
||
<li><strong>🖱️ Interaction Layer:</strong> مدیریت رویدادهای Mouse (mousedown, mousemove, mouseup, dblclick) و Keyboard برای تعامل با المانها.</li>
|
||
<li><strong>💾 Persistence Layer:</strong> سیستم ذخیرهسازی مبتنی بر JSON File API (بدون نیاز به LocalStorage یا Backend).</li>
|
||
<li><strong>🎛️ UI Layer:</strong> رابط کاربری مبتنی بر Sidebar، Tab Bar، Modal ها و Properties Panel.</li>
|
||
</ul>
|
||
<div class="code-block">
|
||
<span class="comment">// ساختار کلی State Object</span><br>
|
||
<span class="keyword">const</span> state = {<br>
|
||
diagrams: [], <span class="comment">// لیست همه نمودارها</span><br>
|
||
activeDiagramId: <span class="keyword">null</span>, <span class="comment">// شناسه نمودار فعال</span><br>
|
||
currentTool: <span class="string">'select'</span>, <span class="comment">// ابزار انتخابشده</span><br>
|
||
selectedElement: <span class="keyword">null</span>, <span class="comment">// المان انتخابشده</span><br>
|
||
isDragging: <span class="keyword">false</span>, <span class="comment">// وضعیت Drag</span><br>
|
||
isDrawingRelationship: <span class="keyword">false</span>,<br>
|
||
darkMode: <span class="keyword">true</span>, <span class="comment">// تم تاریک/روشن</span><br>
|
||
gridType: <span class="string">'lines'</span>, <span class="comment">// نوع خطکشی بوم</span><br>
|
||
fileMetadata: { ... } <span class="comment">// متادیتای پروژه</span><br>
|
||
};
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۳</div>
|
||
<div class="section-title">
|
||
<h3>تکنولوژیهای بهکار رفته</h3>
|
||
<div class="subtitle">Technology Stack</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<table class="styled-table">
|
||
<thead>
|
||
<tr>
|
||
<th>لایه</th>
|
||
<th>تکنولوژی</th>
|
||
<th>نقش در پروژه</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>ساختار</td>
|
||
<td>HTML5 Semantic</td>
|
||
<td>ساختار صفحه و المانهای DOM</td>
|
||
</tr>
|
||
<tr>
|
||
<td>استایل</td>
|
||
<td>CSS3 + CSS Variables</td>
|
||
<td>طراحی RTL، تم داینامیک، گرادیانتها</td>
|
||
</tr>
|
||
<tr>
|
||
<td>رسم گرافیکی</td>
|
||
<td>HTML5 Canvas 2D API</td>
|
||
<td>موتور رسم نمودارها، Grid و المانها</td>
|
||
</tr>
|
||
<tr>
|
||
<td>منطق برنامه</td>
|
||
<td>Vanilla JavaScript (ES6+)</td>
|
||
<td>State Management، Event Handling، Drawing Engine</td>
|
||
</tr>
|
||
<tr>
|
||
<td>ذخیرهسازی</td>
|
||
<td>File API + JSON</td>
|
||
<td>Export/Import پروژه بهصورت فایل JSON</td>
|
||
</tr>
|
||
<tr>
|
||
<td>فونت</td>
|
||
<td>Vazirmatn (Google Fonts)</td>
|
||
<td>تایپوگرافی فارسی حرفهای</td>
|
||
</tr>
|
||
<tr>
|
||
<td>استایل کمکی</td>
|
||
<td>Tailwind CSS (CDN)</td>
|
||
<td>Utility classes برای UI سریع</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="info-box">
|
||
<strong>💡 نکته معماری:</strong> انتخاب Vanilla JS به جای فریمورکهایی مانند React یا Angular، باعث کاهش چشمگیر حجم نهایی (Bundle Size)، اجرای سریعتر و عدم وابستگی به ابزارهای Build شده است. این رویکرد برای ابزارهای تخصصی و آفلاین، انتخاب بهینهای است.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۴</div>
|
||
<div class="section-title">
|
||
<h3>نمودارهای پشتیبانیشده</h3>
|
||
<div class="subtitle">Supported UML Diagrams</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>این ابزار هشت نوع نمودار استاندارد UML را پشتیبانی میکند که هر کدام در رجیستری <code>DIAGRAM_TYPES</code> تعریف شدهاند. این رجیستری بهعنوان <strong>Single Source of Truth</strong> برای ابزارها، گروهها و قابلیتهای هر نمودار عمل میکند.</p>
|
||
<div class="diagram-grid">
|
||
<div class="diagram-card">
|
||
<div class="icon">⭕</div>
|
||
<h4>Use Case Diagram</h4>
|
||
<p>مدلسازی Actorها، Use Caseها، System Boundary و روابط Include/Extend/Generalization.</p>
|
||
</div>
|
||
<div class="diagram-card">
|
||
<div class="icon">🔄</div>
|
||
<h4>State Machine Diagram</h4>
|
||
<p>Initial/Final State، Stateها، Composite State و Transition با برچسب اختیاری.</p>
|
||
</div>
|
||
<div class="diagram-card">
|
||
<div class="icon">🔀</div>
|
||
<h4>Activity Diagram</h4>
|
||
<p>Action، Decision/Merge، Fork/Join و جریانهای Control/Object Flow.</p>
|
||
</div>
|
||
<div class="diagram-card">
|
||
<div class="icon">🧩</div>
|
||
<h4>Component Diagram</h4>
|
||
<p>Component، Interface (Provided/Required)، Package و روابط Dependency/Connector.</p>
|
||
</div>
|
||
<div class="diagram-card">
|
||
<div class="icon">🖥️</div>
|
||
<h4>Deployment Diagram</h4>
|
||
<p>Node، Device، Execution Environment، Artifact و روابط Deploy/Manifest.</p>
|
||
</div>
|
||
<div class="diagram-card">
|
||
<div class="icon">🗂️</div>
|
||
<h4>Class Diagram</h4>
|
||
<p>Class، Interface، Abstract، Enumeration با Attributes/Methods و روابط کامل UML.</p>
|
||
</div>
|
||
<div class="diagram-card">
|
||
<div class="icon">🔢</div>
|
||
<h4>Sequence Diagram</h4>
|
||
<p>Participant، Activation، Combined Fragment و پیامهای Sync/Async/Return/Self.</p>
|
||
</div>
|
||
<div class="diagram-card">
|
||
<div class="icon">▤</div>
|
||
<h4>Swimlane Diagram</h4>
|
||
<p>Swimlane افقی/عمودی با قابلیت Resize، Action، Decision و Fork/Join درون آن.</p>
|
||
</div>
|
||
</div>
|
||
<div class="code-block">
|
||
<span class="comment">// Registry الگوی طراحی - نمونه تعریف یک نمودار</span><br>
|
||
<span class="keyword">const</span> DIAGRAM_TYPES = {<br>
|
||
usecase: {<br>
|
||
id: <span class="string">'usecase'</span>,<br>
|
||
name: <span class="string">'نمودار مورد کاربرد (Use Case)'</span>,<br>
|
||
icon: <span class="string">'⭕'</span>,<br>
|
||
tools: [<span class="string">'select'</span>, <span class="string">'actor'</span>, <span class="string">'useCase'</span>, <span class="string">'boundary'</span>, ...],<br>
|
||
groups: [<span class="string">'selection'</span>, <span class="string">'uc-elements'</span>, <span class="string">'uc-relations'</span>, ...]<br>
|
||
},<br>
|
||
<span class="comment">// ... سایر نمودارها</span><br>
|
||
};
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۵</div>
|
||
<div class="section-title">
|
||
<h3>موتور رسم (Drawing Engine)</h3>
|
||
<div class="subtitle">Canvas Rendering Engine</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>موتور رسم، قلب تپنده این پروژه است و بر پایه <strong>Immediate Mode Rendering</strong> طراحی شده است. در این رویکرد، در هر فریم (یا پس از هر تغییر state) کل بوم پاکسازی شده و تمامی المانها از نو رسم میشوند. این رویکرد اگرچه در نگاه اول پرهزینه به نظر میرسد، اما به دلیل سادگی، قابلیت اطمینان بالا و عدم نیاز به مدیریت پیچیده Diff، برای این نوع ابزارها ایدهآل است.</p>
|
||
<h4 style="margin-top: 20px; color: var(--primary); font-size: 16px;">چرخه رسم (Render Loop):</h4>
|
||
<ul class="module-list">
|
||
<li><strong>۱. پاکسازی بوم:</strong> <code>ctx.clearRect()</code> و رسم پسزمینه بر اساس تم.</li>
|
||
<li><strong>۲. رسم Grid:</strong> بر اساس نوع انتخابی (Lines/Dots/None) با استفاده از CSS Variables.</li>
|
||
<li><strong>۳. رسم المانها:</strong> فراخوانی توابع اختصاصی هر نمودار (مانند <code>drawUseCase</code>, <code>drawClassDiagram</code>).</li>
|
||
<li><strong>۴. رسم روابط:</strong> پس از المانها، روابط با محاسبه مرکز المانهای مبدأ و مقصد رسم میشوند.</li>
|
||
<li><strong>۵. رسم Selection:</strong> المان انتخابشده با خطچین آبیرنگ مشخص میشود.</li>
|
||
<li><strong>۶. رسم Relationship Preview:</strong> در حالت رسم رابطه، خط موقتی تا موقعیت ماوس نمایش داده میشود.</li>
|
||
</ul>
|
||
<div class="code-block">
|
||
<span class="comment">// چرخه اصلی رسم</span><br>
|
||
<span class="keyword">function</span> <span class="func">draw</span>() {<br>
|
||
<span class="keyword">const</span> d = <span class="func">getActive</span>(), tc = <span class="func">getTC</span>();<br>
|
||
ctx.<span class="func">clearRect</span>(0, 0, canvas.width, canvas.height);<br>
|
||
ctx.fillStyle = tc.canvasBg;<br>
|
||
ctx.<span class="func">fillRect</span>(0, 0, canvas.width, canvas.height);<br>
|
||
<span class="func">drawGrid</span>(ctx, canvas.width, canvas.height, tc, <span class="keyword">false</span>);<br>
|
||
<span class="keyword">if</span> (!d) <span class="keyword">return</span>;<br>
|
||
<span class="func">drawDiag</span>(ctx, d, tc); <span class="comment">// Dispatch به تابع اختصاصی</span><br>
|
||
}
|
||
</div>
|
||
<div class="info-box">
|
||
<strong>💡 بهینهسازی:</strong> برای جلوگیری از رسمهای مکرر غیرضروری، از تکنیک <code>requestAnimationFrame</code> و <code>scheduleResize()</code> استفاده شده است تا Resize رویدادها بهصورت هوشمند مدیریت شوند.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۶</div>
|
||
<div class="section-title">
|
||
<h3>سیستم مدیریت تم و رنگ</h3>
|
||
<div class="subtitle">Theme & Color System</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>سیستم تم این پروژه بر پایه <strong>CSS Custom Properties (Variables)</strong> طراحی شده است. با تغییر کلاس <code>body.dark</code>، تمامی متغیرهای رنگی بهصورت آنی تغییر میکنند و موتور رسم نیز از طریق تابع <code>getTC()</code> این مقادیر را در زمان اجرا (Runtime) از DOM استخراج میکند.</p>
|
||
<table class="styled-table">
|
||
<thead>
|
||
<tr>
|
||
<th>متغیر CSS</th>
|
||
<th>نقش</th>
|
||
<th>مثال مقدار (Dark Mode)</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td><code>--canvas-bg</code></td><td>پسزمینه بوم</td><td>#0f1724</td></tr>
|
||
<tr><td><code>--actor-stroke</code></td><td>رنگ خط Actor</td><td>#cbd5e0</td></tr>
|
||
<tr><td><code>--class-fill</code></td><td>رنگ زمینه Class</td><td>#1e2d40</td></tr>
|
||
<tr><td><code>--seq-msg</code></td><td>رنگ پیامهای Sequence</td><td>#cbd5e0</td></tr>
|
||
<tr><td><code>--selected</code></td><td>رنگ المان انتخابشده</td><td>#667eea</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="success-box">
|
||
<strong>✓ مزیت این رویکرد:</strong> افزودن یک تم جدید (مانند تم آبی، سبز یا High-Contrast) تنها با تغییر چند متغیر CSS امکانپذیر است و هیچ تغییری در منطق JavaScript نیاز نیست.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۷</div>
|
||
<div class="section-title">
|
||
<h3>سیستم تعامل و Hit Testing</h3>
|
||
<div class="subtitle">Interaction & Hit Testing System</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>برای تشخیص اینکه ماوس روی کدام المان قرار دارد، از الگوی <strong>Hit Testing</strong> استفاده میشود. تابع <code>hitTest(x, y)</code> بر اساس نوع نمودار فعال، الگوریتمهای متفاوتی را اجرا میکند:</p>
|
||
<ul class="module-list">
|
||
<li><strong>Actor:</strong> محاسبه فاصله اقلیتسی (Bounding Box 50×80 پیکسل).</li>
|
||
<li><strong>Use Case (بیضی):</strong> استفاده از معادله استاندارد بیضی <code>(x²/a²) + (y²/b²) ≤ 1</code>.</li>
|
||
<li><strong>State/Action/Component (مستطیل با گوشه گرد):</strong> بررسی Bounding Box.</li>
|
||
<li><strong>Decision (لوزی):</strong> استفاده از معادله لوزی <code>|x| + |y| ≤ size</code>.</li>
|
||
<li><strong>Class:</strong> بررسی بر اساس ارتفاع محاسبهشده داینامیک (<code>_computedH</code>).</li>
|
||
<li><strong>Swimlane:</strong> علاوه بر Hit Test بدنه، بررسی ۸ Handle برای Resize.</li>
|
||
</ul>
|
||
<div class="warning-box">
|
||
<strong>⚠️ چالش فنی:</strong> در نمودار Class، ارتفاع بهصورت داینامیک بر اساس تعداد Attributes و Methods محاسبه میشود. این مقدار در هر Draw در <code>cls._computedH</code> ذخیره میگردد تا در Hit Test نیز قابل استفاده باشد.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۸</div>
|
||
<div class="section-title">
|
||
<h3>سیستم ذخیرهسازی و بازیابی</h3>
|
||
<div class="subtitle">Persistence & File System</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>سیستم Persistence این پروژه کاملاً مبتنی بر <strong>JSON File API</strong> است و از LocalStorage یا IndexedDB استفاده نمیکند. این تصمیم معماری، مزایای زیر را به همراه دارد:</p>
|
||
<ul class="module-list">
|
||
<li><strong>قابلیت اشتراکگذاری آسان:</strong> فایل JSON بهراحتی قابل ارسال از طریق ایمیل، Git یا پیامرسانها است.</li>
|
||
<li><strong>نسخهبندی (Versioning):</strong> فایلها میتوانند در Git نگهداری و Diff شوند.</li>
|
||
<li><strong>عدم وابستگی به مرورگر:</strong> با پاکسازی Cache مرورگر، دادهها از بین نمیروند.</li>
|
||
<li><strong>ساختار قابل توسعه:</strong> فرمت JSON بهراحتی قابل گسترش است.</li>
|
||
</ul>
|
||
<div class="code-block">
|
||
<span class="comment">// ساختار فایل خروجی JSON</span><br>
|
||
{<br>
|
||
<span class="string">"version"</span>: <span class="string">"5.1"</span>,<br>
|
||
<span class="string">"fileTitle"</span>: <span class="string">"عنوان پروژه"</span>,<br>
|
||
<span class="string">"author"</span>: <span class="string">"هادی خزاعی اصل"</span>,<br>
|
||
<span class="string">"organization"</span>: <span class="string">"رایان پرداز کاوش"</span>,<br>
|
||
<span class="string">"createdAt"</span>: <span class="string">"2026-09-07T10:30:00.000Z"</span>,<br>
|
||
<span class="string">"preferences"</span>: { <span class="string">"gridType"</span>: <span class="string">"lines"</span>, <span class="string">"darkMode"</span>: <span class="keyword">true</span> },<br>
|
||
<span class="string">"diagrams"</span>: [ /* آرایه نمودارها */ ]<br>
|
||
}
|
||
</div>
|
||
<div class="info-box">
|
||
<strong>💡 Backward Compatibility:</strong> در هنگام Load فایل، کد با استفاده از <code>||</code> operator، فیلدهای اختیاری را مقداردهی پیشفرض میکند تا فایلهای نسخههای قدیمیتر نیز بدون خطا بارگذاری شوند.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۹</div>
|
||
<div class="section-title">
|
||
<h3>الگوهای طراحی بهکار رفته</h3>
|
||
<div class="subtitle">Design Patterns</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>در این پروژه، چندین الگوی طراحی شناختهشده بهصورت عملی پیادهسازی شدهاند:</p>
|
||
<table class="styled-table">
|
||
<thead>
|
||
<tr>
|
||
<th>الگو</th>
|
||
<th>محل کاربرد</th>
|
||
<th>توضیح</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Registry Pattern</strong></td>
|
||
<td><code>DIAGRAM_TYPES</code></td>
|
||
<td>مرجع مرکزی تعریف انواع نمودار و قابلیتهای آنها</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>State Pattern</strong></td>
|
||
<td>آبجکت <code>state</code></td>
|
||
<td>مدیریت وضعیت سراسری برنامه</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Strategy Pattern</strong></td>
|
||
<td>توابع <code>drawUseCase</code>, <code>drawClassDiagram</code>, ...</td>
|
||
<td>انتخاب استراتژی رسم بر اساس نوع نمودار</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Command Pattern</strong></td>
|
||
<td>مدیریت ابزارها (Tools)</td>
|
||
<td>هر ابزار یک رفتار مشخص را در mousedown/mouseup اجرا میکند</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Observer Pattern</strong></td>
|
||
<td>Event Listeners</td>
|
||
<td>واکنش به رویدادهای Mouse، Keyboard و UI</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Factory Pattern</strong></td>
|
||
<td><code>createNewDiagram()</code></td>
|
||
<td>ساخت ساختار اولیه نمودار بر اساس نوع</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Singleton Pattern</strong></td>
|
||
<td>Canvas Context، State Object</td>
|
||
<td>تنها یک نمونه از منابع حیاتی در طول اجرا</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۱۰</div>
|
||
<div class="section-title">
|
||
<h3>قابلیتهای کلیدی و UX</h3>
|
||
<div class="subtitle">Key Features & UX</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<ul class="module-list">
|
||
<li><strong>🗂️ مدیریت چند نمودار (Multi-Tab):</strong> امکان باز کردن همزمان چندین نمودار در تبهای مجزا با امکان سوئیچ سریع.</li>
|
||
<li><strong>🌙 تم تاریک/روشن:</strong> سوئیچ آنی با حفظ ترجیحات در فایل پروژه.</li>
|
||
<li><strong>⌨️ کلیدهای میانبر:</strong> Ctrl+S (ذخیره)، Ctrl+N (جدید)، Delete (حذف)، B (Sidebar)، G (Grid).</li>
|
||
<li><strong>🎨 Properties Panel:</strong> ویرایش زنده ویژگیهای المان انتخابشده در پایین صفحه.</li>
|
||
<li><strong>🗂️ Class Editor Modal:</strong> ویرایشگر پیشرفته Attributes و Methods با Visibility، Static و Type.</li>
|
||
<li><strong>📐 Resize Handles:</strong> قابلیت تغییر اندازه Swimlane با ۸ Handle در گوشهها و اضلاع.</li>
|
||
<li><strong>🖼️ Export to PNG:</strong> خروجی با کیفیت از نمودار فعلی با قابلیت انتخاب رنگ پسزمینه یا شفافیت.</li>
|
||
<li><strong>📦 Grid System:</strong> سه حالت (Lines, Dots, None) برای کمک به چیدمان دقیق المانها.</li>
|
||
<li><strong>🔗 Relationship Drawing:</strong> رسم روابط با Drag از مبدأ به مقصد و Prompt برای برچسب و Multiplicity.</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۱۱</div>
|
||
<div class="section-title">
|
||
<h3>نقاط قوت و پیشنهادات بهبود</h3>
|
||
<div class="subtitle">Strengths & Recommendations</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<table class="styled-table">
|
||
<thead>
|
||
<tr>
|
||
<th>دسته</th>
|
||
<th>نقاط قوت فعلی</th>
|
||
<th>پیشنهادات بهبود</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>معماری</strong></td>
|
||
<td>بدون وابستگی خارجی، سبک و سریع</td>
|
||
<td>ماژولار کردن کد با ES Modules برای نگهداری بهتر</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>عملکرد</strong></td>
|
||
<td>اجرای روان در نمودارهای کوچک و متوسط</td>
|
||
<td>پیادهسازی Dirty Rectangle Rendering برای نمودارهای بزرگ</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>UX</strong></td>
|
||
<td>رابط کاربری شهودی با RTL کامل</td>
|
||
<td>افزودن Undo/Redo با Command History</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>ذخیرهسازی</strong></td>
|
||
<td>خروجی JSON قابل اشتراک</td>
|
||
<td>افزودن Auto-Save در LocalStorage بهعنوان Backup</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>توسعهپذیری</strong></td>
|
||
<td>Registry Pattern برای افزودن نمودار جدید</td>
|
||
<td>افزودن نمودارهای Package و Communication</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>خروجی</strong></td>
|
||
<td>PNG با کیفیت</td>
|
||
<td>افزودن Export به SVG، PDF و XMI استاندارد</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-number">۱۲</div>
|
||
<div class="section-title">
|
||
<h3>جمعبندی نهایی</h3>
|
||
<div class="subtitle">Final Conclusion</div>
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<p>پروژه «ابزار رسم نمودارهای UML» یک نمونه موفق از توسعه یک اپلیکیشن تخصصی و حرفهای با استفاده از تکنولوژیهای پایه وب است. این ابزار با تکیه بر معماری State-Centric، موتور رسم مبتنی بر Canvas و سیستم Registry منعطف، توانایی مدلسازی کامل سیستمهای نرمافزاری را در محیطی آفلاین و سبک فراهم میآورد.</p>
|
||
<div class="conclusion-box">
|
||
<h3>🎯 نتیجهگیری معماری</h3>
|
||
<p>این پروژه نشان میدهد که برای ساخت ابزارهای تخصصی، لزومی به استفاده از فریمورکهای سنگین نیست. با طراحی دقیق معماری، انتخاب الگوهای مناسب و تمرکز بر تجربه کاربری، میتوان محصولی در سطح Enterprise تولید کرد که کاملاً مستقل، قابل نگهداری و توسعهپذیر باشد.</p>
|
||
<div class="highlight">
|
||
<strong>💎 ارزش نهایی:</strong> ابزاری کاملاً آفلاین، سبک، حرفهای و مستقل که نیاز هر معمار و تحلیلگر نرمافزار را برای مدلسازی سریع و دقیق برطرف میسازد.
|
||
</div>
|
||
</div>
|
||
<div class="info-box">
|
||
<strong>📞 گام بعدی:</strong> برای توسعه نسخههای آتی، پیشنهاد میشود ماژولهای Undo/Redo، Export به فرمتهای استاندارد (XMI, SVG) و افزودن نمودارهای Interaction اضافه گردد.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="page-info">
|
||
این مستند محرمانه بوده و صرفاً جهت استفاده داخلی تیم فنی تهیه شده است. هرگونه کپیبرداری یا افشا بدون اجازه کتبی ممنوع است.
|
||
</div>
|
||
</div>
|
||
<footer class="document-footer">
|
||
<div class="footer-brand">طراحی، تحلیل و توسعه: هادی خزاعی اصل</div>
|
||
<div class="footer-divider"></div>
|
||
<div>تاریخ تهیه: ۱۶ شهریور ۱۴۰۵ — ساعت ۱۰:۳۰ | نسخه: ۱.۰ | طبقهبندی: محرمانه / فنی</div>
|
||
</footer>
|
||
</div>
|
||
</body>
|
||
</html> |