Download Webapp/templates/global.html from Fancy-yousa/FeatureSelect-Methods-Leaderboard: direct link, hf CLI and curl.
- Browser
- Download file 15 kB
-
https://huggingface.co/spaces/Fancy-yousa/FeatureSelect-Methods-Leaderboard/resolve/main/Webapp/templates/global.html
- Command line
-
hf download hf://spaces/Fancy-yousa/FeatureSelect-Methods-Leaderboard/Webapp/templates/global.html
-
curl -L -o global.html https://huggingface.co/spaces/Fancy-yousa/FeatureSelect-Methods-Leaderboard/resolve/main/Webapp/templates/global.html
15 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Global Leaderboard</title> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <style> | |
| :root { | |
| --primary-color: #8e44ad; /* Purple for global view */ | |
| --secondary-color: #2c3e50; | |
| --background-color: #f8f9fa; | |
| --text-color: #333; | |
| --border-color: #dee2e6; | |
| --hover-color: #f1f1f1; | |
| --sidebar-width: 280px; | |
| } | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| margin: 0; | |
| padding: 0; | |
| background-color: var(--background-color); | |
| color: var(--text-color); | |
| display: flex; | |
| min-height: 100vh; | |
| } | |
| /* Sidebar Styling */ | |
| .sidebar { | |
| width: var(--sidebar-width); | |
| background-color: var(--secondary-color); | |
| color: white; | |
| position: fixed; | |
| height: 100vh; | |
| overflow-y: auto; | |
| padding: 20px; | |
| box-sizing: border-box; | |
| left: 0; | |
| top: 0; | |
| z-index: 100; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 20px; | |
| } | |
| .sidebar h2 { | |
| font-size: 1.2em; | |
| margin-bottom: 10px; | |
| color: #ecf0f1; | |
| border-bottom: 1px solid #34495e; | |
| padding-bottom: 5px; | |
| } | |
| .nav-links { | |
| list-style: none; | |
| padding: 0; | |
| margin: 0; | |
| } | |
| .nav-links li a { | |
| display: block; | |
| padding: 10px; | |
| color: #bdc3c7; | |
| text-decoration: none; | |
| border-radius: 4px; | |
| transition: background 0.2s; | |
| } | |
| .nav-links li a:hover, .nav-links li a.active { | |
| background: rgba(255,255,255,0.1); | |
| color: white; | |
| } | |
| /* Main Content Styling */ | |
| .main-content { | |
| margin-left: var(--sidebar-width); | |
| flex: 1; | |
| padding: 40px; | |
| max-width: calc(100% - var(--sidebar-width)); | |
| box-sizing: border-box; | |
| min-width: 0; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| background: white; | |
| padding: 20px; | |
| border-radius: 8px; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| } | |
| header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 20px; | |
| border-bottom: 2px solid var(--primary-color); | |
| padding-bottom: 10px; | |
| } | |
| h1 { | |
| margin: 0; | |
| color: var(--secondary-color); | |
| } | |
| .description-box { | |
| background-color: #e8f4fd; | |
| border-left: 4px solid #3498db; | |
| padding: 15px; | |
| margin-bottom: 20px; | |
| border-radius: 4px; | |
| } | |
| .description-box h3 { | |
| margin-top: 0; | |
| color: #2980b9; | |
| } | |
| .description-box p { | |
| margin: 5px 0; | |
| line-height: 1.5; | |
| } | |
| .weights-control { | |
| background-color: #f1f1f1; | |
| padding: 15px; | |
| border-radius: 8px; | |
| margin-bottom: 20px; | |
| border: 1px solid #ddd; | |
| } | |
| .weights-control h3 { | |
| margin-top: 0; | |
| margin-bottom: 15px; | |
| font-size: 1.1em; | |
| } | |
| .sliders-container { | |
| display: flex; | |
| gap: 20px; | |
| flex-wrap: wrap; | |
| align-items: center; | |
| } | |
| .slider-group { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .slider-group label { | |
| font-weight: bold; | |
| min-width: 60px; | |
| } | |
| input[type="number"] { | |
| width: 80px; | |
| padding: 5px; | |
| border: 1px solid #ccc; | |
| border-radius: 4px; | |
| } | |
| input[readonly] { | |
| background-color: #e9ecef; | |
| color: #666; | |
| } | |
| button.recalc-btn { | |
| background-color: var(--primary-color); | |
| color: white; | |
| border: none; | |
| padding: 8px 20px; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| font-size: 14px; | |
| margin-left: auto; | |
| } | |
| button.recalc-btn:hover { | |
| opacity: 0.9; | |
| } | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| margin-top: 10px; | |
| } | |
| th, td { | |
| padding: 12px 15px; | |
| text-align: left; | |
| border-bottom: 1px solid var(--border-color); | |
| } | |
| th { | |
| background-color: var(--secondary-color); | |
| color: white; | |
| cursor: pointer; | |
| user-select: none; | |
| position: sticky; | |
| top: 0; | |
| } | |
| th:hover { | |
| background-color: #34495e; | |
| } | |
| th .arrow { | |
| font-size: 10px; | |
| margin-left: 5px; | |
| opacity: 0.7; | |
| } | |
| tr:hover { | |
| background-color: var(--hover-color); | |
| } | |
| .score-bar { | |
| height: 6px; | |
| background-color: #e9ecef; | |
| border-radius: 3px; | |
| overflow: hidden; | |
| margin-top: 5px; | |
| } | |
| .score-fill { | |
| height: 100%; | |
| background-color: var(--primary-color); | |
| } | |
| .version-tag { | |
| font-size: 0.8em; | |
| color: #7f8c8d; | |
| margin-top: 5px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="sidebar"> | |
| <div style="text-align: center; margin-bottom: 20px;"> | |
| <h1 style="font-size: 1.5em; margin: 0; color: white;">AutoFS</h1> | |
| <div style="font-size: 0.8em; color: #bdc3c7;">Feature Selection Leaderboard</div> | |
| </div> | |
| <div> | |
| <h2>Navigation</h2> | |
| <ul class="nav-links"> | |
| <li><a href="/">π Overview</a></li> | |
| <li><a href="/#main-table">π Leaderboard</a></li> | |
| <li><a href="/#charts">π Charts</a></li> | |
| <li><a href="/#details">βΉοΈ Details</a></li> | |
| <li><a href="/global" class="active">π Global Rankings</a></li> | |
| <li><a href="/submit">π€ Submit Data/Method</a></li> | |
| </ul> | |
| </div> | |
| <div style="margin-top: auto; padding-top: 20px; border-top: 1px solid #34495e;"> | |
| <p style="font-size: 0.8em; color: #bdc3c7; text-align: center;"> | |
| Need help?<br> | |
| <a href="mailto:support@autofs.com" style="color: var(--primary-color);">Contact Support</a> | |
| </p> | |
| </div> | |
| </div> | |
| <div class="main-content"> | |
| <div class="container"> | |
| <header> | |
| <div> | |
| <h1>π Global Algorithm Rankings</h1> | |
| <div id="last-updated" class="version-tag">Data Last Updated: Loading...</div> | |
| </div> | |
| <!-- Removed redundant back link as sidebar handles navigation --> | |
| </header> | |
| <div class="description-box"> | |
| <h3>About Global Rankings</h3> | |
| <p> | |
| This page provides a comprehensive evaluation of feature selection algorithms across all available datasets. | |
| Algorithms are ranked based on a weighted score combining <strong>Accuracy (F1)</strong>, <strong>Robustness (AUC)</strong>, and <strong>Efficiency (Time)</strong>. | |
| You can adjust the importance of each factor below to customize the ranking criteria. | |
| </p> | |
| </div> | |
| <div class="weights-control"> | |
| <h3>π Scoring Formula: S = Ξ±Β·F1 + Ξ²Β·AUC</h3> | |
| <p style="font-size: 0.9em; color: #666; margin-bottom: 10px;"> | |
| Constraint: Ξ± + Ξ² = 1. | |
| </p> | |
| <div class="sliders-container"> | |
| <div class="slider-group"> | |
| <label for="weight-a">F1 (Ξ±):</label> | |
| <input type="number" id="weight-a" value="0.5" step="0.05" min="0" max="1"> | |
| </div> | |
| <div class="slider-group"> | |
| <label for="weight-b">AUC (Ξ²):</label> | |
| <input type="number" id="weight-b" value="0.5" readonly title="Auto-calculated: 1 - Ξ±"> | |
| </div> | |
| <button class="recalc-btn" onclick="calculateAndRender()">Recalculate Rankings</button> | |
| </div> | |
| </div> | |
| <div id="loading-indicator" style="text-align: center; color: #666;">Loading global stats...</div> | |
| <table id="global-table"> | |
| <thead> | |
| <tr> | |
| <th data-key="rank">#</th> | |
| <th data-key="algorithm">Algorithm <span class="arrow">β</span></th> | |
| <th data-key="mean_f1_global">Global F1 <span class="arrow">β</span></th> | |
| <th data-key="mean_auc_global">Global AUC <span class="arrow">β</span></th> | |
| <th data-key="final_score">Final Score <span class="arrow">β</span></th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <!-- Data rows --> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| <script> | |
| let rawData = []; | |
| let processedData = []; | |
| let sortKey = 'final_score'; | |
| let sortDirection = -1; // Descending by default | |
| const tableBody = document.querySelector("#global-table tbody"); | |
| const weightA = document.getElementById("weight-a"); | |
| const weightB = document.getElementById("weight-b"); | |
| const lastUpdatedDiv = document.getElementById("last-updated"); | |
| // Fetch datasets info to get latest date | |
| function fetchLastUpdated() { | |
| fetch("/api/datasets") | |
| .then(res => res.json()) | |
| .then(data => { | |
| if (data.length > 0) { | |
| // Sort by date to find latest? Or just take one? | |
| // Usually we want the overall latest date. | |
| // Let's just pick the first one's date or find the max date if needed. | |
| // For simplicity, just showing "Latest" | |
| const dates = data.map(d => d.last_updated).filter(d => d !== 'Unknown').sort().reverse(); | |
| if (dates.length > 0) { | |
| lastUpdatedDiv.textContent = `Data Last Updated: ${dates[0]}`; | |
| } else { | |
| lastUpdatedDiv.textContent = `Data Last Updated: Unknown`; | |
| } | |
| } | |
| }); | |
| } | |
| function fetchGlobalStats() { | |
| fetch("/api/global_stats") | |
| .then(res => res.json()) | |
| .then(data => { | |
| rawData = data; | |
| document.getElementById("loading-indicator").style.display = 'none'; | |
| calculateAndRender(); | |
| }) | |
| .catch(err => { | |
| console.error("Error:", err); | |
| document.getElementById("loading-indicator").textContent = "Error loading data."; | |
| }); | |
| } | |
| // Weight auto-adjustment logic | |
| function updateWeights(changedInput) { | |
| let a = parseFloat(weightA.value) || 0; | |
| // Clamp inputs to 0-1 | |
| if (a < 0) a = 0; if (a > 1) a = 1; | |
| if (changedInput === 'a') { | |
| let b = 1 - a; | |
| // Update UI | |
| weightA.value = parseFloat(a.toFixed(2)); | |
| weightB.value = parseFloat(b.toFixed(2)); | |
| } | |
| } | |
| weightA.addEventListener('input', () => updateWeights('a')); | |
| function calculateAndRender() { | |
| const a = parseFloat(weightA.value) || 0; | |
| const b = parseFloat(weightB.value) || 0; | |
| // Process data | |
| processedData = rawData.map(d => { | |
| const score = (a * d.mean_f1_global) + (b * d.mean_auc_global); | |
| return { | |
| ...d, | |
| final_score: score | |
| }; | |
| }); | |
| sortData(); | |
| renderTable(); | |
| } | |
| function sortData() { | |
| processedData.sort((x, y) => { | |
| const valX = x[sortKey]; | |
| const valY = y[sortKey]; | |
| if (valX < valY) return -1 * sortDirection; | |
| if (valX > valY) return 1 * sortDirection; | |
| return 0; | |
| }); | |
| } | |
| function safeFixed(val, digits=4) { | |
| if (val === undefined || val === null) return 'N/A'; | |
| return Number(val).toFixed(digits); | |
| } | |
| function renderTable() { | |
| tableBody.innerHTML = ""; | |
| if (processedData.length === 0) { | |
| tableBody.innerHTML = '<tr><td colspan="5" style="text-align:center;">No data available</td></tr>'; | |
| return; | |
| } | |
| processedData.forEach((row, index) => { | |
| const tr = document.createElement("tr"); | |
| // Highlight rank 1-3 | |
| let rankHtml = index + 1; | |
| if (index === 0) rankHtml = 'π₯ 1'; | |
| if (index === 1) rankHtml = 'π₯ 2'; | |
| if (index === 2) rankHtml = 'π₯ 3'; | |
| tr.innerHTML = ` | |
| <td>${rankHtml}</td> | |
| <td><strong>${row.algorithm}</strong> <span style="font-size:0.8em; color:#999">(${row.datasets_count} datasets)</span></td> | |
| <td>${safeFixed(row.mean_f1_global)}</td> | |
| <td>${safeFixed(row.mean_auc_global)}</td> | |
| <td> | |
| <strong>${safeFixed(row.final_score)}</strong> | |
| <div class="score-bar"><div class="score-fill" style="width: ${Math.min(row.final_score * 100, 100)}%"></div></div> | |
| </td> | |
| `; | |
| tableBody.appendChild(tr); | |
| }); | |
| updateSortArrows(); | |
| } | |
| function updateSortArrows() { | |
| document.querySelectorAll('th .arrow').forEach(span => span.textContent = 'β'); | |
| const activeHeader = document.querySelector(`th[data-key="${sortKey}"] .arrow`); | |
| if (activeHeader) activeHeader.textContent = sortDirection === 1 ? 'β' : 'β'; | |
| } | |
| document.querySelectorAll('th[data-key]').forEach(th => { | |
| th.addEventListener('click', () => { | |
| const key = th.dataset.key; | |
| if (sortKey === key) { | |
| sortDirection *= -1; | |
| } else { | |
| sortKey = key; | |
| sortDirection = (key === 'rank') ? 1 : -1; | |
| } | |
| if (key === 'rank') { | |
| sortKey = 'final_score'; | |
| sortDirection = -1; | |
| } | |
| sortData(); | |
| renderTable(); | |
| }); | |
| }); | |
| document.addEventListener("DOMContentLoaded", () => { | |
| fetchLastUpdated(); | |
| fetchGlobalStats(); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |