├── preview.png
├── README.md
├── package.json
├── server.js
├── output
└── result.txt
├── odometer-theme-default.css
├── index.html
└── odometer.min.js
/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ergors/coronavirus-live-map/HEAD/preview.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Coronavirus live map
2 |
3 | 
4 |
5 | A simple map chart for coronavirus cases and deaths.
6 | For this applications I used geocharts from google and simple crawling with nodejs.
7 | I did this for studying web scraping in nodejs and Geocharts of google maps API.
8 | ## How run it?
9 | ### Dependencies
10 | ```
11 | - nodejs
12 | - cheerio
13 | - request
14 | ```
15 | ### Setup server
16 | After install dependencies you can simply run `node .` in project folder to download coronavirus data. Then you open the index.html in browser and edit `'mapsApiKey':` with your google API key.
17 |
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "coronavirusmap.github.io",
3 | "version": "1.0.0",
4 | "description": "Live map of coronavirus confirmed cases",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/ergoproxyDNS/coronavirusmap.github.io.git"
12 | },
13 | "keywords": [
14 | "coronavirus",
15 | "live",
16 | "map"
17 | ],
18 | "author": "Ergo",
19 | "license": "ISC",
20 | "bugs": {
21 | "url": "https://github.com/ergoproxyDNS/coronavirusmap.github.io/issues"
22 | },
23 | "homepage": "https://github.com/ergoproxyDNS/coronavirusmap.github.io#readme",
24 | "dependencies": {
25 | "cheerio": "^1.0.0-rc.3",
26 | "request": "^2.88.2"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const request = require('request');
2 | const cheerio = require('cheerio');
3 | const fs = require('fs');
4 | const path = require('path');
5 | const target = "https://www.worldometers.info/coronavirus/#countries";
6 |
7 |
8 | process.stdout.write("Downloading coronavirus status...\n");
9 | fs.readdir("output", (err, files) => {
10 | if (err) throw err;
11 | //limpar arquivos do diretorio
12 | for (const file of files) {
13 | fs.unlink(path.join("output", file), err => {
14 | if (err) throw err;
15 | });
16 | }
17 | });
18 | request(target, function(err, res, body){
19 | if (err) console.log("Ocorreu um erro " + err);
20 | var $ = cheerio.load(body);
21 | function GetResults(){
22 | console.log("Writing counter...");
23 | $(".maincounter-number span").each(function(i, elm) {
24 | let resultado = $(this).html().trim() + '\n';
25 | // 3 numbers
26 | // 1 -> total cases
27 | // 2 -> total deaths
28 | fs.appendFileSync("output/result.txt", resultado);
29 | });
30 | console.log("Writing country results...")
31 | $("tr td").each(function(i, elm) {
32 | let resultado = $(this).html().trim() + '\n';
33 | // 7 columns each country
34 | // 1 -> country name
35 | // 2 -> total cases
36 | fs.appendFileSync("output/result.txt", resultado);
37 | });
38 | }
39 | GetResults();
40 |
41 | });
42 |
43 |
--------------------------------------------------------------------------------
/output/result.txt:
--------------------------------------------------------------------------------
1 | 65,247
2 | 1,491
3 | 7,099
4 | China
5 | 64,658
6 | +4,854
7 | 1,488
8 | +123
9 | 7,014
10 | 10,584
11 | Asia
12 | Japan
13 | 252
14 | +50
15 | 1
16 | +1
17 | 10
18 | 5
19 | Asia
20 | Singapore
21 | 58
22 | +8
23 |
24 |
25 | 15
26 | 8
27 | Asia
28 | Hong Kong
29 | 53
30 | +3
31 | 1
32 |
33 | 1
34 | 2
35 | Asia
36 | Thailand
37 | 33
38 |
39 |
40 |
41 | 12
42 | 1
43 | Asia
44 | S. Korea
45 | 28
46 |
47 |
48 |
49 | 7
50 |
51 | Asia
52 | Malaysia
53 | 19
54 | +1
55 |
56 |
57 | 3
58 |
59 | Asia
60 | Taiwan
61 | 18
62 |
63 |
64 |
65 | 1
66 |
67 | Asia
68 | Vietnam
69 | 16
70 | +1
71 |
72 |
73 | 7
74 |
75 | Asia
76 | Germany
77 | 16
78 |
79 |
80 |
81 | 1
82 |
83 | Europe
84 | Australia
85 | 15
86 |
87 |
88 |
89 | 8
90 |
91 | Oceania
92 | USA
93 | 15
94 | +2
95 |
96 |
97 | 3
98 |
99 | N.America
100 | France
101 | 11
102 |
103 |
104 |
105 | 2
106 | 1
107 | Europe
108 | Macao
109 | 10
110 |
111 |
112 |
113 | 3
114 |
115 | Asia
116 | U.K.
117 | 9
118 |
119 |
120 |
121 | 1
122 |
123 | Europe
124 | U.A.E.
125 | 8
126 |
127 |
128 |
129 | 1
130 | 1
131 | Asia
132 | Canada
133 | 7
134 |
135 |
136 |
137 | 1
138 |
139 | N.America
140 | India
141 | 5
142 | +2
143 |
144 |
145 | 1
146 |
147 | Asia
148 | Philippines
149 | 3
150 |
151 | 1
152 |
153 | 2
154 |
155 | Asia
156 | Italy
157 | 3
158 |
159 |
160 |
161 |
162 | 2
163 | Europe
164 | Russia
165 | 2
166 |
167 |
168 |
169 | 2
170 |
171 | Europe
172 | Spain
173 | 2
174 |
175 |
176 |
177 |
178 |
179 | Europe
180 | Sweden
181 | 1
182 |
183 |
184 |
185 |
186 |
187 | Europe
188 | Nepal
189 | 1
190 |
191 |
192 |
193 | 1
194 |
195 | Asia
196 | Sri Lanka
197 | 1
198 |
199 |
200 |
201 | 1
202 |
203 | Asia
204 | Finland
205 | 1
206 |
207 |
208 |
209 | 1
210 |
211 | Europe
212 | Cambodia
213 | 1
214 |
215 |
216 |
217 | 1
218 |
219 | Asia
220 | Belgium
221 | 1
222 |
223 |
224 |
225 |
226 |
227 | Europe
228 |
--------------------------------------------------------------------------------
/odometer-theme-default.css:
--------------------------------------------------------------------------------
1 | .odometer.odometer-auto-theme, .odometer.odometer-theme-default {
2 | display: inline-block;
3 | vertical-align: middle;
4 | *vertical-align: auto;
5 | *zoom: 1;
6 | *display: inline;
7 | position: relative;
8 | }
9 | .odometer.odometer-auto-theme .odometer-digit, .odometer.odometer-theme-default .odometer-digit {
10 | display: inline-block;
11 | vertical-align: middle;
12 | *vertical-align: auto;
13 | *zoom: 1;
14 | *display: inline;
15 | position: relative;
16 | }
17 | .odometer.odometer-auto-theme .odometer-digit .odometer-digit-spacer, .odometer.odometer-theme-default .odometer-digit .odometer-digit-spacer {
18 | display: inline-block;
19 | vertical-align: middle;
20 | *vertical-align: auto;
21 | *zoom: 1;
22 | *display: inline;
23 | visibility: hidden;
24 | }
25 | .odometer.odometer-auto-theme .odometer-digit .odometer-digit-inner, .odometer.odometer-theme-default .odometer-digit .odometer-digit-inner {
26 | text-align: left;
27 | display: block;
28 | position: absolute;
29 | top: 0;
30 | left: 0;
31 | right: 0;
32 | bottom: 0;
33 | overflow: hidden;
34 | }
35 | .odometer.odometer-auto-theme .odometer-digit .odometer-ribbon, .odometer.odometer-theme-default .odometer-digit .odometer-ribbon {
36 | display: block;
37 | }
38 | .odometer.odometer-auto-theme .odometer-digit .odometer-ribbon-inner, .odometer.odometer-theme-default .odometer-digit .odometer-ribbon-inner {
39 | display: block;
40 | -webkit-backface-visibility: hidden;
41 | }
42 | .odometer.odometer-auto-theme .odometer-digit .odometer-value, .odometer.odometer-theme-default .odometer-digit .odometer-value {
43 | display: block;
44 | -webkit-transform: translateZ(0);
45 | }
46 | .odometer.odometer-auto-theme .odometer-digit .odometer-value.odometer-last-value, .odometer.odometer-theme-default .odometer-digit .odometer-value.odometer-last-value {
47 | position: absolute;
48 | }
49 | .odometer.odometer-auto-theme.odometer-animating-up .odometer-ribbon-inner, .odometer.odometer-theme-default.odometer-animating-up .odometer-ribbon-inner {
50 | -webkit-transition: -webkit-transform 2s;
51 | -moz-transition: -moz-transform 2s;
52 | -ms-transition: -ms-transform 2s;
53 | -o-transition: -o-transform 2s;
54 | transition: transform 2s;
55 | }
56 | .odometer.odometer-auto-theme.odometer-animating-up.odometer-animating .odometer-ribbon-inner, .odometer.odometer-theme-default.odometer-animating-up.odometer-animating .odometer-ribbon-inner {
57 | -webkit-transform: translateY(-100%);
58 | -moz-transform: translateY(-100%);
59 | -ms-transform: translateY(-100%);
60 | -o-transform: translateY(-100%);
61 | transform: translateY(-100%);
62 | }
63 | .odometer.odometer-auto-theme.odometer-animating-down .odometer-ribbon-inner, .odometer.odometer-theme-default.odometer-animating-down .odometer-ribbon-inner {
64 | -webkit-transform: translateY(-100%);
65 | -moz-transform: translateY(-100%);
66 | -ms-transform: translateY(-100%);
67 | -o-transform: translateY(-100%);
68 | transform: translateY(-100%);
69 | }
70 | .odometer.odometer-auto-theme.odometer-animating-down.odometer-animating .odometer-ribbon-inner, .odometer.odometer-theme-default.odometer-animating-down.odometer-animating .odometer-ribbon-inner {
71 | -webkit-transition: -webkit-transform 2s;
72 | -moz-transition: -moz-transform 2s;
73 | -ms-transition: -ms-transform 2s;
74 | -o-transition: -o-transform 2s;
75 | transition: transform 2s;
76 | -webkit-transform: translateY(0);
77 | -moz-transform: translateY(0);
78 | -ms-transform: translateY(0);
79 | -o-transform: translateY(0);
80 | transform: translateY(0);
81 | }
82 |
83 | .odometer.odometer-auto-theme, .odometer.odometer-theme-default {
84 | font-family: "Helvetica Neue", sans-serif;
85 | line-height: 1.1em;
86 | }
87 | .odometer.odometer-auto-theme .odometer-value, .odometer.odometer-theme-default .odometer-value {
88 | text-align: center;
89 | }
90 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Total Cases:
73 |😷
75 |Total Deaths:
81 |💀
83 |