Skip to content

Latest commit

 

History

History
480 lines (441 loc) · 15.5 KB

archive_explorer.md

File metadata and controls

480 lines (441 loc) · 15.5 KB
<script> const { createApp, ref, computed, watch } = Vue; const PackageExplorer = { setup() { // #### global variables #### const packages = ref(null); const samples = ref(null); const searchQuery = ref(''); const archiveType = ref('community-archive'); const loading = ref(true); const mapLegend = ref(null); const mapInstance = ref(null); var mapMarkers = []; var markerClusters = L.markerClusterGroup({ chunkedLoading: true }); const selectedPackageTitle = ref(null); const selectedPackage = ref(null); const filteredPackages = ref([]); // #### load data #### const loadPackages = async () => { try { let apiUrl = 'https://server.poseidon-adna.org/packages'; apiUrl += '?archive=' + archiveType.value; const response_pacs = await fetch(apiUrl); const response_pacs_json = await response_pacs.json(); const latestPackages = response_pacs_json.serverResponse.packageInfo.filter((p) => p.isLatest); packages.value = latestPackages; } catch (error) { console.error(error); } }; const loadSamples = async () => { try { let apiUrl = 'https://server.poseidon-adna.org/individuals?additionalJannoColumns=Genetic_Sex,Country,Location,Latitude,Longitude,Date_Type,Date_C14_Labnr,Date_BC_AD_Median,MT_Haplogroup,Y_Haplogroup,Capture_Type,UDG,Library_Built,Genotype_Ploidy,Nr_SNPs,Coverage_on_Target_SNPs,Publication'; apiUrl += '&archive=' + archiveType.value; const response_inds = await fetch(apiUrl); const response_inds_json = await response_inds.json(); const filteredSamples = response_inds_json.serverResponse.extIndInfo.filter((p) => p.isLatest); samples.value = filteredSamples; } catch (error) { console.error(error); } }; // #### download button #### const downloadGenotypeData = (packageTitle) => { const downloadLink = document.createElement('a'); downloadLink.href = `https://server.poseidon-adna.org/zip_file/${packageTitle}?archive=${archiveType.value}`; downloadLink.download = `${packageTitle}.zip`; downloadLink.click(); }; // #### search #### const packageTitles = computed(() => { if (!packages.value) { return []; } return packages.value.map((pac) => pac.packageTitle.toLowerCase()); }); // watch for changes in searchQuery and update filteredPackages accordingly watch([searchQuery, packageTitles], ([newSearchQuery, newPackageTitles]) => { if (!newPackageTitles || !newSearchQuery) { filteredPackages.value = packages.value; return; } const lowercaseQuery = newSearchQuery.toLowerCase(); const matchingPackageTitles = newPackageTitles.filter((title) => title.includes(lowercaseQuery) ); filteredPackages.value = packages.value.filter((pac) => matchingPackageTitles.includes(pac.packageTitle.toLowerCase()) ); }); // #### map #### const addSamplesToMap = async (requestedPackageTitle) => { try { // check if necessary data and objects are there if (!mapInstance.value) { return; } if (!samples.value) { return; } // filter to one package, if this is requested if (requestedPackageTitle === undefined) { samplesFiltered = samples.value; } else { samplesFiltered = getSamplesForPackage(requestedPackageTitle); } // compile markers samplesFiltered.forEach((s) => { // determine spatial coordinates const addCols = s.additionalJannoColumns; const lat = addCols[3][1]; const lng = addCols[4][1]; if (lat == 0 && lng == 0) { return; } // prepare popup message const popupContentLines = []; const packageLink = `Open package `; popupContentLines.push(`Poseidon ID: ${s.poseidonID}`); popupContentLines.push(`Package: ${s.packageTitle}`); popupContentLines.push(`Package Version: ${s.packageVersion}`); if (addCols[2][1] !== "") { popupContentLines.push(`Location: ${addCols[2][1]}`); } if (addCols[7][1] !== "") { popupContentLines.push(`Age BC/AD: ${addCols[7][1]}`); } popupContentLines.push(`${packageLink}`); // construct marker const popupContent = popupContentLines.join('
'); const oneMarker = L.marker([lat, lng]).bindPopup(popupContent); mapMarkers.push(oneMarker); }); markerClusters.addLayers(mapMarkers); mapInstance.value.addLayer(markerClusters); // zoom var bounds = markerClusters.getBounds(); if (bounds.isValid()) { mapInstance.value.fitBounds(bounds); } // fill legend var nrSamples = samplesFiltered.length; var nrSamplesLoaded = mapMarkers.length; mapLegend.value.update(nrSamplesLoaded,nrSamples - nrSamplesLoaded); } catch (error) { console.error(error); } }; const resetMarkers = () => { markerClusters.removeLayers(mapMarkers); mapMarkers = []; }; const updateMap = async (requestedPackageTitle) => { if (markerClusters) { resetMarkers(); } addSamplesToMap(requestedPackageTitle); }; document.addEventListener('click', (event) => { if (event.target.tagName === 'A' && event.target.getAttribute('data-package-title')) { selectPackage(event.target.getAttribute('data-package-title')); } }); // #### per-package pages #### const getSamplesForPackage = (requestedPackageTitle) => { if (!samples.value) { return; } return samples.value.filter((s) => s.packageTitle === requestedPackageTitle); }; const selectPackage = async (requestedPackageTitle) => { loading.value = true; selectedPackageTitle.value = requestedPackageTitle; selectedPackage.value = packages.value.filter((pac) => pac.packageTitle === selectedPackageTitle.value )[0]; await updateMap(requestedPackageTitle); loading.value = false; } const unselectPackage = async () => { loading.value = true; selectedPackageTitle.value = null; await updateMap(); mapInstance.value.setView([30, 10], 1); loading.value = false; } // primitive attempt to enable a URL selection for packages // has to be done way more professionally // const selectPackageByURL = async () => { // let uri = window.location.href.split('?'); // if (uri.length == 2) { // let vars = uri[1].split('&'); // let getVars = {}; // let tmp = ''; // vars.forEach(function(v) { // tmp = v.split('='); // if(tmp.length == 2) // getVars[tmp[0]] = tmp[1]; // }); // if (getVars["package"]) { // await loadAllData(); // selectPackage(getVars["package"]); // console.log(selectedPackageTitle.value); // } // } // } // selectPackageByURL(); // #### general logic #### const loadAllData = async () => { await loadPackages(); await loadSamples(); }; const showSelection = async () => { loading.value = true; await loadAllData(); await updateMap(); loading.value = false; }; // trigger loading of the website showSelection(); return { packages, searchQuery, archiveType, loading, mapLegend, mapInstance, filteredPackages, showSelection, resetMarkers, downloadGenotypeData, getSamplesForPackage, selectPackage, selectedPackageTitle, selectedPackage, unselectPackage }; } }; const MapView = { template: `
`, mounted() { // prepare base map const map = L.map('map').setView([37, 10], 1); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {}).addTo(map); // map legend const legend = L.control({ position: 'bottomright' }); legend.onAdd = function (map) { this._div = L.DomUtil.create('div', 'legend'); this._div.innerHTML += "Loading..."; return this._div; }; legend.update = function (nrLoaded, nrNotLoadable) { this._div.innerHTML = nrLoaded + " samples loaded
" + nrNotLoadable + " lat/lon missing
"; }; legend.addTo(map); // store legend and map in global variables this.$parent.mapLegend = legend; this.$parent.mapInstance = map; }, }; const app = createApp(PackageExplorer); app.component('map-view', MapView); app.mount('#archiveExplorer'); </script>
_  Loading...
Poseidon Community Archive Poseidon AADR Archive Poseidon Minotaur Archive
Back to the package overview page
Package: {{ selectedPackageTitle }}

Description {{ selectedPackage.description }}
Package version v{{ selectedPackage.packageVersion }} (that is the latest available version) (that is not the latest available version) for Poseidon v{{ selectedPackage.poseidonVersion }}.
It was last modified on {{ selectedPackage.lastModified }}.
Resources See this package on GitHub: Download this package as .zip archive:
Nr of samples {{ selectedPackage.nrIndividuals }}
Poseidon_ID Groups Details
{{ sample.poseidonID }} {{ sample.groupNames.toString() }}
View sample details
{{ addCol[0] }}: {{ addCol[1] }}
*More variables are available in the complete .janno file.
{{ pac.packageTitle }}
v{{ pac.packageVersion }}, Samples: {{ pac.nrIndividuals }}
{{ pac.description }}
<style> .loading-banner { width: 100%; height: 30px; text-align: right; } .loading-spinner { display: inline-block; animation: spin 1s infinite linear; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } #archive-type-select { width: 100%; padding: 5px; } #go-back-button { width: 100%; padding: 5px; margin-bottom: 10px; } .search-bar { margin-top: 10px; margin-bottom: 10px; } .search-bar input[type="text"] { width: 100%; padding: 5px; } .package-heading { margin-top: 10px; margin-bottom: 10px; font-weight: bold; font-size: 25px; } .table-container { max-height: 400px; overflow-y: scroll; width: 100%; } .table-default { width: 100%; display: table !important; table-layout: fixed; word-wrap: break-word; } .legend { padding: 6px 8px; font: 14px/16px Arial, Helvetica, sans-serif; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; color: #777; } </style>