// Global variables for sorting and filtering let currentSortColumn = -1; let isAscending = true; let columnFilters = {}; let columnValues = {}; // Function to update the table based on filters async function updateTable() { const navigation = document.getElementById('navigation').value; const embdType = document.getElementById('embdType').value; const similarity = document.getElementById('similarity').value; // Get all checked embedding dimensions const embdDims = Array.from(document.querySelectorAll('input[name="embdDim"]:checked')) .map(checkbox => checkbox.value); // Prepare filter data const filters = { navigation: navigation, embd_type: embdType, embd_dims: embdDims, similarity: similarity }; try { const response = await fetch('/api/filter', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(filters) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); updateTableContent(data); } catch (error) { console.error('Error updating table:', error); alert('Failed to update table. Please try again.'); } } // Function to update table content function updateTableContent(data) { const tbody = document.querySelector('#leaderboardTable tbody'); tbody.innerHTML = ''; data.forEach(row => { const tr = document.createElement('tr'); row.forEach(cell => { const td = document.createElement('td'); td.innerHTML = cell; // Use innerHTML instead of textContent to handle HTML content tr.appendChild(td); }); tbody.appendChild(tr); }); } // Initialize when document is ready document.addEventListener('DOMContentLoaded', () => { initializeColumnValues(); document.addEventListener('click', handleClickOutside); }); // Initialize unique values for each column function initializeColumnValues() { const table = document.getElementById('leaderboardTable'); const headers = Array.from(table.querySelectorAll('th')); const rows = Array.from(table.querySelectorAll('tbody tr')); headers.forEach((header, columnIndex) => { const columnName = header.querySelector('span').textContent; const values = new Set(); rows.forEach(row => { const cell = row.cells[columnIndex]; const value = cell.textContent.trim(); if (value) values.add(value); }); columnValues[columnName] = Array.from(values).sort(); }); } // Handle clicking outside filter dropdowns function handleClickOutside(event) { const dropdowns = document.querySelectorAll('.filter-dropdown'); dropdowns.forEach(dropdown => { const filterBtn = dropdown.parentElement.querySelector('.filter-btn'); if (!dropdown.contains(event.target) && !filterBtn.contains(event.target)) { dropdown.style.display = 'none'; } }); } // Toggle filter dropdown function toggleFilter(event, columnName) { event.stopPropagation(); const dropdown = document.getElementById(`filter-${columnName}`); const options = document.getElementById(`options-${columnName}`); // Close other dropdowns document.querySelectorAll('.filter-dropdown').forEach(d => { if (d !== dropdown) d.style.display = 'none'; }); if (dropdown.style.display === 'none') { dropdown.style.display = 'block'; if (!options.children.length) { populateFilterOptions(columnName); } } else { dropdown.style.display = 'none'; } } // Populate filter options function populateFilterOptions(columnName) { const options = document.getElementById(`options-${columnName}`); options.innerHTML = ''; columnValues[columnName].forEach(value => { const option = document.createElement('div'); option.className = 'filter-option'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.value = value; checkbox.checked = columnFilters[columnName]?.includes(value) || false; const label = document.createElement('span'); label.textContent = value; option.appendChild(checkbox); option.appendChild(label); options.appendChild(option); }); } // Filter options based on search input function filterOptions(columnName) { const searchInput = document.querySelector(`#filter-${columnName} .filter-search`); const searchTerm = searchInput.value.toLowerCase(); const options = document.getElementById(`options-${columnName}`); Array.from(options.children).forEach(option => { const text = option.textContent.toLowerCase(); option.style.display = text.includes(searchTerm) ? '' : 'none'; }); } // Apply filter function applyFilter(columnName) { const options = document.getElementById(`options-${columnName}`); const checkedValues = Array.from(options.querySelectorAll('input[type="checkbox"]:checked')) .map(cb => cb.value); columnFilters[columnName] = checkedValues; updateTableVisibility(); document.getElementById(`filter-${columnName}`).style.display = 'none'; } // Clear filter function clearFilter(columnName) { const options = document.getElementById(`options-${columnName}`); options.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false); delete columnFilters[columnName]; updateTableVisibility(); document.getElementById(`filter-${columnName}`).style.display = 'none'; } // Update table visibility based on filters function updateTableVisibility() { const table = document.getElementById('leaderboardTable'); const rows = Array.from(table.querySelectorAll('tbody tr')); const headers = Array.from(table.querySelectorAll('th')); rows.forEach(row => { let visible = true; Object.entries(columnFilters).forEach(([columnName, selectedValues]) => { if (!selectedValues.length) return; const columnIndex = headers.findIndex(header => header.querySelector('span').textContent === columnName ); const cellValue = row.cells[columnIndex].textContent.trim(); if (!selectedValues.includes(cellValue)) { visible = false; } }); row.style.display = visible ? '' : 'none'; }); } // Sort table function sortTable(columnIndex) { const table = document.getElementById('leaderboardTable'); const tbody = table.querySelector('tbody'); const rows = Array.from(tbody.querySelectorAll('tr')); // Update sort direction if (currentSortColumn === columnIndex) { isAscending = !isAscending; } else { currentSortColumn = columnIndex; isAscending = true; } // Sort rows rows.sort((a, b) => { let aValue = a.cells[columnIndex].textContent; let bValue = b.cells[columnIndex].textContent; // Remove HTML tags for comparison aValue = aValue.replace(/<[^>]*>/g, '').trim(); bValue = bValue.replace(/<[^>]*>/g, '').trim(); // Check if the values are numbers const aNum = parseFloat(aValue); const bNum = parseFloat(bValue); if (!isNaN(aNum) && !isNaN(bNum)) { return isAscending ? aNum - bNum : bNum - aNum; } // Sort as strings return isAscending ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue); }); // Update table tbody.innerHTML = ''; rows.forEach(row => tbody.appendChild(row)); // Update sort indicators const headers = table.querySelectorAll('.sort-icon'); headers.forEach((icon, index) => { icon.textContent = index === columnIndex ? (isAscending ? '↑' : '↓') : '↕'; }); } // Initialize table sorting and filtering document.addEventListener('DOMContentLoaded', () => { // Add event listener for checkboxes const checkboxes = document.querySelectorAll('input[name="embdDim"]'); checkboxes.forEach(checkbox => { checkbox.addEventListener('change', updateTable); }); });