diff options
-rw-r--r-- | bh20simplewebuploader/main.py | 7 | ||||
-rw-r--r-- | bh20simplewebuploader/static/main.js | 149 | ||||
-rw-r--r-- | bh20simplewebuploader/static/map.js | 67 | ||||
-rw-r--r-- | bh20simplewebuploader/templates/demo-run.html | 26 | ||||
-rw-r--r-- | bh20simplewebuploader/templates/demo.html | 30 | ||||
-rw-r--r-- | bh20simplewebuploader/templates/footer.html | 3 | ||||
-rw-r--r-- | bh20simplewebuploader/templates/header.html | 18 | ||||
-rw-r--r-- | bh20simplewebuploader/templates/map.html | 24 |
8 files changed, 164 insertions, 160 deletions
diff --git a/bh20simplewebuploader/main.py b/bh20simplewebuploader/main.py index 1147176..e8bb507 100644 --- a/bh20simplewebuploader/main.py +++ b/bh20simplewebuploader/main.py @@ -628,7 +628,7 @@ def validated_page(): @app.route('/demo') def demo_page(): - return render_template('demo.html',menu='DEMO') + return render_template('demo.html',menu='DEMO',load_map=True) @app.route('/blog',methods=['GET']) def blog_page(): @@ -644,11 +644,6 @@ def about_page(): buf = get_html_body('doc/web/about.html','https://github.com/arvados/bh20-seq-resource/blob/master/doc/web/about.org') return render_template('about.html',menu='ABOUT',embed=buf) -## -@app.route('/map') -def map_page(): - return render_template('map.html',menu='DEMO') - ## Dynamic API functions starting here ## This is quick and dirty for now, just to get something out and demonstrate the queries diff --git a/bh20simplewebuploader/static/main.js b/bh20simplewebuploader/static/main.js index 4703047..1633c25 100644 --- a/bh20simplewebuploader/static/main.js +++ b/bh20simplewebuploader/static/main.js @@ -13,70 +13,41 @@ function myFunction() { } } -let map = L.map( 'map', { - center: [37.0902, -95.7129], // Default to U.S.A - minZoom: 3, - zoom: 0 -}); -L.tileLayer( 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', - subdomains: ['a','b','c'] -}).addTo( map ); - -let markers = L.markerClusterGroup().addTo(map) - - function fetchAPI(apiEndPoint) { - fetch(scriptRoot + apiEndPoint) - .then(response => { - return response.json(); - }) - .then(data => { - console.log(data); - markers.clearLayers(); - document.getElementById("results").classList.remove("invisible"); - document.getElementById("loader").classList.add("invisible"); - if (!(apiEndPoint === "/api/getAllaccessions")) { - for (let i = 0; i < data.length; i++) { - let {"count": fastaCount, GPS, LocationLabel: label } = data[i]; - let coordinates = GPS.split(" "); - if (!(coordinates == null)) { - let lat, lon; - [lon, lat] = coordinates.map(parseFloat); - let point = L.point() - let marker = L.marker([lat, lon]); - marker.bindPopup("<b>" + label + "</b><br/>" + "FastaCount: " +fastaCount); - markers.addLayer(marker) - }} - } - // Reload the map - map.invalidateSize(); - }); - document.getElementById("results").classList.add("invisible"); - document.getElementById("loader").classList.remove("invisible"); - -} - -// Copy from function above but now added as table instead of plain json -function fetchAPIV2(apiEndPoint) { - fetch(scriptRoot + apiEndPoint) - .then(response => { - return response.json(); - }) - .then(data => { - console.log(data) - htmlString="<table>" - - // Depending on what we want to explore we'd have to call a different function ....? But how to Include that? - for (var i=0; i<data.length;i++) { - htmlString=htmlString+"<tr><td><a href='#' onclick='fetchSEQByLocation(\""+data[i]["key"]+"\");'>"+data[i]["label"]+"</a></td><td>"+data[i]["count"]+"<td></tr>" - } - htmlString=htmlString+"</table>" - - document.getElementById("table").innerHTML = htmlString - }); - - document.getElementById("results").classList.add("invisible"); + fetch(scriptRoot + apiEndPoint) + .then(response => { + return response.json(); + }) + .then(data => { + console.log(data); + }); + document.getElementById("map_view").classList.add("invisible"); + document.getElementById("loader").classList.remove("invisible"); +} + +// Copy from function above but now output HTML table instead of plain json +function fetchHTMLTable(apiEndPoint) { + fetch(scriptRoot + apiEndPoint) + .then(response => { + return response.json(); + }) + .then(data => { + console.log(data) + htmlString="<table>" + + // Depending on what we want to explore we'd have to call a different function ....? But how to Include that? + /* + for (var i=0; i<data.length;i++) { + htmlString=htmlString+"<tr><td><a href='#' onclick='fetchSEQByLocation(\""+data[i]["key"]+"\");'>"+data[i]["label"]+"</a></td><td>"+data[i]["count"]+"<td></tr>" + } +*/ + for (var i=0; i<data.length;i++) { + htmlString=htmlString+"<tr><td>"+data[i]["label"]+"</td><td>"+data[i]["count"]+"<td></tr>" + } + htmlString=htmlString+"</table>" + + document.getElementById("table").innerHTML = htmlString + }); } @@ -85,36 +56,39 @@ let search = () => { fetchAPI(scriptRoot + "/api/getDetailsForSeq?seq=" + encodeURIComponent(m)); } +// Get count from Arvados let fetchCount = () => { fetchAPI("/api/getCount"); } +// Get count from Virtuoso let fetchCountDB = () => { fetchAPI("/api/getCountDB"); } let fetchSEQCountBySpecimen = () => { - fetchAPIV2("/api/getSEQCountbySpecimenSource"); + fetchHTMLTable("/api/getSEQCountbySpecimenSource"); } let fetchSEQCountByLocation = () => { - fetchAPIV2("/api/getSEQCountbyLocation"); + fetchHTMLTable("/api/getSEQCountbyLocation"); } let fetchSEQCountByTech = () => { - fetchAPIV2("/api/getSEQCountbytech"); + fetchHTMLTable("/api/getSEQCountbytech"); } let fetchAllaccessions = () => { - fetchAPI("/api/getAllaccessions"); + fetchHTMLTable("/api/getAllaccessions"); }; -let fetchCountByGPS = () => { - fetchAPI("/api/getCountByGPS"); +let fetchMap = () => { + fetchAPI("/api/getCountByGPS"); + updateMapMarkers(); }; let fetchSEQCountbyLocation = () => { - fetchAPIV2("/api/getSEQCountbyLocation"); + fetchHTMLTable("/api/getSEQCountbyLocation"); }; let fetchSEQByLocation = () => { @@ -122,7 +96,7 @@ let fetchSEQByLocation = () => { }; let fetchSEQCountbyContinent = () => { - fetchAPIV2("/api/getSEQCountbyContinent"); + fetchHTMLTable("/api/getSEQCountbyContinent"); } @@ -252,36 +226,3 @@ function on_submit_button() { return false; } } - - - -// - -function drawMap(){ - -// initialize the map on the "map" div with a given center and zoom -var mymap = L.map('mapid').setView([51.505, -0.09], 1); - -L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' -}).addTo(mymap); - -fetch(scriptRoot + "api/getCountByGPS") - .then(response => { - console.log(response) - return response.json(); - }) - .then(data => { - - for (var i=0; i<data.length;i++) { - gps=data[i]["GPS"].split(" ") - var circle = L.circle([gps[1], gps[0]], { - color: 'red', - fillColor: '#f03', - fillOpacity: 0.5, - radius: parseInt(data[i]["count"]) //not working for whatever reason - }).addTo(mymap); - } - - }); -} diff --git a/bh20simplewebuploader/static/map.js b/bh20simplewebuploader/static/map.js new file mode 100644 index 0000000..afc6c3f --- /dev/null +++ b/bh20simplewebuploader/static/map.js @@ -0,0 +1,67 @@ +let map = L.map( 'map', { + center: [37.0902, -95.7129], // Default to U.S.A + minZoom: 3, + zoom: 0 +}); +L.tileLayer( 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', + subdomains: ['a','b','c'] +}).addTo( map ); + +let markers = L.markerClusterGroup().addTo(map) + + +function drawMap(){ + +// initialize the map on the "map" div with a given center and zoom +var mymap = L.map('mapid').setView([51.505, -0.09], 1); + +L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' +}).addTo(mymap); + +fetch(scriptRoot + "api/getCountByGPS") + .then(response => { + console.log(response) + return response.json(); + }) + .then(data => { + + for (var i=0; i<data.length;i++) { + gps=data[i]["GPS"].split(" ") + var circle = L.circle([gps[1], gps[0]], { + color: 'red', + fillColor: '#f03', + fillOpacity: 0.5, + radius: parseInt(data[i]["count"]) //not working for whatever reason + }).addTo(mymap); + } + + }); +} + + + +/* This function updates the map with markers + * +*/ +function updateMapMarkers() { + markers.clearLayers(); // remove all markers + document.getElementById("results").classList.remove("invisible"); + document.getElementById("loader").classList.add("invisible"); + for (let i = 0; i < data.length; i++) { + let {"count": fastaCount, GPS, LocationLabel: label } = data[i]; + let coordinates = GPS.split(" "); + if (!(coordinates == null)) { + let lat, lon; + [lon, lat] = coordinates.map(parseFloat); + let point = L.point() + let marker = L.marker([lat, lon]); + marker.bindPopup("<b>" + label + "</b><br/>" + "FastaCount: " +fastaCount); + markers.addLayer(marker) + }} + // Reload the map + map.invalidateSize(); + document.getElementById("map_view").classList.add("invisible"); + document.getElementById("loader").classList.add("invisible"); +} diff --git a/bh20simplewebuploader/templates/demo-run.html b/bh20simplewebuploader/templates/demo-run.html index a8f9edc..e69de29 100644 --- a/bh20simplewebuploader/templates/demo-run.html +++ b/bh20simplewebuploader/templates/demo-run.html @@ -1,26 +0,0 @@ -<section class="search-section"> - <div class="filter-options" action="#"> - <p>[Demo] Display content sequences by: </p> - <div> - <button class="button" onclick="fetchSEQCountBySpecimen()">Count by Specimen source</button> - <button class="button" onclick="fetchSEQCountByLocation()">Count by Location</button> - <button class="button" onclick="fetchSEQCountByTech()">Count by Sequencer</button> - <button class="button" onclick="fetchAllaccessions()">Show All accessions</button> - <button class="button" onclick="fetchSEQCountbyContinent()">Count by Continent</button> - <button class="button" onclick="fetchCountByGPS()">Map</button> - - </div> - - </div> - -</section> -<div id="loader" class="loader invisible"> -</div> - -<section id="results" class="invisible"> - <div id="map"></div> -</section> - - <section> - <div id="table"></div> - </section> diff --git a/bh20simplewebuploader/templates/demo.html b/bh20simplewebuploader/templates/demo.html index 44aded0..2e290c6 100644 --- a/bh20simplewebuploader/templates/demo.html +++ b/bh20simplewebuploader/templates/demo.html @@ -5,8 +5,34 @@ {% include 'banner.html' %} {% include 'menu.html' %} {% include 'search.html' %} - <p>The Virtuoso database contains <span id="CounterDB"></span> public sequences!</p> - {% include 'demo-run.html' %} + <p>The Virtuoso database contains <span id="CounterDB"></span> public sequences!</p> + + <section class="search-section"> + <div class="filter-options" action="#"> + <p>[Demo] Display content sequences by: </p> + <div> + <button class="button" onclick="fetchSEQCountBySpecimen()">Count by Specimen source</button> + <button class="button" onclick="fetchSEQCountByLocation()">Count by Location</button> + <button class="button" onclick="fetchSEQCountByTech()">Count by Sequencer</button> + <!-- <button class="button" onclick="fetchAllaccessions()">Show All accessions</button> --> + <button class="button" onclick="fetchSEQCountbyContinent()">Count by Continent</button> + <button class="button" onclick="fetchMap()">Map</button> + </div> + + </div> + + </section> + <div id="loader" class="loader invisible"> + </div> + + <section id="map_view" class="invisible"> + <div id="map"></div> + </section> + + <section> + <div id="table"></div> + </section> + {% include 'footer.html' %} <script type="text/javascript"> diff --git a/bh20simplewebuploader/templates/footer.html b/bh20simplewebuploader/templates/footer.html index 2064036..f84cef5 100644 --- a/bh20simplewebuploader/templates/footer.html +++ b/bh20simplewebuploader/templates/footer.html @@ -47,6 +47,9 @@ </center> </div> </section> +{% if load_map %} +<script type="text/javascript" src="/static/map.js"></script> +{% endif %} <script type="text/javascript" src="/static/main.js"></script> <script type="text/javascript"> diff --git a/bh20simplewebuploader/templates/header.html b/bh20simplewebuploader/templates/header.html index 0ac5157..1d66590 100644 --- a/bh20simplewebuploader/templates/header.html +++ b/bh20simplewebuploader/templates/header.html @@ -6,22 +6,4 @@ {% if blog %} <link rel="Blog stylesheet" type="text/css" href="/static/blog.css" /> {% endif %} - <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" - integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" - crossorigin=""/> - <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css" - integrity="sha512-RLEjtaFGdC4iQMJDbMzim/dOvAu+8Qp9sw7QE4wIMYcg2goVoivzwgSZq9CsIxp4xKAZPKh5J2f2lOko2Ze6FQ==" - crossorigin=""/> - - <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css" - integrity="sha512-BBToHPBStgMiw0lD4AtkRIZmdndhB6aQbXpX7omcrXeG2PauGBl2lzq2xUZTxaLxYz5IDHlmneCZ1IJ+P3kYtQ==" - crossorigin=""/> - - <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" - integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" - crossorigin=""></script> - - <script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js" - integrity="sha512-MQlyPV+ol2lp4KodaU/Xmrn+txc1TP15pOBF/2Sfre7MRsA/pB4Vy58bEqe9u7a7DczMLtU5wT8n7OblJepKbg==" - crossorigin=""></script> </head> diff --git a/bh20simplewebuploader/templates/map.html b/bh20simplewebuploader/templates/map.html index 595af0c..4aa22b9 100644 --- a/bh20simplewebuploader/templates/map.html +++ b/bh20simplewebuploader/templates/map.html @@ -1,7 +1,26 @@ <!DOCTYPE html> <html> {% include 'header.html' %} -<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" + <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" + integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" + crossorigin=""/> + <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css" + integrity="sha512-RLEjtaFGdC4iQMJDbMzim/dOvAu+8Qp9sw7QE4wIMYcg2goVoivzwgSZq9CsIxp4xKAZPKh5J2f2lOko2Ze6FQ==" + crossorigin=""/> + + <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css" + integrity="sha512-BBToHPBStgMiw0lD4AtkRIZmdndhB6aQbXpX7omcrXeG2PauGBl2lzq2xUZTxaLxYz5IDHlmneCZ1IJ+P3kYtQ==" + crossorigin=""/> + + <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" + integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" + crossorigin=""></script> + + <script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js" + integrity="sha512-MQlyPV+ol2lp4KodaU/Xmrn+txc1TP15pOBF/2Sfre7MRsA/pB4Vy58bEqe9u7a7DczMLtU5wT8n7OblJepKbg==" + crossorigin=""></script> + + <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/> @@ -11,9 +30,6 @@ {% include 'footer.html' %} - - - <script type="text/javascript"> let scriptRoot = {{ request.script_root|tojson|safe }}; // examples </script> |