Algoline / static /index.html
Al1Abdullah's picture
Algoline - Automated Machine Learning Platform
9fb2e52
Raw
History Blame Contribute Delete
21.6 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Algoline</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=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<!-- Theme Toggle -->
<button class="theme-toggle" id="theme-toggle" onclick="toggleTheme()" title="Toggle theme">
<svg id="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
<svg id="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
</button>
<!-- ════════════════════════════════════════════
SIDEBAR
════════════════════════════════════════════ -->
<nav class="sidebar">
<div class="sidebar-logo">
<span>Algoline</span>
</div>
<div class="sidebar-nav">
<a class="nav-item active" onclick="showSection('data')" data-section="data">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/>
</svg>
<span>Data</span>
</a>
<a class="nav-item" onclick="showSection('explore')" data-section="explore">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
</svg>
<span>Explore</span>
</a>
<a class="nav-item" onclick="showSection('build')" data-section="build">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
</svg>
<span>Build</span>
</a>
<a class="nav-item" onclick="showSection('export')" data-section="export">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>
</svg>
<span>Export</span>
</a>
</div>
</nav>
<!-- ════════════════════════════════════════════
MAIN CONTENT
════════════════════════════════════════════ -->
<div class="main-content">
<!-- ──────── DATA SECTION ──────── -->
<div id="sec-data" class="section active">
<h1 class="section-title">Data</h1>
<p class="section-subtitle">Upload a dataset to begin your machine learning pipeline</p>
<!-- Upload Area -->
<input type="file" id="file-input" accept=".csv,.tsv,.xlsx,.xls" style="display:none">
<div class="upload-area" id="upload-area" onclick="document.getElementById('file-input').click()">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/>
</svg>
<div class="upload-area-title">Drop your dataset here or click to browse</div>
<div class="upload-area-sub">Supports CSV, TSV, XLSX</div>
</div>
<!-- Metrics (hidden initially) -->
<div id="data-metrics" class="metrics-grid" style="display:none"></div>
<!-- Auto Insights (hidden initially) -->
<div id="data-insights" style="display:none"></div>
<!-- Target Selection -->
<div id="target-section" style="display:none">
<div class="card">
<div class="target-row">
<div class="form-group" style="margin:0">
<label class="form-label">Target Column</label>
<select class="form-select" id="target-select" onchange="setTarget(this.value)">
<option value="">Select target...</option>
</select>
</div>
<div id="task-badge-wrap"></div>
</div>
</div>
</div>
<!-- Data Tabs -->
<div id="data-tabs-section" class="mt-md" style="display:none">
<div class="card">
<div class="tab-bar" id="data-tab-bar">
<button class="tab-btn active" onclick="switchDataTab('preview')">Preview</button>
<button class="tab-btn" onclick="switchDataTab('types')">Types</button>
<button class="tab-btn" onclick="switchDataTab('stats')">Stats</button>
</div>
<div id="data-tab-preview" class="tab-panel active">
<div class="table-wrap" style="max-height:400px;overflow-y:auto" id="preview-table"></div>
</div>
<div id="data-tab-types" class="tab-panel">
<div class="table-wrap" style="max-height:400px;overflow-y:auto" id="types-table"></div>
</div>
<div id="data-tab-stats" class="tab-panel">
<div class="table-wrap" style="max-height:400px;overflow-y:auto" id="stats-table"></div>
</div>
</div>
</div>
</div>
<!-- ──────── EXPLORE SECTION ──────── -->
<div id="sec-explore" class="section">
<h1 class="section-title">Explore</h1>
<p class="section-subtitle">18 essential ML visualizations for data understanding and preprocessing</p>
<div class="card">
<div class="tab-bar" id="explore-main-tabs">
<button class="tab-btn active" onclick="switchExploreMain('plots')">Visualizations</button>
<button class="tab-btn" onclick="switchExploreMain('quality')">Data Quality</button>
</div>
<!-- Plots Panel -->
<div id="explore-panel-plots" class="tab-panel active">
<div class="flex-row mb-md" style="gap:12px;flex-wrap:wrap;align-items:flex-end">
<div class="form-group" style="margin:0;min-width:240px;flex:1">
<label class="form-label">Plot Type</label>
<select class="form-select" id="plot-type" onchange="onPlotTypeChange()">
<optgroup label="Distribution Analysis">
<option value="histogram">Histogram</option>
<option value="kde">KDE Plot</option>
<option value="boxplot">Box Plot</option>
<option value="violin">Violin Plot</option>
</optgroup>
<optgroup label="Missing Data">
<option value="missing_bar">Missing Value Bar Chart</option>
<option value="missing_heatmap">Missing Value Heatmap</option>
</optgroup>
<optgroup label="Correlation and Relationships">
<option value="correlation">Correlation Heatmap</option>
<option value="pairplot">Pair Plot</option>
<option value="scatter">Scatter Plot</option>
<option value="jointplot">Joint Plot</option>
</optgroup>
<optgroup label="Target Analysis">
<option value="countplot">Count Plot</option>
<option value="pie">Pie Chart</option>
<option value="class_dist">Class Distribution</option>
<option value="target_hist">Target Histogram</option>
<option value="mean_target">Mean Target per Category</option>
</optgroup>
<optgroup label="Advanced">
<option value="scatter_index">Scatter vs Index</option>
<option value="grouped_box">Grouped Box Plot</option>
<option value="facetgrid">FacetGrid / Small Multiples</option>
</optgroup>
</select>
</div>
<div class="form-group" id="feat1-group" style="margin:0;min-width:180px;flex:0.7">
<label class="form-label">Feature</label>
<select class="form-select" id="plot-feat1" onchange="generatePlot()">
<option value="">Select...</option>
</select>
</div>
<div class="form-group" id="feat2-group" style="margin:0;min-width:180px;flex:0.7;display:none">
<label class="form-label">Feature 2</label>
<select class="form-select" id="plot-feat2" onchange="generatePlot()">
<option value="">Select...</option>
</select>
</div>
</div>
<div class="chart-container" id="explore-chart"></div>
<div id="explore-msg" style="display:none;text-align:center;padding:40px 0;color:var(--text-muted)"></div>
</div>
<!-- Quality Panel -->
<div id="explore-panel-quality" class="tab-panel">
<div class="table-wrap" id="quality-table"></div>
</div>
</div>
</div>
<!-- ──────── BUILD SECTION ──────── -->
<div id="sec-build" class="section">
<h1 class="section-title">Build</h1>
<p class="section-subtitle">Configure preprocessing, train models, tune the best, and evaluate results</p>
<!-- Configuration Card -->
<div class="card relative" id="build-config-card">
<!-- Task -->
<div class="form-group">
<label class="form-label">Task Type</label>
<div class="radio-group" id="task-radio-group">
<label class="radio-item active" onclick="selectTask(this,'classification')">
<input type="radio" name="task" value="classification" checked>
Classification
</label>
<label class="radio-item" onclick="selectTask(this,'regression')">
<input type="radio" name="task" value="regression">
Regression
</label>
</div>
</div>
<!-- Collapsible Preprocessing -->
<div>
<div class="collapsible-header open" onclick="toggleCollapsible(this)">
<span>Preprocessing Options</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="collapsible-body open">
<div class="checkbox-grid">
<label class="checkbox-item"><input type="checkbox" name="prep" value="drop_duplicates" checked> Drop Duplicates</label>
<label class="checkbox-item"><input type="checkbox" name="prep" value="remove_outliers"> Remove Outliers</label>
<label class="checkbox-item"><input type="checkbox" name="prep" value="normalize" checked> Normalize</label>
<label class="checkbox-item"><input type="checkbox" name="prep" value="drop_multicollinear" checked> Drop Multicollinear</label>
<label class="checkbox-item"><input type="checkbox" name="prep" value="transform_skew"> Transform Skew</label>
<label class="checkbox-item"><input type="checkbox" name="prep" value="feature_selection"> Feature Selection</label>
<label class="checkbox-item"><input type="checkbox" name="prep" value="polynomial_features"> Polynomial Features</label>
<label class="checkbox-item"><input type="checkbox" name="prep" value="fix_imbalance"> Fix Class Imbalance</label>
</div>
</div>
</div>
<!-- Sliders -->
<div class="flex-row mt-md" style="gap:32px">
<div class="form-group" style="flex:1;margin:0">
<label class="form-label">Test Size</label>
<div class="range-wrap">
<input type="range" id="test-size" min="0.1" max="0.4" step="0.05" value="0.2" oninput="document.getElementById('test-size-val').textContent=this.value">
<span class="range-val" id="test-size-val">0.2</span>
</div>
</div>
<div class="form-group" style="flex:1;margin:0">
<label class="form-label">CV Folds</label>
<div class="range-wrap">
<input type="range" id="cv-folds" min="2" max="10" step="1" value="5" oninput="document.getElementById('cv-folds-val').textContent=this.value">
<span class="range-val" id="cv-folds-val">5</span>
</div>
</div>
</div>
<!-- Train Button -->
<div class="mt-md">
<button class="btn btn-primary" id="train-btn" onclick="trainModels()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
Train All Models
</button>
</div>
<!-- Loading Overlay -->
<div class="loading-overlay hidden" id="train-loading">
<div class="spinner"></div>
<div class="loading-text" id="train-status">Initializing pipeline...</div>
</div>
</div>
<!-- Results (hidden until training completes) -->
<div id="build-results" style="display:none">
<!-- Training Summary Banner -->
<div id="training-summary" style="display:none"></div>
<!-- Best Model -->
<div class="card mt-md" id="best-model-card" style="border-left: 3px solid #6366f1; background: linear-gradient(135deg, rgba(99,102,241,0.08) 0%, rgba(255,255,255,0.04) 100%); animation: glowPulse 3s ease-in-out infinite">
<div class="card-label">Best Model</div>
<div style="display:flex;align-items:center;gap:10px">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color:var(--accent)"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<div class="card-value" id="best-model-name">--</div>
</div>
</div>
<!-- Leaderboard -->
<div class="card mt-md">
<div class="card-label">Leaderboard</div>
<div class="table-wrap mt-sm" style="max-height:360px;overflow-y:auto" id="leaderboard-table"></div>
</div>
<!-- Metric Comparison -->
<div class="card mt-md">
<div class="flex-row mb-md">
<div class="form-group" style="margin:0;min-width:200px">
<label class="form-label">Compare Metric</label>
<select class="form-select" id="metric-select" onchange="renderMetricChart()"></select>
</div>
</div>
<div class="chart-container" id="metric-chart"></div>
</div>
<!-- Tuning -->
<div class="card mt-md relative" id="tune-card">
<div class="card-label">Hyperparameter Tuning</div>
<div class="flex-row mt-sm" style="gap:16px;align-items:flex-end">
<div class="form-group" style="margin:0;min-width:160px">
<label class="form-label">Method</label>
<select class="form-select" id="tune-method">
<option value="random">Random Search</option>
<option value="optuna">Optuna (Bayesian)</option>
<option value="grid">Grid Search</option>
</select>
</div>
<div class="form-group" style="margin:0;min-width:180px">
<label class="form-label">Iterations</label>
<div class="range-wrap">
<input type="range" id="tune-iter" min="5" max="50" step="5" value="10" oninput="document.getElementById('tune-iter-val').textContent=this.value">
<span class="range-val" id="tune-iter-val">10</span>
</div>
</div>
<button class="btn btn-secondary btn-sm" id="tune-btn" onclick="tuneModel()">Tune</button>
</div>
<div id="tune-results" class="mt-md" style="display:none">
<div id="tune-improved" class="mb-md" style="font-size:13px;font-weight:500"></div>
<div class="table-wrap" style="max-height:300px;overflow-y:auto" id="tune-table"></div>
</div>
<div class="loading-overlay hidden" id="tune-loading">
<div class="spinner"></div>
<div class="loading-text">Tuning hyperparameters...</div>
</div>
</div>
<!-- Evaluation Plots -->
<div class="card mt-md">
<div class="card-label">Evaluation Plots</div>
<div class="plot-grid mt-sm" id="eval-plots"></div>
</div>
</div>
</div>
<!-- ──────── EXPORT SECTION ──────── -->
<div id="sec-export" class="section">
<h1 class="section-title">Export</h1>
<p class="section-subtitle">Download your trained pipeline, results, and predictions</p>
<div class="card" id="export-summary-card">
<div class="card-label">Pipeline Summary</div>
<div class="summary-grid mt-sm" id="export-summary">
<div class="card" style="padding:16px">
<div class="card-label">Model</div>
<div class="card-value" style="font-size:16px" id="export-model">--</div>
</div>
<div class="card" style="padding:16px">
<div class="card-label">Task</div>
<div class="card-value" style="font-size:16px" id="export-task">--</div>
</div>
<div class="card" style="padding:16px">
<div class="card-label">Predictions</div>
<div class="card-value" style="font-size:16px" id="export-preds">--</div>
</div>
</div>
</div>
<div class="card mt-md">
<div class="card-label">Downloads</div>
<div class="download-row mt-sm">
<button class="btn btn-secondary" onclick="downloadExport('pipeline')">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
Pipeline (.pkl)
</button>
<button class="btn btn-secondary" onclick="downloadExport('leaderboard')">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
Leaderboard (.csv)
</button>
<button class="btn btn-secondary" onclick="downloadExport('predictions')">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/></svg>
Predictions (.csv)
</button>
</div>
</div>
</div>
</div>
<!-- ════════════════════════════════════════════
JAVASCRIPT
════════════════════════════════════════════ -->
<script src="/static/js/app.js"></script>
</body>
</html>