134 lines
3.8 KiB
JavaScript
134 lines
3.8 KiB
JavaScript
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 <a> element for the download link
|
|
const a = document.createElement("a");
|
|
|
|
// Set the Href of <a> 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 <a> to the document
|
|
document.body.appendChild(a);
|
|
|
|
// Click the <a> element
|
|
a.click();
|
|
|
|
// Remove the <a> element and revoke the URL object
|
|
document.body.removeChild(a);
|
|
URL.revokeObjectURL(url);
|
|
} |