Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Model Performance Leaderboard</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| min-height: 100vh; | |
| padding: 20px; | |
| } | |
| .container { | |
| max-width: 1400px; | |
| margin: 0 auto; | |
| background: white; | |
| border-radius: 12px; | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); | |
| overflow: hidden; | |
| } | |
| .header { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| padding: 30px; | |
| text-align: center; | |
| } | |
| .header h1 { | |
| font-size: 2.5em; | |
| margin-bottom: 15px; | |
| font-weight: 300; | |
| } | |
| .dataset-info { | |
| padding: 15px; | |
| background: rgba(255, 255, 255, 0.1); | |
| border-radius: 8px; | |
| backdrop-filter: blur(10px); | |
| font-size: 1.1em; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| flex-wrap: wrap; | |
| gap: 20px; | |
| } | |
| .dataset-link { | |
| color: #ffd700; | |
| text-decoration: none; | |
| font-weight: 500; | |
| border-bottom: 2px solid transparent; | |
| transition: all 0.3s ease; | |
| } | |
| .dataset-link:hover { | |
| border-bottom-color: #ffd700; | |
| } | |
| .info-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .table-container { | |
| overflow-x: auto; | |
| padding: 30px; | |
| } | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| background: white; | |
| border-radius: 8px; | |
| overflow: hidden; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.07); | |
| } | |
| th { | |
| background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); | |
| color: white; | |
| padding: 18px 15px; | |
| text-align: center; | |
| font-weight: 600; | |
| font-size: 0.95em; | |
| letter-spacing: 0.5px; | |
| position: relative; | |
| cursor: pointer; | |
| user-select: none; | |
| transition: background 0.3s ease; | |
| } | |
| th:hover { | |
| background: linear-gradient(135deg, #43a3f5 0%, #00e5f5 100%); | |
| } | |
| th.sortable::after { | |
| content: '↕️'; | |
| position: absolute; | |
| right: 8px; | |
| font-size: 0.8em; | |
| opacity: 0.7; | |
| } | |
| th.sort-asc::after { | |
| content: '↑'; | |
| opacity: 1; | |
| } | |
| th.sort-desc::after { | |
| content: '↓'; | |
| opacity: 1; | |
| } | |
| td { | |
| padding: 16px 15px; | |
| border-bottom: 1px solid #e8ecf4; | |
| font-size: 0.9em; | |
| transition: background-color 0.2s ease; | |
| text-align: center; | |
| } | |
| tr:hover { | |
| background-color: #f8faff; | |
| } | |
| tr:nth-child(even) { | |
| background-color: #fafbff; | |
| } | |
| tr:nth-child(even):hover { | |
| background-color: #f0f4ff; | |
| } | |
| .model-link { | |
| color: #667eea; | |
| text-decoration: none; | |
| font-weight: 500; | |
| border-bottom: 2px solid transparent; | |
| transition: all 0.3s ease; | |
| display: inline-block; | |
| } | |
| .model-link:hover { | |
| color: #5a67d8; | |
| border-bottom-color: #5a67d8; | |
| transform: translateY(-1px); | |
| } | |
| .number-cell { | |
| font-family: 'Courier New', monospace; | |
| font-weight: 500; | |
| text-align: center; | |
| } | |
| /* Model Size Categories */ | |
| .model-tiny { | |
| background: linear-gradient(90deg, #e8f5e8, #f0fff0); | |
| border-left: 4px solid #4caf50; | |
| } | |
| .model-small { | |
| background: linear-gradient(90deg, #e3f2fd, #f1f8ff); | |
| border-left: 4px solid #2196f3; | |
| } | |
| .model-medium { | |
| background: linear-gradient(90deg, #fff3e0, #fef7f0); | |
| border-left: 4px solid #ff9800; | |
| } | |
| .model-large { | |
| background: linear-gradient(90deg, #f3e5f5, #faf5ff); | |
| border-left: 4px solid #9c27b0; | |
| } | |
| .model-xlarge { | |
| background: linear-gradient(90deg, #ffebee, #fff5f5); | |
| border-left: 4px solid #f44336; | |
| } | |
| .model-xxlarge { | |
| background: linear-gradient(90deg, #fce4ec, #fff0f5); | |
| border-left: 4px solid #e91e63; | |
| } | |
| /* F1 Score Categories */ | |
| .f1-score { | |
| color: #2d3748; | |
| font-weight: 600; | |
| padding: 4px 8px; | |
| border-radius: 4px; | |
| } | |
| .legend { | |
| padding: 30px; | |
| background: #f8fafc; | |
| border-top: 1px solid #e2e8f0; | |
| } | |
| .legend h3 { | |
| color: #2d3748; | |
| margin-bottom: 20px; | |
| font-size: 1.2em; | |
| } | |
| .legend-section { | |
| margin-bottom: 25px; | |
| } | |
| .legend-title { | |
| font-weight: 600; | |
| color: #4a5568; | |
| margin-bottom: 10px; | |
| } | |
| .legend-items { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 15px; | |
| } | |
| .legend-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| padding: 8px 12px; | |
| border-radius: 6px; | |
| background: white; | |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
| } | |
| .legend-color { | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 3px; | |
| border: 2px solid #e2e8f0; | |
| } | |
| .legend-color.tiny { | |
| background: linear-gradient(90deg, #e8f5e8, #f0fff0); | |
| border-color: #4caf50; | |
| } | |
| .legend-color.small { | |
| background: linear-gradient(90deg, #e3f2fd, #f1f8ff); | |
| border-color: #2196f3; | |
| } | |
| .legend-color.medium { | |
| background: linear-gradient(90deg, #fff3e0, #fef7f0); | |
| border-color: #ff9800; | |
| } | |
| .legend-color.large { | |
| background: linear-gradient(90deg, #f3e5f5, #faf5ff); | |
| border-color: #9c27b0; | |
| } | |
| .legend-color.xlarge { | |
| background: linear-gradient(90deg, #ffebee, #fff5f5); | |
| border-color: #f44336; | |
| } | |
| .legend-color.xxlarge { | |
| background: linear-gradient(90deg, #fce4ec, #fff0f5); | |
| border-color: #e91e63; | |
| } | |
| @media (max-width: 768px) { | |
| .container { | |
| margin: 10px; | |
| border-radius: 8px; | |
| } | |
| .header { | |
| padding: 20px; | |
| } | |
| .header h1 { | |
| font-size: 2em; | |
| } | |
| .dataset-info { | |
| flex-direction: column; | |
| gap: 10px; | |
| } | |
| .table-container { | |
| padding: 15px; | |
| } | |
| th, td { | |
| padding: 12px 8px; | |
| font-size: 0.85em; | |
| } | |
| .legend-items { | |
| flex-direction: column; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="header"> | |
| <h1>Model Performance Leaderboard</h1> | |
| <div class="dataset-info"> | |
| <div class="info-item"> | |
| <strong>Dataset:</strong> | |
| <a href="#" id="datasetLink" class="dataset-link" target="_blank"></a> | |
| </div> | |
| <div class="info-item"> | |
| <strong>Task:</strong> | |
| <span id="taskTag"></span> | |
| </div> | |
| <div class="info-item"> | |
| <strong>Models:</strong> | |
| <span id="totalModels">0</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="table-container"> | |
| <table id="modelTable"> | |
| <thead> | |
| <tr> | |
| <th>Model</th> | |
| <th>Architecture</th> | |
| <th class="sortable" data-column="input_size">Input Size</th> | |
| <th class="sortable" data-column="params">Parameters</th> | |
| <th class="sortable" data-column="flops">FLOPs</th> | |
| <th class="sortable" data-column="macro_f1">Macro F1</th> | |
| <th class="sortable" data-column="micro_f1">Micro F1</th> | |
| </tr> | |
| </thead> | |
| <tbody id="tableBody"> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="legend" id="legend"> | |
| <h3>Legend</h3> | |
| </div> | |
| </div> | |
| <script> | |
| // Configuration - Modify these values | |
| const dataset_repo_id = "animetimm/danbooru-wdtagger-v4-w640-ws-full"; | |
| const pretrained_tag = "dbv4-full"; | |
| // F1 Score grading criteria - customize these (will be sorted automatically) | |
| const macro_f1_grades = [{"name": "SOTA", "min": 0.55, "max": 1.0}, {"name": "Premium", "min": 0.5, "max": 0.55}, {"name": "Production", "min": 0.45, "max": 0.5}, {"name": "Acceptable", "min": 0.35, "max": 0.45}, {"name": "Limited", "min": 0.25, "max": 0.35}, {"name": "Poor", "min": 0.0, "max": 0.25}]; | |
| const micro_f1_grades = [{"name": "Excellent", "min": 0.65, "max": 1.0}, {"name": "Good", "min": 0.55, "max": 0.65}, {"name": "Fair", "min": 0.45, "max": 0.55}, {"name": "Poor", "min": 0.0, "max": 0.45}]; | |
| // Model data - All numeric values should be integers | |
| const modelData = [{"hf_repo": "animetimm/mobilenetv3_large_150d.dbv4-full", "architecture": "mobilenetv3_large_150d", "input_size": 384, "params": 29323076, "flops": 4624605304, "macro_f1": 0.39986178278923035, "micro_f1": 0.6051648259162903}, {"hf_repo": "animetimm/swinv2_base_window8_256.dbv4-full", "architecture": "swinv2_base_window8_256", "input_size": 448, "params": 99681716, "flops": 121619540992, "macro_f1": 0.5412678718566895, "micro_f1": 0.6831042170524597}, {"hf_repo": "animetimm/caformer_b36.dbv4-full", "architecture": "caformer_b36", "input_size": 384, "params": 134019362, "flops": 132216862464, "macro_f1": 0.546269953250885, "micro_f1": 0.6886452436447144}, {"hf_repo": "animetimm/caformer_s36.dbv4-full", "architecture": "caformer_s36", "input_size": 384, "params": 62811426, "flops": 44387998208, "macro_f1": 0.5037783980369568, "micro_f1": 0.6700260043144226}, {"hf_repo": "animetimm/mobilenetv3_large_100.dbv4-full.r224", "architecture": "mobilenetv3_large_100", "input_size": 224, "params": 20183788, "flops": 473726488, "macro_f1": 0.22153329849243164, "micro_f1": 0.46757057309150696}, {"hf_repo": "animetimm/mobilenetv4_conv_aa_large.dbv4-full", "architecture": "mobilenetv4_conv_aa_large", "input_size": 448, "params": 47291620, "flops": 19236604672, "macro_f1": 0.4578114449977875, "micro_f1": 0.6412474513053894}, {"hf_repo": "animetimm/mobilenetv3_large_100.dbv4-full", "architecture": "mobilenetv3_large_100", "input_size": 384, "params": 20183788, "flops": 1319630808, "macro_f1": 0.31062445044517517, "micro_f1": 0.5330070853233337}, {"hf_repo": "animetimm/caformer_m36.dbv4-full", "architecture": "caformer_m36", "input_size": 384, "params": 82657058, "flops": 74891684160, "macro_f1": 0.5149331092834473, "micro_f1": 0.6760287284851074}, {"hf_repo": "animetimm/mobilenetv4_conv_small.dbv4-full", "architecture": "mobilenetv4_conv_small", "input_size": 384, "params": 18474780, "flops": 1129638656, "macro_f1": 0.31232455372810364, "micro_f1": 0.5285327434539795}, {"hf_repo": "animetimm/eva02_large_patch14_448.dbv4-full", "architecture": "eva02_large_patch14_448", "input_size": 448, "params": 316843132, "flops": 620893090720, "macro_f1": 0.5694285035133362, "micro_f1": 0.6934136152267456}, {"hf_repo": "animetimm/convnext_base.dbv4-full", "architecture": "convnext_base", "input_size": 448, "params": 100354364, "flops": 123085808640, "macro_f1": 0.5211434960365295, "micro_f1": 0.6690741181373596}, {"hf_repo": "animetimm/vit_base_patch16_224.dbv4-full", "architecture": "vit_base_patch16_224", "input_size": 448, "params": 95842748, "flops": 134226315264, "macro_f1": 0.5003648996353149, "micro_f1": 0.6635887622833252}, {"hf_repo": "animetimm/caformer_s18.dbv4-full", "architecture": "caformer_s18", "input_size": 384, "params": 49855980, "flops": 22908156416, "macro_f1": 0.46389710903167725, "micro_f1": 0.6472342610359192}, {"hf_repo": "animetimm/mobilenetv4_conv_small_050.dbv4-full", "architecture": "mobilenetv4_conv_small_050", "input_size": 384, "params": 16939708, "flops": 412690688, "macro_f1": 0.1943172812461853, "micro_f1": 0.42909061908721924}, {"hf_repo": "animetimm/resnet50.dbv4-full", "architecture": "resnet50", "input_size": 384, "params": 49071356, "flops": 24169668608, "macro_f1": 0.3815140128135681, "micro_f1": 0.5716947913169861}, {"hf_repo": "animetimm/resnet152.dbv4-full", "architecture": "resnet152", "input_size": 384, "params": 83707132, "flops": 67908067328, "macro_f1": 0.44751423597335815, "micro_f1": 0.6240524649620056}, {"hf_repo": "animetimm/resnet101.dbv4-full", "architecture": "resnet101", "input_size": 384, "params": 68063484, "flops": 46033559552, "macro_f1": 0.4368686378002167, "micro_f1": 0.621998131275177}, {"hf_repo": "animetimm/resnet34.dbv4-full", "architecture": "resnet34", "input_size": 384, "params": 27684860, "flops": 21578584064, "macro_f1": 0.29000505805015564, "micro_f1": 0.5299346446990967}, {"hf_repo": "animetimm/resnet18.dbv4-full", "architecture": "resnet18", "input_size": 384, "params": 17576700, "flops": 10695888896, "macro_f1": 0.2587496340274811, "micro_f1": 0.4992590844631195}, {"hf_repo": "animetimm/convnextv2_huge.dbv4-full", "architecture": "convnextv2_huge", "input_size": 512, "params": 692617532, "flops": 1201620803328, "macro_f1": 0.5797423720359802, "micro_f1": 0.6970885992050171}, {"hf_repo": "animetimm/mobilevitv2_200.dbv4-full", "architecture": "mobilevitv2_200", "input_size": 384, "params": 30212229, "flops": 32430201184, "macro_f1": 0.4009774625301361, "micro_f1": 0.6083968877792358}]; | |
| let currentSort = {column: 'macro_f1', direction: 'desc'}; | |
| let f1Colors = {}; | |
| let sortedMacroGrades = []; | |
| let sortedMicroGrades = []; | |
| // Generate colors with green-blue-yellow gradient (high to low performance) | |
| // Avoiding green-like colors in the blue-to-yellow transition | |
| function generateColors(count) { | |
| const colors = []; | |
| if (count === 1) { | |
| colors.push('hsl(120, 60%, 85%)'); // Green for single grade | |
| return colors; | |
| } | |
| for (let i = 0; i < count; i++) { | |
| const ratio = i / (count - 1); // 0 to 1, where 0 is best performance | |
| let hue, saturation, lightness; | |
| if (ratio <= 0.5) { | |
| // Green to Blue transition (high to medium performance) | |
| // 120 (green) to 220 (blue) | |
| hue = 120 + (ratio * 2) * 100; | |
| } else { | |
| // Blue to Yellow transition (medium to low performance) | |
| // Avoid the green zone (90-150 degrees) by going through purple/magenta | |
| const adjustedRatio = (ratio - 0.5) * 2; // 0 to 1 for second half | |
| // Go from 220 (blue) through 280 (purple) to 45 (orange-yellow) | |
| // This avoids the green zone completely | |
| if (adjustedRatio <= 0.6) { | |
| // Blue to purple transition | |
| hue = 220 + adjustedRatio * 100; // 220 to 320 | |
| } else { | |
| // Purple to orange-yellow transition (wrapping around) | |
| const finalRatio = (adjustedRatio - 0.6) / 0.4; // 0 to 1 | |
| hue = 320 + finalRatio * 85; // 320 to 405, then wrap to 45 | |
| if (hue > 360) hue -= 360; | |
| } | |
| } | |
| // Adjust saturation and lightness for better visual distinction | |
| if (ratio <= 0.5) { | |
| // Green to blue: higher saturation for better performance | |
| saturation = 70 + (1 - ratio * 2) * 15; // 70-85% | |
| lightness = 80 + ratio * 2 * 5; // 80-85% | |
| } else { | |
| // Blue to yellow: maintain good contrast | |
| saturation = 65 + ((ratio - 0.5) * 2) * 20; // 65-85% | |
| lightness = 85 + ((ratio - 0.5) * 2) * 5; // 85-90% | |
| } | |
| colors.push(`hsl(${Math.round(hue)}, ${Math.round(saturation)}%, ${Math.round(lightness)}%)`); | |
| } | |
| return colors; | |
| } | |
| // Sort grades by max value (descending - highest performance first) | |
| function sortGrades(grades) { | |
| return [...grades].sort((a, b) => b.max - a.max); | |
| } | |
| // Initialize F1 colors | |
| function initializeF1Colors() { | |
| // Sort grades by performance (highest max value first) | |
| sortedMacroGrades = sortGrades(macro_f1_grades); | |
| sortedMicroGrades = sortGrades(micro_f1_grades); | |
| const macroColors = generateColors(sortedMacroGrades.length); | |
| const microColors = generateColors(sortedMicroGrades.length); | |
| f1Colors.macro = {}; | |
| f1Colors.micro = {}; | |
| sortedMacroGrades.forEach((grade, index) => { | |
| f1Colors.macro[grade.name] = macroColors[index]; | |
| }); | |
| sortedMicroGrades.forEach((grade, index) => { | |
| f1Colors.micro[grade.name] = microColors[index]; | |
| }); | |
| } | |
| function getModelSizeClass(params) { | |
| if (params < 20000000) return 'model-tiny'; // < 20M | |
| if (params < 50000000) return 'model-small'; // 20M - 50M | |
| if (params < 100000000) return 'model-medium'; // 50M - 100M | |
| if (params < 200000000) return 'model-large'; // 100M - 200M | |
| if (params < 1000000000) return 'model-xlarge'; // 200M - 1B | |
| return 'model-xxlarge'; // > 1B | |
| } | |
| function getF1Grade(score, grades) { | |
| for (let grade of grades) { | |
| if (score >= grade.min && score <= grade.max) { | |
| return grade.name; | |
| } | |
| } | |
| return grades[grades.length - 1].name; // Default to last grade | |
| } | |
| function formatParams(params) { | |
| if (params >= 1000000000) { | |
| return (params / 1000000000).toFixed(1) + 'B'; | |
| } else if (params >= 1000000) { | |
| return (params / 1000000).toFixed(1) + 'M'; | |
| } else if (params >= 1000) { | |
| return (params / 1000).toFixed(1) + 'K'; | |
| } | |
| return params.toString(); | |
| } | |
| function formatFlops(flops) { | |
| if (flops >= 1000000000000) { | |
| return (flops / 1000000000000).toFixed(1) + 'T'; | |
| } else if (flops >= 1000000000) { | |
| return (flops / 1000000000).toFixed(1) + 'G'; | |
| } else if (flops >= 1000000) { | |
| return (flops / 1000000).toFixed(1) + 'M'; | |
| } else if (flops >= 1000) { | |
| return (flops / 1000).toFixed(1) + 'K'; | |
| } | |
| return flops.toString(); | |
| } | |
| function formatInputSize(size) { | |
| return `${size}×${size}`; | |
| } | |
| function formatNumber(value) { | |
| if (typeof value === 'number') { | |
| return value.toFixed(3); | |
| } | |
| return value; | |
| } | |
| function parseNumericValue(value) { | |
| return typeof value === 'number' ? value : parseFloat(value) || 0; | |
| } | |
| function renderTable(data) { | |
| const tbody = document.getElementById('tableBody'); | |
| tbody.innerHTML = ''; | |
| data.forEach(model => { | |
| const row = document.createElement('tr'); | |
| const sizeClass = getModelSizeClass(model.params); | |
| row.className = sizeClass; | |
| const macroGrade = getF1Grade(model.macro_f1, macro_f1_grades); | |
| const microGrade = getF1Grade(model.micro_f1, micro_f1_grades); | |
| row.innerHTML = ` | |
| <td> | |
| <a href="https://huggingface.co/${model.hf_repo}" | |
| target="_blank" | |
| class="model-link">${model.hf_repo}</a> | |
| </td> | |
| <td>${model.architecture}</td> | |
| <td class="number-cell">${formatInputSize(model.input_size)}</td> | |
| <td class="number-cell">${formatParams(model.params)}</td> | |
| <td class="number-cell">${formatFlops(model.flops)}</td> | |
| <td class="number-cell"> | |
| <span class="f1-score" style="background-color: ${f1Colors.macro[macroGrade]}; color: #2d3748;">${formatNumber(model.macro_f1)}</span> | |
| </td> | |
| <td class="number-cell"> | |
| <span class="f1-score" style="background-color: ${f1Colors.micro[microGrade]}; color: #2d3748;">${formatNumber(model.micro_f1)}</span> | |
| </td> | |
| `; | |
| tbody.appendChild(row); | |
| }); | |
| updateStats(data); | |
| } | |
| function updateStats(data) { | |
| const totalModels = data.length; | |
| document.getElementById('totalModels').textContent = totalModels; | |
| } | |
| function renderLegend() { | |
| const legendContainer = document.getElementById('legend'); | |
| legendContainer.innerHTML = '<h3>Legend</h3>'; | |
| // Model Size Legend | |
| const modelSizeSection = document.createElement('div'); | |
| modelSizeSection.className = 'legend-section'; | |
| modelSizeSection.innerHTML = ` | |
| <div class="legend-title">Model Size (by Parameters)</div> | |
| <div class="legend-items"> | |
| <div class="legend-item"> | |
| <div class="legend-color tiny"></div> | |
| <span>Tiny (< 20M)</span> | |
| </div> | |
| <div class="legend-item"> | |
| <div class="legend-color small"></div> | |
| <span>Small (20M - 50M)</span> | |
| </div> | |
| <div class="legend-item"> | |
| <div class="legend-color medium"></div> | |
| <span>Medium (50M - 100M)</span> | |
| </div> | |
| <div class="legend-item"> | |
| <div class="legend-color large"></div> | |
| <span>Large (100M - 200M)</span> | |
| </div> | |
| <div class="legend-item"> | |
| <div class="legend-color xlarge"></div> | |
| <span>X-Large (200M - 1B)</span> | |
| </div> | |
| <div class="legend-item"> | |
| <div class="legend-color xxlarge"></div> | |
| <span>XX-Large (> 1B)</span> | |
| </div> | |
| </div> | |
| `; | |
| legendContainer.appendChild(modelSizeSection); | |
| // Macro F1 Legend | |
| const macroF1Section = document.createElement('div'); | |
| macroF1Section.className = 'legend-section'; | |
| macroF1Section.innerHTML = '<div class="legend-title">Macro F1 Performance</div>'; | |
| const macroItems = document.createElement('div'); | |
| macroItems.className = 'legend-items'; | |
| sortedMacroGrades.forEach(grade => { | |
| const item = document.createElement('div'); | |
| item.className = 'legend-item'; | |
| item.innerHTML = ` | |
| <div class="legend-color" style="background-color: ${f1Colors.macro[grade.name]};"></div> | |
| <span>${grade.name} (${grade.min.toFixed(2)} - ${grade.max.toFixed(2)})</span> | |
| `; | |
| macroItems.appendChild(item); | |
| }); | |
| macroF1Section.appendChild(macroItems); | |
| legendContainer.appendChild(macroF1Section); | |
| // Micro F1 Legend | |
| const microF1Section = document.createElement('div'); | |
| microF1Section.className = 'legend-section'; | |
| microF1Section.innerHTML = '<div class="legend-title">Micro F1 Performance</div>'; | |
| const microItems = document.createElement('div'); | |
| microItems.className = 'legend-items'; | |
| sortedMicroGrades.forEach(grade => { | |
| const item = document.createElement('div'); | |
| item.className = 'legend-item'; | |
| item.innerHTML = ` | |
| <div class="legend-color" style="background-color: ${f1Colors.micro[grade.name]};"></div> | |
| <span>${grade.name} (${grade.min.toFixed(2)} - ${grade.max.toFixed(2)})</span> | |
| `; | |
| microItems.appendChild(item); | |
| }); | |
| microF1Section.appendChild(microItems); | |
| legendContainer.appendChild(microF1Section); | |
| } | |
| function sortData(column) { | |
| const headers = document.querySelectorAll('th'); | |
| // Reset all sort indicators | |
| headers.forEach(th => { | |
| th.classList.remove('sort-asc', 'sort-desc'); | |
| }); | |
| // Determine sort direction | |
| if (currentSort.column === column) { | |
| currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc'; | |
| } else { | |
| currentSort.direction = 'asc'; | |
| } | |
| currentSort.column = column; | |
| // Add sort indicator | |
| const currentHeader = document.querySelector(`[data-column="${column}"]`); | |
| if (currentHeader) { | |
| currentHeader.classList.add(currentSort.direction === 'asc' ? 'sort-asc' : 'sort-desc'); | |
| } | |
| // Sort data | |
| const sortedData = [...modelData].sort((a, b) => { | |
| let aVal = parseNumericValue(a[column]); | |
| let bVal = parseNumericValue(b[column]); | |
| if (currentSort.direction === 'asc') { | |
| return aVal - bVal; | |
| } else { | |
| return bVal - aVal; | |
| } | |
| }); | |
| renderTable(sortedData); | |
| } | |
| // Initialize | |
| document.addEventListener('DOMContentLoaded', function () { | |
| // Initialize colors | |
| initializeF1Colors(); | |
| // Set dataset information | |
| document.getElementById('datasetLink').href = `https://huggingface.co/datasets/${dataset_repo_id}`; | |
| document.getElementById('datasetLink').textContent = dataset_repo_id; | |
| document.getElementById('taskTag').textContent = pretrained_tag; | |
| // Initialize with default sort (macro_f1 descending) | |
| if (modelData.length > 0) { | |
| // Set initial sort indicator for macro_f1 column | |
| const macroF1Header = document.querySelector('[data-column="macro_f1"]'); | |
| if (macroF1Header) { | |
| macroF1Header.classList.add('sort-desc'); | |
| } | |
| // Sort data by macro_f1 descending | |
| const sortedData = [...modelData].sort((a, b) => { | |
| let aVal = parseNumericValue(a.macro_f1); | |
| let bVal = parseNumericValue(b.macro_f1); | |
| return bVal - aVal; // Descending order | |
| }); | |
| renderTable(sortedData); | |
| } else { | |
| renderTable(modelData); | |
| } | |
| renderLegend(); | |
| // Add sort event listeners | |
| document.querySelectorAll('th.sortable').forEach(th => { | |
| th.addEventListener('click', function () { | |
| const column = this.getAttribute('data-column'); | |
| sortData(column); | |
| }); | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |