Skip to content

Commit e95d44f

Browse files
committed
Added toggle for data source and made help text clearer
1 parent cdea2f6 commit e95d44f

File tree

7 files changed

+354
-57
lines changed

7 files changed

+354
-57
lines changed

Diff for: package.json

+3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@
1010
"dependencies": {
1111
"@amcharts/amcharts4": "^4.9.13",
1212
"@amcharts/amcharts4-geodata": "^4.1.14",
13+
"@syncfusion/ej2-vue-inputs": "^18.1.43",
1314
"color-interpolate": "^1.0.5",
1415
"core-js": "^3.6.4",
1516
"data-forge": "^1.8.4",
1617
"date-fns": "^2.12.0",
1718
"least-squares": "^0.0.2",
19+
"sass": "^1.26.3",
20+
"sass-loader": "^8.0.2",
1821
"vue": "^2.6.11",
1922
"vue-router": "^3.1.6"
2023
},

Diff for: src/components/DataToggle.vue

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<template>
2+
<div class="toggle">
3+
<svg v-if="dataType === 'cases'" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="notes-medical" class="svg-inline--fa fa-notes-medical fa-w-12" role="img" viewBox="0 0 384 512"><path fill="currentColor" d="M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm96 304c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48zm0-192c0 4.4-3.6 8-8 8H104c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v16z"/></svg>
4+
<svg v-else-if="dataType === 'deaths'" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="skull" class="svg-inline--fa fa-skull fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M256 0C114.6 0 0 100.3 0 224c0 70.1 36.9 132.6 94.5 173.7 9.6 6.9 15.2 18.1 13.5 29.9l-9.4 66.2c-1.4 9.6 6 18.2 15.7 18.2H192v-56c0-4.4 3.6-8 8-8h16c4.4 0 8 3.6 8 8v56h64v-56c0-4.4 3.6-8 8-8h16c4.4 0 8 3.6 8 8v56h77.7c9.7 0 17.1-8.6 15.7-18.2l-9.4-66.2c-1.7-11.7 3.8-23 13.5-29.9C475.1 356.6 512 294.1 512 224 512 100.3 397.4 0 256 0zm-96 320c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm192 0c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64z"/></svg>
5+
6+
<div class="tooltip">
7+
<p>Data based on {{ dataType === 'cases' ? 'confirmed cases' : 'deaths' }} by country.</p>
8+
<p>Click to change.</p>
9+
</div>
10+
</div>
11+
</template>
12+
13+
<script>
14+
export default {
15+
props: {
16+
dataType: { type: String, required: true },
17+
}
18+
};
19+
</script>
20+
21+
<style scoped lang="scss">
22+
23+
.toggle {
24+
width: 40px;
25+
height: 40px;
26+
cursor: pointer;
27+
color: #9a9a9a;
28+
position: relative;
29+
30+
&:hover {
31+
color: #565656;
32+
}
33+
34+
svg {
35+
position: absolute;
36+
top: 50%;
37+
left: 0;
38+
height: 100%;
39+
width: 100%;
40+
transform: translateY(-50%);
41+
}
42+
43+
p {
44+
margin: 0;
45+
}
46+
}
47+
48+
.tooltip {
49+
display: none;
50+
width: 300px;
51+
}
52+
53+
.toggle:hover .tooltip {
54+
position: absolute;
55+
top: 0px;
56+
left: 60px;
57+
display: block;
58+
background: white;
59+
border: 1px solid black;
60+
padding: 0.5em;
61+
}
62+
63+
</style>

Diff for: src/components/Help.vue

+33-28
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
<template>
1+
<template functional>
22
<div class="help">
3-
<div class="opener" @click="toggle">
3+
<div class="opener">
44
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="question-circle" class="svg-inline--fa fa-question-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z"></path></svg>
55
</div>
66

7-
<div v-if="isOpen" @click.stop ref="panel" class="panel">
7+
<div ref="panel" class="panel">
88
<p>
99
The fight against COVID-19 is being waged across the globe. This visualisation shows which countries are winning against exponential growth.
1010
Countries are colour coded to represent the rate at which infection is spreading. Green countries have fought back against the growth and the number
@@ -16,47 +16,52 @@
1616

1717
<script>
1818
export default {
19-
data () {
20-
return {
21-
isOpen: false
22-
};
23-
},
24-
methods: {
25-
toggle (e) {
26-
this.isOpen = !this.isOpen;
19+
// data () {
20+
// return {
21+
// isOpen: false
22+
// };
23+
// },
24+
// methods: {
25+
// toggle (e) {
26+
// this.isOpen = !this.isOpen;
2727
28-
if (this.isOpen) {
29-
document.addEventListener('click', this.closeOnOutsideClick);
30-
} else {
31-
document.removeEventListener('click', this.closeOnOutsideClick);
32-
}
28+
// if (this.isOpen) {
29+
// document.addEventListener('click', this.closeOnOutsideClick);
30+
// }
3331
34-
e.stopPropagation();
35-
},
36-
closeOnOutsideClick (e) {
37-
this.isOpen = false;
38-
}
39-
}
32+
// e.stopPropagation();
33+
// },
34+
// closeOnOutsideClick (e) {
35+
// this.isOpen = false;
36+
37+
// document.removeEventListener('click', this.closeOnOutsideClick);
38+
// }
39+
// }
4040
};
4141
</script>
4242

4343
<style scoped>
4444
45+
.help {
46+
position: relative;
47+
}
48+
4549
.opener {
46-
position: absolute;
47-
z-index: 1;
48-
left: 10px;
49-
top: 10px;
5050
width: 50px;
5151
height: 50px;
5252
cursor: pointer;
5353
color: #9a9a9a;
5454
}
5555
56+
.help:hover .panel {
57+
display: block;
58+
}
59+
5660
.panel {
61+
display: none;
5762
position: absolute;
58-
left: 80px;
59-
top: 10px;
63+
left: 60px;
64+
top: 0px;
6065
border: 1px solid #565656;
6166
background: white;
6267
width: 300px;

Diff for: src/lib/countryLookup.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ export default {
117117
'Kazakhstan': 'KZ',
118118
'Kenya': 'KE',
119119
'Kiribati': 'KI',
120-
'Korea (Democratic People\s Republic of)': 'KP',
121-
'Korea, Republic of': 'KR',
120+
'Korea (Democratic People\'s Republic of)': 'KP',
121+
'South Korea': 'KR',
122122
'Kuwait': 'KW',
123123
'Kyrgyzstan': 'KG',
124124
'Lao People\'s Democratic Republic': 'LA',

Diff for: src/lib/data.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import { parse, format, addDays } from 'date-fns';
33
import LeastSquares from 'least-squares';
44
import countryLookup from './countryLookup';
55

6-
const dataUrl = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv';
7-
// const dataUrl = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv';
6+
const casesUrl = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv';
7+
const deathsUrl = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv';
88

9-
export async function loadData (period = 7) {
10-
const response = await fetch(dataUrl);
9+
export async function loadData (dataType, period = 7) {
10+
const response = await fetch(dataType === 'cases' ? casesUrl : deathsUrl);
1111
const data = await response.text();
1212

1313
const dfAll = fromCSV(data);

Diff for: src/views/Home.vue

+72-19
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
11
<template>
22
<Loading v-if="loading" />
33
<div v-else class="container">
4-
<!-- <h1 class="title">Are We Winning?</h1> -->
5-
<Help />
4+
<div class="options">
5+
<Help />
6+
<DataToggle :data-type="dataType" @click.native="changeDataType()" />
7+
</div>
68
<Map class="map" :countries="countries" />
9+
<ejs-slider id="range" min="1" max="20" v-model="dateRange" type="Range"></ejs-slider>
710
</div>
811
</template>
912

1013
<script>
14+
import Vue from 'vue';
1115
import * as interpolate from 'color-interpolate';
16+
import { SliderPlugin } from '@syncfusion/ej2-vue-inputs';
1217
import { loadData } from '@/lib/data';
1318
import Help from '@/components/Help';
19+
import DataToggle from '@/components/DataToggle';
1420
import Map from '@/components/Map';
1521
import Loading from '@/components/Loading';
1622
23+
// TODO
24+
// - Fade map etc in
25+
// - Date range slider to pick dates for calculation
26+
// - Toggle between confirmed cases and deaths
27+
// - Download data sets and save to local storage for quicker subsequent loads on same day
28+
// - Confirm calculation is correct / useful
29+
// - Get data working for grey countries
30+
// - Finalise colour scheme!
31+
32+
Vue.use(SliderPlugin);
33+
1734
// const gradient = ['#017a29', '#c7c214', '#c40707'];
1835
// const gradient = ['#447c46', '#5b995e', '#81c784', '#d0855c', '#c84646'];
1936
// const gradient = ['#440154', '#414487', '#2a788e', '#22a884', '#7ad151', '#fde725'];
@@ -25,36 +42,59 @@ const badGradient = ['#FFECB3', '#EF6C00'];
2542
export default {
2643
name: 'Home',
2744
components: {
45+
DataToggle,
2846
Help,
2947
Loading,
3048
Map
3149
},
3250
data () {
3351
return {
3452
loading: true,
53+
dataType: 'cases',
54+
dateRange: null,
3555
countries: null
3656
};
3757
},
3858
async created () {
39-
const data = await loadData();
59+
await this.loadData();
60+
},
61+
computed: {
62+
periodLength () {
63+
return 7; // Default to 7 days
64+
}
65+
},
66+
watch: {
67+
dataType () {
68+
this.loadData();
69+
}
70+
},
71+
methods: {
72+
async loadData () {
73+
this.loading = true;
4074
41-
const max = 8;
42-
const min = -8;
75+
const data = await loadData(this.dataType, this.periodLength);
4376
44-
const goodColormap = interpolate(goodGradient);
45-
const badColormap = interpolate(badGradient);
46-
const normalize = x => (Math.max(Math.min(x, max), min) + Math.abs(min)) / (Math.abs(max) + Math.abs(min));
77+
const max = 8;
78+
const min = -8;
4779
48-
this.countries = data.map(c => ({
49-
id: c.id,
50-
gradient: c.gradient,
51-
fill: c.gradient === 0
52-
? '#C8E6C9'
53-
: (c.gradient < 0 ? goodColormap(normalize(c.gradient)) : badColormap(normalize(c.gradient)))
54-
}));
80+
const goodColormap = interpolate(goodGradient);
81+
const badColormap = interpolate(badGradient);
82+
const normalize = x => (Math.max(Math.min(x, max), min) + Math.abs(min)) / (Math.abs(max) + Math.abs(min));
5583
56-
this.loading = false;
57-
},
84+
this.countries = data.map(c => ({
85+
id: c.id,
86+
gradient: c.gradient,
87+
fill: c.gradient === 0
88+
? '#C8E6C9'
89+
: (c.gradient < 0 ? goodColormap(normalize(c.gradient)) : badColormap(normalize(c.gradient)))
90+
}));
91+
92+
this.loading = false;
93+
},
94+
changeDataType () {
95+
this.dataType = this.dataType === 'cases' ? 'deaths' : 'cases';
96+
}
97+
}
5898
};
5999
</script>
60100

@@ -64,18 +104,31 @@ export default {
64104
box-sizing: border-box;
65105
display: flex;
66106
flex-direction: column;
67-
/* padding: 3em; */
68107
height: 100%;
69108
}
70109
71110
.map {
72111
flex: 1;
73112
}
74113
114+
.options {
115+
z-index: 1;
116+
position: absolute;
117+
left: 10px;
118+
top: 10px;
119+
display: flex;
120+
flex-direction: column;
121+
align-items: center;
122+
}
123+
124+
.options > * {
125+
margin-bottom: 1em;
126+
}
127+
75128
.fade-enter-active, .fade-leave-active {
76129
transition: opacity .5s;
77130
}
78-
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
131+
.fade-enter, .fade-leave-to {
79132
opacity: 0;
80133
}
81134

0 commit comments

Comments
 (0)