index.html 21.4 KB
Newer Older
1
2
<html>
    <head>
3
        <meta charset="utf-8"/>
4
        <title>Scary COVID-19 Data</title>
Michał Woźniak's avatar
fix    
Michał Woźniak committed
5
        <script src="./wtf_wikipedia-client.min.js"></script>
Michał Woźniak's avatar
charts!    
Michał Woźniak committed
6
        <script src="./Chart.bundle.min.js"></script>
Michał Woźniak's avatar
fix    
Michał Woźniak committed
7
        <script src="./covid.js"></script>
Michał Woźniak's avatar
Michał Woźniak committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        <style>
            @font-face {
                font-family: "Play Regular";
                src: url(./Play/Play-Regular.ttf);
            }
            @font-face {
                font-family: "Play Bold";
                src: url(./Play/Play-Bold.ttf);
            }
            body {
                background: #444;
                color: springgreen;
                font-family: "Play Regular";
                padding:0px;
                margin:0px;
                font-size: 16pt;
Michał Woźniak's avatar
Michał Woźniak committed
24
25
26
                display: flex;
                flex-direction: column;
                min-height:100vh;
Michał Woźniak's avatar
Michał Woźniak committed
27
28
29
30
31
32
33
34
35
36
            }
            body > * {
                padding-left:5vw;
                padding-right:5vw;
            }
            body > * > * {
                text-shadow: none;
            }
            h1 {
                text-align:center;
Michał Woźniak's avatar
Michał Woźniak committed
37
38
39
40
41
42
                padding-top:2em;
                padding-bottom:0.7em;
                font-family: "Play Regular";
                font-weight: normal;
                font-size: 260%;
                text-shadow:-1px -1px 1px black, 1px 1px 0px #888;
Michał Woźniak's avatar
Michał Woźniak committed
43
            }
Michał Woźniak's avatar
Michał Woźniak committed
44
            h2, h3, h4, h5, h6, h7, strong {
Michał Woźniak's avatar
Michał Woźniak committed
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
                font-family: "Play Bold";
            }
            a {
                color: yellow;
            }
            
            #covid-stats {
                display: grid;
                grid-auto-flow: column;
                background: springgreen;
                color: #444;
            }
            #covid-stats > * {
                margin:0em;
                padding:0.5em;
                display: grid;
            }
            #covid-stats .value {
                font-weight: bold;
                font-family: "Play Bold";
Michał Woźniak's avatar
Michał Woźniak committed
65
                align-self: end;
Michał Woźniak's avatar
Michał Woźniak committed
66
            }
Michał Woźniak's avatar
Michał Woźniak committed
67
            #covid-stats h2,
68
            .site-data-container h2 {
Michał Woźniak's avatar
Michał Woźniak committed
69
70
71
72
73
                font-size: 140%;
                font-family: "Play Regular";
                font-weight: bold;
                text-transform: uppercase;
            }
Michał Woźniak's avatar
Michał Woźniak committed
74
75
            #covid-stats h2 {
                color: #444;
Michał Woźniak's avatar
Michał Woźniak committed
76
                opacity: 0.4;
Michał Woźniak's avatar
Michał Woźniak committed
77
78
            }
            .sources {
Michał Woźniak's avatar
Michał Woźniak committed
79
80
81
82
83
84
                font-size: 80%;
                font-style: italic;
                margin-top: 0.4em;
                text-align: right;
                opacity: 0.5;
            }
85
            .site-data {
Michał Woźniak's avatar
Michał Woźniak committed
86
                display: grid;
Michał Woźniak's avatar
Michał Woźniak committed
87
                grid-template-columns: auto auto auto;
Michał Woźniak's avatar
Michał Woźniak committed
88
89
                grid-template-rows: auto auto auto;
                grid-template-areas: 
Michał Woźniak's avatar
Michał Woźniak committed
90
91
92
                    "auto auto auto"
                    "auto auto auto"
                    "sources sources sources";
Michał Woźniak's avatar
Michał Woźniak committed
93
94
95
                grid-auto-flow: row;
                padding-top:1em;
                padding-bottom:1em;
Michał Woźniak's avatar
Michał Woźniak committed
96
            }
97
            .site-data > * {
Michał Woźniak's avatar
Michał Woźniak committed
98
                display: grid;
Michał Woźniak's avatar
Michał Woźniak committed
99
100
101
                margin:0px;
                padding:0.5em;
            }
102
            .site-data > h2 {
Michał Woźniak's avatar
Michał Woźniak committed
103
104
                grid-area: header;
            }
105
            .site-data > .sources {
Michał Woźniak's avatar
Michał Woźniak committed
106
                grid-area: sources;
Michał Woźniak's avatar
Michał Woźniak committed
107
            }
108
            .site-data > * .value {
Michał Woźniak's avatar
Michał Woźniak committed
109
110
111
                font-weight: bold;
                font-family: "Play Bold";
            }
112
            #sites-data-container {
Michał Woźniak's avatar
Michał Woźniak committed
113
                flex-grow:1;
114
115
116
117
118
119
120
                display: flex;
                flex-direction: row;
                align-items:flex-start;
                justify-content: center;
                flex-wrap: wrap;
            }
            #sites-data-container .site-data-container {
Michał Woźniak's avatar
Michał Woźniak committed
121
                display: flex;
Michał Woźniak's avatar
Michał Woźniak committed
122
                flex-direction: column;
123
124
                align-items:center;
                width:23em;
Michał Woźniak's avatar
Michał Woźniak committed
125
            }
Michał Woźniak's avatar
Michał Woźniak committed
126
127
128
129
130
131
132
133
            footer {
                font-size: 70%;
                text-align:center;
                opacity:0.8;
                line-height:150%;
                font-family: Monospace;
                background: black;
            }
134
            .site-data-container .sites-select {
Michał Woźniak's avatar
Michał Woźniak committed
135
136
137
138
139
140
141
142
143
144
                display: inline;
                -moz-appearance: none;
                -webkit-appearance: none;
                appearance: none;
                border:dotted 1px springgreen;
                padding:0.25em;
                background:none;
                color:springgreen;
                font-family: inherit;
                font-size:inherit;
145
                min-width:15em;
Michał Woźniak's avatar
Michał Woźniak committed
146
            }
147
            .site-data-container .sites-select option {
148
149
                font-size:70%;
            }
150
            .site-data-container h2 {
Michał Woźniak's avatar
Michał Woźniak committed
151
152
                position:relative;
            }
153
            .site-data-container h2::after {
Michał Woźniak's avatar
Michał Woźniak committed
154
155
156
157
158
159
160
                position:absolute;
                right:0.5em;
                top:0.25em;
                content: "▾";
                display: block;
                color: springgreen;
            }
161
            #site-menu-control-container,
162
            #add-site-container {
163
                width:0px;
164
            }
165
            #site-menu-control-container > *,
166
            #add-site-container > a {
167
168
169
170
                font-size: 250%;
                text-decoration: none;
                border: dotted 1px springgreen;
                width: 1em;
171
                height: 0.97em;
172
173
174
175
176
                line-height: 90%;
                outline:none;
                text-align: Center;
                margin-top: 0.47em;
                color: springgreen;
177
                display: none;
Michał Woźniak's avatar
Michał Woźniak committed
178
179
180
            }
            #add-site.visible {
                display: inline-block;
181
            }
Michał Woźniak's avatar
Michał Woźniak committed
182
            .site-data-container:nth-of-type(7) + #add-site-container > #add-site {
Michał Woźniak's avatar
Michał Woźniak committed
183
184
                display:none;
            }
Michał Woźniak's avatar
Michał Woźniak committed
185
            .site-data-container:nth-of-type(3) ~ #add-site-container > #remove-site {
186
187
                display:inline-block;
            }
188
            #site-menu-control-container #site-menu-control {
Michał Woźniak's avatar
Michał Woźniak committed
189
190
191
192
                display: inline-block;
                margin-left: -1em;
                line-height: 78%;
            }
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
            #site-menu-control-container input[type=checkbox][name=menu-shown]:checked ~ #site-menu-control {
                background:springgreen;
                color:black;
            }
            
            #site-menu-control-container .site-menu-container {
                display:none;
                min-width: 18.95em;
                height: 13em;
                background:black;
                position: relative;
                z-index: 10;
                left: 1em;
                top: -3em;
                font-size: 100%;
                margin-bottom: -15em;
                padding:1em;
                color:springgreen;
                flex-direction:column;
            }
            #site-menu-control-container .site-menu-container .spacer {
                flex-grow:1;
            }
            #site-menu-control-container .site-menu-container p {
                text-align:left;
                font-size:90%;
            }
            #site-menu-control-container .site-menu-container p:first-child {
                margin-top:0px;
            }
            #site-menu-control-container input[type=checkbox][name=menu-shown]:checked ~ .site-menu-container {
                display: flex;
            }
            .site-menu-container input {
                padding: 0.5em;
                border-radius: 0.2em;
                background: #444;
                box-shadow: 0px 0px 2px #555;
                border: none;
                color: springgreen;
                margin-top: 0.3em;
                -moz-appearance: none;
                -webkit-appearance: none;
                appearance: none;
                font-family: "Play Regular";
                font-size: 80%;
                text-align: center;
                font-variant: all-small-caps;
                transition:background-color 0.5s, color 0.5s;
            }
            .site-menu-container input:hover {
                background: springgreen;
                color: black;
                box-shadow: 0px 0px 2px springgreen;
            }
            
Michał Woźniak's avatar
Michał Woźniak committed
249
            #the-chart-container {
250
251
                height:80vh;
                min-height:600px;
Michał Woźniak's avatar
Michał Woźniak committed
252
253
254
                background: #333;
                padding-top: 1em;
                padding-bottom: 1em;
Michał Woźniak's avatar
Michał Woźniak committed
255
            }
Michał Woźniak's avatar
charts!    
Michał Woźniak committed
256
            #the-chart {
Michał Woźniak's avatar
Michał Woźniak committed
257
                display:block;
Michał Woźniak's avatar
charts!    
Michał Woźniak committed
258
            }
259
260
261
            #disclaimers-container {
                font-size:80%;
            }
262
263
264
265
266
            .chart-config-container {
                margin-top:1em;
                display:flex;
                justify-content: center;
                font-size:80%;
267
                flex-wrap: wrap;
268
269
270
            }
            .chart-config-container input {
                display:none;
271
272
273
274
275
276
277
278
279
280
            }
            .chart-config-container label input {
                display:inline-block;
                background:none;
                border:none;
                font-weight: bold;
                color:springgreen;
            }
            .chart-config-container label input[type=date] {
                
281
282
283
284
285
286
287
            }
            .chart-config-container label {
                padding: 0.5em;
                border-radius:0.2em;
                background:#404040;
                box-shadow: inset 0px 0px 2px #333;
            }
288
289
290
            /*
             * chart controls mechanics
             */
291
292
293
            .chart-config-container input#chart-data-confirmed:checked ~ .chart-config-group label[for=chart-data-confirmed],
            .chart-config-container input#chart-data-recovered:checked ~ .chart-config-group label[for=chart-data-recovered],
            .chart-config-container input#chart-data-deaths:checked ~ .chart-config-group label[for=chart-data-deaths],
Michał Woźniak's avatar
Michał Woźniak committed
294
            .chart-config-container input#chart-data-active:checked ~ .chart-config-group label[for=chart-data-active],
295
296
297
298
299
300
            .chart-config-container input#chart-type-logarithmic:checked ~ .chart-config-group label[for=chart-type-logarithmic],
            .chart-config-container input#chart-type-linear:checked ~ .chart-config-group label[for=chart-type-linear],
            .chart-config-container input#chart-cases-cumulative:checked ~ .chart-config-group label[for=chart-cases-cumulative],
            .chart-config-container input#chart-cases-new:checked ~ .chart-config-group label[for=chart-cases-new],
            .chart-config-container input#chart-values-absolute:checked ~ .chart-config-group label[for=chart-values-absolute],
            .chart-config-container input#chart-values-per-million:checked ~ .chart-config-group label[for=chart-values-per-million],
301
            .chart-config-container input#chart-start-date:checked ~ .chart-config-group label[for=chart-start-date],
302
303
304
305
            .chart-config-container input#chart-start-first:checked ~ .chart-config-group label[for=chart-start-first],
            .chart-config-container input#chart-start-tenth:checked ~ .chart-config-group label[for=chart-start-tenth],
            .chart-config-container input#chart-start-hundredth:checked ~ .chart-config-group label[for=chart-start-hundredth],
            .chart-config-container input#chart-start-thousandth:checked ~ .chart-config-group label[for=chart-start-thousandth] {
306
307
308
309
                background:springgreen;
                color:black;
                box-shadow: 0px 0px 2px springgreen;
            }
310
311
312
            .chart-config-container input#chart-start-date:checked ~ .chart-config-group label[for=chart-start-date] > input {
                color:black;
            }
313
314
315
            .chart-config-group {
                display:flex;
                justify-content: center;
316
317
318
319
320
                margin:0.5em 1em;
            }
            .chart-config-group > p {
                margin:0em;
                padding:0.5em;
321
            }
322
323
324
            .chart-config-group .per-million,
            .chart-config-group .data-confirmed,
            .chart-config-group .data-recovered,
Michał Woźniak's avatar
Michał Woźniak committed
325
326
            .chart-config-group .data-deaths,
            .chart-config-group .data-active {
327
328
                display:none;
            }
329
330
331
            .chart-config-container input#chart-values-per-million:checked ~ .chart-config-group .per-million,
            .chart-config-container input#chart-data-confirmed:checked ~ .chart-config-group .data-confirmed,
            .chart-config-container input#chart-data-recovered:checked ~ .chart-config-group .data-recovered,
Michał Woźniak's avatar
Michał Woźniak committed
332
333
            .chart-config-container input#chart-data-deaths:checked ~ .chart-config-group .data-deaths,
            .chart-config-container input#chart-data-active:checked ~ .chart-config-group .data-active {
334
335
                display:inline;
            }
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
            .chart-config-group.chart-average {
                display:none;
            }
            .chart-config-container input#chart-cases-new:checked ~ .chart-config-group.chart-average {
                display:flex;
            }
            .chart-config-container #chart-average {
                display: inline;
                -webkit-appearance: none;
                -moz-appearance: none;
                appearance: none;
                color:springgreen;
                width: 4em;
                text-align: center;
                padding: 0.5em;
                border: none;
                border-radius:0.2em;
                background:#404040;
                box-shadow: inset 0px 0px 2px #333;
                font-weight:bold;
            }
357
358
359
360
            .chart-config-container .break {
                flex-basis: 100%;
                height: 0;
            }
Michał Woźniak's avatar
Michał Woźniak committed
361
        </style>
362
363
    </head>
    <body>
364
365
366
367
368
369
370
371
        <h1>Scary COVID-19 data</h1>
        <div id="covid-stats">
            <h2>Global stats</h2>
            <div id="confirmed"><span class="label">Confirmed cases:</span> <span class="value"></span></div>
            <div id="deaths"><span class="label">Deaths:</span> <span class="value"></span></div>
            <div id="recovered"><span class="label">Recovered:</span> <span class="value"></span></div>
            <div id="mortality"><span class="label">Mortality rate:</span> <span class="value"></span></div>
        </div>
372
        <div class="sources"><a href="https://github.com/CSSEGISandData/COVID-19">source</a></div>
373
        <div id="sites-data-container">
374
375
376
377
378
            <div id="site-menu-control-container">
                <input type="checkbox" id="menu-shown" name="menu-shown"/>
                <label id="site-menu-control" for="menu-shown"></label>
                <div class="site-menu-container">
                    <p>Show 6 sites with:</p>
379
380
381
382
                    <input type="button" id="site-menu-button-rate" value="largest growth rate"/>
                    <input type="button" id="site-menu-button-percentage" value="highest percentage of population infected"/>
                    <input type="button" id="site-menu-button-deaths" value="most deaths"/>
                    <input type="button" id="site-menu-button-active-drop" value="greatest drop of number of active cases"/>
383
384
385
                    <div class="spacer"></div>
                    <input type="button" id="site-menu-button-reset" value="Reset all"/>
                </div>
Michał Woźniak's avatar
Michał Woźniak committed
386
            </div>
387
388
389
390
391
392
            <div class="site-data-container">
                <h2><select class="sites-select" tabindex="1">
                    <option value="select one">(select an area)</option>
                </select></h2>
                <div class="site-data">
                </div>
Michał Woźniak's avatar
Michał Woźniak committed
393
            </div>
394
395
396
397
            <div id="add-site-container">
                <a href="#add-site" id="add-site">+</a>
                <a href="#remove-site" id="remove-site">-</a>
            </div>
398
        </div>
Michał Woźniak's avatar
charts!    
Michał Woźniak committed
399
400
        <div id="the-chart-container">
            <canvas id="the-chart"></canvas>
Michał Woźniak's avatar
Michał Woźniak committed
401
402
        </div>
        <div class="chart-config-container">
403
            <input type="radio" id="chart-data-confirmed" name="chart-data" value="confirmed" checked="checked"/>
404
            <input type="radio" id="chart-data-recovered" name="chart-data" value="recovered"/>
405
            <input type="radio" id="chart-data-deaths" name="chart-data" value="deaths"/>
Michał Woźniak's avatar
Michał Woźniak committed
406
            <input type="radio" id="chart-data-active" name="chart-data" value="active"/>
407
408
409
410
411
412
            <input type="radio" id="chart-type-logarithmic" name="chart-type" value="logarithmic" checked="checked"/>
            <input type="radio" id="chart-type-linear" name="chart-type" value="linear"/>
            <input type="radio" id="chart-cases-cumulative" name="chart-cases" value="cumulative" checked="checked"/>
            <input type="radio" id="chart-cases-new" name="chart-cases" value="new"/>
            <input type="radio" id="chart-values-absolute" name="chart-values" value="absolute" checked="checked"/>
            <input type="radio" id="chart-values-per-million" name="chart-values" value="per-million"/>
413
            <input type="radio" id="chart-start-date" name="chart-start" value="date"/>
414
415
416
417
            <input type="radio" id="chart-start-first" name="chart-start" value="1"/>
            <input type="radio" id="chart-start-tenth" name="chart-start" value="10" checked="checked"/>
            <input type="radio" id="chart-start-hundredth" name="chart-start" value="100"/>
            <input type="radio" id="chart-start-thousandth" name="chart-start" value="1000"/>
418
            <div class="chart-config-group">
419
420
421
422
                <p>Show:</p>
                <label for="chart-data-confirmed">confirmed cases</label>
                <label for="chart-data-recovered">recoveries</label>
                <label for="chart-data-deaths">deaths</label>
Michał Woźniak's avatar
Michał Woźniak committed
423
                <label for="chart-data-active">active cases</label>
424
            </div>
Michał Woźniak's avatar
Michał Woźniak committed
425
426
427
428
429
            <div class="chart-config-group">
                <p>Scale:</p>
                <label for="chart-type-logarithmic">logarithmic</label>
                <label for="chart-type-linear">linear</label>
            </div>
430
            <div class="break"></div>
Michał Woźniak's avatar
Michał Woźniak committed
431
432
433
434
435
            <div class="chart-config-group">
                <p>Cases:</p>
                <label for="chart-cases-cumulative">cumulative</label>
                <label for="chart-cases-new">new</label>
            </div>
436
437
438
439
440
            <div class="chart-config-group chart-average">
                <p>Average over:</p>
                <input type="number" min="1" max="15" step="2" value="1" name="chart-average" id="chart-average"/>
                <p>datapoints</p>
            </div>
Michał Woźniak's avatar
Michał Woźniak committed
441
442
443
444
445
            <div class="chart-config-group">
                <p>Values:</p>
                <label for="chart-values-absolute">absolute</label>
                <label for="chart-values-per-million">per 1M</label>
            </div>
446
            <div class="break"></div>
Michał Woźniak's avatar
Michał Woźniak committed
447
            <div class="chart-config-group">
448
                <p>Start</p>
449
450
                <label for="chart-start-date">on: <input type="date" name="chart-start-date" value="2020-03-22" min="2020-03-22"/></label>
                <p>or from:</p>
Michał Woźniak's avatar
Michał Woźniak committed
451
452
453
454
                <label for="chart-start-first">1st</label>
                <label for="chart-start-tenth">10th</label>
                <label for="chart-start-hundredth">100th</label>
                <label for="chart-start-thousandth">1000th</label>
Michał Woźniak's avatar
Michał Woźniak committed
455
                <p><span class="data-confirmed">case</span><span class="data-recovered">recovery</span><span class="data-deaths">death</span><span class="data-active">active case</span><span class="per-million"> per 1M</span></p>
456
            </div>
Michał Woźniak's avatar
charts!    
Michał Woźniak committed
457
        </div>
458
459
460
        <div id="disclaimers-container">
            <h3>Disclaimers:</h3>
            <ul>
461
462
                <li><p>This is all back-of-the-napkin math. Take with a grain (or preferably, a spoonfull) of salt. Check your own sources. Make your own analysis.</p></li>
                <li><p>There are bugs. A reasonable attempt is made to clean the data before displaying it.</p></li>
463
464
465
            </ul>
            <h3>Some great resources:</h3>
            <ul>
466
                <li><p><a href="https://covid.hi.is/english/">University of Iceland's COVID data model</a> (and its <a href="https://github.com/bgautijonsson/covid19/">sources</a>);</p></li>
467
468
                <li><p><a href="https://covid-cases.now.sh/">COVID-19 Statistics</a> with some decent models and predictions;</p></li>
                <li><p><a href="https://aatishb.com/covidtrends/">a brilliant chart</a> showing very clearly when a country starts being able to control the outbreak;</p></li>
469
                <li><p>John Hopkins University's <a href="https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6">COVID-19 dashboard</a>, and their <a href="https://github.com/CSSEGISandData/COVID-19">cleaned global data in CSVs</a>, updated daily (this is the base data for this site).</p></li>
470
471
            </ul>
        </div>
472
        <footer>
Michał Woźniak's avatar
Michał Woźniak committed
473
            <p>cobbled together by <a href="https://mastodon.social/@rysiek/">@rysiek</a>; <a href="https://git.rys.io/rysiek/covid/">code is here</a>; license: <a href="./LICENSE">Affero GPL</a><br/>
Michał Woźniak's avatar
charts!    
Michał Woźniak committed
474
            uses <a href="https://github.com/spencermountain/wtf_wikipedia"><code>wtf_wikipedia</code></a> and <a href="https://www.chartjs.org/">Charts.js</a> (both <a href="./LICENSE.wtf_wikipedia-charts.js.txt">MIT-licensed</a>) and the Play font (licensed under the <a href="./Play/OFL.txt">OFL</a>)<br/>
475
476
            data from <a href="https://github.com/CSSEGISandData/COVID-19">John Hopkins University</a> via <a href="https://github.com/pomber/covid19"><code>pomber/covid19</code></a></p>
            <p>there are no <a href="https://barnacles.online">barnacle trackers</a> on this page:<br/>no fonts, styles, scripts, nor images fetched from third-party servers</p>
477
        </footer>
478
479
    </body>
</html>