Spaces:
Sleeping
Sleeping
| {% extends "layout.html" %} | |
| {% block title %}DBSCAN Clusters - Quantum AI{% endblock %} | |
| {% block page_header %} | |
| <h1>DBSCAN Clusters</h1> | |
| <p>Density-Based Spatial Clustering of Applications with Noise (DBSCAN).</p> | |
| {% endblock %} | |
| {% block content %} | |
| <div class="service-panel glass-card"> | |
| <form action="/dbscan" method="post" enctype="multipart/form-data" class="quantum-form"> | |
| <div class="upload-zone" id="dropZone"> | |
| <i class="fas fa-braille upload-icon"></i> | |
| <div class="upload-text"> | |
| <strong>Upload Data Structure</strong> | |
| <span>Supports .CSV or .XLSX datasets</span> | |
| </div> | |
| <input type="file" name="file" accept=".csv, .xlsx" required> | |
| </div> | |
| <div class="settings-grid"> | |
| <div class="input-group"> | |
| <label>Epsilon (eps)</label> | |
| <input type="number" name="eps" value="0.5" min="0.01" max="10" step="0.01" required> | |
| </div> | |
| <div class="input-group"> | |
| <label>Min Samples</label> | |
| <input type="number" name="min_samples" value="5" min="1" max="100" required> | |
| </div> | |
| </div> | |
| <button type="submit" class="btn-quantum full-width"> | |
| <i class="fas fa-project-diagram"></i> Analyze Density | |
| </button> | |
| </form> | |
| {% if error %} | |
| <div class="error-msg animate-fade-in"> | |
| <i class="fas fa-exclamation-triangle"></i> {{ error }} | |
| </div> | |
| {% endif %} | |
| {% if plot_url %} | |
| <div class="result-container animate-fade-in"> | |
| <div class="result-header">Density Map Visualization</div> | |
| <div class="visualization-box"> | |
| <img src="data:image/png;base64,{{ plot_url }}" alt="DBSCAN Plot"> | |
| </div> | |
| {% if cluster_info %} | |
| <div class="cluster-stats"> | |
| <label>Density Distribution (-1 denotes noise)</label> | |
| <div class="stats-grid"> | |
| {% for cluster, count in cluster_info.items() %} | |
| <div class="stat-card {% if cluster|int == -1 %}noise-card{% endif %}"> | |
| <span class="cluster-id">{% if cluster|int == -1 %}Noise (Outliers){% else %}Cluster {{ cluster }}{% | |
| endif %}</span> | |
| <span class="count-value">{{ count }} Entities</span> | |
| </div> | |
| {% endfor %} | |
| </div> | |
| </div> | |
| {% endif %} | |
| </div> | |
| {% endif %} | |
| </div> | |
| <style> | |
| .service-panel { | |
| max-width: 900px; | |
| margin: 0 auto; | |
| } | |
| .settings-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 1.5rem; | |
| margin-top: 1.5rem; | |
| } | |
| .input-group label { | |
| font-size: 0.85rem; | |
| font-weight: 700; | |
| color: var(--text-secondary); | |
| text-transform: uppercase; | |
| margin-bottom: 0.5rem; | |
| display: block; | |
| } | |
| input[type="number"] { | |
| background: rgba(0, 0, 0, 0.2); | |
| border: 1px solid var(--glass-border); | |
| border-radius: var(--radius-md); | |
| padding: 0.75rem 1rem; | |
| color: var(--text-primary); | |
| font-size: 1.1rem; | |
| width: 100%; | |
| } | |
| .visualization-box { | |
| background: white; | |
| padding: 1.5rem; | |
| border-radius: var(--radius-lg); | |
| margin-top: 1rem; | |
| display: flex; | |
| justify-content: center; | |
| overflow: hidden; | |
| } | |
| .visualization-box img { | |
| max-width: 100%; | |
| height: auto; | |
| } | |
| .cluster-stats { | |
| margin-top: 2rem; | |
| } | |
| .cluster-stats label { | |
| color: var(--text-secondary); | |
| font-weight: 600; | |
| display: block; | |
| margin-bottom: 1rem; | |
| } | |
| .stats-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); | |
| gap: 1rem; | |
| } | |
| .stat-card { | |
| background: rgba(255, 255, 255, 0.03); | |
| padding: 1.25rem; | |
| border-radius: var(--radius-md); | |
| display: flex; | |
| flex-direction: column; | |
| border-left: 3px solid var(--accent-blue); | |
| } | |
| .stat-card.noise-card { | |
| border-left-color: #ef4444; | |
| } | |
| .cluster-id { | |
| font-size: 0.8rem; | |
| font-weight: 700; | |
| color: var(--text-secondary); | |
| text-transform: uppercase; | |
| margin-bottom: 4px; | |
| } | |
| .count-value { | |
| font-size: 1.2rem; | |
| font-weight: 800; | |
| } | |
| .error-msg { | |
| background: rgba(239, 68, 68, 0.1); | |
| color: #ef4444; | |
| padding: 1rem; | |
| border-radius: var(--radius-md); | |
| margin: 1rem 0; | |
| } | |
| </style> | |
| {% endblock %} |