| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>AutoFS Leaderboard</title> |
|
|
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
|
|
| <style> |
| body { |
| font-family: Arial, sans-serif; |
| margin: 40px; |
| } |
| |
| table { |
| border-collapse: collapse; |
| width: 100%; |
| } |
| |
| th, td { |
| border: 1px solid #ddd; |
| padding: 10px; |
| text-align: center; |
| } |
| |
| th { |
| cursor: pointer; |
| background-color: #f5f5f5; |
| user-select: none; |
| } |
| |
| th span { |
| margin-left: 6px; |
| font-size: 12px; |
| opacity: 0.7; |
| } |
| |
| tr:nth-child(even) { |
| background-color: #fafafa; |
| } |
| |
| .chart-row { |
| display: flex; |
| gap: 40px; |
| margin-top: 40px; |
| } |
| |
| .chart-container { |
| width: 50%; |
| } |
| |
| .chart-row-single { |
| display: flex; |
| justify-content: center; |
| margin-top: 40px; |
| } |
| |
| .chart-container-single { |
| width: 60%; |
| } |
| </style> |
| </head> |
| <body> |
|
|
| <h1>Feature Selection Leaderboard</h1> |
|
|
| <table> |
| <thead> |
| <tr> |
| <th>Rank</th> |
| <th onclick="sortTable('algorithm')">Algorithm <span id="arrow-algorithm">↕</span></th> |
| <th onclick="sortTable('num_features')">#Features <span id="arrow-num_features">↕</span></th> |
| <th onclick="sortTable('mean_f1')">Mean F1 <span id="arrow-mean_f1">↕</span></th> |
| <th onclick="sortTable('mean_auc')">Mean AUC <span id="arrow-mean_auc">↕</span></th> |
| <th onclick="sortTable('time')">Time (s) <span id="arrow-time">↕</span></th> |
| </tr> |
| </thead> |
| <tbody id="tbody"></tbody> |
| </table> |
|
|
| |
| <div class="chart-row"> |
| <div class="chart-container"> |
| <canvas id="f1Chart"></canvas> |
| </div> |
| <div class="chart-container"> |
| <canvas id="aucChart"></canvas> |
| </div> |
| </div> |
|
|
| |
| <div class="chart-row-single"> |
| <div class="chart-container-single"> |
| <canvas id="timeChart"></canvas> |
| </div> |
| </div> |
|
|
| <script> |
| let leaderboardData = {{ leaderboard | tojson }}; |
| let sortKey = null; |
| let sortAsc = true; |
| let f1Chart, aucChart, timeChart; |
| |
| const metricOrder = { |
| algorithm: "asc", |
| num_features: "asc", |
| mean_f1: "desc", |
| mean_auc: "desc", |
| time: "asc" |
| }; |
| |
| function renderTable() { |
| const tbody = document.getElementById("tbody"); |
| tbody.innerHTML = ""; |
| |
| const n = leaderboardData.length; |
| |
| const isBestFirst = |
| (metricOrder[sortKey] === "desc" && !sortAsc) || |
| (metricOrder[sortKey] === "asc" && sortAsc); |
| |
| leaderboardData.forEach((r, i) => { |
| const rank = isBestFirst ? i + 1 : n - i; |
| |
| tbody.insertAdjacentHTML("beforeend", ` |
| <tr> |
| <td>${rank}</td> |
| <td>${r.algorithm}</td> |
| <td>${r.num_features}</td> |
| <td>${r.mean_f1.toFixed(4)}</td> |
| <td>${r.mean_auc.toFixed(4)}</td> |
| <td>${r.time.toFixed(2)}</td> |
| </tr> |
| `); |
| }); |
| } |
| |
| function sortTable(key) { |
| if (sortKey === key) { |
| sortAsc = !sortAsc; |
| } else { |
| sortKey = key; |
| sortAsc = metricOrder[key] === "asc"; |
| } |
| |
| leaderboardData.sort((a, b) => { |
| if (typeof a[key] === "string") { |
| return sortAsc |
| ? a[key].localeCompare(b[key]) |
| : b[key].localeCompare(a[key]); |
| } |
| return sortAsc ? a[key] - b[key] : b[key] - a[key]; |
| }); |
| |
| updateArrows(); |
| renderTable(); |
| updateCharts(); |
| } |
| |
| function updateArrows() { |
| document.querySelectorAll("th span").forEach(s => s.textContent = "↕"); |
| document.getElementById("arrow-" + sortKey).textContent = sortAsc ? "↑" : "↓"; |
| } |
| |
| function updateCharts() { |
| const labels = leaderboardData.map(r => r.algorithm); |
| |
| if (f1Chart) f1Chart.destroy(); |
| if (aucChart) aucChart.destroy(); |
| if (timeChart) timeChart.destroy(); |
| |
| const baseOptions = title => ({ |
| responsive: true, |
| maintainAspectRatio: true, |
| aspectRatio: 2, |
| plugins: { title: { display: true, text: title } } |
| }); |
| |
| f1Chart = new Chart(document.getElementById("f1Chart"), { |
| type: "line", |
| data: { |
| labels, |
| datasets: [{ label: "Mean F1", data: leaderboardData.map(r => r.mean_f1) }] |
| }, |
| options: baseOptions("Mean F1 Curve") |
| }); |
| |
| aucChart = new Chart(document.getElementById("aucChart"), { |
| type: "line", |
| data: { |
| labels, |
| datasets: [{ label: "Mean AUC", data: leaderboardData.map(r => r.mean_auc) }] |
| }, |
| options: baseOptions("Mean AUC Curve") |
| }); |
| |
| timeChart = new Chart(document.getElementById("timeChart"), { |
| type: "line", |
| data: { |
| labels, |
| datasets: [{ label: "Time (s)", data: leaderboardData.map(r => r.time) }] |
| }, |
| options: baseOptions("Runtime Curve") |
| }); |
| } |
| |
| renderTable(); |
| updateCharts(); |
| </script> |
|
|
| </body> |
| </html> |
|
|