| | <!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> |
| |
|