Commit 3f24326f authored by Michał Woźniak's avatar Michał Woźniak
Browse files

we now can display multiple sites

parent 548fd73f
Pipeline #90 passed with stage
in 0 seconds
...@@ -165,62 +165,74 @@ let getEstimatedDays = (site) => { ...@@ -165,62 +165,74 @@ let getEstimatedDays = (site) => {
} }
/*
* handling a .sites-select change
*/
let selectSite = (e) => {
var theSelect = event.target
if ('selectTimeout' in theSelect) {
if (theSelect.selectTimeout !== false) {
clearTimeout(theSelect.selectTimeout)
theSelect.selectTimeout = false
}
} else {
theSelect.selectTimeout = false;
}
var siteData = theSelect.parentElement.parentElement.getElementsByClassName("site-data")[0];
// need to handle the corner cases, eh
var site = theSelect.value
// using History.pushState() because we don't want the onhashchange event to fire
if (theSelect.managesHash) {
history.pushState({}, '', '#' + site.toLowerCase().replace(/[^a-z0-9]/g, '-'))
}
theSelect.selectTimeout = setTimeout(function(){
theSelect.selectTimeout = false
console.log(`+-- fetching data for: ${site}`)
siteData.innerHTML = `<div class="please-wait">Fetching data, please wait...</div>`
getSiteCases(site)
.then((wikiData)=>{
var data = wikiData.data
var ratio = data[data.length-1].cases / data[data.length-2].cases
var cases = data[data.length-1].cases
console.log(`+-- covid data for: ${site}`
+ `\n date : ${data[data.length-1].date}`
+ `\n cases : ${cases}`
+ `\n cases day prior : ${data[data.length-2].cases}`
+ `\n ratio : ${ratio}`
+ `\n source link : ${wikiData.source_link}`
+ `\n source title : ${wikiData.source_title}`)
getSitePopulation(site)
.then((population)=>{
siteData.innerHTML = `
<div><span class="label">Population:</span><span class="value">${population}</span></div>
<div><span class="label">Cases:</span><span class="value">${cases}</span></div>
<div><span class="label">% infected:</span><span class="value">${Math.round((cases/population)*10000)/100}%</span></div>
<div><span class="label">Rate:</span><span class="value">${Math.round((ratio - 1) * 10000) / 100}%</span></div>
<div><span class="label">Doubles every:</span><span class="value">${Math.round(Math.log(2)/Math.log(ratio))} days</span></div>
<div><span class="label">Half infected in:</span><span class="value">${Math.round(Math.log(population*0.5/cases)/Math.log(ratio))} days</span></div>
<div class="sources"><a href="${wikiData.source_link}">source</a></div>`
})
})
.catch((e)=>{
siteData.innerHTML = `<div class="error">Something went wrong. Either a bug, or no data.</div>`
})
}, 500)
}
/* /*
* make sure stuff is set-up properly * make sure stuff is set-up properly
*/ */
document.addEventListener('DOMContentLoaded', (e)=>{ document.addEventListener('DOMContentLoaded', (e)=>{
// fill out site drop-down // fill out site drop-down
var siteSelect = document.getElementById("sites"); var sitesSelects = document.getElementsByClassName("sites-select");
sitesSelects[0].addEventListener('change', selectSite);
// handle user interaction sitesSelects[0].managesHash = true
var siteSelectTimeout = false
var siteData = document.getElementById("site-data");
siteSelect.addEventListener('change', (e) => {
if (siteSelectTimeout !== false) {
clearTimeout(siteSelectTimeout)
siteSelectTimeout = false
}
// need to handle the corner cases, eh
var site = event.target.value
// using History.pushState() because we don't want the onhashchange event to fire
history.pushState({}, '', '#' + site.toLowerCase().replace(/[^a-z0-9]/g, '-'))
siteSelectTimeout = setTimeout(function(){
siteSelectTimeout = false
console.log(`+-- fetching data for: ${site}`)
siteData.innerHTML = `<div class="please-wait">Fetching data, please wait...</div>`
getSiteCases(site)
.then((wikiData)=>{
var data = wikiData.data
var ratio = data[data.length-1].cases / data[data.length-2].cases
var cases = data[data.length-1].cases
console.log(`+-- covid data for: ${site}`
+ `\n date : ${data[data.length-1].date}`
+ `\n cases : ${cases}`
+ `\n cases day prior : ${data[data.length-2].cases}`
+ `\n ratio : ${ratio}`
+ `\n source link : ${wikiData.source_link}`
+ `\n source title : ${wikiData.source_title}`)
getSitePopulation(site)
.then((population)=>{
siteData.innerHTML = `
<div><span class="label">Population:</span><span class="value">${population}</span></div>
<div><span class="label">Cases:</span><span class="value">${cases}</span></div>
<div><span class="label">% infected:</span><span class="value">${Math.round((cases/population)*10000)/100}%</span></div>
<div><span class="label">Rate:</span><span class="value">${Math.round((ratio - 1) * 10000) / 100}%</span></div>
<div><span class="label">Doubles every:</span><span class="value">${Math.round(Math.log(2)/Math.log(ratio))} days</span></div>
<div><span class="label">Half infected in:</span><span class="value">${Math.round(Math.log(population*0.5/cases)/Math.log(ratio))} days</span></div>
<div class="sources"><a href="${wikiData.source_link}">source</a></div>`
})
})
.catch((e)=>{
siteData.innerHTML = `<div class="error">Something went wrong. Either a bug, or no data.</div>`
})
}, 500)
});
// fill out the covid data box // fill out the covid data box
getCovidData() getCovidData()
...@@ -233,7 +245,9 @@ document.addEventListener('DOMContentLoaded', (e)=>{ ...@@ -233,7 +245,9 @@ document.addEventListener('DOMContentLoaded', (e)=>{
var cOpt = document.createElement("option"); var cOpt = document.createElement("option");
cOpt.value = sites[site]; cOpt.value = sites[site];
cOpt.innerHTML = sites[site]; cOpt.innerHTML = sites[site];
siteSelect.appendChild(cOpt); // yes, this only handles the first sites select
// since at that point there is only one sites select
sitesSelects[0].appendChild(cOpt);
} }
return sites return sites
}) })
...@@ -252,11 +266,20 @@ document.addEventListener('DOMContentLoaded', (e)=>{ ...@@ -252,11 +266,20 @@ document.addEventListener('DOMContentLoaded', (e)=>{
var hash_sites = sites.filter(site => (site.toLowerCase().replace(/[^a-z]/g, '-') === window.location.hash.substr(1))) var hash_sites = sites.filter(site => (site.toLowerCase().replace(/[^a-z]/g, '-') === window.location.hash.substr(1)))
if (hash_sites.length === 1) { if (hash_sites.length === 1) {
console.log(` +-- got site from hash: ${hash_sites[0]}`) console.log(` +-- got site from hash: ${hash_sites[0]}`)
siteSelect.value = hash_sites[0] // this only handles the first sitesSelect
siteSelect.dispatchEvent(new Event('change')); // all others are not currently addressable in hash
sitesSelects[0].value = hash_sites[0]
sitesSelects[0].dispatchEvent(new Event('change'));
} }
} }
}, false); }, false);
document.getElementById('add-site').addEventListener('click', (e)=>{
var newSite = sitesSelects[sitesSelects.length - 1].parentElement.parentElement.cloneNode(true)
newSite.getElementsByClassName('site-data')[0].innerHTML="";
sitesSelects[0].parentElement.parentElement.parentElement.appendChild(newSite)
sitesSelects[sitesSelects.length - 1].addEventListener('change', selectSite);
})
}); });
// https://en.wikipedia.org/wiki/File:Epidemic_curve_update_18_march_20.png // https://en.wikipedia.org/wiki/File:Epidemic_curve_update_18_march_20.png
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
font-family: "Play Bold"; font-family: "Play Bold";
} }
#covid-stats h2, #covid-stats h2,
#site-data-container h2 { .site-data-container h2 {
font-size: 140%; font-size: 140%;
font-family: "Play Regular"; font-family: "Play Regular";
font-weight: bold; font-weight: bold;
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
text-align: right; text-align: right;
opacity: 0.5; opacity: 0.5;
} }
#site-data { .site-data {
display: grid; display: grid;
grid-template-columns: auto auto auto; grid-template-columns: auto auto auto;
grid-template-rows: auto auto auto; grid-template-rows: auto auto auto;
...@@ -90,26 +90,33 @@ ...@@ -90,26 +90,33 @@
padding-top:1em; padding-top:1em;
padding-bottom:1em; padding-bottom:1em;
} }
#site-data > * { .site-data > * {
display: grid; display: grid;
margin:0px; margin:0px;
padding:0.5em; padding:0.5em;
} }
#site-data > h2 { .site-data > h2 {
grid-area: header; grid-area: header;
} }
#site-data > .sources { .site-data > .sources {
grid-area: sources; grid-area: sources;
} }
#site-data > * .value { .site-data > * .value {
font-weight: bold; font-weight: bold;
font-family: "Play Bold"; font-family: "Play Bold";
} }
#site-data-container { #sites-data-container {
flex-grow:1; flex-grow:1;
display: flex;
flex-direction: row;
align-items:flex-start;
justify-content: center;
flex-wrap: wrap;
}
#sites-data-container .site-data-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items:center; align-items:flex-start;
} }
footer { footer {
font-size: 70%; font-size: 70%;
...@@ -119,7 +126,7 @@ ...@@ -119,7 +126,7 @@
font-family: Monospace; font-family: Monospace;
background: black; background: black;
} }
#site-data-container #sites { .site-data-container .sites-select {
display: inline; display: inline;
-moz-appearance: none; -moz-appearance: none;
-webkit-appearance: none; -webkit-appearance: none;
...@@ -132,13 +139,13 @@ ...@@ -132,13 +139,13 @@
font-size:inherit; font-size:inherit;
min-width:15em; min-width:15em;
} }
#site-data-container #sites option { .site-data-container .sites-select option {
font-size:70%; font-size:70%;
} }
#site-data-container h2 { .site-data-container h2 {
position:relative; position:relative;
} }
#site-data-container h2::after { .site-data-container h2::after {
position:absolute; position:absolute;
right:0.5em; right:0.5em;
top:0.25em; top:0.25em;
...@@ -146,6 +153,23 @@ ...@@ -146,6 +153,23 @@
display: block; display: block;
color: springgreen; color: springgreen;
} }
#add-site-container {
order:99;
}
#add-site {
font-size: 250%;
text-decoration: none;
border: dotted 1px springgreen;
width: 1em;
height: 0.98em;
display: inline-block;
line-height: 90%;
margin-left:0.5em;
outline:none;
text-align: Center;
margin-top: 0.47em;
color: springgreen;
}
</style> </style>
</head> </head>
<body> <body>
...@@ -158,12 +182,15 @@ ...@@ -158,12 +182,15 @@
<div id="mortality"><span class="label">Mortality rate:</span> <span class="value"></span></div> <div id="mortality"><span class="label">Mortality rate:</span> <span class="value"></span></div>
</div> </div>
<div class="sources"><a href="https://en.wikipedia.org/wiki/2019%E2%80%9320_coronavirus_pandemic">source</a></div> <div class="sources"><a href="https://en.wikipedia.org/wiki/2019%E2%80%9320_coronavirus_pandemic">source</a></div>
<div id="site-data-container"> <div id="sites-data-container">
<h2><select id="sites" tabindex="1"> <div class="site-data-container">
<option value="select one">(select an area)</option> <h2><select class="sites-select" tabindex="1">
</select></h2> <option value="select one">(select an area)</option>
<div id="site-data"> </select></h2>
<div class="site-data">
</div>
</div> </div>
<div id="add-site-container"><a href="#add-site" id="add-site">+</a></div>
</div> </div>
<p><strong>Disclaimer:</strong> this is all back-of-the-napkin math using data from Wikipedia. Take with a grain (or preferably, a spoonfull) of salt. Check your own sources; some great resources: <a href="http://covid.hi.is/">University of Iceland's COVID data model</a> (and its <a href="https://github.com/bgautijonsson/covid19/">sources</a>).</p> <p><strong>Disclaimer:</strong> this is all back-of-the-napkin math using data from Wikipedia. Take with a grain (or preferably, a spoonfull) of salt. Check your own sources; some great resources: <a href="http://covid.hi.is/">University of Iceland's COVID data model</a> (and its <a href="https://github.com/bgautijonsson/covid19/">sources</a>).</p>
<footer> <footer>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment