├── README.md ├── app.R ├── data ├── aichach.kml ├── coords.dbf ├── coords.prj ├── coords.shp ├── coords.shx ├── february.csv ├── february_europe.csv ├── germany.csv ├── gspc_backup.csv ├── infected.dbf ├── infected.prj ├── infected.shp ├── infected.shx ├── january.csv ├── locked.csv ├── ne_50m_admin_0_countries.cpg ├── ne_50m_admin_0_countries.dbf ├── ne_50m_admin_0_countries.prj ├── ne_50m_admin_0_countries.shp ├── ne_50m_admin_0_countries.shx ├── pandemic.csv └── top10_february.csv ├── gomap.js ├── html_files ├── chapter1.html ├── chapter2.html ├── chapter3.html ├── chapter4.html ├── chapter5.html ├── landing.html ├── leaders_1.html ├── leaders_2.html ├── leaders_3.html ├── leaders_4.html ├── leaders_5.html ├── leaders_6.html ├── leaders_7.html ├── leaders_8.html ├── lockdown1.html ├── lockdown2.html ├── lockdown3.html ├── selector.html ├── text2_1.html ├── text2_2.html ├── text_1.html ├── text_10.html ├── text_11.html ├── text_12.html ├── text_13.html ├── text_1_1.html ├── text_2.html ├── text_3.html ├── text_4.html ├── text_5.html ├── text_6.html ├── text_7.html ├── text_8.html ├── text_8_1.html ├── text_9.html ├── today.html ├── today_1.html ├── today_2.html └── today_3.html ├── second_wave.R ├── server ├── create_story.R ├── data_wrangling │ ├── forecasting.R │ ├── group_data.R │ ├── highcharter_data.R │ ├── html_files.R │ ├── increase_data.R │ ├── jhu.R │ ├── lockdown_data.R │ ├── s_n_p.R │ └── top_15.R ├── event_observer.R ├── highcharter_outputs.R ├── leaflet_maps.R ├── load_data.R ├── modal.R ├── observer.R ├── plotly_outputs.R ├── reactive_events.R ├── server.r ├── text_outputs.R └── ui_outputs.R ├── styles.css ├── styles.scss └── ui └── ui.R /README.md: -------------------------------------------------------------------------------- 1 | [![eRum2020::CovidR](https://badgen.net/https/runkit.io/erum2020-covidr/badge/branches/master/hahn-covid-shinyline?cache=300)](https://milano-r.github.io/erum2020-covidr-contest/hahn-covid-shinyline.html) 2 | 3 | # Covid Shinyline: The 2019-20 Coronavirus Pandemic visualized with R and Shiny 4 | Covid Shinyline uses the data from Johns Hopkins University to visualize the outbreak of the novel coronavirus. The data is available from [this repository](https://github.com/CSSEGISandData/COVID-19/tree/master/csse_covid_19_data). 5 | 6 | You can scroll through the story so far, look at the countries currently leading in various statistics and view the figures on a world map. 7 | 8 | The app uses the [mapbox API](https://docs.mapbox.com/api/). If you have an API key, save it in a **key.env** file that looks like this: 9 | ```{bash} 10 | MAPBOX_KEY=YOUR_SECRET_API_KEY 11 | ``` 12 | If you do not have such a key, the app will display a dark basemap from carto. 13 | # Run it on your machine 14 | You can run Covid Shinyline on your own machine using the following code: 15 | ```R 16 | packages = c( 17 | "data.table", "dotenv", "dplyr", "english", "forecast", "fresh", "highcharter", "htmltools", "leaflet", 18 | "leaflet.extras", "plotly", "plyr", "quantmod", "readr", "sass", "sf", "shiny", "shinyanimate", "shinybusy", 19 | "shinyjs", "shinyWidgets", "stringr", "waiter" 20 | ) 21 | install.packages(packages, repos = "https://cran.rstudio.com/") 22 | devtools::install_github("rstudio/leaflet.mapboxgl") 23 | library(shiny) 24 | runGitHub("covid_shiny", "nicoFhahn") 25 | ``` 26 | # Screenshots 27 | ![alt text](https://i.imgur.com/yP3b7eA.png "Logo Title Text 1") 28 | ![alt text](https://i.imgur.com/BLrMttV.png "Logo Title Text 1") 29 | 30 | ### Acknowledgments 31 | The folks over at RStudio with the [SuperZIP demo](https://github.com/rstudio/shiny-examples/tree/master/063-superzip-example) which heavily inspired the layout of the leaflet map. 32 | 33 | ### Questions/issues/contact 34 | nico@f-hahn.de, or open a GitHub issue 35 | -------------------------------------------------------------------------------- /app.R: -------------------------------------------------------------------------------- 1 | library(plyr) 2 | library(data.table) 3 | library(dotenv) 4 | library(dplyr) 5 | library(english) 6 | library(forecast) 7 | library(fresh) 8 | library(highcharter) 9 | library(htmltools) 10 | library(leaflet) 11 | library(leaflet.extras) 12 | library(leaflet.mapboxgl) 13 | library(plotly) 14 | library(quantmod) 15 | library(readr) 16 | library(sass) 17 | library(sf) 18 | library(shiny) 19 | library(shinyanimate) 20 | library(shinybusy) 21 | library(shinyjs) 22 | library(shinyWidgets) 23 | library(stringr) 24 | library(waiter) 25 | # load the data 26 | options(scipen = 15) 27 | # load the api key for mapbox and the seed 28 | try(load_dot_env("key.env"), silent = TRUE) 29 | key <- Sys.getenv("MAPBOX_KEY") 30 | options(mapbox.accessToken = key) 31 | css <- sass(sass_file("styles.scss")) 32 | # load the interface 33 | # source(file.path("server", "load_data.R"), local = TRUE) 34 | source(file.path("server", "create_story.R"), local = TRUE) 35 | ui <- source(file.path("ui", "ui.R"), local = TRUE)$value 36 | # load the server 37 | server <- function(input, output, session) { 38 | source(file.path("server", "leaflet_maps.R"), local = TRUE)$value 39 | source(file.path("server", "event_observer.R"), local = TRUE)$value 40 | source(file.path("server", "reactive_events.R"), local = TRUE)$value 41 | source(file.path("server", "text_outputs.R"), local = TRUE)$value 42 | source(file.path("server", "ui_outputs.R"), local = TRUE)$value 43 | source(file.path("server", "plotly_outputs.R"), local = TRUE)$value 44 | source(file.path("server", "highcharter_outputs.R"), local = TRUE)$value 45 | source(file.path("server", "observer.R"), local = TRUE)$value 46 | source(file.path("server", "modal.R"), local = TRUE)$value 47 | waiter_hide() 48 | } 49 | shinyApp(ui, server) 50 | -------------------------------------------------------------------------------- /data/coords.dbf: -------------------------------------------------------------------------------- 1 | xA WFIDN 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -------------------------------------------------------------------------------- /data/coords.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /data/coords.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoFhahn/covid_shiny/e38eacd23c892d3f967f39c7b5394d7e30744379/data/coords.shp -------------------------------------------------------------------------------- /data/coords.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoFhahn/covid_shiny/e38eacd23c892d3f967f39c7b5394d7e30744379/data/coords.shx -------------------------------------------------------------------------------- /data/february.csv: -------------------------------------------------------------------------------- 1 | Province/State,Country/Region,confirmed,date,deaths,geometry 2 | Iran,Iran,0,2020-02-01,0,"c(53, 32)" 3 | Italy,Italy,2,2020-02-01,0,"c(12, 43)" 4 | "Korea, South","Korea, South",12,2020-02-01,0,"c(128, 36)" 5 | Iran,Iran,0,2020-02-02,0,"c(53, 32)" 6 | Italy,Italy,2,2020-02-02,0,"c(12, 43)" 7 | "Korea, South","Korea, South",15,2020-02-02,0,"c(128, 36)" 8 | Iran,Iran,0,2020-02-03,0,"c(53, 32)" 9 | Italy,Italy,2,2020-02-03,0,"c(12, 43)" 10 | "Korea, South","Korea, South",15,2020-02-03,0,"c(128, 36)" 11 | Iran,Iran,0,2020-02-04,0,"c(53, 32)" 12 | Italy,Italy,2,2020-02-04,0,"c(12, 43)" 13 | "Korea, South","Korea, South",16,2020-02-04,0,"c(128, 36)" 14 | Iran,Iran,0,2020-02-05,0,"c(53, 32)" 15 | Italy,Italy,2,2020-02-05,0,"c(12, 43)" 16 | "Korea, South","Korea, South",19,2020-02-05,0,"c(128, 36)" 17 | Iran,Iran,0,2020-02-06,0,"c(53, 32)" 18 | Italy,Italy,2,2020-02-06,0,"c(12, 43)" 19 | "Korea, South","Korea, South",23,2020-02-06,0,"c(128, 36)" 20 | Iran,Iran,0,2020-02-07,0,"c(53, 32)" 21 | Italy,Italy,3,2020-02-07,0,"c(12, 43)" 22 | "Korea, South","Korea, South",24,2020-02-07,0,"c(128, 36)" 23 | Iran,Iran,0,2020-02-08,0,"c(53, 32)" 24 | Italy,Italy,3,2020-02-08,0,"c(12, 43)" 25 | "Korea, South","Korea, South",24,2020-02-08,0,"c(128, 36)" 26 | Iran,Iran,0,2020-02-09,0,"c(53, 32)" 27 | Italy,Italy,3,2020-02-09,0,"c(12, 43)" 28 | "Korea, South","Korea, South",25,2020-02-09,0,"c(128, 36)" 29 | Iran,Iran,0,2020-02-10,0,"c(53, 32)" 30 | Italy,Italy,3,2020-02-10,0,"c(12, 43)" 31 | "Korea, South","Korea, South",27,2020-02-10,0,"c(128, 36)" 32 | Iran,Iran,0,2020-02-11,0,"c(53, 32)" 33 | Italy,Italy,3,2020-02-11,0,"c(12, 43)" 34 | "Korea, South","Korea, South",28,2020-02-11,0,"c(128, 36)" 35 | Iran,Iran,0,2020-02-12,0,"c(53, 32)" 36 | Italy,Italy,3,2020-02-12,0,"c(12, 43)" 37 | "Korea, South","Korea, South",28,2020-02-12,0,"c(128, 36)" 38 | Iran,Iran,0,2020-02-13,0,"c(53, 32)" 39 | Italy,Italy,3,2020-02-13,0,"c(12, 43)" 40 | "Korea, South","Korea, South",28,2020-02-13,0,"c(128, 36)" 41 | Iran,Iran,0,2020-02-14,0,"c(53, 32)" 42 | Italy,Italy,3,2020-02-14,0,"c(12, 43)" 43 | "Korea, South","Korea, South",28,2020-02-14,0,"c(128, 36)" 44 | Iran,Iran,0,2020-02-15,0,"c(53, 32)" 45 | Italy,Italy,3,2020-02-15,0,"c(12, 43)" 46 | "Korea, South","Korea, South",28,2020-02-15,0,"c(128, 36)" 47 | Iran,Iran,0,2020-02-16,0,"c(53, 32)" 48 | Italy,Italy,3,2020-02-16,0,"c(12, 43)" 49 | "Korea, South","Korea, South",29,2020-02-16,0,"c(128, 36)" 50 | Iran,Iran,0,2020-02-17,0,"c(53, 32)" 51 | Italy,Italy,3,2020-02-17,0,"c(12, 43)" 52 | "Korea, South","Korea, South",30,2020-02-17,0,"c(128, 36)" 53 | Iran,Iran,0,2020-02-18,0,"c(53, 32)" 54 | Italy,Italy,3,2020-02-18,0,"c(12, 43)" 55 | "Korea, South","Korea, South",31,2020-02-18,0,"c(128, 36)" 56 | Iran,Iran,2,2020-02-19,2,"c(53, 32)" 57 | Italy,Italy,3,2020-02-19,0,"c(12, 43)" 58 | "Korea, South","Korea, South",31,2020-02-19,0,"c(128, 36)" 59 | Iran,Iran,5,2020-02-20,2,"c(53, 32)" 60 | Italy,Italy,3,2020-02-20,0,"c(12, 43)" 61 | "Korea, South","Korea, South",104,2020-02-20,1,"c(128, 36)" 62 | Iran,Iran,18,2020-02-21,4,"c(53, 32)" 63 | Italy,Italy,20,2020-02-21,1,"c(12, 43)" 64 | "Korea, South","Korea, South",204,2020-02-21,2,"c(128, 36)" 65 | Iran,Iran,28,2020-02-22,5,"c(53, 32)" 66 | Italy,Italy,62,2020-02-22,2,"c(12, 43)" 67 | "Korea, South","Korea, South",433,2020-02-22,2,"c(128, 36)" 68 | Iran,Iran,43,2020-02-23,8,"c(53, 32)" 69 | Italy,Italy,155,2020-02-23,3,"c(12, 43)" 70 | "Korea, South","Korea, South",602,2020-02-23,6,"c(128, 36)" 71 | Iran,Iran,61,2020-02-24,12,"c(53, 32)" 72 | Italy,Italy,229,2020-02-24,7,"c(12, 43)" 73 | "Korea, South","Korea, South",833,2020-02-24,8,"c(128, 36)" 74 | Iran,Iran,95,2020-02-25,16,"c(53, 32)" 75 | Italy,Italy,322,2020-02-25,10,"c(12, 43)" 76 | "Korea, South","Korea, South",977,2020-02-25,10,"c(128, 36)" 77 | Iran,Iran,139,2020-02-26,19,"c(53, 32)" 78 | Italy,Italy,453,2020-02-26,12,"c(12, 43)" 79 | "Korea, South","Korea, South",1261,2020-02-26,12,"c(128, 36)" 80 | Iran,Iran,245,2020-02-27,26,"c(53, 32)" 81 | Italy,Italy,655,2020-02-27,17,"c(12, 43)" 82 | "Korea, South","Korea, South",1766,2020-02-27,13,"c(128, 36)" 83 | Iran,Iran,388,2020-02-28,34,"c(53, 32)" 84 | Italy,Italy,888,2020-02-28,21,"c(12, 43)" 85 | "Korea, South","Korea, South",2337,2020-02-28,13,"c(128, 36)" 86 | Iran,Iran,593,2020-02-29,43,"c(53, 32)" 87 | Italy,Italy,1128,2020-02-29,29,"c(12, 43)" 88 | "Korea, South","Korea, South",3150,2020-02-29,16,"c(128, 36)" 89 | -------------------------------------------------------------------------------- /data/february_europe.csv: -------------------------------------------------------------------------------- 1 | Country.Region,confirmed,date,deaths 2 | Italy,1128,2020-02-29,29 3 | France,100,2020-02-29,2 4 | Germany,79,2020-02-29,0 5 | Spain,45,2020-02-29,0 6 | United Kingdom,23,2020-02-29,0 7 | Switzerland,18,2020-02-29,0 8 | Norway,15,2020-02-29,0 9 | Sweden,12,2020-02-29,0 10 | Austria,9,2020-02-29,0 11 | Croatia,6,2020-02-29,0 12 | Netherlands,6,2020-02-29,0 13 | Greece,4,2020-02-29,0 14 | Denmark,3,2020-02-29,0 15 | Finland,3,2020-02-29,0 16 | Romania,3,2020-02-29,0 17 | Belarus,1,2020-02-29,0 18 | Belgium,1,2020-02-29,0 19 | Estonia,1,2020-02-29,0 20 | Iceland,1,2020-02-29,0 21 | Ireland,1,2020-02-29,0 22 | Lithuania,1,2020-02-29,0 23 | Luxembourg,1,2020-02-29,0 24 | North Macedonia,1,2020-02-29,0 25 | San Marino,1,2020-02-29,0 26 | -------------------------------------------------------------------------------- /data/germany.csv: -------------------------------------------------------------------------------- 1 | date,confirmed,deaths 2 | 2020-01-21,0,0 3 | 2020-01-22,0,0 4 | 2020-01-23,0,0 5 | 2020-01-24,0,0 6 | 2020-01-25,0,0 7 | 2020-01-26,0,0 8 | 2020-01-27,1,0 9 | 2020-01-28,4,0 10 | 2020-01-29,4,0 11 | 2020-01-30,4,0 12 | 2020-01-31,5,0 13 | 2020-02-01,8,0 14 | 2020-02-02,10,0 15 | 2020-02-03,12,0 16 | 2020-02-04,12,0 17 | 2020-02-05,12,0 18 | 2020-02-06,12,0 19 | 2020-02-07,13,0 20 | 2020-02-08,13,0 21 | 2020-02-09,14,0 22 | 2020-02-10,14,0 23 | 2020-02-11,16,0 24 | 2020-02-12,16,0 25 | 2020-02-13,16,0 26 | 2020-02-14,16,0 27 | 2020-02-15,16,0 28 | 2020-02-16,16,0 29 | 2020-02-17,16,0 30 | 2020-02-18,16,0 31 | 2020-02-19,16,0 32 | 2020-02-20,16,0 33 | 2020-02-21,16,0 34 | 2020-02-22,16,0 35 | 2020-02-23,16,0 36 | 2020-02-24,16,0 37 | 2020-02-25,17,0 38 | 2020-02-26,27,0 39 | 2020-02-27,46,0 40 | 2020-02-28,48,0 41 | 2020-02-29,79,0 42 | 2020-03-01,130,0 43 | 2020-03-02,159,0 44 | 2020-03-03,196,0 45 | 2020-03-04,262,0 46 | 2020-03-05,482,0 47 | 2020-03-06,670,0 48 | 2020-03-07,799,0 49 | 2020-03-08,1040,0 50 | 2020-03-09,1176,2 51 | 2020-03-10,1457,2 52 | 2020-03-11,1908,3 53 | 2020-03-12,2078,3 54 | 2020-03-13,3675,7 55 | 2020-03-14,4585,9 56 | 2020-03-15,5795,11 57 | 2020-03-16,7272,17 58 | 2020-03-17,9257,24 59 | 2020-03-18,12327,28 60 | 2020-03-19,15320,44 61 | 2020-03-20,19848,67 62 | 2020-03-21,22213,84 63 | 2020-03-22,24873,94 64 | 2020-03-23,29056,123 65 | 2020-03-24,32986,157 66 | 2020-03-25,37323,206 67 | 2020-03-26,43938,267 68 | 2020-03-27,50871,342 69 | 2020-03-28,57695,433 70 | 2020-03-29,62095,533 71 | 2020-03-30,66885,645 72 | 2020-03-31,71808,775 73 | 2020-04-01,77872,920 74 | 2020-04-02,84794,1107 75 | 2020-04-03,91159,1275 76 | 2020-04-04,96092,1444 77 | 2020-04-05,100123,1584 78 | 2020-04-06,103374,1810 79 | 2020-04-07,107663,2016 80 | 2020-04-08,113296,2349 81 | 2020-04-09,118181,2607 82 | 2020-04-10,122171,2767 83 | 2020-04-11,124908,2736 84 | 2020-04-12,127854,3022 85 | 2020-04-13,130072,3194 86 | 2020-04-14,131359,3294 87 | 2020-04-15,134753,3804 88 | 2020-04-16,137698,4052 89 | 2020-04-17,141397,4352 90 | 2020-04-18,143342,4459 91 | 2020-04-19,145184,4586 92 | 2020-04-20,147065,4862 93 | -------------------------------------------------------------------------------- /data/infected.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoFhahn/covid_shiny/e38eacd23c892d3f967f39c7b5394d7e30744379/data/infected.dbf -------------------------------------------------------------------------------- /data/infected.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /data/infected.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoFhahn/covid_shiny/e38eacd23c892d3f967f39c7b5394d7e30744379/data/infected.shp -------------------------------------------------------------------------------- /data/infected.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoFhahn/covid_shiny/e38eacd23c892d3f967f39c7b5394d7e30744379/data/infected.shx -------------------------------------------------------------------------------- /data/january.csv: -------------------------------------------------------------------------------- 1 | Country/Region,date,confirmed,deaths 2 | China,2020-01-21,548,17 3 | China,2020-01-22,643,18 4 | China,2020-01-23,920,26 5 | China,2020-01-24,1406,42 6 | China,2020-01-25,2075,56 7 | China,2020-01-26,2877,82 8 | China,2020-01-27,5509,131 9 | China,2020-01-28,6087,133 10 | China,2020-01-29,8141,171 11 | China,2020-01-30,9802,213 12 | China,2020-01-31,11891,259 13 | Outside China,2020-01-21,7,0 14 | Outside China,2020-01-22,11,0 15 | Outside China,2020-01-23,21,0 16 | Outside China,2020-01-24,28,0 17 | Outside China,2020-01-25,43,0 18 | Outside China,2020-01-26,50,0 19 | Outside China,2020-01-27,69,0 20 | Outside China,2020-01-28,79,0 21 | Outside China,2020-01-29,93,0 22 | Outside China,2020-01-30,125,0 23 | Outside China,2020-01-31,147,0 24 | -------------------------------------------------------------------------------- /data/locked.csv: -------------------------------------------------------------------------------- 1 | Country/Region,lockdown,date 2 | Russia,Partial,2020-03-27 3 | South Africa,Yes,2020-03-26 4 | New Zealand,Yes,2020-03-25 5 | Saudi Arabia,parts,2020-03-25 6 | Colombia,Yes,2020-03-24 7 | India,Yes,2020-03-24 8 | United Kingdom,Yes,2020-03-23 9 | Australia,Partial,2020-03-25 10 | China,parts,2020-01-31 11 | Jordan,Yes,2020-03-21 12 | Argentina,Yes,2020-03-21 13 | Israel,Partial,2020-03-19 14 | Belgium,Yes,2020-03-17 15 | Germany,Yes,2020-03-22 16 | Malaysia,Yes,2020-03-16 17 | Czechia,Partial,2020-03-16 18 | France,Yes,2020-03-16 19 | Morocco,Yes,2020-03-20 20 | Kenya,Partial,2020-03-22 21 | Spain,Yes,2020-03-14 22 | Poland,Partial,2020-03-13 23 | Kuwait,Partial,2020-03-13 24 | Ireland,Partial,2020-03-12 25 | Norway,Partial,2020-03-12 26 | El Salvador,Partial,2020-03-11 27 | Denmark,Partial,2020-03-13 28 | Italy,Yes,2020-03-10 29 | Portugal,Yes,2020-03-18 30 | Slovenia,Yes,2020-03-20 31 | Ukraine,Yes,2020-03-17 32 | Egypt,Partial,2020-03-25 33 | Hungary,Yes,2020-03-27 34 | Brazil,parts,2020-03-23 35 | United States of America,parts,2020-03-23 36 | Thailand,Partial,2020-04-03 37 | Singapore, Yes, 2020-04-07 38 | United Arab Emirates, Partial, 2020-03-26 39 | Peru, Partial, 2020-04-03 40 | Panama, Partial, 2020-04-01 -------------------------------------------------------------------------------- /data/ne_50m_admin_0_countries.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /data/ne_50m_admin_0_countries.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoFhahn/covid_shiny/e38eacd23c892d3f967f39c7b5394d7e30744379/data/ne_50m_admin_0_countries.dbf -------------------------------------------------------------------------------- /data/ne_50m_admin_0_countries.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /data/ne_50m_admin_0_countries.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoFhahn/covid_shiny/e38eacd23c892d3f967f39c7b5394d7e30744379/data/ne_50m_admin_0_countries.shp -------------------------------------------------------------------------------- /data/ne_50m_admin_0_countries.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoFhahn/covid_shiny/e38eacd23c892d3f967f39c7b5394d7e30744379/data/ne_50m_admin_0_countries.shx -------------------------------------------------------------------------------- /data/pandemic.csv: -------------------------------------------------------------------------------- 1 | date,confirmed,deaths 2 | 2020-02-13,473,2 3 | 2020-02-14,527,2 4 | 2020-02-15,617,3 5 | 2020-02-16,711,4 6 | 2020-02-17,824,4 7 | 2020-02-18,925,4 8 | 2020-02-19,1020,6 9 | 2020-02-20,1120,9 10 | 2020-02-21,1269,13 11 | 2020-02-22,1571,15 12 | 2020-02-23,1936,24 13 | 2020-02-24,2320,34 14 | 2020-02-25,2652,43 15 | 2020-02-26,3222,53 16 | 2020-02-27,4146,68 17 | 2020-02-28,5184,82 18 | 2020-02-29,6655,104 19 | 2020-03-01,8437,124 20 | 2020-03-02,10170,171 21 | 2020-03-03,12579,213 22 | 2020-03-04,14734,271 23 | 2020-03-05,17349,333 24 | 2020-03-06,21111,416 25 | 2020-03-07,25077,486 26 | 2020-03-08,28998,702 27 | 2020-03-09,32730,865 28 | 2020-03-10,37733,1123 29 | 2020-03-11,44954,1454 30 | -------------------------------------------------------------------------------- /data/top10_february.csv: -------------------------------------------------------------------------------- 1 | date,Country/Region,confirmed,deaths 2 | 2020-02-29,China,79356,2837 3 | 2020-02-29,"Korea, South",3150,16 4 | 2020-02-29,Italy,1128,29 5 | 2020-02-29,Diamond Princess,705,6 6 | 2020-02-29,Iran,593,43 7 | 2020-02-29,Japan,241,5 8 | 2020-02-29,Singapore,102,0 9 | 2020-02-29,France,100,2 10 | 2020-02-29,Germany,79,0 11 | 2020-02-29,US,68,1 12 | -------------------------------------------------------------------------------- /gomap.js: -------------------------------------------------------------------------------- 1 | $(document).on("click", ".go-map", function(e) { 2 | e.preventDefault(); 3 | $el = $(this); 4 | var lat = $el.data("lat"); 5 | var long = $el.data("long"); 6 | var zip = $el.data("zip"); 7 | $($("#nav a")[0]).tab("show"); 8 | Shiny.onInputChange("goto", { 9 | lat: lat, 10 | lng: long, 11 | zip: zip, 12 | nonce: Math.random() 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /html_files/chapter1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | Chapter 1 11 |
12 |
13 | The Beginning 14 |
15 |
16 |
17 |
18 | November 2019 - End of January 2020 19 |
20 |
21 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /html_files/chapter2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | Chapter 2 11 |
12 |
13 | The Spread 14 |
15 |
16 |
17 |
18 | End of January 2020 - Beginning of March 2020 19 |
20 |
21 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /html_files/chapter3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | Chapter 3 11 |
12 |
13 | The Pandemic 14 |
15 |
16 |
17 |
18 | Beginning of March 2020 - Today 19 |
20 |
21 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /html_files/chapter4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | Chapter 4 11 |
12 |
13 | Global Leaders 14 |
15 |
16 |
17 |
18 | Today 19 |
20 |
21 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /html_files/chapter5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | Chapter 5 11 |
12 |
13 | Locking Down 14 |
15 |
16 |
17 |
18 | Today 19 |
20 |
21 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /html_files/landing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | The 2019-21 Coronavirus Pandemic 11 |
12 |
13 | A timeline 14 |
15 |
16 |
17 |
18 | A project by Nico Hahn
19 | With data from the Johns Hopkins University 20 |
21 |
22 |
23 |

Scroll

24 |
25 |
26 |
27 |
28 |
29 | 30 | 33 | 34 | -------------------------------------------------------------------------------- /html_files/leaders_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | After going through the timeline, let's see which countries are leading in various statistics. 10 |
11 |
12 | Starting with the countries with the most infections... 13 |
14 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /html_files/leaders_2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | and the countries with the most deaths. 10 |
11 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /html_files/leaders_3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | However, these figures lose their significance as long as we do not include the population of the countries in our calculations. 10 |
11 |
12 | Let's see which countries have the most infections per 1.000 inhabitants. 13 |
14 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /html_files/leaders_4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | 14 countries that are not among the countries with the most infections are 10 | among the countries with the highest infection rate.
Interestingly, the country with the most infections, the United States, does not appear here. 11 | among the countries with the highest infection rate.
Interestingly, the country with the most infections, the United States, does not appear here. 12 | among the countries with the highest infection rate.
Interestingly, the country with the most infections, the United States, does not appear here. 13 | among the countries with the highest infection rate.
Interestingly, the country with the most infections, the United States, does not appear here. 14 | among the countries with the highest infection rate.
Interestingly, the country with the most infections, the United States, does not appear here. 15 | among the countries with the highest infection rate.
Interestingly, the country with the most infections, the United States, does not appear here. 16 | among the countries with the highest infection rate.
Interestingly, the country with the most infections, the United States, does not appear here. 17 | among the countries with the highest infection rate.
The country with the most infections, the United States, is ninth. 18 | among the countries with the highest infection rate.
The country with the most infections, the United States, is tenth. 19 | among the countries with the highest infection rate.
The country with the most infections, the United States, is twelfth. 20 | among the countries with the highest infection rate.
The country with the most infections, the United States, is twelfth. 21 | among the countries with the highest infection rate.
The country with the most infections, the United States, is twelfth. 22 | among the countries with the highest infection rate.
The country with the most infections, the United States, is twelfth. 23 | among the countries with the highest infection rate.
The country with the most infections, the United States, is twelfth. 24 | among the countries with the highest infection rate.
The country with the most infections, the United States, is twelfth. 25 | among the countries with the highest infection rate.
The country with the most infections, the United States, is twelfth. 26 | among the countries with the highest infection rate.
The country with the most infections, the United States, is thirteenth. 27 | among the countries with the highest infection rate.
The country with the most infections, the United States, is thirteenth. 28 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 29 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 30 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 31 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 32 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 33 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 34 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 35 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 36 | among the countries with the highest infection rate.
The country with the most infections, the United States, is eleventh. 37 |
38 |
39 | And if we take a look at the deaths per 1.000 inhabitants, it looks like this. 40 |
41 | 42 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /html_files/leaders_5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | Once again, 14 countries that are not among the countries with the most deaths are among 10 | the countries with the highest death rate.
Once again, the country with the most deaths, the United States, does not appear here. 11 | the countries with the highest death rate.
Once again, the country with the most deaths, the United States, does not appear here. 12 | the countries with the highest death rate.
Once again, the country with the most deaths, the United States, does not appear here. 13 | the countries with the highest death rate.
Once again, the country with the most deaths, the United States, does not appear here. 14 | the countries with the highest death rate.
Once again, the country with the most deaths, the United States, does not appear here. 15 | the countries with the highest death rate.
Once again, the country with the most deaths, the United States, does not appear here. 16 | the countries with the highest death rate.
Once again, the country with the most deaths, the United States, does not appear here. 17 | the countries with the highest death rate.
The country with the most deaths, the United States, is fourteenth. 18 | the countries with the highest death rate.
The country with the most deaths, the United States, is thirteenth. 19 | the countries with the highest death rate.
The country with the most deaths, the United States, is thirteenth. 20 | the countries with the highest death rate.
The country with the most deaths, the United States, is thirteenth. 21 | the countries with the highest death rate.
The country with the most deaths, the United States, is sixteenth. 22 | the countries with the highest death rate.
The country with the most deaths, the United States, is sixteenth. 23 | the countries with the highest death rate.
The country with the most deaths, the United States, is fifteenth. 24 | the countries with the highest death rate.
The country with the most deaths, the United States, is fifteenth. 25 | the countries with the highest death rate.
The country with the most deaths, the United States, is fifteenth. 26 | the countries with the highest death rate.
The country with the most deaths, the United States, is fourteenth. 27 | the countries with the highest death rate.
The country with the most deaths, the United States, is fourteenth. 28 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 29 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 30 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 31 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 32 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 33 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 34 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 35 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 36 | the countries with the highest death rate.
The country with the most deaths, the United States, is twelfth. 37 |
38 |
39 | Let's take a look at the countries that have seen the highest increase in new infections and deaths in the last two weeks. 40 |
41 | 42 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /html_files/leaders_6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | In Australia, the number of new infections has increased from 250.651 to 462.955, an increase of 85%.
However, these numbers can easily be influenced by outliers. 10 | Countries that didn't have a lot of cases a fortnight ago. 11 | Countries that didn't have a lot of cases a fortnight ago. 12 | Countries that didn't have a lot of cases a fortnight ago. 13 | Let's see what the data looks like when a country must have had at least 740.000 infections two weeks ago. 14 | Let's see what the data looks like when a country must have had at least 740.000 infections two weeks ago. 15 | Let's see what the data looks like when a country must have had at least 740.000 infections two weeks ago. 16 | Let's see what the data looks like when a country must have had at least 740.000 infections two weeks ago. 17 | Let's see what the data looks like when a country must have had at least 740.000 infections two weeks ago. 18 | Let's see what the data looks like when a country must have had at least 740.000 infections two weeks ago. 19 | Let's see what the data looks like when a country must have had at least 740.000 infections two weeks ago. 20 | Let's see what the data looks like when a country must have had at least 500 infections two weeks ago. 21 | Let's see what the data looks like when a country must have had at least 20.000 infections two weeks ago. 22 | Let's see what the data looks like when a country must have had at least 250 infections two weeks ago. 23 | Let's see what the data looks like when a country must have had at least 250 infections two weeks ago. 24 | Let's see what the data looks like when a country must have had at least 80.000 infections two weeks ago. 25 | Let's see what the data looks like when a country must have had at least 80.000 infections two weeks ago. 26 | Let's see what the data looks like when a country must have had at least 250 infections two weeks ago. 27 | Let's see what the data looks like when a country must have had at least 250 infections two weeks ago. 28 | Let's see what the data looks like when a country must have had at least 250 infections two weeks ago. 29 | Let's see what the data looks like when a country must have had at least 90.000 infections two weeks ago. 30 | Let's see what the data looks like when a country must have had at least 250 infections two weeks ago. 31 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 32 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 33 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 34 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 35 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 36 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 37 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 38 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 39 | Let's see what the data looks like when a country must have had at least 30.000 infections two weeks ago. 40 |
41 | 42 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /html_files/leaders_7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | France now has the highest increase in new infections. 10 | The figures rose from
8.681.667 to 10.296.909, an increase of
19%.
The previous leader, Australia, is not even in the top 16. 11 | The figures rose from
8.681.667 to 10.296.909, an increase of
19%.
The previous leader, Australia, is not even in the top 16. 12 | The figures rose from
8.681.667 to 10.296.909, an increase of
19%.
The previous leader, Australia, is not even in the top 16. 13 | The figures rose from
8.681.667 to 10.296.909, an increase of
19%.
The previous leader, Australia, is not even in the top 16. 14 | The figures rose from
8.681.667 to 10.296.909, an increase of
19%.
The previous leader, Australia, is not even in the top 16. 15 | The figures rose from
8.681.667 to 10.296.909, an increase of
19%.
The previous leader, Australia, is not even in the top 16. 16 | The figures rose from
8.681.667 to 10.296.909, an increase of
19%.
The previous leader, Australia, is not even in the top 16. 17 | The figures rose from
5.716 to 9.331, an increase of
63%.
The previous leader, Barbados, is not even in the top 16. 18 | The figures rose from
28.535 to 40.904, an increase of
43%.
The previous leader, Eritrea, is not even in the top 17. 19 | The figures rose from
467.730 to 925.342, an increase of
98%.
The previous leader, Samoa, is not even in the top 15. 20 | The figures rose from
467.730 to 925.342, an increase of
98%.
The previous leader, Samoa, is not even in the top 15. 21 | The figures rose from
66.888 to 133.029, an increase of
99%.
The previous leader, Marshall Islands, is not even in the top 16. 22 | The figures rose from
66.888 to 133.029, an increase of
99%.
The previous leader, Marshall Islands, is not even in the top 16. 23 | The figures rose from
66.888 to 133.029, an increase of
99%.
The previous leader, Marshall Islands, is not even in the top 16. 24 | The figures rose from
280.229 to 593.592, an increase of
112%.
The previous leader, Lithuania, is not even in the top 15. 25 | The figures rose from
9.578 to 22.719, an increase of
137%.
The previous leader, Solomon Islands, is not even in the top 15. 26 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 27 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 28 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 29 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 30 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 31 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 32 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 33 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 34 | The figures rose from
61.318 to 109.374, an increase of
78%.
The previous leader, Jordan, is not even in the top 15. 35 |
36 |
37 | Let's conclude this part by looking at the same thing from a different perspective.
Which countries had the smallest increase in new infections in the last two weeks? 38 |
39 | 40 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /html_files/leaders_8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | Bangladesh only reported 5.037new cases.
An increase of only 0%. 10 |
11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /html_files/lockdown1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | Let's see what types of lockdown are imposed in which countries. 9 |
10 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /html_files/lockdown2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | But do these drastic measures actually help? 10 |
11 |
12 | To answer this question, we need to look at the average daily growth rate before a country has introduced a particular type of lockdown and compare it with the growth rate afterwards. 13 |
14 |
15 | In addition, we will compare these rates with the average daily growth rate when no curfew was imposed on any country. 16 |
17 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /html_files/lockdown3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | According to the data, people being forced to stay at home contributes to slowing the spread of Covid-19. 10 |
11 |
12 | Do your part. 13 |
14 |
15 | Stay home if you can. 16 |
17 |
18 | If you are interested in the spread of the novel coronavirus in a specific country, you can look at the tab "Worldwide cases". 19 |
20 |
21 | Back to the beginning 22 |
23 |
24 | Made by Nico Hahn. 25 |
26 |
27 | With data from the Johns Hopkins University and Natural Earth. 28 |
29 |
30 | Visualizations with Leaflet, Highcharter and Plotly. 31 |
32 |
33 | Written in R. 34 |
35 |
36 | Special thanks go to Leon Beu, who advised me on the design of the site. 37 |
38 | 39 | 42 | 43 | -------------------------------------------------------------------------------- /html_files/selector.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 19 | 24 | 25 | 26 | 33 | 38 | 39 | 40 | 47 | 52 | 53 | 54 | 61 | 66 | 67 | 68 | 75 | 80 | 81 |
13 | 14 | 18 | 20 |
21 | November 2019 - End of January 2020 22 |
23 |
27 | 28 | 32 | 34 |
35 | End of January 2020 - Beginning of March 2020 36 |
37 |
41 | 42 | 46 | 48 |
49 | Beginning of March 2020 - Today 50 |
51 |
55 | 56 | 60 | 62 |
63 | Today 64 |
65 |
69 | 70 | 74 | 76 |
77 | Today 78 |
79 |
82 | 83 | 86 | 87 | -------------------------------------------------------------------------------- /html_files/text2_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | January 30, 2020 9 |
10 |
11 | On Jan. 30, over 8.000 people in China were infected with the virus. 12 |
13 |
14 | The World Health Organization officially declares a "public health emergency of international concern". 15 |
16 | 17 |
18 | Let's see which countries have reported cases up to this point. 19 |
20 | 21 | 24 | 25 | -------------------------------------------------------------------------------- /html_files/text2_2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | January 30, 2020 9 |
10 |
11 | On Jan. 30, over 8.000 people in China were infected with the virus. 12 |
13 |
14 | The World Health Organization officially declares a "public health emergency of international concern". 15 |
16 | 17 |
18 | Let's see which countries have reported cases up to this point. 19 |
20 | 21 | 24 | 25 | -------------------------------------------------------------------------------- /html_files/text_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | Beginning of Spring, 2020 9 |
10 |
11 | The sun is shining, birds are chirping. 12 |
13 |
14 | It's a lovely spring day 15 |
16 |
17 | But there are hardly any people outside, almost all shops are closed and almost no planes are flying. 18 |
19 |
20 | What the hell happened here? 21 |
22 | 23 | 26 | 27 | -------------------------------------------------------------------------------- /html_files/text_10.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | March 23, 2020 9 |
10 |
11 | On Mar. 23, Boris Johnson announced a nationwide lockdown prohibiting gatherings of more than two people and obliging people to stay in their homes except for trips for food or medicine, exercise or to go to work when absolutely necessary. 12 |
13 |
14 | March 24, 2020 15 |
16 |
17 | On Mar. 24, the Indian Prime Minister announced a total lockdown which will take effect at midnight on 25 March. 18 |
19 |
20 | The 2020 Olympic Games in Tokyo are postponed to 2021. 21 |
22 |
23 | March 25, 2020 24 |
25 |
26 | On Mar. 25, the lockdown on the Hubei region was lifted.
Most of the inhabitants were allowed to leave the region again, provided they are healthy. 27 |
28 |
29 | March 26, 2020 30 |
31 |
32 | On Mar. 26, the number of infected people in New York City has risen to over 30.000. 33 |
34 |
35 | The United States of America has overtaken Italy and China in the number of confirmed Covid-19 cases, making it the country with the most infections worldwide. 36 |
37 | 38 | 41 | 42 | -------------------------------------------------------------------------------- /html_files/text_11.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | Now let us take a look into the future and see what the numbers might look like in 30 days.
10 | How many confirmed Covid-19 cases could there be? 11 |
12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /html_files/text_12.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | In 30 days we could have anywhere between 332.237.860 and 347.495.666 confirmed cases. 10 |
11 |
12 | And how many people might have died by Februar 01? 13 |
14 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /html_files/text_13.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | March 27, 2020 9 |
10 |
11 | On Mar. 27, it was announced that British Prime Minister Boris Johnson had tested positive for coronavirus. 12 |
13 |
14 | March 28, 2020 15 |
16 |
17 | On Mar. 28, the USA became the first country in the world to exceed the 100 000 confirmed cases mark. 18 |
19 |
20 | April 3, 2020 21 |
22 |
23 | On Apr. 3, 1 Million confirmed cases were surpassed. 24 |
25 |
26 | April 6, 2020 27 |
28 |
29 | On Apr. 6, UK Prime Minister Boris Johnson has been moved to intensive care in hospital after his coronavirus symptoms worsened. 30 |
31 |
32 | April 10, 2020 33 |
34 |
35 | On Apr. 10, the global death toll has exceeded 100.000. 36 |
37 |
38 | April 14, 2020 39 |
40 |
41 | On Apr. 10, France announced that it would extend the nationwide lockdown until May 11th. 42 |
43 |
44 | April 15, 2020 45 |
46 |
47 | On Apr. 15, 2 Million confirmed cases were surpassed. Only 12 days after surpassing 1 Million confirmed cases. 48 |
49 |
50 | April 24, 2020 51 |
52 |
53 | On Apr. 24, the global death toll has exceeded 200.000. Only 14 days after exceeding 100 000 confirmed deaths. 54 |
55 |
56 | April 27, 2020 57 |
58 |
59 | On Apr. 27, 3 Million confirmed cases were surpassed. Again only 12 days after surpassing 2 Million confirmed cases. 60 |
61 |
62 | April 28, 2020 63 |
64 |
65 | On Apr. 28, the United States of America became the first country with over 1 Million confirmed cases. 66 |
67 |
68 | May 20, 2020 69 |
70 |
71 | On May 20, 5 Million confirmed cases were surpassed. 23 days after surpassing 3 Million confirmed cases. 72 |
73 |
74 | May 24, 2020 75 |
76 |
77 | On May 24, the United States of America became the first country with over 100.000 deaths as a result of Covid-19. 78 |
79 |
80 | June 19, 2020 81 |
82 |
83 | On Jun. 19, Brazil became the second country with over 1 Million confirmed cases. 84 |
85 |
86 | June 28, 2020 87 |
88 |
89 | On Jun. 28, 10 Million confirmed cases were surpassed. 38 days after surpassing 5 Million confirmed cases. 90 |
91 |
92 | June 29, 2020 93 |
94 |
95 | On Jun. 29, the global death toll has exceeded 500.000. 66 days after exceeding 100.000 confirmed deaths. 96 |
97 |
98 | July 16, 2020 99 |
100 |
101 | On Jul. 16, India became the third country with over 1 Million confirmed cases. 102 |
103 |
104 | August 9, 2020 105 |
106 |
107 | On Apr. 9, the United States of America became the first country with over 5 Million confirmed cases. 108 |
109 |
110 | August 11, 2020 111 |
112 |
113 | On Aug. 11, 20 Million confirmed cases were surpassed. 44 days after surpassing 10 Million confirmed cases. 114 |
115 |
116 | September 15, 2020 117 |
118 |
119 | On Sep. 15, India became the second country with over 5 Million confirmed cases. 120 |
121 |
122 | September 18, 2020 123 |
124 |
125 | On Sep. 18, 30 Million confirmed cases were surpassed. 38 days after surpassing 20 Million confirmed cases. 126 |
127 |
128 | September 29, 2020 129 |
130 |
131 | On Sep. 29, the global death toll has exceeded 1 million. 92 days after exceeding 500.000 confirmed deaths. 132 |
133 |
134 | October 7, 2020 135 |
136 |
137 | On Oct. 7, Brazil became the third country with over 5 Million confirmed cases. 138 |
139 | 140 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /html_files/text_1_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | November 17, 2019 9 |
10 |
11 | On Nov. 17, the first case of the novel coronavirus occurred in the Hubei province in China. 12 |
13 |
14 | Not much is known about patient 0 except that he is a 55-year-old man from Wuhan. 15 |
16 |
17 | The city that will soon be known as the epicenter of the coronavirus outbreak. 18 |
19 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /html_files/text_2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | December 1, 2019 9 |
10 |
11 | On Dec. 1, the first known patient began to show symptoms. 12 |
13 |
14 | Others would soon follow. 15 |
16 |
17 | December 31, 2019 18 |
19 |
20 | On Dec. 31, the World Health Organization was contacted by the Chinese government and informed of "cases of pneumonia of unknown etiology (unknown cause) detected in Wuhan". 21 |
22 |
23 | At that time there was no evidence that the virus could be easily spread by humans.
24 | Chinese authorities had identified 266 people who had been infected by the virus by that time. 25 |
26 |
27 | January 11, 2020 28 |
29 |
30 | On Jan. 11, Chinese state media reported the first known death caused by the virus.
31 | The man had several serious medical conditions, including chronic liver disease, and died from heart failure and pneumonia. 32 |
33 |
34 | January 21, 2020 35 |
36 |
37 | On Jan. 21, the W.H.O. began releasing situation reports on a daily basis. 38 |
39 |
40 | Cases were reported in Japan, Thailand, South Korea, Taiwan and the United States. The latter beeing the first case outside Asia. 41 |
42 |
43 | January 23, 2020 44 |
45 |
46 | On Jan. 23, the city of Wuhan was quarantined from the rest of China.
47 | Planes and trains were not allowed to leave the city, and buses, subways and ferries within the city were suspended. 48 |
49 |
50 | At this point, over 570 people had been infected and at least 17 were reported dead. 51 |
52 | 53 | 56 | 57 | -------------------------------------------------------------------------------- /html_files/text_3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | January 31, 2020 9 |
10 |
11 | On Jan. 31, the United States suspended entry for people who had recently been to China with the exception of immediate family members of American citizens or permanent residents. 12 |
13 |
14 | Italy becomes the first state in the European Union to declare a state of emergency. 15 |
16 |
17 | Several other countries have already closed the borders to all visitors arriving from mainland China. 18 |
19 |
20 | If we look at the number of confirmed cases for the month of January, we can see that the number of infections outside China grew at nearly the same rate as the number of infections in the country. 21 |
22 |
23 | In China the number of cases increased by 2.070% compared to 2.000% in the rest of the world. 24 |
25 | 26 | 29 | 90 | 91 | -------------------------------------------------------------------------------- /html_files/text_4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | February 2, 2020 9 |
10 |
11 | On Feb. 2, the Philippines saw the first confirmed death from Covid-19 outside mainland China. 12 |
13 |
14 | The coronavirus death toll has risen to at least 360 people worldwide. 15 |
16 |
17 | February 5, 2020 18 |
19 |
20 | On Feb. 5, the Bill & Melinda Gates Foundation announced that it will spend up to $100 million to improve detection, isolation and treatment efforts for Covid-19. 21 |
22 |
23 | The W.H.O. stated that there had been a substantial increase in new cases over the last 24 hours, on a scale not seen since the beginning of the epidemic. 24 |
25 |
26 | A cruise ship in Japan, the "Diamond Princess", quarantined over 3.600 passengers aboard.
By Mar. 16, 712 out of the 3.711 passengers had tested positive for the virus. 27 |
28 |
29 | The number of reported cases in Wuhan has exceeded the 10.000 mark. 30 |
31 |
32 | February 9, 2020 33 |
34 |
35 | On Feb. 9, just over 40.000 cases were confirmed in mainland China and almost 30 000 cases in Hubei. 36 |
37 |
38 | The number of coronavirus deaths in China has risen to over 800, surpassing the number of victims from the SARS epidemic of 2002-03, which killed 774 people. 39 |
40 |
41 | February 15, 2020 42 |
43 |
44 | On Feb. 15, the first death outside Asia was confirmed, an 80 year old Chinese tourist in France.
At that time there were 12 confirmed cases in France. 45 |
46 |
47 | February 21, 2020 48 |
49 |
50 | On Feb. 21, Italy confirmed 17 new cases, bringing the total to 20. The authorities also reported the first death in Italy. 51 |
52 |
53 | Iran announced 13 new cases, bringing the total up to 18, and South Korea confirmed 100 more cases, bringing the total to 204. 54 |
55 |
56 | February 23, 2020 57 |
58 |
59 | On Feb. 23, Italy confirmed 73 new cases, bringing the total up to 155. 60 |
61 |
62 | Prime minister Giuseppe Conte announces measures which place around 50.000 people in lockdown in an effort to bring the virus under control. 63 |
64 | 65 | 68 | 69 | -------------------------------------------------------------------------------- /html_files/text_5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | February 26, 2020 9 |
10 |
11 | On Feb. 26, the World Health Organization reported that for the first time the number of new cases outside China exceeded the number of new cases in China on February 25. 12 |
13 |
14 | This follows a spike of cases in Italy, Iran and South Korea with cases in China dropping. 15 |
16 |
17 | February 27, 2020 18 |
19 |
20 | On Feb. 27, various US stock market indices, including the NASDAQ-100, the S&P 500 Index and the Dow Jones Industrial Average, recorded the sharpest decline since 2008 due to growing concerns about the coronavirus outbreak. 21 |
22 | 23 | 26 | 27 | -------------------------------------------------------------------------------- /html_files/text_6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | February 28, 2020 9 |
10 |
11 | On Feb. 28, the W.H.O. raised the coronavirus alert to the highest level. 12 |
13 |
14 | This comes after more countries confirmed their first cases, with the outbreak reaching as far as sub-Saharan Africa. 15 |
16 |
17 | Numbers in Europe continue to rise, especially in Italy. 18 |
19 |
20 | Cases in 14 European countries could be traced back to Italy. 21 |
22 |
23 | End of February 2020 24 |
25 |
26 | Let's see how the numbers looked in Europe at the end of February. 27 | 28 |
29 | 30 | 33 | 34 | -------------------------------------------------------------------------------- /html_files/text_7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | However... 9 |
10 |
11 | These figures still pale in comparison to those in the rest of the world. 12 |
13 |
14 | Let's take a look at the 10 countries with the most infections. 15 |
16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /html_files/text_8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | March 2, 2020 9 |
10 |
11 | On Mar. 2, the European Centre for Disease Prevention and Control announced that it has increased the risk level from moderate to high for people in the European Union. 12 |
13 |
14 | March 3, 2020 15 |
16 |
17 | On Mar. 3, the World Health Organization announced that the global death rate of the coronavirus was 3.4%, far higher than that of the common flu. 18 |
19 |
20 | Italy announced that quarantine red zones could be established to contain the spread of the virus. 21 |
22 |
23 | March 8, 2020 24 |
25 |
26 | On Mar. 8,over 16 million people were quarantined in Italy.
Schools, gyms, museums, nightclubs and other venues across the country were forced to close aswell. 27 |
28 |
29 | France banned gatherings of over 1.000 people to stop the spread of the virus. 30 |
31 |
32 | March 9, 2020 33 |
34 |
35 | On Mar. 9, Italy imposed a nationwide quarantine. People may only travel for necessity, work and health reasons. 36 |
37 | 38 | 41 | 42 | -------------------------------------------------------------------------------- /html_files/text_8_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | March 11, 2020 9 |
10 |
11 | On Mar. 11, Donald Trump announced that all travel from Europe (except the UK) to the US will be suspended for 30 days. 12 |
13 |
14 | The National Basketball Association suspended the remainder of its 2020 season after players tested positive for the virus. 15 |
16 |
17 | The Covid-19 outbreak has been declared a pandemic by the World Health Organization after a massive increase in the number of cases outside China in the last 14 days. 18 |
19 | 20 | 21 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /html_files/text_9.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | March 13, 2020 9 |
10 |
11 | On Mar. 13, Donald Trump officially declared a national emergency, allocating about $50 billion for relief efforts. 12 |
13 |
14 | The Premier League suspended their season after Arsenal F.C. manager Mikel Arteta and a Chelsea F.C. player tested positive for the disease. 15 |
16 |
17 | March 17, 2020 18 |
19 |
20 | On Mar. 17, France imposed a nationwide lockdown.
In order to contain the spread of the coronavirus, citizens in France are generally not allowed to leave their homes for the next 14 days. 21 |
22 |
23 | The European Union banned non-essential travel from outside the Union to the 26 countries. 24 |
25 |
26 | The 2020 UEFA European Football Championship has been postponed to the following year. 27 |
28 |
29 | March 21, 2020 30 |
31 |
32 | On Mar. 21, Netflix and YouTube reduced their video quality in the European Union to help prevent Internet gridlock as tens of millions of Europeans work at home or self-isolate. 33 |
34 |
35 | March 22, 2020 36 |
37 |
38 | On Mar. 22, the federal and state governments of Germany agreed on a "comprehensive ban on contact". 39 |
40 | 41 | 44 | 45 | -------------------------------------------------------------------------------- /html_files/today.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | Anywhere between 5.539.833 and
5.706.858. 10 |
11 |
12 | So what now? 13 |
14 |
15 | So far no cure or vaccine has been found. 16 |
17 |
18 | But you can do your part to prevent the coronavirus from spreading. 19 |
20 |
21 | Wash your hands. With soap. Then wash them again. 22 |
23 |
24 | Stay informed. 25 |
26 |
27 | And most importantly 28 |
29 |
30 | Stay home if you can. 31 |
32 | 33 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /html_files/today_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | Today 9 |
10 |
11 | Let's see how the numbers look like today. 12 |
13 |
14 | To date 289.279.435 people have been infected with the virus and 5.440.497 have died. 15 |
16 | 17 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /html_files/today_2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | In the United States, 54.859.966 people are infected with the virus, making it the country with the most 9 | infections worldwide. 10 | infections worldwide. 11 | infections worldwide. 12 | infections worldwide. 13 | infections worldwide. 14 | infections worldwide. 15 | infections worldwide. 16 | infections worldwide. 17 | infections worldwide. 18 | infections worldwide. 19 | infections worldwide. 20 | infections worldwide. 21 | infections worldwide. 22 | infections worldwide. 23 | infections worldwide. 24 | infections worldwide. 25 | infections worldwide. 26 | infections worldwide. 27 | infections worldwide. 28 | infections worldwide. 29 | infections worldwide. 30 | infections worldwide. 31 | infections worldwide. 32 | infections worldwide. 33 | infections worldwide. 34 | infections worldwide. 35 | infections worldwide. 36 |
37 | 38 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /html_files/today_3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 825.816 people have died in the United States as a result of the coronavirus.
9 | This makes the United States the country with the most deaths attributable to the virus. 10 |
11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /second_wave.R: -------------------------------------------------------------------------------- 1 | head(daily_cases2) 2 | daily_cases4 <- daily_cases2 3 | colnames(daily_cases4)[2] <- "SOVEREIGNT" 4 | continents <- st_drop_geometry(countries_old[, c("SOVEREIGNT", "CONTINENT")]) 5 | daily_cases5 <- join(daily_cases4, continents, by = "SOVEREIGNT") 6 | daily_cases5[daily_cases5$SOVEREIGNT == "Eswatini"]$CONTINENT = "Africa" 7 | daily_cases5[daily_cases5$SOVEREIGNT == "North Macedonia"]$CONTINENT = "Europe" 8 | daily_cases5[daily_cases5$SOVEREIGNT == "Bahamas"]$CONTINENT = "North America" 9 | daily_cases5[daily_cases5$SOVEREIGNT == "Burma"]$CONTINENT = "Asia" 10 | daily_cases5[daily_cases5$SOVEREIGNT == "Congo (Brazzaville)"]$CONTINENT = "Africa" 11 | daily_cases5[daily_cases5$SOVEREIGNT == "Congo (Kinshasa)"]$CONTINENT = "Africa" 12 | daily_cases5[daily_cases5$SOVEREIGNT == "Cote d'Ivoire"]$CONTINENT = "Africa" 13 | daily_cases5[daily_cases5$SOVEREIGNT == "Korea, South"]$CONTINENT = "Asia" 14 | daily_cases5[daily_cases5$SOVEREIGNT == "Sao Tome and Principe"]$CONTINENT = "Africa" 15 | daily_cases5[daily_cases5$SOVEREIGNT == "Serbia"]$CONTINENT = "Europe" 16 | daily_cases5[daily_cases5$SOVEREIGNT == "Taiwan*"]$CONTINENT = "Asia" 17 | daily_cases5[daily_cases5$SOVEREIGNT == "Tanzania"]$CONTINENT = "Africa" 18 | daily_cases5[daily_cases5$SOVEREIGNT == "Timor-Leste"]$CONTINENT = "Asia" 19 | daily_cases5[daily_cases5$SOVEREIGNT == "US"]$CONTINENT = "North America" 20 | daily_cases6 <- daily_cases5[ 21 | !( 22 | (daily_cases5$SOVEREIGNT == "Australia" & daily_cases5$CONTINENT %in% c("Asia", "Seven seas (open ocean)")) | 23 | (daily_cases5$SOVEREIGNT == "Denmark" & daily_cases5$CONTINENT %in% c("North America"))| 24 | (daily_cases5$SOVEREIGNT == "Netherlands" & daily_cases5$CONTINENT %in% c("North America"))| 25 | (daily_cases5$SOVEREIGNT == "France" & daily_cases5$CONTINENT %in% c("North America", "Oceania", "Seven seas (open ocean)")) | 26 | (daily_cases5$SOVEREIGNT == "United Kingdom" & daily_cases5$CONTINENT %in% c("North America", "South America", "Oceania", "Seven seas (open ocean)")) 27 | )] 28 | daily_cases6 <- daily_cases6[!duplicated(daily_cases6)] 29 | daily_cases4$SOVEREIGNT == daily_cases6$SOVEREIGNT 30 | daily_cases6 <- daily_cases6[, .( 31 | confirmed = sum(confirmed), 32 | deaths = sum(deaths), 33 | recovered = sum(recovered) 34 | ), keyby = .(date, CONTINENT)] 35 | daily_cases6 <- daily_cases6[complete.cases(daily_cases6)] 36 | daily_cases6$new_confirmed <- 0 37 | daily_cases6$new_confirmed[8:nrow(daily_cases6)] <- daily_cases6$confirmed[-(1:7)] - daily_cases6$confirmed[1:(nrow(daily_cases6) - 7)] 38 | highchart() %>% 39 | hc_xAxis( 40 | categories = unique(daily_cases6$date), 41 | gridLineWidth = 0, 42 | title = list(text = "Date") 43 | ) %>% 44 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 45 | hc_add_series( 46 | name = "Africa", 47 | data = daily_cases6$new_confirmed[daily_cases6$CONTINENT == "Africa"], 48 | color = "#EAC435" 49 | ) %>% 50 | hc_add_series( 51 | name = "Asia", 52 | data = daily_cases6$new_confirmed[daily_cases6$CONTINENT == "Asia"], 53 | color = "#5EFC8D" 54 | ) %>% 55 | hc_add_series( 56 | name = "Europe", 57 | data = daily_cases6$new_confirmed[daily_cases6$CONTINENT == "Europe"], 58 | color = "#347FD5" 59 | ) %>% 60 | hc_add_series( 61 | name = "North America", 62 | data = daily_cases6$new_confirmed[daily_cases6$CONTINENT == "North America"], 63 | color = "#EE6352" 64 | ) %>% 65 | hc_add_series( 66 | name = "Oceania", 67 | data = daily_cases6$new_confirmed[daily_cases6$CONTINENT == "Oceania"], 68 | color = "#E475FA" 69 | ) %>% 70 | hc_add_series( 71 | name = "South America", 72 | data = daily_cases6$new_confirmed[daily_cases6$CONTINENT == "South America"], 73 | color = "#FF334E" 74 | ) %>% 75 | hc_add_theme(hc_theme_monokai()) %>% 76 | hc_title( 77 | text = "Daily Number of confirmed 78 | cases" 79 | ) %>% 80 | hc_legend(align = "left") %>% 81 | hc_chart(backgroundColor = "#161616") %>% 82 | hc_plotOptions( 83 | line = list(marker = list(enabled = FALSE)) 84 | ) 85 | -------------------------------------------------------------------------------- /server/create_story.R: -------------------------------------------------------------------------------- 1 | # this part pretty generates some basic sentences for some parts of the timeline or global leaders 2 | # i won't go into detail 3 | infected_world <- daily_cases[ 4 | daily_cases$date == max(daily_cases$date), ]$confirmed 5 | died <- daily_cases[daily_cases$date == max(daily_cases$date), ]$deaths 6 | file_1[14] <- paste( 7 | "To date", 8 | format(infected_world, big.mark = "."), 9 | "people have been infected with the virus and", 10 | format(died, big.mark = "."), 11 | "have died." 12 | ) 13 | today <- daily_cases2[daily_cases2$date == max(daily_cases2$date), ] 14 | country <- as.character(today[today$confirmed == max(today$confirmed), 2]) 15 | if (country == "US") { 16 | country <- "the United States" 17 | } 18 | file_2[8] <- paste( 19 | "In ", 20 | country, 21 | ", ", 22 | format( 23 | as.numeric(today[today$confirmed == max(today$confirmed), 3]), 24 | big.mark = "." 25 | ), 26 | " people are infected with the virus, making it the country with the most 27 | infections worldwide.", 28 | sep = "" 29 | ) 30 | country <- as.character(today[today$deaths == max(today$deaths), 2]) 31 | if (country == "US") { 32 | country <- "the United States" 33 | } 34 | file_3[8] <- paste( 35 | format( 36 | as.numeric(today[today$deaths == max(today$deaths), 4]), 37 | big.mark = "." 38 | ), 39 | "people have died in", 40 | country, 41 | "as a result of the coronavirus.
" 42 | ) 43 | 44 | file_3[9] <- paste( 45 | "This makes", 46 | country, 47 | "the country with the most deaths attributable to the virus." 48 | ) 49 | country <- as.character(today[today$confirmed == max(today$confirmed), 2]) 50 | if (country == "US") { 51 | country <- "the United States" 52 | } 53 | 54 | new_in_1 <- sum( 55 | !top15_confirmed_per_capita$country %in% top15_confirmed$`Country/Region` 56 | ) 57 | if (new_in_1 > 0) { 58 | text_1 <- paste( 59 | new_in_1, 60 | "countries that are not among the countries with the most infections are 61 | among the countries with the highest infection rate." 62 | ) 63 | } else { 64 | text_1 <- "It's still the same countries." 65 | } 66 | 67 | appears_1 <- today[ 68 | today$confirmed == max(today$confirmed), 69 | ]$`Country/Region` %in% top15_confirmed_per_capita$country 70 | if (!appears_1) { 71 | text_2 <- paste( 72 | "Interestingly, the country with the most infections, ", 73 | country, 74 | ", does not appear here.", 75 | sep = "" 76 | ) 77 | } else { 78 | pos <- match( 79 | as.character(today[today$confirmed == max(today$confirmed), 2]), 80 | top15_confirmed_per_capita$country 81 | ) 82 | text_2 <- paste( 83 | "The country with the most infections, ", 84 | country, 85 | ", is ", 86 | ordinal(pos), 87 | ".", 88 | sep = "" 89 | ) 90 | } 91 | 92 | file_4[9] <- paste(text_1, text_2, sep = "
") 93 | 94 | country <- as.character(today[today$deaths == max(today$deaths), 2]) 95 | if (country == "US") { 96 | country <- "the United States" 97 | } 98 | 99 | new_in_2 <- sum( 100 | !top15_deaths_per_capita$country %in% top15_deaths$`Country/Region` 101 | ) 102 | if (new_in_2 > 0) { 103 | if (new_in_1 == new_in_2) { 104 | start <- "Once again," 105 | } else { 106 | start <- "This time," 107 | } 108 | text_1 <- paste( 109 | start, 110 | new_in_2, 111 | "countries that are not among the countries with the most deaths are among 112 | the countries with the highest death rate." 113 | ) 114 | } else { 115 | if (new_in_1 == 0) { 116 | text_1 <- "Once again, the same countries remain." 117 | } else { 118 | text_1 <- "It's still the same countries." 119 | } 120 | } 121 | 122 | appears_2 <- today[ 123 | today$deaths == max(today$deaths), 124 | ]$`Country/Region` %in% top15_confirmed_per_capita$country 125 | if (!appears_2) { 126 | if (!appears_1) { 127 | text_2 <- paste( 128 | "Once again, the country with the most deaths, ", 129 | country, 130 | ", does not appear here.", 131 | sep = "" 132 | ) 133 | } else { 134 | text_2 <- paste( 135 | "Interestingly, the country with the most deaths, ", 136 | country, 137 | ", does not appear here.", 138 | sep = "" 139 | ) 140 | } 141 | } else { 142 | pos <- match( 143 | as.character(today[today$deaths == max(today$deaths), 2]), 144 | top15_deaths_per_capita$country 145 | ) 146 | text_2 <- paste( 147 | "The country with the most deaths, ", 148 | country, 149 | ", is ", 150 | ordinal(pos), 151 | ".", 152 | sep = "" 153 | ) 154 | } 155 | 156 | file_5[9] <- paste(text_1, text_2, sep = "
") 157 | 158 | country_1 <- df_most[1, ]$country 159 | if (country_1 == "US") { 160 | country_1 <- "the United States" 161 | } 162 | text_1 <- paste( 163 | "In ", 164 | country_1, 165 | ", the number of new infections has increased from ", 166 | format(df_most[1, ]$old, big.mark = "."), " to ", 167 | format(df_most[1, ]$new, big.mark = "."), ", an increase of ", 168 | format(df_most[1, ]$increase, big.mark = "."), 169 | "%.", 170 | sep = "" 171 | ) 172 | text_2 <- "However, these numbers can easily be influenced by outliers. 173 | Countries that didn't have a lot of cases a fortnight ago." 174 | text_3 <- paste( 175 | "Let's see what the data looks like when a country must have had at least", 176 | format(limit, big.mark = "."), 177 | "infections two weeks ago." 178 | ) 179 | 180 | 181 | file_6[9] <- paste(text_1, text_2, sep = "
") 182 | file_6[12] <- text_3 183 | 184 | country_2 <- df_limit_most[1, ]$country 185 | if (country_2 == "US") { 186 | country_2 <- "the United States" 187 | } 188 | 189 | if (country_1 != country_2) { 190 | if (country_2 == "the United States") { 191 | country_2 <- "The United States" 192 | } 193 | 194 | text_1 <- paste( 195 | country_2, 196 | " now has the highest increase in new infections. 197 | The figures rose from
", 198 | format(df_limit_most[1, ]$old, big.mark = "."), " to ", 199 | format(df_limit_most[1, ]$new, big.mark = "."), ", an increase of
", 200 | format(df_limit_most[1, ]$increase, big.mark = "."), 201 | "%.", 202 | sep = "" 203 | ) 204 | if (country_1 %in% df_limit_most$country) { 205 | text_1 <- paste( 206 | text_1, 207 | paste( 208 | country_1, 209 | " is in ", 210 | ordinal( 211 | match( 212 | df_most[1, ]$country, 213 | df_limit_most$country 214 | ) 215 | ), 216 | "place.", 217 | sep = "" 218 | ), 219 | sep = "
" 220 | ) 221 | } else { 222 | text_1 <- paste( 223 | text_1, 224 | paste( 225 | "The previous leader, ", 226 | country_1, 227 | ", is not even in the top ", 228 | nrow(df_limit_most), 229 | ".", 230 | sep = "" 231 | ), 232 | sep = "
" 233 | ) 234 | } 235 | } 236 | 237 | file_7[9] <- text_1 238 | 239 | if (df_limit_few$country[1] == "China") { 240 | text_1 <- paste( 241 | "China.
The country where it all began.
Only ", 242 | format((df_limit_few$new - df_limit_few$old)[1], big.mark = "."), 243 | " new cases.
An increase of only ", df_limit_few$increase[1], "%.", 244 | sep = "" 245 | ) 246 | } else { 247 | text_1 <- paste( 248 | as.character(df_limit_few$country[1]), " only reported ", 249 | format((df_limit_few$new - df_limit_few$old)[1], big.mark = "."), 250 | "new cases.
An increase of only ", df_limit_few$increase[1], "%.", 251 | sep = "" 252 | ) 253 | } 254 | 255 | file_8[9] <- text_1 256 | 257 | text_1 <- paste( 258 | "In 30 days we could have anywhere between", 259 | format(max(forecast_df$lower95_conf, na.rm = TRUE), big.mark = "."), 260 | "and", 261 | format(max(forecast_df$upper95_conf, na.rm = TRUE), big.mark = "."), 262 | "confirmed cases." 263 | ) 264 | 265 | text_2 <- paste( 266 | "And how many people might have died by", 267 | format(Sys.Date() + 30, "%B %d?") 268 | ) 269 | 270 | file_9[9] <- text_1 271 | file_9[12] <- text_2 272 | 273 | text_1 <- paste( 274 | "Anywhere between ", 275 | format(max(forecast_df$lower95_death, na.rm = TRUE), big.mark = "."), 276 | " and
", 277 | format(max(forecast_df$upper95_death, na.rm = TRUE), big.mark = "."), 278 | ".", 279 | sep = "" 280 | ) 281 | 282 | file_10[9] <- text_1 283 | 284 | writeLines(file_1, "html_files/today_1.html") 285 | writeLines(file_2, "html_files/today_2.html") 286 | writeLines(file_3, "html_files/today_3.html") 287 | writeLines(file_4, "html_files/leaders_4.html") 288 | writeLines(file_5, "html_files/leaders_5.html") 289 | writeLines(file_6, "html_files/leaders_6.html") 290 | writeLines(file_7, "html_files/leaders_7.html") 291 | writeLines(file_8, "html_files/leaders_8.html") 292 | writeLines(file_9, "html_files/text_12.html") 293 | writeLines(file_10, "html_files/today.html") 294 | -------------------------------------------------------------------------------- /server/data_wrangling/forecasting.R: -------------------------------------------------------------------------------- 1 | inds <- daily_cases$date 2 | 3 | ## Create a time series object 4 | 5 | myts_conf <- ts(daily_cases$confirmed, # random data 6 | start = c(2020, as.numeric(format(inds[1], "%j"))), 7 | frequency = 365 8 | ) 9 | myts_death <- ts(daily_cases$deaths, # random data 10 | start = c(2020, as.numeric(format(inds[1], "%j"))), 11 | frequency = 365 12 | ) 13 | 14 | # forecast the confirmed cases 15 | forecast_conf <- forecast(auto.arima(myts_conf), h = 30, level = 95) 16 | # round the numbers 17 | forecast_conf$lower <- round(forecast_conf$lower) 18 | forecast_conf$upper <- round(forecast_conf$upper) 19 | forecast_conf$mean <- round(forecast_conf$mean) 20 | # forecast the number of deaths 21 | forecast_death <- forecast(auto.arima(myts_death), h = 30, level = 95) 22 | # round the numbers 23 | forecast_death$lower <- round(forecast_death$lower) 24 | forecast_death$upper <- round(forecast_death$upper) 25 | forecast_death$mean <- round(forecast_death$mean) 26 | # create dates for the forecast 27 | dates_ts <- seq( 28 | from = daily_cases$date[1], 29 | to = max(daily_cases$date) + 30, 30 | by = 1 31 | ) 32 | # create forecast data.frame 33 | forecast_df <- data.frame( 34 | date = dates_ts, 35 | confirmed = c( 36 | daily_cases$confirmed, 37 | rep(NA, length(dates_ts) - length(daily_cases$confirmed)) 38 | ), 39 | fitted_conf = c( 40 | rep(NA, length(dates_ts) - length(forecast_conf$mean)), 41 | forecast_conf$mean 42 | ), 43 | upper95_conf = c( 44 | rep(NA, length(dates_ts) - length(forecast_conf$mean)), 45 | forecast_conf$upper 46 | ), 47 | lower95_conf = c( 48 | rep(NA, length(dates_ts) - length(forecast_conf$mean)), 49 | forecast_conf$lower 50 | ), 51 | deaths = c( 52 | daily_cases$deaths, 53 | rep(NA, length(dates_ts) - length(daily_cases$deaths)) 54 | ), 55 | fitted_death = c( 56 | rep(NA, length(dates_ts) - length(forecast_death$mean)), 57 | forecast_death$mean 58 | ), 59 | upper95_death = c( 60 | rep(NA, length(dates_ts) - length(forecast_death$mean)), 61 | forecast_death$upper 62 | ), 63 | lower95_death = c( 64 | rep(NA, length(dates_ts) - length(forecast_death$mean)), 65 | forecast_death$lower 66 | ) 67 | ) 68 | -------------------------------------------------------------------------------- /server/data_wrangling/group_data.R: -------------------------------------------------------------------------------- 1 | daily_cases <- corona_sf[, .( 2 | confirmed = sum(confirmed), 3 | deaths = sum(deaths), 4 | recovered = sum(recovered) 5 | ), by = date] 6 | 7 | daily_cases2 <- corona_sf[, .( 8 | confirmed = sum(confirmed), 9 | deaths = sum(deaths), 10 | recovered = sum(recovered) 11 | ), keyby = .(date, `Country/Region`)] 12 | daily_cases2 <- daily_cases2[order( 13 | daily_cases2$date, daily_cases2$`Country/Region` 14 | ), ] 15 | a <- corona_sf[!duplicated(corona_sf$`Country/Region`), ] 16 | a <- a[order(a$`Country/Region`), ] 17 | daily_cases2$geometry <- rep(a$geometry, length(unique(daily_cases2$date))) 18 | -------------------------------------------------------------------------------- /server/data_wrangling/highcharter_data.R: -------------------------------------------------------------------------------- 1 | infected <- read_sf("data/infected.shp") 2 | coords_inf <- read_sf("data/coords.shp") 3 | january <- fread("data/january.csv") 4 | february <- fread("data/february.csv") 5 | feb_euro <- fread("data/february_europe.csv") 6 | top10feb <- fread("data/top10_february.csv") 7 | pandemic <- fread("data/pandemic.csv") 8 | germany <- fread("data/germany.csv") -------------------------------------------------------------------------------- /server/data_wrangling/html_files.R: -------------------------------------------------------------------------------- 1 | file_1 <- readLines("html_files/today_1.html") 2 | file_2 <- readLines("html_files/today_2.html") 3 | file_3 <- readLines("html_files/today_3.html") 4 | file_4 <- readLines("html_files/leaders_4.html") 5 | file_5 <- readLines("html_files/leaders_5.html") 6 | file_6 <- readLines("html_files/leaders_6.html") 7 | file_7 <- readLines("html_files/leaders_7.html") 8 | file_8 <- readLines("html_files/leaders_8.html") 9 | file_9 <- readLines("html_files/text_12.html") 10 | file_10 <- readLines("html_files/today.html") -------------------------------------------------------------------------------- /server/data_wrangling/increase_data.R: -------------------------------------------------------------------------------- 1 | # get data for the last 14 days 2 | daily_cases3 <- daily_cases2[ 3 | daily_cases2$date %in% c(max( 4 | daily_cases2$date), 5 | max(daily_cases2$date) - 14 6 | ), 7 | ] 8 | # remove cruise ships 9 | daily_cases3 <- daily_cases3[ 10 | daily_cases3$`Country/Region` != "Diamond Princess", 11 | ] 12 | daily_cases3 <- daily_cases3[, .( 13 | confirmed = sum(confirmed), 14 | deaths = sum(deaths) 15 | ), keyby = .(date, `Country/Region`)] 16 | # split the data by day 17 | splitted <- split(daily_cases3, daily_cases3$date) 18 | # calculate the increases 19 | df <- data.table( 20 | country = splitted[[1]]$`Country/Region`, 21 | increase = (splitted[[2]]$confirmed / splitted[[1]]$confirmed) * 100 - 100, 22 | old = splitted[[1]]$confirmed, 23 | new = splitted[[2]]$confirmed 24 | ) 25 | 26 | df <- df[!is.infinite(df$increase), ] 27 | df$increase <- round(df$increase) 28 | # get countries with the highest increase 29 | df_most <- df[ 30 | df$increase %in% df[order( 31 | df$increase, decreasing = TRUE 32 | ), ][1:15, ]$increase, 33 | ] 34 | df_most <- df_most[order(df_most$increase, decreasing = TRUE), ] 35 | # set some limit 36 | if (any(df_most$old[1:3] < 25)) { 37 | limit <- 250 38 | } else if (any(df_most$old[1:3] < 50)) { 39 | limit <- 500 40 | } else { 41 | limit <- round_any(mean(df_most$old), 10000) 42 | } 43 | df_limit <- df[df$old >= limit, ] 44 | # get countries with the highest increase 45 | df_limit_most <- df_limit[ 46 | df_limit$increase %in% df_limit[order( 47 | df_limit$increase, decreasing = TRUE 48 | ), ][1:15, ]$increase, 49 | ] 50 | df_limit_most <- df_limit_most[ 51 | order(df_limit_most$increase, decreasing = TRUE), ] 52 | # get countries with the lowest increase 53 | df_limit_few <- df_limit[ 54 | df_limit$increase %in% df_limit[order( 55 | df_limit$increase 56 | ), ][1:15, ]$increase, 57 | ] 58 | df_limit_few <- df_limit_few[order(df_limit_few$increase), ] 59 | df_few <- df[df$increase %in% df[order(df$increase), ][1:15, ]$increase, ] 60 | df_few <- df_few[order(df_few$increase), ] 61 | -------------------------------------------------------------------------------- /server/data_wrangling/jhu.R: -------------------------------------------------------------------------------- 1 | # download the data 2 | confirmed <- fread("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv") 3 | confirmed[confirmed$`Country/Region` == "Israel", 5:ncol(confirmed)] <- confirmed[confirmed$`Country/Region` == "Israel", 5:ncol(confirmed)] + confirmed[confirmed$`Country/Region` == "West Bank and Gaza", 5:ncol(confirmed)] 4 | confirmed <- confirmed[confirmed$`Country/Region` != "West Bank and Gaza", ] 5 | # now a whole bunch of preprocessing 6 | # get the cases for the first day 7 | confirmed_long <- confirmed[, 1:5] 8 | # i hate dates and found no easier way to do this even though i know there is 9 | date <- str_split(colnames(confirmed)[5], "/")[[1]] 10 | date_new <- paste(ifelse(nchar(date[1]) == 2, date[1], paste(0, date[1], sep = "")), 11 | ifelse(nchar(date[2]) == 2, date[2], paste(0, date[2], sep = "")), 12 | paste("20", date[3], sep = ""), 13 | sep = "/" 14 | ) 15 | confirmed_long$date <- as.Date(date_new, format = "%m/%d/%Y") 16 | colnames(confirmed_long)[5] <- "confirmed" 17 | # "slowly" transform into a long data set. once again better ways exist but yeah 18 | confirmed_long2 <- lapply(6:ncol(confirmed), function(i, ...) { 19 | confirmed_new <- subset(confirmed, select = c(1:4, i)) 20 | colnames(confirmed_new)[5] <- "confirmed" 21 | date <- str_split(colnames(confirmed)[i], "/")[[1]] 22 | date_new <- paste(ifelse(nchar(date[1]) == 2, date[1], paste(0, date[1], sep = "")), 23 | ifelse(nchar(date[2]) == 2, date[2], paste(0, date[2], sep = "")), 24 | paste("20", date[3], sep = ""), 25 | sep = "/" 26 | ) 27 | confirmed_new$date <- as.Date(date_new, format = "%m/%d/%Y") 28 | confirmed_new 29 | }) 30 | confirmed_long <- rbind(confirmed_long, rbindlist(confirmed_long2)) 31 | # old death 32 | deaths <- fread("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv") 33 | deaths[deaths$`Country/Region` == "Israel", 5:ncol(deaths)] <- deaths[deaths$`Country/Region` == "Israel", 5:ncol(deaths)] + deaths[deaths$`Country/Region` == "West Bank and Gaza", 5:ncol(deaths)] 34 | deaths <- deaths[deaths$`Country/Region` != "West Bank and Gaza", ] 35 | if (any(!confirmed$`Country/Region` %in% deaths$`Country/Region`)) { 36 | frames <- deaths[1:sum(!confirmed$`Country/Region` %in% deaths$`Country/Region`), ] 37 | frames$`Province/State` <- confirmed$`Province/State`[ 38 | !confirmed$`Country/Region` %in% deaths$`Country/Region` 39 | ] 40 | frames$`Country/Region` <- confirmed$`Country/Region`[ 41 | !confirmed$`Country/Region` %in% deaths$`Country/Region` 42 | ] 43 | frames$Lat <- confirmed$Lat[ 44 | !confirmed$`Country/Region` %in% deaths$`Country/Region` 45 | ] 46 | frames$Long <- confirmed$Long[ 47 | !confirmed$`Country/Region` %in% deaths$`Country/Region` 48 | ] 49 | frames[ 50 | seq_len( 51 | sum(!confirmed$`Country/Region` %in% deaths$`Country/Region`) 52 | ), 53 | 5:ncol(frames) 54 | ] <- 0 55 | deaths <- rbind(deaths, frames) 56 | } 57 | 58 | deaths_long <- deaths[, 1:5] 59 | colnames(deaths_long)[5] <- "deaths" 60 | deaths_long$date <- as.Date(date_new, format = "%m/%d/%Y") 61 | deaths_long2 <- lapply(6:ncol(deaths), function(i, ...) { 62 | deaths_new <- subset(deaths, select = c(1:4, i)) 63 | colnames(deaths_new)[5] <- "deaths" 64 | date <- str_split(colnames(deaths)[i], "/")[[1]] 65 | date_new <- paste(ifelse(nchar(date[1]) == 2, date[1], paste(0, date[1], sep = "")), 66 | ifelse(nchar(date[2]) == 2, date[2], paste(0, date[2], sep = "")), 67 | paste("20", date[3], sep = ""), 68 | sep = "/" 69 | ) 70 | deaths_new$date <- as.Date(date_new, format = "%m/%d/%Y") 71 | deaths_new 72 | }) 73 | 74 | deaths_long <- rbind(deaths_long, rbindlist(deaths_long2)) 75 | 76 | recovered <- fread("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_recovered_global.csv") 77 | recovered[recovered$`Country/Region` == "Israel", 5:ncol(recovered)] <- recovered[recovered$`Country/Region` == "Israel", 5:ncol(recovered)] + recovered[recovered$`Country/Region` == "West Bank and Gaza", 5:ncol(recovered)] 78 | recovered <- recovered[recovered$`Country/Region` != "West Bank and Gaza", ] 79 | if (any(!confirmed$`Country/Region` %in% recovered$`Country/Region`)) { 80 | frames <- recovered[1:sum(!confirmed$`Country/Region` %in% recovered$`Country/Region`), ] 81 | frames$`Province/State` <- confirmed$`Province/State`[ 82 | !confirmed$`Country/Region` %in% recovered$`Country/Region` 83 | ] 84 | frames$`Country/Region` <- confirmed$`Country/Region`[ 85 | !confirmed$`Country/Region` %in% recovered$`Country/Region` 86 | ] 87 | frames$Lat <- confirmed$Lat[ 88 | !confirmed$`Country/Region` %in% recovered$`Country/Region` 89 | ] 90 | frames$Long <- confirmed$Long[ 91 | !confirmed$`Country/Region` %in% recovered$`Country/Region` 92 | ] 93 | frames[ 94 | seq_len( 95 | sum(!confirmed$`Country/Region` %in% recovered$`Country/Region`) 96 | ), 97 | 5:ncol(frames) 98 | ] <- 0 99 | recovered <- rbind(recovered, frames) 100 | } 101 | 102 | recovered_long <- recovered[, 1:5] 103 | colnames(recovered_long)[5] <- "recovered" 104 | recovered_long$date <- as.Date(date_new, format = "%m/%d/%Y") 105 | recovered_long2 <- lapply(6:ncol(recovered), function(i, ...) { 106 | recovered_new <- subset(recovered, select = c(1:4, i)) 107 | colnames(recovered_new)[5] <- "recovered" 108 | date <- str_split(colnames(recovered)[i], "/")[[1]] 109 | date_new <- paste(ifelse(nchar(date[1]) == 2, date[1], paste(0, date[1], sep = "")), 110 | ifelse(nchar(date[2]) == 2, date[2], paste(0, date[2], sep = "")), 111 | paste("20", date[3], sep = ""), 112 | sep = "/" 113 | ) 114 | recovered_new$date <- as.Date(date_new, format = "%m/%d/%Y") 115 | recovered_new 116 | }) 117 | recovered_long <- rbind(recovered_long, rbindlist(recovered_long2)) 118 | 119 | canada_confirmed <- confirmed_long[confirmed_long$`Country/Region` == "Canada", ][, .( 120 | `Province/State` = unique(`Country/Region`), 121 | `Country/Region` = unique(`Country/Region`), 122 | confirmed = sum(confirmed), 123 | Lat = mean(Lat), 124 | Long = mean(Long), 125 | date = unique(date) 126 | ), keyby = .(date, `Country/Region`)][, 3:8] 127 | 128 | canada_deaths <- deaths_long[deaths_long$`Country/Region` == "Canada", ][, .( 129 | `Province/State` = unique(`Country/Region`), 130 | `Country/Region` = unique(`Country/Region`), 131 | Lat = mean(Lat), 132 | Long = mean(Long), 133 | deaths = sum(deaths), 134 | date = unique(date) 135 | ), keyby = .(date, `Country/Region`)][, 3:8] 136 | 137 | china_confirmed <- confirmed_long[confirmed_long$`Country/Region` == "China", ][, .( 138 | `Province/State` = unique(`Country/Region`), 139 | `Country/Region` = unique(`Country/Region`), 140 | confirmed = sum(confirmed), 141 | Lat = mean(Lat), 142 | Long = mean(Long), 143 | date = unique(date) 144 | ), keyby = .(date, `Country/Region`)][, 3:8] 145 | 146 | china_deaths <- deaths_long[deaths_long$`Country/Region` == "China", ][, .( 147 | `Province/State` = unique(`Country/Region`), 148 | `Country/Region` = unique(`Country/Region`), 149 | Lat = mean(Lat), 150 | Long = mean(Long), 151 | deaths = sum(deaths), 152 | date = unique(date) 153 | ), keyby = .(date, `Country/Region`)][, 3:8] 154 | 155 | china_recovered <- recovered_long[recovered_long$`Country/Region` == "China", ][, .( 156 | `Province/State` = unique(`Country/Region`), 157 | `Country/Region` = unique(`Country/Region`), 158 | Lat = mean(Lat), 159 | Long = mean(Long), 160 | recovered = sum(recovered, na.rm = TRUE), 161 | date = unique(date) 162 | ), keyby = .(date, `Country/Region`)][, 3:8] 163 | 164 | confirmed_long <- rbind(confirmed_long[!confirmed_long$`Country/Region` %in% c("Canada", "China")], canada_confirmed, china_confirmed) 165 | deaths_long <- rbind(deaths_long[!deaths_long$`Country/Region` %in% c("Canada", "China")], canada_deaths, china_deaths) 166 | recovered_long <- rbind(recovered_long[!recovered_long$`Country/Region` %in% c("China")], china_recovered) 167 | 168 | confirmed_long <- confirmed_long[order(confirmed_long$date, confirmed_long$`Country/Region`, confirmed_long$`Province/State`), ] 169 | deaths_long <- deaths_long[order(deaths_long$date, deaths_long$`Country/Region`, deaths_long$`Province/State`), ] 170 | recovered_long <- recovered_long[order(recovered_long$date, recovered_long$`Country/Region`, recovered_long$`Province/State`), ] 171 | 172 | confirmed_long[, deaths := deaths_long[, "deaths"]] 173 | confirmed_long[, recovered := recovered_long[, "recovered"]] 174 | confirmed_long[confirmed_long$`Country/Region` == "Canada", ]$Lat <- 53.91469 175 | confirmed_long[confirmed_long$`Country/Region` == "Canada", ]$Long <- -106.48272 176 | confirmed_long[confirmed_long$`Country/Region` == "China", ]$Lat <- 34.89679 177 | confirmed_long[confirmed_long$`Country/Region` == "China", ]$Long <- 104.75355 178 | confirmed_long[confirmed_long$`Country/Region` == "Holy See", ]$`Country/Region` <- "Vatican" 179 | corona <- confirmed_long 180 | # add a day 0 frame 181 | rows <- seq_len(length(unique(paste(corona$`Country/Region`, corona$`Province/State`)))) 182 | corona_0 <- corona[rows, ] 183 | corona_0$confirmed <- 0 184 | corona_0$deaths <- 0 185 | corona_0$recovered <- 0 186 | corona_0$date <- min(corona$date) - 1 187 | corona <- rbind(corona_0, corona) 188 | # save the first and last date for later 189 | dates <- c(min(corona$date), max(corona$date)) 190 | corona = corona[corona$`Province/State` != "Unknown"] 191 | if (nrow(corona[corona$recovered == 0 & corona$date == Sys.Date() - 1]) > 0) { 192 | corona$temp <- paste(corona$`Province/State`, corona$`Country/Region`) 193 | missing <- corona[corona$recovered == 0 & corona$date == Sys.Date() - 1]$temp 194 | for(x in missing) { 195 | if (!all(corona[corona$temp == x]$recovered == 0)) { 196 | last_ind <- max(which(corona[corona$temp == x]$recovered != 0)) 197 | corona[corona$temp == x]$recovered[(last_ind + 1):nrow(corona[corona$temp == x])] <- corona[corona$temp == x]$recovered[last_ind] 198 | } 199 | } 200 | corona$temp <- NULL 201 | 202 | } 203 | # turn into a geo data.frame 204 | corona_sf <- data.table(st_as_sf(corona, coords = c("Long", "Lat"), crs = 4326)) 205 | # replace empty province with the country/region 206 | corona_sf$`Province/State`[is.na(corona_sf$`Province/State`)] <- corona_sf$`Country/Region`[is.na(corona_sf$`Province/State`)] 207 | -------------------------------------------------------------------------------- /server/data_wrangling/lockdown_data.R: -------------------------------------------------------------------------------- 1 | # load lockdown data 2 | locked <- read_csv("https://raw.githubusercontent.com/nicoFhahn/covid_shiny/master/data/locked.csv") 3 | # we want to calculate the growth rate for each of the 14 days prior to the lockdown 4 | locked_days <- daily_cases2[ 5 | daily_cases2$date %in% seq(min(locked$date) - 15, max(daily_cases2$date), by = 1), 6 | ] 7 | # join the daily cases by the data 8 | locked_days <- right_join(locked_days, locked, by = "Country/Region") 9 | locked_days <- locked_days[locked_days$lockdown != "parts_special", ] 10 | # throw away to old data 11 | locked_days <- locked_days[locked_days$date.x + 15 >= locked_days$date.y, ] 12 | # split by the type of lockdown 13 | locked_split <- split(locked_days, locked_days$lockdown) 14 | change <- lapply(locked_split, function(x) { 15 | # get data ahead of the lockdown 16 | pre <- x[x$date.x < x$date.y, ] 17 | # order it 18 | pre <- pre[order(pre$`Country/Region`), ] 19 | # get number of day (1-14) 20 | pre$day <- unlist(lapply(as.numeric(table(pre$`Country/Region`) - 1), seq, from = 0, by = 1)) 21 | # calculate the growth 22 | pre$growth_conf <- pre$confirmed / lag(pre$confirmed, default = first(pre$confirmed)) 23 | # throw away growth on day 0, infinite and nans 24 | pre <- pre[pre$day != 0, ] 25 | pre <- pre[!is.infinite(pre$growth_conf), ] 26 | pre <- pre[!is.nan(pre$growth_conf), ] 27 | # calculate mean growth rate by country 28 | pre <- pre %>% 29 | group_by(`Country/Region`) %>% 30 | summarise( 31 | growth = mean(growth_conf, na.rm = TRUE) 32 | ) 33 | # do the same again for the days after 34 | post <- x[x$date.x >= x$date.y - 1, ] 35 | post <- post[order(post$`Country/Region`), ] 36 | post$day <- unlist(lapply(as.numeric(table(post$`Country/Region`) - 1), seq, from = 0, by = 1)) 37 | post$growth_conf <- post$confirmed / lag(post$confirmed, default = first(post$confirmed)) 38 | post <- post[post$day != 0, ] 39 | post <- post[!is.infinite(post$growth_conf), ] 40 | post <- post[!is.nan(post$growth_conf), ] 41 | post <- post %>% 42 | group_by(`Country/Region`) %>% 43 | summarise( 44 | growth = mean(growth_conf, na.rm = TRUE) 45 | ) 46 | list( 47 | data.frame( 48 | pre_lockdown = mean(pre$growth), 49 | post_lockdown = mean(post$growth) 50 | ), 51 | pre$growth 52 | ) 53 | }) 54 | # get the countries with no lockdown 55 | no_lock <- daily_cases2[!daily_cases2$`Country/Region` %in% locked$`Country/Region`, ] 56 | # order them 57 | no_lock <- no_lock[order(no_lock$`Country/Region`), ] 58 | # set the day 59 | no_lock$day <- unlist(lapply(as.numeric(table(no_lock$`Country/Region`) - 1), seq, from = 0, by = 1)) 60 | # calculate the growth rates 61 | no_lock$growth_conf <- no_lock$confirmed / lag(no_lock$confirmed, default = first(no_lock$confirmed)) 62 | # throw away growth on day 0, infinite and nans 63 | no_lock <- no_lock[no_lock$day != 0, ] 64 | no_lock <- no_lock[!is.infinite(no_lock$growth_conf), ] 65 | no_lock <- no_lock[!is.nan(no_lock$growth_conf), ] 66 | # calculate for each coutnry 67 | no_lock <- no_lock %>% 68 | group_by(`Country/Region`) %>% 69 | summarise( 70 | growth = mean(growth_conf, na.rm = TRUE) 71 | ) 72 | # calculate the mean growth rate in countries with no lockdown 73 | # and countries with a lockdown but prior to it 74 | rate <- mean(c(no_lock$growth, unlist(lapply(change, function(x) x[[2]])))) 75 | change_df <- Reduce(rbind, lapply(change, function(x) x[[1]])) 76 | # create a data frame 77 | lock_df <- data.frame( 78 | lockdown = c(unlist(lapply(names(change), rep, 2)), "No lockdown"), 79 | infection_rate = round(unlist(c(change_df[1, ], change_df[2, ], change_df[3, ], rate)), 2), 80 | time = c(rep(c("Pre or no lockdown", "Post lockdown"), 3), "Pre or no lockdown") 81 | ) 82 | # edit some variables for plotting purposes 83 | lock_df$lockdown <- as.character(lock_df$lockdown) 84 | lock_df$lockdown[lock_df$lockdown == "Yes"] <- "Full lockdown" 85 | lock_df$lockdown[lock_df$lockdown == "Partial"] <- "Partial lockdown" 86 | lock_df$lockdown[lock_df$lockdown == "parts"] <- "Lockdown in parts of country" 87 | lock_df$lockdown <- ordered(lock_df$lockdown, levels = c( 88 | "No lockdown", "Lockdown in parts of country", "Partial lockdown", "Full lockdown" 89 | )) 90 | lock_df$time <- ordered(lock_df$time, levels = c("Pre or no lockdown", "Post lockdown")) 91 | lock_df <- lock_df[order(lock_df$lockdown), ] 92 | 93 | # create a sf data frame that contains polygon and type of lockdown 94 | locked_2 <- locked 95 | colnames(locked_2)[1] <- "ADMIN" 96 | missing_frame <- data.frame( 97 | ADMIN = countries$ADMIN[!countries$ADMIN %in% locked_2$ADMIN], 98 | lockdown = "No lockdown", 99 | date = NA 100 | ) 101 | locked_2 <- rbind(locked_2, missing_frame) 102 | locked_countries <- right_join(countries, locked_2, by = "ADMIN") 103 | locked_countries <- locked_countries[locked_countries$ADMIN != "Antarctica", ] 104 | locked_countries$lockdown[locked_countries$lockdown == "Yes"] <- "Full lockdown" 105 | locked_countries$lockdown[locked_countries$lockdown == "Partial"] <- "Partial lockdown" 106 | locked_countries$lockdown[locked_countries$lockdown == "parts"] <- "Lockdown in parts of country" 107 | locked_countries$lockdown[locked_countries$lockdown == "parts_special"] <- "Lockdown in parts of country" 108 | locked_countries$lockdown <- ordered(locked_countries$lockdown, levels = c( 109 | "No lockdown", "Lockdown in parts of country", "Partial lockdown", "Full lockdown" 110 | )) 111 | pal <- colorFactor(c("#161616", "#EABF00", "#F26D00", "#FF003F"), domain = locked_countries$lockdown) 112 | -------------------------------------------------------------------------------- /server/data_wrangling/s_n_p.R: -------------------------------------------------------------------------------- 1 | # try to download the data 2 | # if not use the backup 3 | a <- try(getSymbols("^GSPC"), silent = TRUE) 4 | if (a != "^GSPC") { 5 | gspc <- read_csv("data/gspc_backup.csv") 6 | } else { 7 | gspc <- as.data.frame(GSPC) 8 | gspc$date <- as.Date(rownames(gspc)) 9 | } -------------------------------------------------------------------------------- /server/data_wrangling/top_15.R: -------------------------------------------------------------------------------- 1 | # get countries with most confirmed cases 2 | top15_confirmed <- today[today$confirmed %in% sort(today$confirmed, decreasing = TRUE)[1:15], ] 3 | top15_confirmed <- top15_confirmed[order(top15_confirmed$confirmed, decreasing = TRUE), ] 4 | # get countries with most deaths 5 | top15_deaths <- today[today$confirmed %in% sort(today$confirmed, decreasing = TRUE)[1:15], ] 6 | top15_deaths <- top15_deaths[order(top15_deaths$deaths, decreasing = TRUE), ] 7 | # spatial intersection to calculate per capita stats 8 | # we don't want countries 9 | # today_inter <- st_intersection(countries[seq_len(nrow(countries)), ], today) 10 | countries_sf <- st_as_sf(countries) 11 | today_sf <- st_as_sf(today, crs = 4326) 12 | today_inter <- st_intersection(countries_sf[seq_len(nrow(countries)), ], today_sf) 13 | # calculate per capita stats 14 | per_capita <- data.table( 15 | country = today_inter$Country.Region, 16 | confirmed = today_inter$confirmed, 17 | confirmed_per_capita = round(today_inter$confirmed / today_inter$POP_EST, 5) * 1000, 18 | deaths = today_inter$deaths, 19 | deaths_per_capita = round(today_inter$deaths / today_inter$POP_EST, 5) * 1000 20 | ) 21 | # get the top 15 for both again 22 | top15_confirmed_per_capita <- per_capita[per_capita$confirmed_per_capita %in% sort(per_capita$confirmed_per_capita, decreasing = TRUE)[1:15], ] 23 | top15_deaths_per_capita <- per_capita[per_capita$deaths_per_capita %in% sort(per_capita$deaths_per_capita, decreasing = TRUE)[1:15], ] 24 | top15_confirmed_per_capita <- top15_confirmed_per_capita[order(top15_confirmed_per_capita$confirmed_per_capita, decreasing = TRUE), ] 25 | top15_deaths_per_capita <- top15_deaths_per_capita[order(top15_deaths_per_capita$deaths_per_capita, decreasing = TRUE), ] 26 | -------------------------------------------------------------------------------- /server/highcharter_outputs.R: -------------------------------------------------------------------------------- 1 | output$highcharter_1 <- renderHighchart({ 2 | highchart() %>% 3 | hc_yAxis_multiples( 4 | list(title = list(text = "Number of cases in China")), 5 | list( 6 | opposite = TRUE, 7 | title = list(text = "Number of cases outside China") 8 | ) 9 | ) %>% 10 | hc_xAxis( 11 | categories = january$date, title = list(text = "Date"), 12 | gridLineWidth = 0 13 | ) %>% 14 | hc_add_series( 15 | name = "Confirmed cases in China ", 16 | data = january$confirmed[january$`Country/Region` == "China"], 17 | color = "#5BC0EB" 18 | ) %>% 19 | hc_add_series( 20 | name = "Confirmed cases outside China", 21 | data = january$confirmed[january$`Country/Region` != "China"], 22 | yAxis = 1, 23 | color = "#FDE74C" 24 | ) %>% 25 | hc_add_theme(hc_theme_monokai()) %>% 26 | hc_title(text = "Number of confirmed cases in January 2020") %>% 27 | hc_chart(backgroundColor = "#161616") %>% 28 | hc_legend(align = "left") %>% 29 | hc_plotOptions( 30 | line = list(marker = list(enabled = FALSE)) 31 | ) 32 | }) 33 | 34 | output$highcharter_2 <- renderHighchart({ 35 | highchart() %>% 36 | hc_xAxis( 37 | categories = unique(february$date), 38 | gridLineWidth = 0, 39 | title = list(text = "Date") 40 | ) %>% 41 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 42 | hc_add_series( 43 | name = "Italy", 44 | data = february$confirmed[february$`Country/Region` == "Italy"], 45 | color = "#F8333C" 46 | ) %>% 47 | hc_add_series( 48 | name = "Iran", 49 | data = february$confirmed[february$`Country/Region` == "Iran"], 50 | color = "#44AF69" 51 | ) %>% 52 | hc_add_series( 53 | name = "South Korea", 54 | data = february$confirmed[february$`Country/Region` == "Korea, South"], 55 | color = "#88CCF1" 56 | ) %>% 57 | hc_add_theme(hc_theme_monokai()) %>% 58 | hc_title( 59 | text = "Number of confirmed cases at the end of February 2020" 60 | ) %>% 61 | hc_legend(align = "left") %>% 62 | hc_chart(backgroundColor = "#161616") %>% 63 | hc_plotOptions( 64 | line = list(marker = list(enabled = FALSE)) 65 | ) 66 | }) 67 | 68 | output$highcharter_3 <- renderHighchart({ 69 | highchart() %>% 70 | hc_xAxis( 71 | categories = gspc$date, title = list(text = "Date"), 72 | gridLineWidth = 0, 73 | plotLines = list( 74 | list( 75 | label = list(text = "February 27, 2020"), 76 | color = "#FCFCFC", 77 | width = 2, 78 | value = match(as.Date("2020-02-27"), gspc$date) 79 | ), 80 | list( 81 | label = list(text = "2008 financial crisis"), 82 | color = "#FCFCFC", 83 | width = 2, 84 | value = match(as.Date("2008-10-09"), gspc$date) 85 | ) 86 | ) 87 | ) %>% 88 | hc_yAxis(title = list(text = "Closing value")) %>% 89 | hc_add_series( 90 | name = "Closing value", 91 | data = gspc$GSPC.Close, 92 | color = "#8AEA9A" 93 | ) %>% 94 | hc_add_theme(hc_theme_monokai()) %>% 95 | hc_title(text = "Closing value of the S&P 500") %>% 96 | hc_legend(align = "left") %>% 97 | hc_chart(backgroundColor = "#161616") %>% 98 | hc_legend(enabled = FALSE) %>% 99 | hc_plotOptions( 100 | line = list(marker = list(enabled = FALSE)) 101 | ) 102 | }) 103 | 104 | output$highcharter_4 <- renderHighchart({ 105 | highchart() %>% 106 | hc_chart(type = "column") %>% 107 | hc_xAxis( 108 | categories = feb_euro$Country.Region, 109 | gridLineWidth = 0, 110 | title = list(text = "Country") 111 | ) %>% 112 | hc_add_series( 113 | data = feb_euro$confirmed, 114 | name = "Confirmed cases", 115 | color = "#00bb8b" 116 | ) %>% 117 | hc_add_theme(hc_theme_monokai()) %>% 118 | hc_title( 119 | text = "Number of confirmed cases at the end of February 2020" 120 | ) %>% 121 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 122 | hc_chart(backgroundColor = "#161616") %>% 123 | hc_legend(enabled = FALSE) 124 | }) 125 | 126 | output$highcharter_5 <- renderHighchart({ 127 | highchart() %>% 128 | hc_chart(type = "column") %>% 129 | hc_xAxis( 130 | categories = top10feb$`Country/Region`, 131 | gridLineWidth = 0, 132 | title = list(text = "Country") 133 | ) %>% 134 | hc_add_series( 135 | data = top10feb$confirmed, 136 | name = "Confirmed cases", 137 | color = "#00bb8b" 138 | ) %>% 139 | hc_add_theme(hc_theme_monokai()) %>% 140 | hc_title( 141 | text = "Number of confirmed cases at the end of February 2020" 142 | ) %>% 143 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 144 | hc_chart(backgroundColor = "#161616") %>% 145 | hc_legend(enabled = FALSE) 146 | }) 147 | 148 | output$highcharter_6 <- renderHighchart({ 149 | highchart() %>% 150 | hc_xAxis( 151 | categories = pandemic$date, 152 | gridLineWidth = 0, 153 | type = "date", 154 | title = list(text = "Date"), 155 | plotLines = list( 156 | list( 157 | label = list(text = "2 weeks prior"), 158 | color = "#FCFCFC", 159 | width = 2, 160 | value = 13 161 | ), 162 | list( 163 | label = list(text = "Declared a pandemic"), 164 | color = "#FCFCFC", 165 | width = 2, 166 | value = 27 167 | ) 168 | ) 169 | ) %>% 170 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 171 | hc_add_series( 172 | data = pandemic$confirmed, 173 | name = "Confirmed cases", 174 | color = "#FDE74C" 175 | ) %>% 176 | hc_add_theme(hc_theme_monokai()) %>% 177 | hc_title( 178 | text = "Number of confirmed cases outside China over the last 28 days" 179 | ) %>% 180 | hc_chart(backgroundColor = "#161616") %>% 181 | hc_legend(enabled = FALSE) %>% 182 | hc_plotOptions( 183 | line = list(marker = list(enabled = FALSE)) 184 | ) 185 | }) 186 | 187 | output$highcharter_7 <- renderHighchart({ 188 | germany <- daily_cases2[daily_cases2$`Country/Region` == "Germany", c(1, 3, 4)] 189 | highchart() %>% 190 | hc_xAxis(categories = germany$date) %>% 191 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 192 | hc_add_series( 193 | data = germany$confirmed, 194 | name = "Confirmed cases", 195 | color = "#EE6352" 196 | ) %>% 197 | hc_add_theme(hc_theme_monokai()) %>% 198 | hc_title(text = "Number of confirmed cases in Germany") %>% 199 | hc_chart(backgroundColor = "#161616") %>% 200 | hc_legend(enabled = FALSE) %>% 201 | hc_xAxis( 202 | title = list(text = "Date"), 203 | gridLineWidth = 0, 204 | plotLines = list( 205 | list( 206 | label = list(text = "Contact ban", verticalAlign = "middle"), 207 | color = "#FCFCFC", 208 | width = 2, 209 | value = 61 210 | ) 211 | ) 212 | ) %>% 213 | hc_plotOptions( 214 | line = list(marker = list(enabled = FALSE)) 215 | ) 216 | }) 217 | 218 | output$highcharter_8 <- renderHighchart({ 219 | highchart() %>% 220 | hc_xAxis( 221 | categories = daily_cases$date, 222 | gridLineWidth = 0, title = list(text = "Date") 223 | ) %>% 224 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 225 | hc_add_series( 226 | data = daily_cases$confirmed, 227 | name = "Confirmed cases", 228 | color = "#00bb8b" 229 | ) %>% 230 | hc_add_theme(hc_theme_monokai()) %>% 231 | hc_title(text = "Number of confirmed cases") %>% 232 | hc_chart(backgroundColor = "#161616") %>% 233 | hc_legend(enabled = FALSE) %>% 234 | hc_plotOptions( 235 | line = list(marker = list(enabled = FALSE)) 236 | ) 237 | }) 238 | 239 | output$highcharter_9 <- renderHighchart({ 240 | daily_cases$increase <- c( 241 | 0, daily_cases$confirmed[-1] - 242 | daily_cases$confirmed 243 | )[seq_len(nrow(daily_cases))] 244 | highchart() %>% 245 | hc_chart(type = "column") %>% 246 | hc_xAxis( 247 | categories = daily_cases$date, 248 | gridLineWidth = 0, 249 | title = list(text = "Date") 250 | ) %>% 251 | hc_add_series( 252 | data = daily_cases$increase, 253 | name = "New infections", 254 | color = "#00bb8b" 255 | ) %>% 256 | hc_add_theme(hc_theme_monokai()) %>% 257 | hc_title(text = "Daily number of new infections") %>% 258 | hc_yAxis(title = list(text = "Confirmed infections")) %>% 259 | hc_chart(backgroundColor = "#161616") %>% 260 | hc_legend(enabled = FALSE) 261 | }) 262 | 263 | output$highcharter_10 <- renderHighchart({ 264 | today <- daily_cases2[daily_cases2$date == max(daily_cases2$date), ] 265 | most_infected <- daily_cases2[ 266 | daily_cases2$`Country/Region` == as.character( 267 | today[today$confirmed == max(today$confirmed), 2] 268 | ), 269 | ] 270 | country <- unique(most_infected$`Country/Region`) 271 | if (country == "US") { 272 | country <- "the United States" 273 | } 274 | highchart() %>% 275 | hc_xAxis( 276 | categories = most_infected$date, title = list(text = "Date"), 277 | gridLineWidth = 0 278 | ) %>% 279 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 280 | hc_add_series( 281 | data = most_infected$confirmed, 282 | name = "Confirmed cases", 283 | color = "#00bb8b" 284 | ) %>% 285 | hc_add_theme(hc_theme_monokai()) %>% 286 | hc_title( 287 | text = paste( 288 | "Number of confirmed cases in", 289 | country 290 | ) 291 | ) %>% 292 | hc_chart(backgroundColor = "#161616") %>% 293 | hc_legend(enabled = FALSE) %>% 294 | hc_plotOptions( 295 | line = list(marker = list(enabled = FALSE)) 296 | ) 297 | }) 298 | 299 | output$highcharter_11 <- renderHighchart({ 300 | today <- daily_cases2[daily_cases2$date == max(daily_cases2$date), ] 301 | most_infected <- daily_cases2[ 302 | daily_cases2$`Country/Region` == as.character( 303 | today[today$confirmed == max(today$confirmed), 2] 304 | ), 305 | ] 306 | most_infected$increase <- c( 307 | 0, most_infected$confirmed[-1] - 308 | most_infected$confirmed 309 | )[seq_len(nrow(most_infected))] 310 | country <- unique(most_infected$`Country/Region`) 311 | if (country == "US") { 312 | country <- "the United States" 313 | } 314 | highchart() %>% 315 | hc_chart(type = "column") %>% 316 | hc_xAxis( 317 | categories = most_infected$date, 318 | gridLineWidth = 0, 319 | title = list(text = "Date") 320 | ) %>% 321 | hc_add_series( 322 | data = most_infected$increase, 323 | name = "Confirmed cases", 324 | color = "#00bb8b" 325 | ) %>% 326 | hc_add_theme(hc_theme_monokai()) %>% 327 | hc_title( 328 | text = paste( 329 | "Daily number of new infections in", 330 | country 331 | ) 332 | ) %>% 333 | hc_yAxis(title = list(text = "Confirmed infections")) %>% 334 | hc_chart(backgroundColor = "#161616") %>% 335 | hc_legend(enabled = FALSE) 336 | }) 337 | 338 | output$highcharter_12 <- renderHighchart({ 339 | most_death <- daily_cases2[ 340 | daily_cases2$`Country/Region` == as.character( 341 | today[today$deaths == max(today$deaths), 2] 342 | ), 343 | ] 344 | highchart() %>% 345 | hc_xAxis( 346 | categories = most_death$date, title = list(text = "Date"), 347 | gridLineWidth = 0 348 | ) %>% 349 | hc_yAxis(title = list(text = "Deaths")) %>% 350 | hc_add_series( 351 | data = most_death$deaths, 352 | name = "Deaths", 353 | color = "#fb5a19" 354 | ) %>% 355 | hc_add_theme(hc_theme_monokai()) %>% 356 | hc_title( 357 | text = paste( 358 | "Number of deaths in", 359 | unique(most_death$`Country/Region`) 360 | ) 361 | ) %>% 362 | hc_chart(backgroundColor = "#161616") %>% 363 | hc_legend(enabled = FALSE) %>% 364 | hc_plotOptions( 365 | line = list(marker = list(enabled = FALSE)) 366 | ) 367 | }) 368 | 369 | output$highcharter_13 <- renderHighchart({ 370 | most_death <- daily_cases2[ 371 | daily_cases2$`Country/Region` == as.character( 372 | today[today$deaths == max(today$deaths), 2] 373 | ), 374 | ] 375 | most_death$increase <- c( 376 | 0, most_death$deaths[-1] - most_death$deaths 377 | )[seq_len(nrow(most_death))] 378 | highchart() %>% 379 | hc_chart(type = "column") %>% 380 | hc_xAxis( 381 | categories = most_death$date, 382 | gridLineWidth = 0, 383 | title = list(text = "Date") 384 | ) %>% 385 | hc_add_series( 386 | data = most_death$increase, 387 | name = "Deaths", 388 | color = "#fb5a19" 389 | ) %>% 390 | hc_add_theme(hc_theme_monokai()) %>% 391 | hc_title( 392 | text = paste( 393 | "Daily number of deaths in", 394 | unique(most_death$`Country/Region`) 395 | ) 396 | ) %>% 397 | hc_yAxis(title = list(text = "Deaths")) %>% 398 | hc_chart(backgroundColor = "#161616") %>% 399 | hc_legend(enabled = FALSE) 400 | }) 401 | 402 | output$highcharter_14 <- renderHighchart({ 403 | highchart() %>% 404 | hc_xAxis( 405 | categories = unique(daily_cases2$date), 406 | gridLineWidth = 0, 407 | title = list(text = "Date"), 408 | plotLines = list( 409 | list( 410 | label = list(text = "U.S. leads in confirmed cases"), 411 | color = "#FCFCFC", 412 | width = 2, 413 | value = 65 414 | ) 415 | ) 416 | ) %>% 417 | hc_yAxis(title = list(text = "Confirmed cases")) %>% 418 | hc_add_series( 419 | name = "Brazil", 420 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "Brazil"], 421 | color = "#FFBD00" 422 | ) %>% 423 | hc_add_series( 424 | name = "China", 425 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "China"], 426 | color = "#5BC0EB" 427 | ) %>% 428 | hc_add_series( 429 | name = "France", 430 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "France"], 431 | color = "#AF3E4D" 432 | ) %>% 433 | hc_add_series( 434 | name = "Germany", 435 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "Germany"], 436 | color = "#EE6352" 437 | ) %>% 438 | hc_add_series( 439 | name = "India", 440 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "India"], 441 | color = "#F4F4F8" 442 | ) %>% 443 | hc_add_series( 444 | name = "Italy", 445 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "Italy"], 446 | color = "#F8333C" 447 | ) %>% 448 | hc_add_series( 449 | name = "Russia", 450 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "Russia"], 451 | color = "#00a896" 452 | ) %>% 453 | hc_add_series( 454 | name = "Spain", 455 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "Spain"], 456 | color = "#F2CCC3" 457 | ) %>% 458 | hc_add_series( 459 | name = "UK", 460 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "United Kingdom"], 461 | color = "#D4A0A7" 462 | ) %>% 463 | hc_add_series( 464 | name = "USA", 465 | data = daily_cases2$confirmed[daily_cases2$`Country/Region` == "US"], 466 | color = "#97C667" 467 | ) %>% 468 | hc_add_theme(hc_theme_monokai()) %>% 469 | hc_title( 470 | text = "Number of confirmed 471 | cases" 472 | ) %>% 473 | hc_legend(align = "left") %>% 474 | hc_chart(backgroundColor = "#161616") %>% 475 | hc_plotOptions( 476 | line = list(marker = list(enabled = FALSE)) 477 | ) 478 | }) 479 | 480 | 481 | output$highcharter_15 <- renderHighchart({ 482 | highchart() %>% 483 | hc_chart(type = "column") %>% 484 | hc_xAxis( 485 | categories = top15_confirmed$`Country/Region`, 486 | gridLineWidth = 0, 487 | title = list(text = "Country") 488 | ) %>% 489 | hc_add_series( 490 | data = top15_confirmed$confirmed, 491 | name = "Confirmed infections", 492 | color = "#00bb8b" 493 | ) %>% 494 | hc_add_theme(hc_theme_monokai()) %>% 495 | hc_title(text = "Countries with the most infections (as of today)") %>% 496 | hc_yAxis(title = list(text = "Confirmed infections")) %>% 497 | hc_chart(backgroundColor = "#161616") %>% 498 | hc_legend(enabled = FALSE) 499 | }) 500 | 501 | output$highcharter_16 <- renderHighchart({ 502 | highchart() %>% 503 | hc_chart(type = "column") %>% 504 | hc_xAxis( 505 | categories = top15_deaths$`Country/Region`, 506 | gridLineWidth = 0, 507 | title = list(text = "Country") 508 | ) %>% 509 | hc_add_series( 510 | data = top15_deaths$deaths, 511 | name = "Deaths", 512 | color = "#fb5a19" 513 | ) %>% 514 | hc_add_theme(hc_theme_monokai()) %>% 515 | hc_title(text = "Countries with the most deaths (as of today)") %>% 516 | hc_yAxis(title = list(text = "Deaths")) %>% 517 | hc_chart(backgroundColor = "#161616") %>% 518 | hc_legend(enabled = FALSE) 519 | }) 520 | 521 | output$highcharter_17 <- renderHighchart({ 522 | highchart() %>% 523 | hc_chart(type = "column") %>% 524 | hc_xAxis( 525 | categories = top15_confirmed_per_capita$country, 526 | gridLineWidth = 0, 527 | title = list(text = "Country") 528 | ) %>% 529 | hc_add_series( 530 | data = top15_confirmed_per_capita$confirmed_per_capita, 531 | name = "Infection rate per 1 000", 532 | color = "#00bb8b" 533 | ) %>% 534 | hc_add_theme(hc_theme_monokai()) %>% 535 | hc_title(text = "Infection rate per 1 000 (as of today)") %>% 536 | hc_yAxis(title = list(text = "Infection rate per 1 000")) %>% 537 | hc_chart(backgroundColor = "#161616") %>% 538 | hc_legend(enabled = FALSE) 539 | }) 540 | 541 | output$highcharter_18 <- renderHighchart({ 542 | highchart() %>% 543 | hc_chart(type = "column") %>% 544 | hc_xAxis( 545 | categories = top15_deaths_per_capita$country, 546 | gridLineWidth = 0, 547 | title = list(text = "Country") 548 | ) %>% 549 | hc_add_series( 550 | data = top15_deaths_per_capita$deaths_per_capita, 551 | name = "Death rate per 1 000", 552 | color = "#fb5a19" 553 | ) %>% 554 | hc_add_theme(hc_theme_monokai()) %>% 555 | hc_title(text = "Death rate per 1 000 (as of today)") %>% 556 | hc_yAxis(title = list(text = "Death rate per 1 000")) %>% 557 | hc_chart(backgroundColor = "#161616") %>% 558 | hc_legend(enabled = FALSE) 559 | }) 560 | 561 | output$highcharter_19 <- renderHighchart({ 562 | highchart() %>% 563 | hc_chart(type = "column") %>% 564 | hc_xAxis( 565 | categories = df_most$country, 566 | gridLineWidth = 0, 567 | title = list(text = "Country") 568 | ) %>% 569 | hc_add_series( 570 | data = df_most$increase, 571 | name = "Increase in %", 572 | color = "#00bb8b" 573 | ) %>% 574 | hc_add_theme(hc_theme_monokai()) %>% 575 | hc_title(text = "Highest increase in new infections in the last 14 days (at least 1 infection)") %>% 576 | hc_yAxis(title = list(text = "Increase in %")) %>% 577 | hc_chart(backgroundColor = "#161616") %>% 578 | hc_legend(enabled = FALSE) 579 | }) 580 | 581 | output$highcharter_20 <- renderHighchart({ 582 | highchart() %>% 583 | hc_chart(type = "column") %>% 584 | hc_xAxis( 585 | categories = df_limit_most$country, 586 | gridLineWidth = 0, 587 | title = list(text = "Country") 588 | ) %>% 589 | hc_add_series( 590 | data = df_limit_most$increase, 591 | name = "Increase in %", 592 | color = "#00bb8b" 593 | ) %>% 594 | hc_add_theme(hc_theme_monokai()) %>% 595 | hc_title(text = paste("Most new infections in the last 14 days (at least", limit, "infections)")) %>% 596 | hc_yAxis(title = list(text = "Increase in %")) %>% 597 | hc_chart(backgroundColor = "#161616") %>% 598 | hc_legend(enabled = FALSE) 599 | }) 600 | 601 | output$highcharter_21 <- renderHighchart({ 602 | highchart() %>% 603 | hc_chart(type = "column") %>% 604 | hc_xAxis( 605 | categories = df_limit_few$country, 606 | gridLineWidth = 0, 607 | title = list(text = "Country") 608 | ) %>% 609 | hc_add_series( 610 | data = df_limit_few$increase, 611 | name = "Increase in %", 612 | color = "#00bb8b" 613 | ) %>% 614 | hc_add_theme(hc_theme_monokai()) %>% 615 | hc_title(text = paste("Fewest infections in the last 14 days (at least", limit, "infections)")) %>% 616 | hc_yAxis(title = list(text = "Increase in %")) %>% 617 | hc_chart(backgroundColor = "#161616") %>% 618 | hc_legend(enabled = FALSE) 619 | }) 620 | 621 | output$highcharter_22 <- renderHighchart({ 622 | highchart() %>% 623 | hc_add_series(forecast_df$confirmed, name = "Original values", color = "#00bb8b") %>% 624 | hc_xAxis(title = list(text = "Date"), categories = forecast_df$date) %>% 625 | hc_add_series(as.matrix(forecast_df[, 4:5]), 626 | type = "arearange", color = "#A2DFDE", 627 | fillOpacity = 0.3, 628 | name = "95% conf." 629 | ) %>% 630 | hc_add_series(forecast_df$fitted_conf, name = "Mean prediction", color = "#00A9A5") %>% 631 | hc_xAxis(title = list(text = "Date"), categories = forecast_df$date) %>% 632 | hc_add_theme(hc_theme_monokai()) %>% 633 | hc_yAxis(title = list(text = "Confirmed cases"), min = 0) %>% 634 | hc_chart(backgroundColor = "#161616") %>% 635 | hc_legend(align = "left") %>% 636 | hc_xAxis( 637 | title = list(text = "Date"), 638 | gridLineWidth = 0, 639 | plotLines = list( 640 | list( 641 | label = list(text = "Today"), 642 | color = "#FCFCFC", 643 | width = 2, 644 | value = nrow(daily_cases) 645 | ) 646 | ) 647 | ) %>% 648 | hc_title(text = "Predicted number of confirmed cases over the next 30 days") %>% 649 | hc_plotOptions( 650 | line = list(marker = list(enabled = FALSE)), 651 | arearange = list(marker = list(enabled = FALSE)) 652 | ) 653 | }) 654 | 655 | output$highcharter_23 <- renderHighchart({ 656 | highchart() %>% 657 | hc_add_series(forecast_df$deaths, name = "Original values", color = "#fb5a19") %>% 658 | hc_xAxis(title = list(text = "Date"), categories = forecast_df$date) %>% 659 | hc_add_series(as.matrix(forecast_df[, 8:9]), 660 | type = "arearange", color = "#F3B1B5", 661 | fillOpacity = 0.3, 662 | name = "95% conf." 663 | ) %>% 664 | hc_add_series(forecast_df$fitted_death, name = "Mean prediction", color = "#DF2935") %>% 665 | hc_xAxis(title = list(text = "Date"), categories = forecast_df$date) %>% 666 | hc_add_theme(hc_theme_monokai()) %>% 667 | hc_yAxis(title = list(text = "Deaths"), min = 0) %>% 668 | hc_chart(backgroundColor = "#161616") %>% 669 | hc_legend(align = "left") %>% 670 | hc_xAxis( 671 | title = list(text = "Date"), 672 | gridLineWidth = 0, 673 | plotLines = list( 674 | list( 675 | label = list(text = "Today"), 676 | color = "#FCFCFC", 677 | width = 2, 678 | value = nrow(daily_cases) 679 | ) 680 | ) 681 | ) %>% 682 | hc_title(text = "Predicted number of deaths over the next 30 days") %>% 683 | hc_plotOptions( 684 | line = list(marker = list(enabled = FALSE)), 685 | arearange = list(marker = list(enabled = FALSE)) 686 | ) 687 | }) 688 | 689 | 690 | output$highcharter_24 <- renderHighchart({ 691 | hchart( 692 | lock_df, "column", 693 | hcaes(x = lockdown, y = infection_rate, group = time), 694 | color = c("#65DEF1", "#D7263D") 695 | ) %>% 696 | hc_xAxis( 697 | title = list(text = "Lockdown status"), 698 | gridLineWidth = 0 699 | ) %>% 700 | hc_title(text = "Average daily growth rate before and after different types of lockdowns") %>% 701 | hc_yAxis(title = list(text = "Growth rate")) %>% 702 | hc_add_theme(hc_theme_monokai()) %>% 703 | hc_chart(backgroundColor = "#161616") %>% 704 | hc_legend(align = "left") 705 | }) 706 | -------------------------------------------------------------------------------- /server/leaflet_maps.R: -------------------------------------------------------------------------------- 1 | output$mymap <- renderLeaflet({ 2 | # if no mapbox key exists use cartodb dark matter 3 | if (key == "") { 4 | map <- leaflet(options = leafletOptions(zoomControl = FALSE)) %>% 5 | addProviderTiles( 6 | "CartoDB.DarkMatter" 7 | ) %>% 8 | setView( 9 | lng = 40, 10 | lat = 30.45, 11 | zoom = 3 12 | ) 13 | } else { 14 | map <- leaflet(options = leafletOptions(zoomControl = FALSE)) %>% 15 | addMapboxGL(style = "mapbox://styles/nicohahn/ckg0iz22c28xx19pqdi54tw53") %>% 16 | setView( 17 | lng = 40, 18 | lat = 30.45, 19 | zoom = 3 20 | ) 21 | } 22 | }) 23 | 24 | output$map_wuhan <- renderLeaflet({ 25 | wuhan <- data.frame( 26 | lon = 114.283, 27 | lat = 30.583 28 | ) 29 | coords <- st_as_sf(wuhan, coords = c("lon", "lat"), crs = 4326) 30 | china <- countries[countries$ADMIN == "China", ] 31 | leaflet(options = leafletOptions( 32 | zoomControl = FALSE, minZoom = 4, maxZoom = 4, attributionControl = FALSE, 33 | dragging = FALSE 34 | )) %>% 35 | addPolylines( 36 | data = st_cast(st_as_sf(china), "MULTILINESTRING"), 37 | color = "#00bb8b", 38 | weight = 1 39 | ) %>% 40 | addPulseMarkers( 41 | lng = wuhan$lon, 42 | lat = wuhan$lat, 43 | icon = makePulseIcon(heartbeat = 0.5, color = "#fb5a19"), 44 | ) %>% 45 | setView( 46 | lat = wuhan$lat + 7, 47 | lng = wuhan$lon, 48 | zoom = 1 49 | ) 50 | }) 51 | 52 | 53 | output$map_emergency <- renderLeaflet({ 54 | leaflet(options = leafletOptions( 55 | zoomControl = FALSE, minZoom = 2, maxZoom = 2, 56 | dragging = FALSE, attributionControl = FALSE 57 | )) %>% 58 | addPolylines( 59 | data = st_cast(infected, "MULTILINESTRING"), 60 | color = "#00bb8b", 61 | weight = 1 62 | ) %>% 63 | addPulseMarkers( 64 | data = coords_inf, 65 | icon = makePulseIcon(heartbeat = 0.5, color = "#fb5a19", iconSize = 3) 66 | ) %>% 67 | setView( 68 | lat = 40, 69 | lng = 0, 70 | zoom = 2 71 | ) 72 | }) 73 | 74 | 75 | output$map_lockdown <- renderLeaflet({ 76 | leaflet(options = leafletOptions( 77 | zoomControl = FALSE, minZoom = 2, maxZoom = 2, 78 | dragging = FALSE, attributionControl = FALSE 79 | )) %>% 80 | addPolygons( 81 | data = st_as_sf(locked_countries), 82 | fillColor = ~ pal(lockdown), 83 | opacity = 1, 84 | fillOpacity = 0.25, 85 | weight = 1, 86 | color = "#FCFCFC", 87 | label = locked_countries$ADMIN 88 | ) %>% 89 | leaflet::addLegend( 90 | data = locked_countries, 91 | pal = pal, 92 | values = ~lockdown, 93 | title = "Lockdown status", 94 | position = "bottomleft" 95 | ) %>% 96 | setView( 97 | lat = 40, 98 | lng = 0, 99 | zoom = 2 100 | ) 101 | }) 102 | -------------------------------------------------------------------------------- /server/load_data.R: -------------------------------------------------------------------------------- 1 | # load johns hopkins data 2 | closeAllConnections() 3 | source(file.path("server/data_wrangling", "jhu.R"), local = TRUE) 4 | # load the country shapes 5 | countries_old <- data.table(read_sf("data/ne_50m_admin_0_countries.shp")) 6 | countries <- countries_old[, .( 7 | POP_EST = sum(POP_EST), 8 | ADMIN = unique(SOVEREIGNT), 9 | geometry = st_union(geometry) 10 | ), by = SOVEREIGNT] 11 | countries_old <- st_as_sf(countries_old, crs = 4326) 12 | # load data for highcharter plots 13 | source(file.path("server/data_wrangling", "highcharter_data.R"), local = TRUE) 14 | 15 | source(file.path("server/data_wrangling", "html_files.R"), local = TRUE) 16 | 17 | 18 | # load grouped data 19 | source(file.path("server/data_wrangling", "group_data.R"), local = TRUE) 20 | 21 | today <- daily_cases2[daily_cases2$date == max(daily_cases2$date), ] 22 | daily_cases2$geometry <- NULL 23 | 24 | # load top_15 data 25 | source(file.path("server/data_wrangling", "top_15.R"), local = TRUE) 26 | 27 | # load increase data 28 | source(file.path("server/data_wrangling", "increase_data.R"), local = TRUE) 29 | 30 | # load forecasting data 31 | source(file.path("server/data_wrangling", "forecasting.R"), local = TRUE) 32 | 33 | # load s&p 500 data 34 | source(file.path("server/data_wrangling", "s_n_p.R"), local = TRUE) 35 | 36 | # load lockdown data 37 | source(file.path("server/data_wrangling", "lockdown_data.R"), local = TRUE) 38 | aic <- read_sf("data/aichach.kml") 39 | # old: 2.24 40 | -------------------------------------------------------------------------------- /server/modal.R: -------------------------------------------------------------------------------- 1 | onclick( 2 | "chapter_sel", 3 | showModal( 4 | tags$div( 5 | id = "modal", 6 | modalDialog( 7 | # make it closable by pressing anywhere around it 8 | easyClose = TRUE, 9 | title = "Click on the chapter you want to go to", 10 | includeHTML("html_files/selector.html") 11 | ) 12 | ) 13 | ) 14 | ) -------------------------------------------------------------------------------- /server/observer.R: -------------------------------------------------------------------------------- 1 | observe(addScrollAnim(session, "hc1", "bounceInRight")) 2 | observe(addScrollAnim(session, "hc2", "bounceInRight")) 3 | observe(addScrollAnim(session, "hc3", "bounceInRight")) 4 | observe(addScrollAnim(session, "hc4", "bounceInRight")) 5 | observe(addScrollAnim(session, "hc5", "bounceInRight")) 6 | observe(addScrollAnim(session, "hc6", "bounceInRight")) 7 | observe(addScrollAnim(session, "hc7", "bounceInRight")) 8 | observe(addScrollAnim(session, "hc8", "bounceInRight")) 9 | observe(addScrollAnim(session, "hc9", "bounceInRight")) 10 | observe(addScrollAnim(session, "hc10", "bounceInRight")) 11 | observe(addScrollAnim(session, "hc11", "bounceInRight")) 12 | observe(addScrollAnim(session, "hc12", "bounceInRight")) 13 | observe(addScrollAnim(session, "hc13", "bounceInRight")) 14 | observe(addScrollAnim(session, "hc14", "bounceInRight")) 15 | observe(addScrollAnim(session, "hc15", "bounceInRight")) 16 | observe(addScrollAnim(session, "hc16", "bounceInRight")) 17 | observe(addScrollAnim(session, "hc17", "bounceInRight")) 18 | observe(addScrollAnim(session, "hc18", "bounceInRight")) 19 | observe(addScrollAnim(session, "hc19", "bounceInRight")) 20 | observe(addScrollAnim(session, "hc20", "bounceInRight")) 21 | observe(addScrollAnim(session, "hc21", "bounceInRight")) 22 | observe(addScrollAnim(session, "hc22", "bounceInRight")) 23 | observe(addScrollAnim(session, "hc23", "bounceInRight")) 24 | observe(addScrollAnim(session, "hc24", "bounceInRight")) 25 | observe(addScrollAnim(session, "lf1", "bounceInRight")) 26 | observe(addScrollAnim(session, "lf2", "bounceInRight")) 27 | observe(addScrollAnim(session, "lf3", "bounceInRight")) 28 | -------------------------------------------------------------------------------- /server/plotly_outputs.R: -------------------------------------------------------------------------------- 1 | # empty plotly without modebar 2 | output$everything_plot <- renderPlotly({ 3 | config(plotly_empty(), displayModeBar = FALSE) 4 | }) 5 | 6 | 7 | # empty plot with no modebar 8 | output$daily_plot_confirmed <- renderPlotly({ 9 | config(plotly_empty(), displayModeBar = FALSE) 10 | }) 11 | 12 | # empty plot with no modebar 13 | output$daily_plot_deaths <- renderPlotly({ 14 | config(plotly_empty(), displayModeBar = FALSE) 15 | }) 16 | -------------------------------------------------------------------------------- /server/reactive_events.R: -------------------------------------------------------------------------------- 1 | # get the country that was clicked 2 | get_country <- eventReactive(input$mymap_click, { 3 | # get the coordinates of the click 4 | coords <- data.frame(lng = input$mymap_click$lng, lat = input$mymap_click$lat) 5 | # coords <- data.frame(lng = 126.21, lat = 39.70) 6 | # turn into points 7 | coords <- st_as_sf(coords, coords = c("lng", "lat"), crs = 4326) 8 | # match with the country shapes 9 | country <- countries_old[unlist(st_intersects(coords, countries_old)), ] 10 | # either return the country or world 11 | if (nrow(country) == 0) { 12 | country <- "world" 13 | } else { 14 | country <- country$ADMIN 15 | if (country == "Palestine") { 16 | country <- "Israel" 17 | } 18 | } 19 | country 20 | }) 21 | 22 | # get the date 23 | get_date <- eventReactive(input$date, { 24 | input$date 25 | }) 26 | -------------------------------------------------------------------------------- /server/server.r: -------------------------------------------------------------------------------- 1 | observe(addScrollAnim(session, "hc1", "bounceInRight")) 2 | observe(addScrollAnim(session, "hc2", "bounceInRight")) 3 | observe(addScrollAnim(session, "hc3", "bounceInRight")) 4 | observe(addScrollAnim(session, "hc4", "bounceInRight")) 5 | observe(addScrollAnim(session, "hc5", "bounceInRight")) 6 | observe(addScrollAnim(session, "hc6", "bounceInRight")) 7 | observe(addScrollAnim(session, "hc7", "bounceInRight")) 8 | observe(addScrollAnim(session, "hc8", "bounceInRight")) 9 | observe(addScrollAnim(session, "hc9", "bounceInRight")) 10 | observe(addScrollAnim(session, "hc10", "bounceInRight")) 11 | observe(addScrollAnim(session, "hc11", "bounceInRight")) 12 | observe(addScrollAnim(session, "hc12", "bounceInRight")) 13 | observe(addScrollAnim(session, "hc13", "bounceInRight")) 14 | observe(addScrollAnim(session, "lf3", "bounceInRight")) 15 | -------------------------------------------------------------------------------- /server/text_outputs.R: -------------------------------------------------------------------------------- 1 | output$total_cases <- renderText({ 2 | a <- get_country() 3 | # display custom text based on what was clicked 4 | if (a != "world") { 5 | text <- paste("Coronavirus cases in ", a, ":", sep = "") 6 | } else { 7 | text <- "Worldwide Coronavirus cases:" 8 | } 9 | text 10 | }) 11 | 12 | # default text 13 | output$text_default <- renderText({ 14 | "Worldwide Coronavirus cases:" 15 | }) 16 | 17 | output$all_default <- renderText({ 18 | # get the daterange 19 | daterange <- get_date() 20 | # check if the first date changed 21 | check1 <- daterange[1] == (min(corona_sf$date) + 1) 22 | # check if the second date changed 23 | check2 <- daterange[2] == max(corona_sf$date) 24 | # calculate the number of cases 25 | if (all(c(check1, check2))) { 26 | paste( 27 | " confirmed:
", 28 | sum(corona_sf[corona_sf$date == max(corona_sf$date), ]$confirmed, 29 | na.rm = TRUE 30 | ) 31 | ) 32 | } else { 33 | daterange[1] <- daterange[1] - 1 34 | cases_beginning <- sum( 35 | corona_sf[corona_sf$date == daterange[1], ]$confirmed, 36 | na.rm = TRUE 37 | ) 38 | cases_end <- sum( 39 | corona_sf[corona_sf$date == daterange[2], ]$confirmed, 40 | na.rm = TRUE 41 | ) 42 | paste( 43 | " confirmed:
", cases_end - cases_beginning 44 | ) 45 | } 46 | }) 47 | 48 | output$all_country <- renderText({ 49 | # get the country 50 | country <- get_country() 51 | daterange <- input$date 52 | # calculate cases based on whether a country was clicked 53 | if (country != "world") { 54 | country_df <- st_as_sf(countries[countries$ADMIN == country, ], crs = 4326) 55 | corona_sf <- st_as_sf(corona_sf, crs = 4326) 56 | if (country == "Israel") { 57 | corona_frame <- corona_sf[corona_sf$`Country/Region` == "Israel", ] 58 | } else { 59 | corona_frame <- corona_sf[unlist(st_contains(country_df, corona_sf)), ] 60 | } 61 | if (country == "Italy") { 62 | corona_frame <- corona_frame[corona_frame$`Country/Region` == "Italy", ] 63 | } 64 | if (nrow(corona_frame) == 0) { 65 | corona_frame <- corona_sf[corona_sf$`Province/State` == country, ] 66 | } 67 | if (nrow(corona_frame) == 0) { 68 | corona_frame <- corona_sf[corona_sf$`Country/Region` == country, ] 69 | } 70 | if (nrow(corona_frame) == 0) { 71 | corona_frame <- corona_frame[seq_len(length(unique(corona_sf$date))), ] 72 | corona_frame$`Province/State` <- country 73 | corona_frame$`Country/Region` <- country 74 | corona_frame$confirmed <- 0 75 | corona_frame$deaths <- 0 76 | corona_frame$recovered <- 0 77 | corona_frame$date <- unique(corona_sf$date) 78 | corona_frame$geometry <- country_df$geometry 79 | } 80 | daterange[1] <- daterange[1] - 1 81 | cases_beginning <- sum( 82 | corona_frame[corona_frame$date == daterange[1], ]$confirmed, 83 | na.rm = TRUE 84 | ) 85 | cases_end <- sum( 86 | corona_frame[corona_frame$date == daterange[2], ]$confirmed, 87 | na.rm = TRUE 88 | ) 89 | paste( 90 | " confirmed:
", cases_end - cases_beginning 91 | ) 92 | } else { 93 | daterange[1] <- daterange[1] - 1 94 | cases_beginning <- sum( 95 | corona_sf[corona_sf$date == daterange[1], ]$confirmed, 96 | na.rm = TRUE 97 | ) 98 | cases_end <- sum( 99 | corona_sf[corona_sf$date == daterange[2], ]$confirmed, 100 | na.rm = TRUE 101 | ) 102 | paste( 103 | " confirmed:
", cases_end - cases_beginning 104 | ) 105 | } 106 | }) 107 | 108 | output$recovered_default <- renderText({ 109 | # get the daterange 110 | daterange <- get_date() 111 | # check if the first date changed 112 | check1 <- daterange[1] == (min(corona_sf$date) + 1) 113 | # check if the second date changed 114 | check2 <- daterange[2] == max(corona_sf$date) 115 | # calculate the number of cases 116 | if (all(c(check1, check2))) { 117 | paste( 118 | " recovered:
", 119 | sum(corona_sf[corona_sf$date == max(corona_sf$date), ]$recovered, 120 | na.rm = TRUE 121 | ) 122 | ) 123 | } else { 124 | daterange[1] <- daterange[1] - 1 125 | cases_beginning <- sum( 126 | corona_sf[corona_sf$date == daterange[1], ]$recovered, 127 | na.rm = TRUE 128 | ) 129 | cases_end <- sum( 130 | corona_sf[corona_sf$date == daterange[2], ]$recovered, 131 | na.rm = TRUE 132 | ) 133 | paste( 134 | " recovered:
", cases_end - cases_beginning 135 | ) 136 | } 137 | }) 138 | 139 | output$recovered_country <- renderText({ 140 | # get the country 141 | country <- get_country() 142 | daterange <- input$date 143 | # calculate cases based on whether a country was clicked 144 | if (country != "world") { 145 | country_df <- st_as_sf(countries[countries$ADMIN == country, ], crs = 4326) 146 | corona_sf <- st_as_sf(corona_sf, crs = 4326) 147 | if (country == "Israel") { 148 | corona_frame <- corona_sf[corona_sf$`Country/Region` == "Israel", ] 149 | } else { 150 | corona_frame <- corona_sf[unlist(st_contains(country_df, corona_sf)), ] 151 | } 152 | if (country == "Italy") { 153 | corona_frame <- corona_frame[corona_frame$`Country/Region` == "Italy", ] 154 | } 155 | if (nrow(corona_frame) == 0) { 156 | corona_frame <- corona_sf[corona_sf$`Province/State` == country, ] 157 | } 158 | if (nrow(corona_frame) == 0) { 159 | corona_frame <- corona_sf[corona_sf$`Country/Region` == country, ] 160 | } 161 | if (nrow(corona_frame) == 0) { 162 | corona_frame <- corona_frame[seq_len(length(unique(corona_sf$date))), ] 163 | corona_frame$`Province/State` <- country 164 | corona_frame$`Country/Region` <- country 165 | corona_frame$confirmed <- 0 166 | corona_frame$deaths <- 0 167 | corona_frame$recovered <- 0 168 | corona_frame$date <- unique(corona_sf$date) 169 | corona_frame$geometry <- country_df$geometry 170 | } 171 | daterange[1] <- daterange[1] - 1 172 | cases_beginning <- sum( 173 | corona_frame[corona_frame$date == daterange[1], ]$recovered, 174 | na.rm = TRUE 175 | ) 176 | cases_end <- sum( 177 | corona_frame[corona_frame$date == daterange[2], ]$recovered, 178 | na.rm = TRUE 179 | ) 180 | paste( 181 | " recovered:
", cases_end - cases_beginning 182 | ) 183 | } else { 184 | daterange[1] <- daterange[1] - 1 185 | cases_beginning <- sum( 186 | corona_sf[corona_sf$date == daterange[1], ]$recovered, 187 | na.rm = TRUE 188 | ) 189 | cases_end <- sum( 190 | corona_sf[corona_sf$date == daterange[2], ]$recovered, 191 | na.rm = TRUE 192 | ) 193 | paste( 194 | " recovered:
", cases_end - cases_beginning 195 | ) 196 | } 197 | }) 198 | 199 | 200 | 201 | output$death_default <- renderText({ 202 | # get the daterange 203 | daterange <- get_date() 204 | # check if the first date changed 205 | check1 <- daterange[1] == (min(corona_sf$date) + 1) 206 | # check if the second date changed 207 | check2 <- daterange[2] == max(corona_sf$date) 208 | # calculate the number of cases 209 | if (all(c(check1, check2))) { 210 | paste( 211 | " deceased:
", 212 | sum(corona_sf[corona_sf$date == max(corona_sf$date), ]$deaths, 213 | na.rm = TRUE 214 | ) 215 | ) 216 | } else { 217 | daterange[1] <- daterange[1] - 1 218 | cases_beginning <- sum( 219 | corona_sf[corona_sf$date == daterange[1], ]$deaths, 220 | na.rm = TRUE 221 | ) 222 | cases_end <- sum( 223 | corona_sf[corona_sf$date == daterange[2], ]$deaths, 224 | na.rm = TRUE 225 | ) 226 | paste(" deceased:
", cases_end - cases_beginning) 227 | } 228 | }) 229 | 230 | output$death_country <- renderText({ 231 | country <- get_country() 232 | daterange <- input$date 233 | # calculate the number of cases based on whether a country was clicked 234 | if (country != "world") { 235 | country_df <- st_as_sf(countries[countries$ADMIN == country, ], crs = 4326) 236 | corona_sf <- st_as_sf(corona_sf, crs = 4326) 237 | if (country == "Israel") { 238 | corona_frame <- corona_sf[corona_sf$`Country/Region` == "Israel", ] 239 | } else { 240 | corona_frame <- corona_sf[unlist(st_contains(country_df, corona_sf)), ] 241 | } 242 | if (country == "Italy") { 243 | corona_frame <- corona_frame[corona_frame$`Country/Region` == "Italy", ] 244 | } 245 | if (nrow(corona_frame) == 0) { 246 | corona_frame <- corona_sf[corona_sf$`Province/State` == country, ] 247 | } 248 | if (nrow(corona_frame) == 0) { 249 | corona_frame <- corona_sf[corona_sf$`Country/Region` == country, ] 250 | } 251 | if (nrow(corona_frame) == 0) { 252 | corona_frame <- corona_frame[seq_len(length(unique(corona_sf$date))), ] 253 | corona_frame$`Province/State` <- country 254 | corona_frame$`Country/Region` <- country 255 | corona_frame$confirmed <- 0 256 | corona_frame$deaths <- 0 257 | corona_frame$recovered <- 0 258 | corona_frame$date <- unique(corona_sf$date) 259 | corona_frame$geometry <- country_df$geometry 260 | } 261 | daterange[1] <- daterange[1] - 1 262 | cases_beginning <- sum( 263 | corona_frame[corona_frame$date == daterange[1], ]$deaths, 264 | na.rm = TRUE 265 | ) 266 | cases_end <- sum( 267 | corona_frame[corona_frame$date == daterange[2], ]$deaths, 268 | na.rm = TRUE 269 | ) 270 | paste(" deceased:
", cases_end - cases_beginning) 271 | } else { 272 | daterange[1] <- daterange[1] - 1 273 | cases_beginning <- sum( 274 | corona_sf[corona_sf$date == daterange[1], ]$deaths, 275 | na.rm = TRUE 276 | ) 277 | cases_end <- sum( 278 | corona_sf[corona_sf$date == daterange[2], ]$deaths, 279 | na.rm = TRUE 280 | ) 281 | paste(" deceased:
", cases_end - cases_beginning) 282 | } 283 | }) 284 | 285 | # default 286 | output$show_everything <- renderText({ 287 | "To show all cases, simply click anywhere in the ocean" 288 | }) 289 | -------------------------------------------------------------------------------- /server/ui_outputs.R: -------------------------------------------------------------------------------- 1 | 2 | # either show default text or click based 3 | output$total_cases_ui <- renderUI({ 4 | if (is.null(input$mymap_click)) { 5 | htmlOutput("text_default") 6 | } else { 7 | htmlOutput("total_cases") 8 | } 9 | }) 10 | 11 | 12 | # either show default text or click based 13 | output$cases_all_ui <- renderUI({ 14 | if (is.null(input$mymap_click)) { 15 | htmlOutput("all_default") 16 | } else { 17 | htmlOutput("all_country") 18 | } 19 | }) 20 | 21 | # either show default text or click based 22 | output$cases_recovered_ui <- renderUI({ 23 | if (is.null(input$mymap_click)) { 24 | htmlOutput("recovered_default") 25 | } else { 26 | htmlOutput("recovered_country") 27 | } 28 | }) 29 | 30 | 31 | # either show default text or click based 32 | output$cases_death_ui <- renderUI({ 33 | b <- get_date() 34 | if (is.null(input$mymap_click)) { 35 | htmlOutput("death_default") 36 | } else { 37 | htmlOutput("death_country") 38 | } 39 | }) 40 | 41 | 42 | # dateinput based on dates available 43 | output$date_ui <- renderUI({ 44 | airDatepickerInput( 45 | "date", "Date range:", 46 | range = TRUE, 47 | value = c(min(corona_sf$date) + 1, max(corona_sf$date)), 48 | minDate = min(corona_sf$date) + 1, 49 | maxDate = max(corona_sf$date), 50 | update_on = "close", 51 | autoClose = TRUE, 52 | todayButton = TRUE, 53 | width = "100%" 54 | ) 55 | }) 56 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | input[type="number"] { 2 | max-width: 80%; 3 | } 4 | 5 | div.outer { 6 | /*position: fixed;*/ 7 | top: 41px; 8 | left: 0; 9 | right: 0; 10 | bottom: 0; 11 | overflow: hidden; 12 | padding: 0; 13 | } 14 | 15 | /* Customize fonts */ 16 | body, label, input, button, select { 17 | font-family: 'Helvetica Neue', Helvetica; 18 | font-weight: 200; 19 | overflow-x:hidden !important; 20 | } 21 | h1, h2, h3, h4 { font-weight: 400; } 22 | 23 | #controls_panel { 24 | /* Appearance */ 25 | background-color: white; 26 | padding: 0 20px 20px 20px; 27 | cursor: move; 28 | /* Fade out while not hovering */ 29 | opacity: 1; 30 | zoom: 0.9; 31 | } 32 | 33 | /* Position and style citation */ 34 | #cite { 35 | position: absolute; 36 | bottom: 10px; 37 | left: 10px; 38 | font-size: 12px; 39 | } 40 | 41 | #mymap { 42 | font-size: 120px; 43 | } 44 | 45 | /* If not using map tiles, show a white background */ 46 | .leaflet-container { 47 | background-color: #161616 !important; 48 | } 49 | 50 | #total_cases, #text_default{ 51 | font-size: 1.5em; 52 | } 53 | 54 | #show_everything { 55 | font-size:1em; 56 | } 57 | 58 | #all_default, #all_country { 59 | font-size: 1.3em; 60 | background-color: rgba(52,84,209,0.5); 61 | text-align: center; 62 | border-radius: 20% 10% 20% 10%; 63 | } 64 | 65 | #recovered_default, #recovered_country { 66 | font-size: 1.3em; 67 | background-color: rgba(35,240,199,0.5); 68 | text-align: center; 69 | border-radius: 20% 10% 20% 10%; 70 | } 71 | 72 | #death_default, #death_country { 73 | font-size: 1.3em; 74 | background-color: rgba(237,37,78,0.5); 75 | text-align: center; 76 | border-radius: 20% 10% 20% 10%; 77 | } 78 | 79 | #date { 80 | text-align:left; 81 | } 82 | 83 | section.content { 84 | padding:0; 85 | } 86 | 87 | .container-fluid { 88 | padding-right:0px !important; 89 | padding-left:0px !important; 90 | } 91 | 92 | 93 | .story_1 { 94 | padding-top:70%; 95 | padding-bottom:80vh; 96 | background-color:#161616; 97 | font-family: 'Open Sans', sans-serif; 98 | font-size:3.8vh; 99 | color:#00bb8b; 100 | font-weight:bold; 101 | line-height:4.875vh; 102 | } 103 | 104 | .story_2 { 105 | padding-bottom:80vh; 106 | background-color:#161616; 107 | font-family: 'Open Sans', sans-serif; 108 | color:#00bb8b; 109 | font-size:3.8vh; 110 | font-weight:bold; 111 | line-height:4.875vh; 112 | } 113 | 114 | .story_3 { 115 | padding-bottom:80vh; 116 | background-color:#161616; 117 | font-family: 'Open Sans', sans-serif; 118 | color:#fb5a19; 119 | font-size:3.8vh; 120 | font-weight:bold; 121 | line-height:4.875vh; 122 | } 123 | 124 | .date_1 { 125 | padding-top:20%; 126 | background-color:#161616; 127 | padding-bottom: 3.4vh; 128 | font-family: 'Open Sans', sans-serif; 129 | font-size:2.2vh; 130 | color:#fb5a19; 131 | line-height:2.875vh; 132 | } 133 | 134 | .date_2 { 135 | background-color:#161616; 136 | padding-bottom: 3.4vh; 137 | font-family: 'Open Sans', sans-serif; 138 | font-size:2.2vh; 139 | color:#fb5a19; 140 | line-height:2.875vh; 141 | } 142 | 143 | .date_4 { 144 | background-color:#161616; 145 | padding-bottom: 3.2vh; 146 | font-family: 'Open Sans', sans-serif; 147 | font-size:2.2vh; 148 | color:#fb5a19; 149 | line-height:2.875vh; 150 | } 151 | 152 | .date_3 { 153 | padding-top:80vh; 154 | background-color:#161616; 155 | padding-bottom: 3.4vh; 156 | font-family: 'Open Sans', sans-serif; 157 | font-size:2.2vh; 158 | color:#fb5a19; 159 | line-height:2.875vh; 160 | } 161 | 162 | .title_big { 163 | /* padding-left:11vh;*/ 164 | text-align:right; 165 | padding-bottom:1%; 166 | background-color:#161616; 167 | font-family: 'Quicksand', sans-serif; 168 | font-weight:bold; 169 | font-size:3vw; 170 | color:#00bb8b; 171 | line-height:6.875vh; 172 | } 173 | 174 | 175 | .title_medium_1 { 176 | /* padding-left:99.15vh;*/ 177 | text-align:right; 178 | padding-bottom:8%; 179 | background-color:#161616; 180 | font-size:2.2vw; 181 | font-family: 'Quicksand', sans-serif; 182 | font-weight:bold; 183 | color:#00bb8b; 184 | line-height:4.875vh; 185 | } 186 | 187 | .title_wrapper_1 { 188 | width: 55.5815vw; 189 | margin-top:27vh; 190 | margin-bottom:18vh; 191 | margin-left: 5.8vw; 192 | } 193 | 194 | .title_wrapper_2 { 195 | width: 55.5815vw; 196 | margin-left: 5.8vw; 197 | margin-bottom:4vh; 198 | } 199 | 200 | 201 | .title_medium_2 { 202 | text-align:right; 203 | padding-bottom:8%; 204 | background-color:#161616; 205 | font-size:4.8vh; 206 | font-family: 'Quicksand', sans-serif; 207 | font-weight:bold; 208 | color:#00bb8b; 209 | line-height:4.875vh; 210 | } 211 | 212 | 213 | 214 | .title_small { 215 | background-color:#161616; 216 | padding-bottom:4vh; 217 | font-size:3vh; 218 | color:#00bb8b; 219 | font-family: 'Quicksand', sans-serif; 220 | font-weight:bold; 221 | line-height:4.875vh; 222 | } 223 | 224 | 225 | #tabset { 226 | border: 0px solid red; 227 | } 228 | 229 | a { 230 | text-decoration: none!important; 231 | padding-bottom:80vh; 232 | } 233 | 234 | a:hover { 235 | color: #006f52 !important; 236 | text-decoration: none; 237 | font-weight: none } 238 | 239 | 240 | .myBtn { 241 | position: fixed; /* Fixed/sticky position */ 242 | bottom: 3vh; /* Place the button at the bottom of the page */ 243 | right: 3vh; /* Place the button 30vh from the right */ 244 | z-index: 99; /* Make sure it does not overlap */ 245 | border: none; /* Remove borders */ 246 | outline: none; /* Remove outline */ 247 | background-color: #161616; /* Set a background color */ 248 | color: #00bb8b; /* Text color */ 249 | cursor: pointer; /* Add a mouse pointer on hover */ 250 | padding: 1vh; /* Some padding */ 251 | border-radius: 1vh; /* Rounded corners */ 252 | font-size: 2vh; /* Increase font size */ 253 | /*border:1px solid #00bb8b;*/ 254 | width: 6%; 255 | } 256 | 257 | .myBtn:hover { 258 | background-color: #00bb8b; 259 | color: #161616;/* Add a dark-grey background on hover */ 260 | } 261 | 262 | .github { 263 | position: fixed; /* Fixed/sticky position */ 264 | bottom: 17vh; /* Place the button at the bottom of the page */ 265 | right: 3vh; /* Place the button 30vh from the right */ 266 | z-index: 99; /* Make sure it does not overlap */ 267 | border: none; /* Remove borders */ 268 | outline: none; /* Remove outline */ 269 | background-color: #161616; /* Set a background color */ 270 | color: #00bb8b; /* Text color */ 271 | cursor: pointer; /* Add a mouse pointer on hover */ 272 | padding: 1vh; /* Some padding */ 273 | border-radius: 1vh; /* Rounded corners */ 274 | font-size: 2vh; /* Increase font size */ 275 | /*border:1px solid #00bb8b; */ 276 | width: 6%; 277 | } 278 | 279 | .github:hover { 280 | background-color: #00bb8b; 281 | color: #161616;/* Add a dark-grey background on hover */ 282 | } 283 | 284 | #chapter_sel { 285 | position: fixed; /* Fixed/sticky position */ 286 | bottom: 10vh; /* Place the button at the bottom of the page */ 287 | right: 3vh; /* Place the button 30vh from the right */ 288 | z-index: 99; /* Make sure it does not overlap */ 289 | border: none; /* Remove borders */ 290 | outline: none; /* Remove outline */ 291 | background-color: #161616; /* Set a background color */ 292 | color: #00bb8b; /* Text color */ 293 | cursor: pointer; /* Add a mouse pointer on hover */ 294 | padding: 1vh; /* Some padding */ 295 | border-radius: 1vh; /* Rounded corners */ 296 | font-size: 2vh; /* Increase font size */ 297 | /*border:1px solid #00bb8b; */ 298 | width: 6%; 299 | } 300 | 301 | #chapter_sel:hover { 302 | background-color: #00bb8b; 303 | color: #161616;/* Add a dark-grey background on hover */ 304 | } 305 | 306 | 307 | .final_1 { 308 | padding-top:15%; 309 | background-color:#161616; 310 | padding-bottom: 2%; 311 | font-family: 'Open Sans', sans-serif; 312 | font-size:2.2vh; 313 | color:#00bb8b; 314 | line-height:2.875vh; 315 | } 316 | 317 | .final_2 { 318 | padding-top:15%; 319 | background-color:#161616; 320 | padding-bottom: 40%; 321 | font-family: 'Open Sans', sans-serif; 322 | font-size:2.2vh; 323 | color:#00bb8b; 324 | line-height:2.875vh; 325 | } 326 | 327 | .wrapper_2 { 328 | padding-left:7.4vw; 329 | padding-bottom: 33.55vh; 330 | padding-top:1vh; 331 | 332 | } 333 | 334 | .wrapper_1 { 335 | margin-left: 5.15vw; 336 | } 337 | 338 | 339 | #lf1 { 340 | z-index: -1; 341 | position:relative; 342 | } 343 | 344 | #lf2 { 345 | z-index: -1; 346 | position:relative; 347 | } 348 | 349 | #lf3 { 350 | z-index: -1; 351 | position:relative; 352 | } 353 | 354 | 355 | 356 | .chapter_big { 357 | /* padding-left:11vh;*/ 358 | text-align:left; 359 | padding-bottom:1%; 360 | background-color:#161616; 361 | font-family: 'Quicksand', sans-serif; 362 | font-weight:bold; 363 | font-size:6.8vh; 364 | color:#00bb8b; 365 | line-height:6.875vh; 366 | } 367 | 368 | 369 | .chapter_medium { 370 | /* padding-left:99.15vh;*/ 371 | text-align:left; 372 | padding-bottom:8%; 373 | background-color:#161616; 374 | font-size:4.8vh; 375 | font-family: 'Quicksand', sans-serif; 376 | font-weight:bold; 377 | color:#00bb8b; 378 | line-height:4.875vh; 379 | } 380 | 381 | .chapter_wrapper_1 { 382 | width: 55.5815vw; 383 | margin-top:23vh; 384 | margin-bottom:18vh; 385 | margin-left: 5.8vw; 386 | } 387 | 388 | .chapter_wrapper_2 { 389 | width: 55.5815vw; 390 | margin-left: 5.8vw; 391 | margin-bottom:64vh; 392 | } 393 | 394 | .chapter_small { 395 | background-color:#161616; 396 | padding-bottom:4vh; 397 | font-size:3vh; 398 | color:#00bb8b; 399 | font-family: 'Quicksand', sans-serif; 400 | font-weight:bold; 401 | line-height:4.875vh; 402 | } 403 | 404 | 405 | .link_small { 406 | background-color:#161616; 407 | text-align: left; 408 | padding-bottom:4vh; 409 | font-size:1.4vh; 410 | color:#00bb8b !important; 411 | font-family: 'Quicksand', sans-serif; 412 | font-weight:bold; 413 | line-height:4.875vh; 414 | } 415 | 416 | .date_chapter { 417 | background-color:#161616; 418 | text-align:right; 419 | padding-bottom:4vh; 420 | font-size:1.4vh; 421 | color:#00bb8b; 422 | font-family: 'Quicksand', sans-serif; 423 | font-weight:bold; 424 | line-height:4.875vh; 425 | } 426 | 427 | #modal .modal-dialog{ 428 | margin-left:62vw; 429 | width:32vw; 430 | color:#00bb8b; 431 | font-family: 'Quicksand', sans-serif; 432 | font-weight:bold; 433 | } 434 | 435 | a:visited { 436 | color: #00bb8b; 437 | } 438 | a:active { 439 | color: #00bb8b; 440 | } 441 | a:link { 442 | color: #00bb8b; 443 | } 444 | 445 | 446 | div.modal-content { 447 | background-color: #161616; 448 | } 449 | 450 | #shiny-modal > div > div > div.modal-header > h4 { 451 | color:#00bb8b; 452 | font-weight:bold; 453 | font-size: 2.2vh; 454 | } 455 | 456 | #shiny-modal > div > div > div.modal-footer > button { 457 | border: none; /* Remove borders */ 458 | outline: none; /* Remove outline */ 459 | background-color: #161616; /* Set a background color */ 460 | color: #00bb8b; /* Text color */ 461 | cursor: pointer; /* Add a mouse pointer on hover */ 462 | padding: 1vh; /* Some padding */ 463 | border-radius: 1vh; /* Rounded corners */ 464 | font-size: 1.6vh; /* Increase font size */ 465 | font-family: 'Quicksand', sans-serif; 466 | /*border:1px solid #00bb8b; */ 467 | } 468 | 469 | 470 | #shiny-modal > div > div > div.modal-footer > button:hover { 471 | border: none; /* Remove borders */ 472 | outline: none; /* Remove outline */ 473 | background-color: #00bb8b; /* Set a background color */ 474 | color: #161616; /* Text color */ 475 | cursor: pointer; /* Add a mouse pointer on hover */ 476 | padding: 1vh; /* Some padding */ 477 | border-radius: 1vh; /* Rounded corners */ 478 | font-size: 1.6vh; /* Increase font size */ 479 | font-family: 'Quicksand', sans-serif; 480 | /*border:1px solid #00bb8b; */ 481 | } 482 | 483 | .clp_btn { 484 | float:right; 485 | color:#161616; 486 | border:none; 487 | outline: none; /* Remove outline */ 488 | background-color: white; /* Set a background color */ 489 | cursor: pointer; /* Add a mouse pointer on hover */ 490 | border-radius: 1vh; /* Rounded corners */ 491 | font-size: 1.8vh; /* Increase font size */ 492 | } 493 | 494 | .clp_btn:hover { 495 | background-color: #161616; 496 | color: white;/* Add a dark-grey background on hover */ 497 | } 498 | 499 | .mapboxgl-ctrl-logo { 500 | opacity: 0; 501 | } 502 | -------------------------------------------------------------------------------- /styles.scss: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Cabin); 2 | 3 | $colorBg: #121212; 4 | $colorOutline: #00bb8b; 5 | $colorOutlineFade: #006f52; 6 | 7 | $widthMouse: 31.2px; /*52 88 6 8 2 10 20 */ 8 | $heightMouse: 52.8px; 9 | $borderMouse: 3.6px; 10 | 11 | $posMouse: 8px; 12 | $posText: 2px; 13 | 14 | $sizeTrackball: 6px; 15 | $posTrackball: 12px; 16 | $shrinkTrackball: 0.4; 17 | 18 | $animDuration: 5s; 19 | 20 | @mixin bgGradient { 21 | background: 22 | $colorOutlineFade 23 | linear-gradient( 24 | transparent 0%, 25 | transparent 50%, 26 | $colorOutline 50%, 27 | $colorOutline 100% 28 | ); 29 | } 30 | 31 | p { 32 | margin-top: 0; 33 | font-family: "Cabin", sans-serif; 34 | letter-spacing: 12px; 35 | text-indent: 12px; 36 | color: $colorOutline; 37 | animation: 38 | colorText $animDuration ease-out infinite, 39 | nudgeText $animDuration ease-out infinite; 40 | } 41 | 42 | .mouse { 43 | @include bgGradient; 44 | position: relative; 45 | width: $widthMouse; 46 | height: $heightMouse; 47 | background-size: 100% 100%; 48 | border-radius: 100px; 49 | background-size: 225%; 50 | animation: 51 | colorSlide $animDuration linear infinite, 52 | nudgeMouse $animDuration ease-out infinite; 53 | &:before, 54 | &:after { 55 | content: ""; 56 | position: absolute; 57 | top: 0; right: 0; bottom: 0; left: 0; 58 | margin: auto; 59 | } 60 | &:before { 61 | width: $widthMouse - $borderMouse; 62 | height: $heightMouse - $borderMouse; 63 | background-color: $colorBg; 64 | border-radius: 100px; 65 | } 66 | &:after { 67 | background-color: $colorOutline; 68 | width: $sizeTrackball; 69 | height: $sizeTrackball; 70 | border-radius: 100%; 71 | animation: trackBallSlide $animDuration linear infinite; 72 | } 73 | } 74 | 75 | @keyframes colorSlide { 76 | 0% { background-position: 0% 100%; } 77 | 20% { background-position: 0% 0%; } 78 | 21% { background-color: $colorOutlineFade; } 79 | 29.99% { 80 | background-color: $colorOutline; 81 | background-position: 0% 0%; 82 | } 83 | 30% { 84 | background-color: $colorOutlineFade; 85 | background-position: 0% 100%; 86 | } 87 | 50% { background-position: 0% 0%; } 88 | 51% { background-color: $colorOutlineFade; } 89 | 59.99% { 90 | background-color: $colorOutline; 91 | background-position: 0% 0%; 92 | } 93 | 60% { 94 | background-color: $colorOutlineFade; 95 | background-position: 0% 100%; 96 | } 97 | 80% { background-position: 0% 0%; } 98 | 81% { background-color: $colorOutlineFade; } 99 | 89.99%, 100% { background-color: $colorOutline; } 100 | } 101 | 102 | @keyframes trackBallSlide { 103 | 0% { 104 | opacity: 1; 105 | transform: scale(1) translateY(-$posTrackball); 106 | } 107 | 6% { 108 | opacity: 1; 109 | transform: scale(0.9) translateY($posTrackball/4); 110 | } 111 | 14% { 112 | opacity: 0; 113 | transform: scale($shrinkTrackball) translateY($posTrackball*2); 114 | } 115 | 15%, 19% { 116 | opacity: 0; 117 | transform: scale($shrinkTrackball) translateY(-$posTrackball); 118 | } 119 | 28%, 29.99% { 120 | opacity: 1; 121 | transform: scale(1) translateY(-$posTrackball); 122 | } 123 | 30% { 124 | opacity: 1; 125 | transform: scale(1) translateY(-$posTrackball); 126 | } 127 | 36% { 128 | opacity: 1; 129 | transform: scale(0.9) translateY($posTrackball/4); 130 | } 131 | 44% { 132 | opacity: 0; 133 | transform: scale($shrinkTrackball) translateY($posTrackball*2); 134 | } 135 | 45%, 49% { 136 | opacity: 0; 137 | transform: scale($shrinkTrackball) translateY(-$posTrackball); 138 | } 139 | 58%, 59.99% { 140 | opacity: 1; 141 | transform: scale(1) translateY(-$posTrackball); 142 | } 143 | 60% { 144 | opacity: 1; 145 | transform: scale(1) translateY(-$posTrackball); 146 | } 147 | 66% { 148 | opacity: 1; 149 | transform: scale(0.9) translateY($posTrackball/4); 150 | } 151 | 74% { 152 | opacity: 0; 153 | transform: scale($shrinkTrackball) translateY($posTrackball*2); 154 | } 155 | 75%, 79% { 156 | opacity: 0; 157 | transform: scale($shrinkTrackball) translateY(-$posTrackball); 158 | } 159 | 88%, 100% { 160 | opacity: 1; 161 | transform: scale(1) translateY(-$posTrackball); 162 | } 163 | } 164 | 165 | @keyframes nudgeMouse { 166 | 0% { transform: translateY(0); } 167 | 20% { transform: translateY($posMouse); } 168 | 30% { transform: translateY(0); } 169 | 50% { transform: translateY($posMouse); } 170 | 60% { transform: translateY(0); } 171 | 80% { transform: translateY($posMouse); } 172 | 90% { transform: translateY(0); } 173 | } 174 | 175 | @keyframes nudgeText { 176 | 0% { transform: translateY(0); } 177 | 20% { transform: translateY($posText); } 178 | 30% { transform: translateY(0); } 179 | 50% { transform: translateY($posText); } 180 | 60% { transform: translateY(0); } 181 | 80% { transform: translateY($posText); } 182 | 90% { transform: translateY(0); } 183 | } 184 | 185 | @keyframes colorText { 186 | 21% { color: $colorOutlineFade; } 187 | 30% { color: $colorOutline; } 188 | 51% { color: $colorOutlineFade; } 189 | 60% { color: $colorOutline; } 190 | 81% { color: $colorOutlineFade; } 191 | 90% { color: $colorOutline; } 192 | } -------------------------------------------------------------------------------- /ui/ui.R: -------------------------------------------------------------------------------- 1 | spins <- list( 2 | spin_1(), 3 | spin_2(), 4 | spin_3(), 5 | spin_3circles(), 6 | spin_3k(), 7 | spin_4, 8 | spin_5, 9 | spin_6, 10 | spin_atebits(), 11 | spin_balance(), 12 | spin_ball(), 13 | spin_chasing_dots(), 14 | spin_circle(), 15 | spin_circle_square(), 16 | spin_circles(), 17 | spin_clock(), 18 | spin_cube_grid(), 19 | spin_dots(), 20 | spin_double_bounce(), 21 | spin_dual_circle(), 22 | spin_dual_ring(), 23 | spin_ellipsis(), 24 | spin_epic(), 25 | spin_facebook(), 26 | spin_fading_circles(), 27 | spin_fill(), 28 | spin_flower(), 29 | spin_flowers(), 30 | spin_folding_cube(), 31 | spin_gauge(), 32 | spin_google(), 33 | spin_half(), 34 | spin_heart(), 35 | spin_heartbeat(), 36 | spin_hexdots(), 37 | spin_hourglass(), 38 | spin_kit(), 39 | spin_loader(), 40 | spin_loaders(), 41 | spin_orbit(), 42 | spin_orbiter(), 43 | spin_pixel(), 44 | spin_plus(), 45 | spin_pong(), 46 | spin_pulsar(), 47 | spin_pulse(), 48 | spin_pushing_shapes(), 49 | spin_puzzle(), 50 | spin_refresh(), 51 | spin_rhombus(), 52 | spin_ring(), 53 | spin_ripple(), 54 | spin_rotate(), 55 | spin_rotating_plane(), 56 | spin_seven_circle(), 57 | spin_solar(), 58 | spin_square_circle(), 59 | spin_squares(), 60 | spin_terminal(), 61 | spin_three_bounce(), 62 | spin_throbber(), 63 | spin_timer(), 64 | spin_wandering_cubes(), 65 | spin_wave(), 66 | spin_whirly(), 67 | spin_wobblebar() 68 | ) 69 | set.seed(Sys.time()) 70 | spinner <- spins[[sample(1:66, 1)]] 71 | fluidPage( 72 | title = "Covid-19 Timeline", 73 | tags$head( 74 | tags$style( 75 | css 76 | ) 77 | ), 78 | tags$style( 79 | HTML(" 80 | .tabbable > .nav > li > a { 81 | background-color: #00bb8b; color:#161616; 82 | border:none; 83 | } 84 | .tabbable > .nav > li > a[data-value='Timeline of the outbreak'] { 85 | background-color: #161616; color:#00bb8b; 86 | border:none; 87 | } 88 | .tabbable > .nav > li > a[data-value='Worldwide cases'] { 89 | background-color: #161616; color:#00bb8b; 90 | border:none; 91 | } 92 | .tabbable > .nav > li[class=active] > a { 93 | background-color: #00bb8b; color:#161616; 94 | border:none; 95 | } 96 | ") 97 | ), 98 | withAnim(), 99 | use_waiter(), 100 | useShinyjs(), 101 | waiter_show_on_load(spinner, color = "#161616"), 102 | add_busy_bar(color = "#00bb8b"), 103 | tabsetPanel( 104 | id = "tabset", 105 | tabPanel( 106 | "Timeline of the outbreak", 107 | HTML(''), 108 | absolutePanel( 109 | draggable = FALSE, 110 | fixed = TRUE, 111 | top = 1200, 112 | left = 10, 113 | HTML( 114 | ' 116 | ' 118 | ), 119 | HTML(' 120 | '), 122 | HTML( 123 | '' 125 | ), 126 | style = "z-index: 420; border:1px solid red;" 127 | ), 128 | fluidRow( 129 | includeHTML("html_files/landing.html") 130 | ), 131 | fluidRow( 132 | column( 133 | width = 4 134 | ), 135 | column( 136 | width = 4, 137 | includeHTML("html_files/text_1.html") 138 | ) 139 | ), 140 | HTML(''), 141 | fluidRow( 142 | includeHTML("html_files/chapter1.html") 143 | ), 144 | fluidRow( 145 | column( 146 | width = 4 147 | ), 148 | column( 149 | width = 4, 150 | includeHTML("html_files/text_1_1.html") 151 | ) 152 | ), 153 | fluidRow( 154 | column( 155 | width = 3 156 | ), 157 | column( 158 | width = 6, 159 | div(id = "lf1", leafletOutput("map_wuhan", height = "80vh")) 160 | ) 161 | ), 162 | fluidRow( 163 | column( 164 | width = 4 165 | ), 166 | column( 167 | width = 4, 168 | includeHTML("html_files/text_2.html") 169 | ) 170 | ), 171 | HTML(''), 172 | fluidRow( 173 | includeHTML("html_files/chapter2.html") 174 | ), 175 | fluidRow( 176 | column( 177 | width = 4 178 | ), 179 | column( 180 | width = 4, 181 | includeHTML("html_files/text2_1.html") 182 | ) 183 | ), 184 | fluidRow( 185 | column( 186 | width = 2 187 | ), 188 | column( 189 | width = 8, 190 | div(id = "lf2", leafletOutput("map_emergency", height = "80vh")) 191 | ) 192 | ), 193 | fluidRow( 194 | column( 195 | width = 4 196 | ), 197 | column( 198 | width = 4, 199 | includeHTML("html_files/text_3.html") 200 | ) 201 | ), 202 | fluidRow( 203 | column( 204 | width = 3 205 | ), 206 | column( 207 | width = 6, 208 | div(id = "hc1", highchartOutput("highcharter_1", height = "65vh")) 209 | ) 210 | ), 211 | fluidRow( 212 | column( 213 | width = 4 214 | ), 215 | column( 216 | width = 4, 217 | includeHTML("html_files/text_4.html") 218 | ) 219 | ), 220 | fluidRow( 221 | column( 222 | width = 3 223 | ), 224 | column( 225 | width = 6, 226 | div(id = "hc2", highchartOutput("highcharter_2", height = "65vh")) 227 | ) 228 | ), 229 | fluidRow( 230 | column( 231 | width = 4 232 | ), 233 | column( 234 | width = 4, 235 | includeHTML("html_files/text_5.html") 236 | ) 237 | ), 238 | fluidRow( 239 | column( 240 | width = 3 241 | ), 242 | column( 243 | width = 6, 244 | div(id = "hc3", highchartOutput("highcharter_3", height = "65vh")) 245 | ) 246 | ), 247 | fluidRow( 248 | column( 249 | width = 4 250 | ), 251 | column( 252 | width = 4, 253 | includeHTML("html_files/text_6.html") 254 | ) 255 | ), 256 | fluidRow( 257 | column( 258 | width = 3 259 | ), 260 | column( 261 | width = 6, 262 | div(id = "hc4", highchartOutput("highcharter_4", height = "65vh")) 263 | ) 264 | ), 265 | fluidRow( 266 | column( 267 | width = 4 268 | ), 269 | column( 270 | width = 4, 271 | includeHTML("html_files/text_7.html") 272 | ) 273 | ), 274 | fluidRow( 275 | column( 276 | width = 3 277 | ), 278 | column( 279 | width = 6, 280 | div(id = "hc5", highchartOutput("highcharter_5", height = "65vh")) 281 | ) 282 | ), 283 | fluidRow( 284 | column( 285 | width = 4 286 | ), 287 | column( 288 | width = 4, 289 | includeHTML("html_files/text_8.html") 290 | ) 291 | ), 292 | HTML(''), 293 | fluidRow( 294 | includeHTML("html_files/chapter3.html") 295 | ), 296 | fluidRow( 297 | column( 298 | width = 4 299 | ), 300 | column( 301 | width = 4, 302 | includeHTML("html_files/text_8_1.html") 303 | ) 304 | ), 305 | fluidRow( 306 | column( 307 | width = 3 308 | ), 309 | column( 310 | width = 6, 311 | div(id = "hc6", highchartOutput("highcharter_6", height = "65vh")) 312 | ) 313 | ), 314 | fluidRow( 315 | column( 316 | width = 4 317 | ), 318 | column( 319 | width = 4, 320 | includeHTML("html_files/text_9.html") 321 | ) 322 | ), 323 | fluidRow( 324 | column( 325 | width = 3 326 | ), 327 | column( 328 | width = 6, 329 | div(id = "hc7", highchartOutput("highcharter_7", height = "65vh")) 330 | ) 331 | ), 332 | fluidRow( 333 | column( 334 | width = 4 335 | ), 336 | column( 337 | width = 4, 338 | includeHTML("html_files/text_10.html") 339 | ) 340 | ), 341 | fluidRow( 342 | column( 343 | width = 3 344 | ), 345 | column( 346 | width = 6, 347 | div(id = "hc14", highchartOutput("highcharter_14", height = "65vh")) 348 | ) 349 | ), 350 | fluidRow( 351 | column( 352 | width = 4 353 | ), 354 | column( 355 | width = 4, 356 | includeHTML("html_files/text_13.html") 357 | ) 358 | ), 359 | fluidRow( 360 | column( 361 | width = 4 362 | ), 363 | column( 364 | width = 4, 365 | includeHTML("html_files/today_1.html") 366 | ) 367 | ), 368 | fluidRow( 369 | column( 370 | width = 3 371 | ), 372 | column( 373 | width = 6, 374 | div(id = "hc8", highchartOutput("highcharter_8", height = "65vh")) 375 | ) 376 | ), 377 | fluidRow( 378 | column( 379 | width = 3 380 | ), 381 | column( 382 | width = 6, 383 | div(class = "story_2"), 384 | div(id = "hc9", highchartOutput("highcharter_9", height = "65vh")) 385 | ) 386 | ), 387 | fluidRow( 388 | column( 389 | width = 4 390 | ), 391 | column( 392 | width = 4, 393 | div(class = "date_3"), 394 | includeHTML("html_files/today_2.html") 395 | ) 396 | ), 397 | fluidRow( 398 | column( 399 | width = 3 400 | ), 401 | column( 402 | width = 6, 403 | div(id = "hc10", highchartOutput("highcharter_10", height = "65vh")) 404 | ) 405 | ), 406 | fluidRow( 407 | column( 408 | width = 3 409 | ), 410 | column( 411 | width = 6, 412 | div(class = "story_2"), 413 | div(id = "hc11", highchartOutput("highcharter_11", height = "65vh")) 414 | ) 415 | ), 416 | fluidRow( 417 | column( 418 | width = 4 419 | ), 420 | column( 421 | width = 4, 422 | div(class = "date_3"), 423 | includeHTML("html_files/today_3.html") 424 | ) 425 | ), 426 | fluidRow( 427 | column( 428 | width = 3 429 | ), 430 | column( 431 | width = 6, 432 | div(id = "hc12", highchartOutput("highcharter_12", height = "65vh")) 433 | ) 434 | ), 435 | fluidRow( 436 | column( 437 | width = 3 438 | ), 439 | column( 440 | width = 6, 441 | div(class = "story_2"), 442 | div(id = "hc13", highchartOutput("highcharter_13", height = "65vh")) 443 | ) 444 | ), 445 | fluidRow( 446 | column( 447 | width = 4 448 | ), 449 | column( 450 | width = 4, 451 | includeHTML("html_files/text_11.html") 452 | ) 453 | ), 454 | fluidRow( 455 | column( 456 | width = 3 457 | ), 458 | column( 459 | width = 6, 460 | div(id = "hc22", highchartOutput("highcharter_22", height = "65vh")) 461 | ) 462 | ), 463 | fluidRow( 464 | column( 465 | width = 4 466 | ), 467 | column( 468 | width = 4, 469 | includeHTML("html_files/text_12.html") 470 | ) 471 | ), 472 | fluidRow( 473 | column( 474 | width = 3 475 | ), 476 | column( 477 | width = 6, 478 | div(id = "hc23", highchartOutput("highcharter_23", height = "65vh")) 479 | ) 480 | ), 481 | fluidRow( 482 | column( 483 | width = 4 484 | ), 485 | column( 486 | width = 4, 487 | includeHTML("html_files/today.html") 488 | ) 489 | ), 490 | HTML(''), 491 | fluidRow( 492 | includeHTML("html_files/chapter4.html") 493 | ), 494 | fluidRow( 495 | column( 496 | width = 4 497 | ), 498 | column( 499 | width = 4, 500 | includeHTML("html_files/leaders_1.html") 501 | ) 502 | ), 503 | fluidRow( 504 | column( 505 | width = 3 506 | ), 507 | column( 508 | width = 6, 509 | div(id = "hc15", highchartOutput("highcharter_15", height = "65vh")) 510 | ) 511 | ), 512 | fluidRow( 513 | column( 514 | width = 4 515 | ), 516 | column( 517 | width = 4, 518 | includeHTML("html_files/leaders_2.html") 519 | ) 520 | ), 521 | fluidRow( 522 | column( 523 | width = 3 524 | ), 525 | column( 526 | width = 6, 527 | div(id = "hc16", highchartOutput("highcharter_16", height = "65vh")) 528 | ) 529 | ), 530 | fluidRow( 531 | column( 532 | width = 4 533 | ), 534 | column( 535 | width = 4, 536 | includeHTML("html_files/leaders_3.html") 537 | ) 538 | ), 539 | fluidRow( 540 | column( 541 | width = 3 542 | ), 543 | column( 544 | width = 6, 545 | div(id = "hc17", highchartOutput("highcharter_17", height = "65vh")) 546 | ) 547 | ), 548 | fluidRow( 549 | column( 550 | width = 4 551 | ), 552 | column( 553 | width = 4, 554 | includeHTML("html_files/leaders_4.html") 555 | ) 556 | ), 557 | fluidRow( 558 | column( 559 | width = 3 560 | ), 561 | column( 562 | width = 6, 563 | div(id = "hc18", highchartOutput("highcharter_18", height = "65vh")) 564 | ) 565 | ), 566 | fluidRow( 567 | column( 568 | width = 4 569 | ), 570 | column( 571 | width = 4, 572 | includeHTML("html_files/leaders_5.html") 573 | ) 574 | ), 575 | fluidRow( 576 | column( 577 | width = 3 578 | ), 579 | column( 580 | width = 6, 581 | div(id = "hc19", highchartOutput("highcharter_19", height = "65vh")) 582 | ) 583 | ), 584 | fluidRow( 585 | column( 586 | width = 4 587 | ), 588 | column( 589 | width = 4, 590 | includeHTML("html_files/leaders_6.html") 591 | ) 592 | ), 593 | fluidRow( 594 | column( 595 | width = 3 596 | ), 597 | column( 598 | width = 6, 599 | div(id = "hc20", highchartOutput("highcharter_20", height = "65vh")) 600 | ) 601 | ), 602 | fluidRow( 603 | column( 604 | width = 4 605 | ), 606 | column( 607 | width = 4, 608 | includeHTML("html_files/leaders_7.html") 609 | ) 610 | ), 611 | fluidRow( 612 | column( 613 | width = 3 614 | ), 615 | column( 616 | width = 6, 617 | div(id = "hc21", highchartOutput("highcharter_21", height = "65vh")) 618 | ) 619 | ), 620 | fluidRow( 621 | column( 622 | width = 4 623 | ), 624 | column( 625 | width = 4, 626 | includeHTML("html_files/leaders_8.html") 627 | ) 628 | ), 629 | HTML(''), 630 | fluidRow( 631 | includeHTML("html_files/chapter5.html") 632 | ), 633 | fluidRow( 634 | column( 635 | width = 4 636 | ), 637 | column( 638 | width = 4, 639 | includeHTML("html_files/lockdown1.html") 640 | ) 641 | ), 642 | fluidRow( 643 | column( 644 | width = 3 645 | ), 646 | column( 647 | width = 6, 648 | div(id = "lf3", leafletOutput("map_lockdown", height = "65vh")) 649 | ) 650 | ), 651 | fluidRow( 652 | column( 653 | width = 4 654 | ), 655 | column( 656 | width = 4, 657 | includeHTML("html_files/lockdown2.html") 658 | ) 659 | ), 660 | fluidRow( 661 | column( 662 | width = 3 663 | ), 664 | column( 665 | width = 6, 666 | div(id = "hc24", highchartOutput("highcharter_24", height = "80vh")) 667 | ) 668 | ), 669 | fluidRow( 670 | column( 671 | width = 4 672 | ), 673 | column( 674 | width = 4, 675 | includeHTML("html_files/lockdown3.html") 676 | ) 677 | ) 678 | ), 679 | tabPanel( 680 | "Worldwide cases", 681 | icon = icon("map"), 682 | tags$head( 683 | shiny::includeCSS("styles.css"), 684 | includeScript("gomap.js") 685 | ), 686 | use_googlefont("Oswald"), 687 | use_theme(create_theme( 688 | theme = "default", 689 | bs_vars_font( 690 | family_sans_serif = "'Oswald', cursive" 691 | ) 692 | )), 693 | leafletOutput( 694 | "mymap", 695 | width = "100%", 696 | height = "100vh" 697 | ), 698 | absolutePanel( 699 | id = "controls_panel", 700 | class = "panel panel-default", 701 | fixed = TRUE, 702 | draggable = TRUE, 703 | top = 40, 704 | left = "auto", 705 | right = 60, 706 | bottom = "auto", 707 | width = "18%", 708 | height = "auto", 709 | br(), 710 | HTML( 711 | '' 713 | ), 714 | tags$div(id = "demo", class = "collapse"), 715 | br(), 716 | h2( 717 | "SARS-CoV-2 Outbreak", 718 | style = "font-size:1.8em;" 719 | ), 720 | div( 721 | id = "panel_wrapper", class = "panel_wrapper collapse in", 722 | uiOutput("total_cases_ui"), 723 | br(), 724 | fluidRow( 725 | column( 726 | width = 4, 727 | uiOutput("cases_all_ui") 728 | ), 729 | column( 730 | width = 4, 731 | uiOutput("cases_recovered_ui") 732 | ), 733 | column( 734 | width = 4, 735 | htmlOutput("cases_death_ui") 736 | ) 737 | ), 738 | br(), 739 | htmlOutput("show_everything"), 740 | br(), 741 | uiOutput("date_ui"), 742 | h2( 743 | "Cumulative numbers:", 744 | style = "font-size:1.25em;" 745 | ), 746 | plotlyOutput("everything_plot", height = "12em"), 747 | h2( 748 | "Daily numbers:", 749 | style = "font-size:1.25em;" 750 | ), 751 | plotlyOutput("daily_plot_confirmed", height = "8em"), 752 | plotlyOutput("daily_plot_deaths", height = "8em"), 753 | br(), 754 | h2( 755 | "Created by Nico Hahn with data from Johns Hopkins University", 756 | style = "font-size:0.75em;" 757 | ), 758 | h2( 759 | "Works best in Firefox", 760 | style = "font-size:0.75em;" 761 | ) 762 | ), 763 | style = "z-index: 420;" 764 | ) 765 | ) 766 | ), 767 | setBackgroundColor("#161616") 768 | ) 769 | --------------------------------------------------------------------------------