//Fetch data async function getData() { //let newCovidDataRaw = await fetch (`./Data/updated-data.json`); let newCovidDataRaw= await fetch (`https://beta.ctvnews.ca/content/dam/common/exceltojson/COVID-19-Canada-New.txt`); let newCovidData = await newCovidDataRaw.json(); //let mapDataRaw = await fetch ('./Data/canada-map.json'); let mapDataRaw = await fetch ('/polopoly_fs/1.4703804!/httpFile/file.txt'); let mapData = await mapDataRaw.json(); //let autoDataCurrentRaw = await fetch ('./Data/scraper-data.json'); let autoDataCurrentRaw = await fetch ('https://stats.ctvnews.ca/covidDapi/getCovidData/all').catch(err => console.log(err)) let autoDataCurrent; if (autoDataCurrentRaw) { autoDataCurrent = await autoDataCurrentRaw.json(); } //let autoDataHistoricalRaw = await fetch ('https://stats.ctvnews.ca/covidDapi/getAllCovidData'); // let autoDataHistorical = await autoDataHistoricalRaw.json(); let autoDataHistorical; await formatCaseData(mapData, newCovidData, autoDataCurrent, autoDataHistorical) return [mapData, autoDataCurrent, autoDataHistorical]; } async function formatCaseData(mapData, newCovidData, autoDataCurrent, autoDataHistorical) { //TO DO: change toDate function to return string of m/dd (use .toMonth() and .toDate() Date methods I think) function toDate(excelDate) { return new Date((excelDate - (25567 + 1))*86400*1000); } const provArray = [{short:'BC', long:'British Columbia'},{short:'AB', long:'Alberta'},{short:'SK', long:'Saskatchewan'},{short:'MB', long:'Manitoba'},{short:'ON', long:'Ontario'},{short:'QC', long:'Quebec'},{short:'NB', long:'New Brunswick'},{short:'NS', long:'Nova Scotia'},{short:'PE', long:'Prince Edward Island'},{short:'NL', long:'Newfoundland and Labrador'},{short:'YT', long:'Yukon'},{short:'NT', long:'Northwest Territories'},{short:'NU', long:'Nunavut'}] let populationArray = [ { name: "British Columbia", population: "5110917", }, { name: "Alberta", population: "4413146", }, { name: "Saskatchewan", population: "1181666", }, { name: "Manitoba", population: "1377517", }, { name: "Ontario", population: "14711827" }, { name: "Quebec", population: "8537674", }, { name: "New Brunswick", population: "779993", }, { name: "Nova Scotia", population: "977457", }, { name: "Prince Edward Island", population: "158158", }, { name: "Newfoundland and Labrador", population: "521365", }, { name: "Yukon", population: "41078", }, { name: "Northwest Territories", population: "44904", }, { name: "Nunavut", population: "39097", }, { name: "Canada", population: "37894799" } ] mapData.features.forEach(province => { let obj = populationArray.find(thing => thing.name === province.properties.PRENAME); if (obj) { province.properties.population = Number(obj.population) } else { console.log('no match found for', province) } }) mapData.properties = {PRENAME: "Canada", population: 37894799} function addTracking(data, key) { data.tracking = []; newCovidData.forEach((day, i, N) => { if (day.Date !== "") { let date = toDate(Number(day.Date)); let total = Number(day[`${key}_Total`]); let newCases = i === 0 ? 0 : Number(N[i][`${key}_Total`]) - Number(N[i-1][`${key}_Total`]); let active = Number(day[`${key}_Total`]) - Number(day[`${key}_Recovered`]) - Number(day[`${key}_Death`]); let recovered = Number(day[`${key}_Recovered`]); let deaths = Number(day[`${key}_Death`]); if (!(newCases < 0 && total === 0)) { data.tracking.push({ date: date, total: total, active: active, recovered: recovered, deaths: deaths, raw: { cumulative: {}, new: {}, average: {}, }, per100k: { cumulative: {}, new: {}, average: {}, } }) } } }) } function per100k(raw, population) { return Math.round(100*(raw*(100000/population)))/100; } function addCumulative(data, population) { data.tracking.forEach(day => { day.raw.cumulative.cases = day.total; day.raw.cumulative.active = day.active; day.raw.cumulative.recovered = day.recovered; day.raw.cumulative.deaths = day.deaths; day.per100k.cumulative.cases = per100k(day.total, population); day.per100k.cumulative.active = per100k(day.active, population); day.per100k.cumulative.recovered = per100k(day.recovered, population); day.per100k.cumulative.deaths = per100k(day.deaths, population); }) } function addNew(data, population) { data.tracking.forEach((day, i, n) => { day.raw.new.cases = i === 0 ? 0 : n[i].raw.cumulative.cases - n[i-1].raw.cumulative.cases; day.raw.new.active = i === 0 ? 0 : n[i].raw.cumulative.active - n[i-1].raw.cumulative.active; day.raw.new.recovered = i === 0 ? 0 : n[i].raw.cumulative.recovered - n[i-1].raw.cumulative.recovered; day.raw.new.deaths = i === 0 ? 0 : n[i].raw.cumulative.deaths - n[i-1].raw.cumulative.deaths; day.per100k.new.cases = per100k(day.raw.new.cases, population) day.per100k.new.active = per100k(day.raw.new.active, population) day.per100k.new.recovered = per100k(day.raw.new.recovered, population) day.per100k.new.deaths = per100k(day.raw.new.deaths, population) }) } function calculateAverage(index, nodes, target, numDays) { let avg = 0; let daysTallied = 0; for (let i = index; i >= Math.max(0, index-(numDays-1)); i--) { avg += nodes[i][target[0]][target[1]][target[2]]; daysTallied += 1; } return Math.round(10*avg/daysTallied)/10; } function addAverage(data, numDays, population) { data.tracking.forEach((day, i, n) => { day.raw.average.cases = calculateAverage(i, n, ['raw','new','cases'], numDays); day.raw.average.active = calculateAverage(i, n, ['raw','new','active'], numDays); day.raw.average.recovered = calculateAverage(i, n, ['raw','new','recovered'], numDays); day.raw.average.deaths = calculateAverage(i, n, ['raw','new','deaths'], numDays); day.per100k.average.cases = per100k(day.raw.average.cases, population) day.per100k.average.active = per100k(day.raw.average.active, population) day.per100k.average.recovered = per100k(day.raw.average.recovered, population) day.per100k.average.deaths = per100k(day.raw.average.deaths, population) }) } addTracking(mapData, 'Can') mapData.features.forEach(province => { addTracking(province, provArray.find(obj => obj.long === province.properties.PRENAME).short) }) addCumulative(mapData, mapData.properties.population) mapData.features.forEach(province => { addCumulative(province, province.properties.population) }) addNew(mapData, mapData.properties.population) mapData.features.forEach(province => { addNew(province, province.properties.population) }) addAverage(mapData, 7, mapData.properties.population) mapData.features.forEach(province => { addAverage(province, 7, province.properties.population) }) let repatCurrent = Number(newCovidData.filter(x => x.Date !== '')[newCovidData.filter(x => x.Date !== '').length - 1].Repatriated); let repatYesterday = Number(newCovidData.filter(x => x.Date !== '')[newCovidData.filter(x => x.Date !== '').length - 2].Repatriated) mapData.repatriated = repatCurrent === 0 ? repatYesterday : repatCurrent; } window.onload = async function() { [mapData, autoDataCurrent, autoDataHistorical] = await getData(); chartSettings.data = mapData; let latestDate = mapData.tracking[mapData.tracking.length-1].date pasteMap() fillOutMap('#covid-canada-map-container', mapData) //createMap('#covid-canada-map-container', mapData) createNewCurveChart('#covid-canada-date-chart', mapData, ['raw', 'average', ['cases']], latestDate) createSquareChart(mapData.tracking[mapData.tracking.length-1]) updateTopTable(mapData) let scraperData = formatProvinceData(autoDataCurrent) chartSettings.date.animated = false; let provArray = ['British Columbia', 'Alberta', 'Saskatchewan', 'Manitoba', 'Ontario', 'Quebec', 'New Brunswick', 'Nova Scotia', 'Prince Edward Island', 'Newfoundland and Labrador', 'Yukon', 'Northwest Territories', 'Nunavut'] // Intersection Observer to load provinces individually const triggers = document.querySelectorAll('.covid-province-container'); observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.intersectionRatio > 0) { let provinceID = entry.target.querySelector('.covid-head').id; let province = provArray.find(prov => getID(prov) === provinceID) console.log('loading provincial data...', province); loadProvince(province) observer.unobserve(entry.target); } }); }); triggers.forEach(trigger => { observer.observe(trigger); }); function loadProvince(province) { let targetDiv = Array.from(document.querySelectorAll('.covid-head')).find(div => div.id === getID(province)) let parentDiv = targetDiv.parentElement.querySelector('.tracking-chart') let data = mapData.features.find(prov => prov.properties.PRENAME === province) createNewCurveChart(parentDiv, data, ['raw', 'average', ['cases']], latestDate) console.log(`Loaded ${province} chart`) setProvinceTable(province, scraperData) } } let chartSettings = { data: null, date: { cumulative: true, animated: true } } function debounce(func){ var timer; return function(event){ if(timer) clearTimeout(timer); timer = setTimeout(func,100,event); }; } function getID(long) { let lower = long.toLowerCase(); let split = lower.split(' '); let hyphen = split.join('-'); return hyphen; }