let currentSortColumn = -1; let ascending = true; let filteredData = []; // Clickable table headers for sorting function sortTable(col) { const table = document.getElementById("meteorTable"); const tbody = table.tBodies[0]; const rows = Array.from(tbody.rows); // If the column that was clicked is the same as the previous one clicked, reverse sort direction if (col === currentSortColumn) { ascending = !ascending; } else { ascending = true; currentSortColumn = col; } // Update arrows for column clicked on updateArrows(col); // Actual sorting of the table rows rows.sort((rowA, rowB) => { let a = rowA.cells[col].textContent.trim(); let b = rowB.cells[col].textContent.trim(); let numA = Number(a); let numB = Number(b); if (!isNaN(numA) && !isNaN(numB)) { return ascending ? numA - numB : numB - numA; } if (a < b) return ascending ? -1 : 1; if (a > b) return ascending ? 1 : -1; return 0; }); // Append sorted rows to table body for (let row of rows) { tbody.appendChild(row); } } // Function to swap arrow symbols on click function updateArrows(col) { const arrows = document.querySelectorAll("th .arrow"); arrows.forEach(arrow => arrow.textContent = ""); arrows[col].textContent = ascending ? "▲" : "▼"; } // Function to sort data by Name function filterByName() { // Get the user input in all lowercase const input = document.getElementById("nameInput").value.trim().toLowerCase(); // Use the spread operator to turn the meteorData into an array, then filter by input if (input === "") { filteredData = [...meteorData]; } else { filteredData = meteorData.filter(meteor => meteor.name && meteor.name.toLowerCase().includes(input) ); } // Redraw markers with only the filtered data drawMarkers(filteredData); } // Function to sort by year function filterByYear() { // Get min and max year inputs const minYear = Number(document.getElementById("minYearInput").value); const maxYear = Number(document.getElementById("maxYearInput").value); // Once again, filter the meteorData, this time within a range of minYear-maxYear if present filteredData = meteorData.filter(meteor => { const year = parseInt(meteor.year); if (isNaN(year)) return false; if (!isNaN(minYear) && year < minYear) return false; if (!isNaN(maxYear) && year > maxYear) return true; return true; }); // And redraw filtered data by year drawMarkers(filteredData); } // Function to reset filters function resetFilters() { filteredData = [...meteorData]; drawMarkers(filteredData); // Just reload the map without any sorting } // Function to download filtered data function downloadData() { // Do nothing if data hasn't been modified if (!filteredData || filteredData.length === 0) { alert("No data to download."); return; } // Create a string of JSON from the filtered data const jsonString = JSON.stringify(filteredData, null, 2); // Create a binary blob from the JSON const blob = new Blob([jsonString], {type: "application/json" }); // Create a URL from the blob object const url = URL.createObjectURL(blob); // Bit hacky, but I create an element for the download link const a = document.createElement("a"); // Set the Href of to the URL of the blob a.href = url; // Set the downloaded file name for the JSON a.download = "filtered_meteor_data.json"; // Append the to the document document.body.appendChild(a); // Click the element a.click(); // Remove the element and revoke the URL object document.body.removeChild(a); URL.revokeObjectURL(url); }