Skip to content

Commit 5bd16d7

Browse files
committed
Add chart for results
1 parent 70b78d5 commit 5bd16d7

File tree

5 files changed

+186
-46
lines changed

5 files changed

+186
-46
lines changed

components/Loader/index.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ export default {
3131
position: fixed;
3232
top: 0;
3333
left: 0;
34+
z-index: 9999;
3435
width: 100%;
3536
height: 100%;
3637
background: rgba(255, 255, 255, 0.8);
3738
text-align: center;
3839
padding-top: 200px;
39-
font-size: 30px;
40-
font-family: sans-serif;
40+
font-size: 100px;
41+
color: #000000;
4142
}
4243
</style>

components/Results/index.vue

Lines changed: 116 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
<template>
22
<div class="results">
3-
<p
4-
v-for="(item, index) in items"
5-
:key="index"
6-
class="cases">
7-
{{ item.label }}
8-
<animated-number
9-
v-if="showValue"
10-
:value="item.value"
11-
:formatValue="formatNumber"
12-
:duration="duration"
13-
:style="`color: ${item.color}`" />
14-
</p>
3+
<div
4+
v-if="showChart"
5+
class="chart-wrapper">
6+
<client-only>
7+
<LineChart
8+
:chart-data="logarithmicData"
9+
:options="chartOptions" />
10+
</client-only>
11+
</div>
12+
<div class="cases-wrapper">
13+
<p
14+
v-for="(item, index) in items"
15+
:key="index"
16+
class="cases">
17+
{{ item.label }}
18+
<AnimatedNumber
19+
v-if="showValue"
20+
:value="item.value"
21+
:formatValue="formatNumber"
22+
:duration="duration"
23+
:style="`color: ${item.color}`" />
24+
</p>
25+
</div>
1526
</div>
1627
</template>
1728

@@ -26,7 +37,72 @@ export default {
2637
props: {
2738
items: Array,
2839
duration: Number,
29-
showValue: Boolean
40+
showValue: Boolean,
41+
chartData: Object,
42+
showChart: {
43+
type: Boolean,
44+
default: false
45+
}
46+
},
47+
computed: {
48+
logarithmicData() {
49+
const cd = this.chartData
50+
const labels = Object.keys(cd.confirmed_history)
51+
return {
52+
labels: labels,
53+
datasets: [
54+
{
55+
data: Object.values(cd.confirmed_history),
56+
label: 'Confirmed',
57+
borderColor: '#ffa500',
58+
fontColor: '#ffffff',
59+
fill: false
60+
},
61+
{
62+
data: Object.values(cd.recovered_history),
63+
label: 'Recovered',
64+
borderColor: '#66a266',
65+
fontColor: '#ffffff',
66+
fill: false
67+
},
68+
{
69+
data: Object.values(cd.dead_history),
70+
label: 'Deaths',
71+
borderColor: '#b20000',
72+
fontColor: '#ffffff',
73+
fill: false
74+
}
75+
]
76+
}
77+
}
78+
},
79+
data() {
80+
return {
81+
chartOptions: {
82+
responsive: true,
83+
legend: false,
84+
// legend: {
85+
// position: 'bottom',
86+
// labels: {
87+
// boxWidth: 10,
88+
// fontColor: '#ffffff'
89+
// }
90+
// },
91+
scales: {
92+
xAxes: [{
93+
ticks: {
94+
fontColor: '#ffffff'
95+
}
96+
}],
97+
yAxes: [{
98+
ticks: {
99+
type: 'logarithmic',
100+
fontColor: '#ffffff'
101+
}
102+
}]
103+
}
104+
}
105+
}
30106
},
31107
methods: {
32108
formatNumber(s) {
@@ -40,11 +116,34 @@ export default {
40116
<style lang="scss" scoped>
41117
.results {
42118
43-
.cases {
44-
margin-bottom: 12px;
119+
.chart-wrapper {
120+
position: relative;
121+
display: inline-block;
122+
margin-bottom: 24px;
123+
width: 100%;
124+
vertical-align: top;
125+
126+
@media only screen and (min-width: 768px) {
127+
margin-right: 24px;
128+
width: 50%;
129+
130+
& ~ .cases-wrapper {
131+
display: inline-block;
132+
margin-top: 0;
133+
vertical-align: top;
134+
}
135+
}
136+
}
137+
138+
.cases-wrapper {
139+
margin-top: 16px;
140+
141+
.cases {
142+
margin-bottom: 12px;
45143
46-
span {
47-
font-weight: 700;
144+
span {
145+
font-weight: 700;
146+
}
48147
}
49148
}
50149
}

components/Search/index.vue

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@
3838
</select>
3939
</div>
4040
<div
41-
v-if="hasSelected && hasSearched && country_case.length"
41+
v-if="hasSelected && hasSearched && !isEmpty(country_case)"
4242
class="search-results">
43-
<p>Cases <span>({{ country_case[0].properties.last_update }})</span></p>
43+
<p>Cases <span>({{ country_case.last_update }})</span></p>
4444
<Results
4545
:items="results"
4646
:duration="duration"
47-
:show-value="!!country_case.length" />
47+
:show-value="!isEmpty(country_case)"
48+
:show-chart="true"
49+
:chart-data="country_case" />
4850
</div>
4951
<button
5052
:disabled="!hasSelected"
@@ -110,21 +112,21 @@ export default {
110112
)
111113
},
112114
results() {
113-
const cases = this.country_case || []
115+
const cases = this.country_case
114116
return [
115117
{
116118
label: 'Confirmed / ',
117-
value: cases.length ? cases[0].properties.confirmed_count : 0,
119+
value: cases.confirmed_count,
118120
color: '#ffa500'
119121
},
120122
{
121123
label: 'Recovered / ',
122-
value: cases.length ? cases[0].properties.recovered_count : 0,
124+
value: cases.recovered_count,
123125
color: '#66a266'
124126
},
125127
{
126128
label: 'Deaths / ',
127-
value: cases.length ? cases[0].properties.dead_count : 0,
129+
value: cases.dead_count,
128130
color: '#b20000'
129131
}
130132
]
@@ -143,6 +145,9 @@ export default {
143145
}
144146
},
145147
methods: {
148+
isEmpty(obj) {
149+
return Object.keys(obj).length === 0 && obj.constructor === Object
150+
},
146151
enter() {
147152
this.setSelection = this.matches[this.current]
148153
this.tempValue = this.country
@@ -283,6 +288,7 @@ export default {
283288
button {
284289
border-radius: 4px;
285290
margin-top: 16px;
291+
margin-bottom: 16px;
286292
padding: 12px 16px 14px;
287293
font-size: 24px;
288294
width: 100%;

plugins/vue-chartjs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { Line } from 'vue-chartjs'
33

44
Vue.component('LineChart', {
55
extends: Line,
6-
props: [ 'chartdata', 'options' ],
6+
props: [ 'chartData', 'options' ],
77
mounted() {
8-
this.renderChart(this.chartdata, this.options)
8+
this.renderChart(this.chartData, this.options)
99
}
1010
})

store/mutations.js

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,45 @@ export default {
3636
)
3737
return timeSince(last) + ' ago'
3838
}
39-
const cases = confirmed.locations.map((location, index) => {
40-
return {
41-
type: 'Feature',
42-
properties: {
43-
country: location.country,
44-
country_code: location.country_code,
45-
confirmed_count: location.latest,
46-
recovered_count: recovered.locations[index].latest || 0,
47-
dead_count: deaths.locations[index].latest || 0,
48-
province: location.province,
49-
last_update: lastUpdate(location.history)
50-
},
51-
geometry: {
52-
type: 'Point',
53-
coordinates: [ location.coordinates.long, location.coordinates.lat ]
39+
const cases = confirmed.locations
40+
.reduce((result, currentValue) => {
41+
if (currentValue.latest) {
42+
result.push(currentValue)
5443
}
55-
}
56-
})
44+
return result
45+
}, [])
46+
.map((location, index) => {
47+
const sortDate = dates => {
48+
const sorted_date = {}
49+
Object.keys(dates)
50+
.sort((a, b) => {
51+
return new Date(a) - new Date(b)
52+
})
53+
.forEach(key => {
54+
sorted_date[key] = dates[key]
55+
})
56+
return sorted_date
57+
}
58+
return {
59+
type: 'Feature',
60+
properties: {
61+
country: location.country,
62+
country_code: location.country_code,
63+
province: location.province,
64+
confirmed_count: location.latest,
65+
confirmed_history: sortDate(location.history),
66+
recovered_count: recovered.locations[index].latest || 0,
67+
recovered_history: sortDate(recovered.locations[index].history),
68+
dead_count: deaths.locations[index].latest || 0,
69+
dead_history: sortDate(deaths.locations[index].history),
70+
last_update: lastUpdate(location.history)
71+
},
72+
geometry: {
73+
type: 'Point',
74+
coordinates: [ location.coordinates.long, location.coordinates.lat ]
75+
}
76+
}
77+
})
5778
state.data = {
5879
type: 'FeatureCollection',
5980
features: cases
@@ -72,6 +93,19 @@ export default {
7293
state.countries = groupProvinceByCountry(data.locations, 'country')
7394
},
7495
SET_COUNTRY_CASE: (state, country_case) => {
75-
state.country_case = country_case
96+
// const merged_history = {}
97+
// const history = [
98+
// country_case[0].properties.confirmed_history,
99+
// country_case[0].properties.recovered_history,
100+
// country_case[0].properties.dead_history
101+
// ]
102+
// history.forEach(item => {
103+
// Object.keys(item).forEach(key => {
104+
// merged_history[key] = merged_history[key] || []
105+
// merged_history[key].push(item[key] || 0)
106+
// })
107+
// })
108+
// state.country_case = Object.assign(country_case[0].properties, { merged_history: merged_history })
109+
state.country_case = Object.assign({}, country_case[0].properties)
76110
}
77111
}

0 commit comments

Comments
 (0)