Published
Edited
Nov 12, 2020
1 fork
10 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
selectedDataSource = dataSources[selectedDataSourceIndex]
Insert cell
// fetch the data from the edelweiss REST api (latest will make sure we get the newest dataset, updated daily)
raw_data = {
const query = countryFilter
const encodedQuery = JSON.stringify({condition: query})
let url = new URL(selectedDataSource.url)
url.searchParams.append('query', encodedQuery);
const data = fetch(url)
.then(response => {
if (!response.ok) throw new Error(response.status);
return response.json();})
return data
}
Insert cell
countryFilter = ({
exactSearch: [ { column: ["location"]}, country ]
})
Insert cell
data = raw_data.results.map(selectedDataSource.rowProcessingFunction)
Insert cell
metadata = fetch(selectedDataSource.metadataUrl)
.then(response => {
if (!response.ok) throw new Error(response.status);
return response.json();})
Insert cell
Insert cell
Insert cell
Insert cell
calculateAndMergeTrueProjectedCases = {
return function(rows) {
// filter out days before the graphStartDAte
const filteredRows = _.filter(rows, row => moment(row[fields.date]).isBetween(graphStartDate, artificialTimeSeriesEnd, null, "[]"))
console.log("filtered", filteredRows)
const filteredStartDate = moment.max(moment(_.first(rows)[fields.date]), graphStartDate)
const endDate = moment.max([moment(_.last(rows)[fields.date]), artificialTimeSeriesEnd])
const startDate = moment.min([filteredStartDate, moment(endDate).subtract(averageDaysToDeathAfterInfection, 'days')])
const numDays = endDate.diff(startDate, "days")
const days = _.map(_.range(0, numDays + 1), diff => moment(startDate).add(diff, "days"))
console.log("days", days)
const dateIndexedFilteredRows = _.fromPairs(_.map(filteredRows, row => [(moment(row[fields.date]).format("YYYY-MM-DD")), row]))
let projectedDays = []
let lastDaysCases = undefined
for (const day of days) {
const currentDateData = dateIndexedFilteredRows[day.format("YYYY-MM-DD")]
const xDaysInFutureData = dateIndexedFilteredRows[moment(day).add(averageDaysToDeathAfterInfection, "days").format("YYYY-MM-DD")]
if (xDaysInFutureData) {
const projected = xDaysInFutureData[fields["total-deaths"]] / (infectedFatalityRate/100)
lastDaysCases = projected
if (currentDateData) {
projectedDays.push(assemblyFinalDataRow(currentDateData, projected))
}
else {
projectedDays.push(assemblyFinalDataRow({[fields.date]: day.format("YYYY-MM-DD")}, projected))
}
}
else {
if (lastDaysCases === undefined) {
console.log("lastdayscases was not defined!")
}
else {
// decide if we are before or after the lockdown and choose the correct doubling rate
let doublingTime = doublingTimeBeforeLockdown
let projected = lastDaysCases * 2**(1/doublingTime)
lastDaysCases = projected
if (currentDateData) {
projectedDays.push(assemblyFinalDataRow(currentDateData, projected))
}
else {
projectedDays.push(assemblyFinalDataRow({[fields.date]: day.format("YYYY-MM-DD")}, projected))
}
}
}
}
console.log("projected", projectedDays)
return projectedDays
}
}
Insert cell
assemblyFinalDataRow = function(data, projected) {
const formattedCases = _.isNil(data[fields.cases]) ? "no data" : data[fields.cases].toLocaleString()
return {...data, [fields.projected]: projected, [fields.projectedFormatted]: (Math.round(projected, 0)).toLocaleString(), [fields.casesFormatted]: formattedCases}
}
Insert cell
Insert cell
Insert cell
Insert cell
artificialTimeSeriesEnd = moment(latestDate).subtract((50-artificialTimeSeriesEndSlider), "days")
Insert cell
Insert cell
fields = ({...metadata.columnNames,...projectedFields})
Insert cell
countries = metadata.regions
Insert cell
Insert cell
// Pick the country selected in the dropdown and calculate the projection for it
targetCountryData = calculateAndMergeTrueProjectedCases(data_by_countries[country])
Insert cell
latestDate = moment(_.chain(data_by_countries[country]).map(datum => datum[fields.date] ).max().value())
Insert cell
countryDailyDeathsGrowthRateAverageLastThreeDays =
{ if (data_by_countries[country].length > 3) {
const len = data_by_countries[country].length
const offset = _.slice(data_by_countries[country], len-4, len-1)
return _.chain(data_by_countries[country]).takeRight(3).zip(offset).map(pair => pair[0][fields["total-deaths"]]/pair[1][fields["total-deaths"]]*100 - 100).sum().value()/3
}
else
return 15.0
}
Insert cell
confirmedCasesGrowthRate = { const ratio = targetCountryData[targetCountryData.length-1][fields["total-cases"]] / targetCountryData[targetCountryData.length-averageDaysToDeathAfterInfection-1][fields["total-cases"]]
return (Math.pow(ratio, 1/averageDaysToDeathAfterInfection)-1.0)*100
}
Insert cell
md`### Imports`
Insert cell
import {slider, select, checkbox} from "@jashkenas/inputs"
Insert cell
import { vl } from "@vega/vega-lite-api"
Insert cell
moment = require("moment");
Insert cell
import { inputsGroup } from "@bumbeishvili/input-groups"
Insert cell
_ = require("lodash");

Insert cell
vegalite = require("@observablehq/vega-lite")
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more