Skip to content

Commit b0aaca1

Browse files
committed
added daily and weekly delta columns
1 parent 4049d5c commit b0aaca1

File tree

5 files changed

+220
-60
lines changed

5 files changed

+220
-60
lines changed

lib/byCountry.js

Whitespace-only changes.

lib/corona.js

Lines changed: 72 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,26 @@ const Table = require('cli-table3');
22
const axios = require('axios');
33
const _ = require('lodash');
44
const chalk = require('chalk');
5-
const emojiFlags = require('emoji-flags');
6-
const h = require('humanize-number');
5+
const helpers = require('./helpers');
6+
const {
7+
getCountry,
8+
getConfirmed,
9+
getActive,
10+
getDeaths,
11+
getRecovered,
12+
getMortalityPer,
13+
getRecoveredPer,
14+
getEmoji,
15+
calActive,
16+
calMortalityPer,
17+
calRecoveredPer,
18+
getOneDayChange,
19+
getOneWeekChange,
20+
getRateOfGrowth,
21+
getTotalStats,
22+
} = require('./helpers');
723

8-
function getConfirmed(confirmed) {
9-
return {
10-
content: chalk.blueBright(h(confirmed)),
11-
hAlign: 'right',
12-
};
13-
}
1424

15-
function getRecoverd(recovered) {
16-
return {
17-
content: chalk.yellowBright(h(recovered)),
18-
hAlign: 'right',
19-
};
20-
}
21-
22-
function getDeaths(deaths) {
23-
return {
24-
content: chalk.grey(h(deaths)),
25-
hAlign: 'right',
26-
}
27-
}
28-
29-
function getActive(confirmed, recovered, deaths) {
30-
return {
31-
content: h(confirmed - recovered - deaths),
32-
hAlign: 'right'
33-
}
34-
}
35-
36-
function getMortalityRate(deaths, confirmed, average = null) {
37-
const mortalityRate = ((deaths / confirmed) * 100).toFixed(2);
38-
return chalk.redBright(mortalityRate);
39-
}
40-
41-
function getRecoveredRate(recovered, confirmed, average = null) {
42-
const recoveredRate = ((recovered / confirmed) * 100).toFixed(2);
43-
return chalk.greenBright(recoveredRate);
44-
}
45-
46-
function getEmoji(countryCode) {
47-
if (countryCode && emojiFlags.countryCode(countryCode)) {
48-
return emojiFlags.countryCode(countryCode).emoji;
49-
}
50-
return '';
51-
}
5225

5326
function getDataByCountry(confirmed, deaths, recovered) {
5427
const countryMap = {};
@@ -66,17 +39,48 @@ function getDataByCountry(confirmed, deaths, recovered) {
6639
confirmed: confirmedMap[mapKey].latest,
6740
recovered: recoveredMap[mapKey].latest,
6841
deaths: deathsMap[mapKey].latest,
42+
confirmedByDay: helpers.historyObjToArr(confirmedMap[mapKey].history),
43+
recoveredByDay: helpers.historyObjToArr(recoveredMap[mapKey].history),
44+
deathsByDay: helpers.historyObjToArr(recoveredMap[mapKey].history),
6945
};
7046
} else {
7147
countryMap[countryName].confirmed += confirmedMap[mapKey].latest;
7248
countryMap[countryName].recovered += recoveredMap[mapKey].latest;
7349
countryMap[countryName].deaths += deathsMap[mapKey].latest;
50+
countryMap[countryName].confirmedByDay = helpers.addArr(
51+
countryMap[countryName].confirmedByDay,
52+
helpers.historyObjToArr(confirmedMap[mapKey].history)
53+
);
54+
countryMap[countryName].recoveredByDay = helpers.addArr(
55+
countryMap[countryName].recoveredByDay,
56+
helpers.historyObjToArr(recoveredMap[mapKey].history)
57+
);
58+
countryMap[countryName].deathsByDay = helpers.addArr(
59+
countryMap[countryName].deathsByDay,
60+
helpers.historyObjToArr(deathsMap[mapKey].history)
61+
);
7462
}
7563
});
76-
const countryArr = Object.keys(countryMap).map(key => countryMap[key]);
64+
const countryArr = extraStats(
65+
Object.keys(countryMap).map(key => countryMap[key])
66+
);
7767
return _.sortBy(countryArr, (o) => -o.confirmed)
7868
}
7969

70+
function getDateByState(confirmed, deaths, recovered) {
71+
72+
}
73+
74+
function extraStats(dataArr) {
75+
return dataArr.map(obj => Object.assign({}, obj,
76+
{
77+
active: calActive(obj),
78+
mortalityPer: calMortalityPer(obj),
79+
recoveredPer: calRecoveredPer(obj),
80+
})
81+
);
82+
}
83+
8084
exports.getCompleteTable = async () => {
8185
const head = [
8286
'',
@@ -87,41 +91,51 @@ exports.getCompleteTable = async () => {
8791
'Active 😷',
8892
'Mortality %',
8993
'Recovered %',
90-
'Flag 🏳'
94+
'1 Day 🔺',
95+
'1 Week 🔺',
96+
// 'RoG',
97+
'🏳',
9198
];
9299
const table = new Table({
93100
head,
94101
chars: { 'top': '═' , 'top-mid': '╤' , 'top-left': '╔' , 'top-right': '╗'
95102
, 'bottom': '═' , 'bottom-mid': '╧' , 'bottom-left': '╚' , 'bottom-right': '╝'
96103
, 'left': '║' , 'left-mid': '╟' , 'mid': '─' , 'mid-mid': '┼'
97-
, 'right': '║' , 'right-mid': '╢' , 'middle': '│' }
104+
, 'right': ' ║' , 'right-mid': '╢' , 'middle': '│' }
98105
});
99106
const result = await axios('https://coronavirus-tracker-api.herokuapp.com/all');
100107
const { latest, confirmed, deaths, recovered } = result.data;
101108
const countryData = getDataByCountry(confirmed, deaths, recovered)
109+
const worldStats = getTotalStats(countryData);
102110
table.push({
103111
'': [
104112
'World',
105-
getConfirmed(latest.confirmed),
106-
getRecoverd(latest.recovered),
107-
getDeaths(latest.deaths),
108-
getActive(latest.confirmed, latest.recovered, latest.deaths),
109-
getMortalityRate(latest.deaths, latest.confirmed),
110-
getRecoveredRate(latest.recovered, latest.confirmed),
113+
getConfirmed(worldStats.confirmed),
114+
getRecovered(worldStats.recovered),
115+
getDeaths(worldStats.deaths),
116+
getActive(worldStats.active),
117+
getMortalityPer(worldStats.mortalityPer),
118+
getRecoveredPer(worldStats.recoveredPer),
119+
getOneDayChange(worldStats),
120+
getOneWeekChange(worldStats),
121+
// '',
111122
'🌎'
112123
]
113124
})
114125
let rank = 1;
115126
countryData.forEach(cd => {
116127
const countryEmoji = getEmoji(cd.countryCode);
117128
const values = [
118-
chalk.cyanBright(cd.country),
129+
getCountry(cd.country),
119130
getConfirmed(cd.confirmed),
120-
getRecoverd(cd.recovered),
131+
getRecovered(cd.recovered),
121132
getDeaths(cd.deaths),
122133
getActive(cd.confirmed, cd.recovered, cd.deaths),
123-
getMortalityRate(cd.deaths, cd.confirmed),
124-
getRecoveredRate(cd.deaths, cd.confirmed),
134+
getMortalityPer(cd.mortalityPer),
135+
getRecoveredPer(cd.recoveredPer),
136+
getOneDayChange(cd),
137+
getOneWeekChange(cd),
138+
// getRateOfGrowth(cd),
125139
getEmoji(cd.countryCode),
126140
]
127141
table.push({ [rank++]: values })

lib/helpers.js

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
const chalk = require('chalk');
2+
const h = require('humanize-number');
3+
const emojiFlags = require('emoji-flags');
4+
const _ = require('lodash');
5+
const moment = require('moment');
6+
const e = exports;
7+
8+
e.getCountry = (country) => {
9+
return chalk.cyan.bold(country);
10+
};
11+
12+
e.getState = (state) => {
13+
if (state) {
14+
return chalk.red(state);
15+
}
16+
return chalk.red('ALL');
17+
};
18+
19+
e.getConfirmed = (confirmed) => {
20+
return {
21+
content: chalk.blueBright(h(confirmed)),
22+
hAlign: 'right',
23+
};
24+
};
25+
26+
e.getRecovered = (recovered) => {
27+
return {
28+
content: chalk.yellowBright(h(recovered)),
29+
hAlign: 'right',
30+
};
31+
};
32+
33+
e.getDeaths = (deaths) => {
34+
return {
35+
content: chalk.whiteBright(h(deaths)),
36+
hAlign: 'right',
37+
};
38+
};
39+
40+
e.getActive = (active) => {
41+
return {
42+
content: chalk.magentaBright(h(active)),
43+
hAlign: 'right'
44+
};
45+
};
46+
47+
e.getMortalityPer = (mortalityPer) => ({
48+
content: chalk.redBright(mortalityPer),
49+
hAlign: 'right',
50+
});
51+
52+
e.getRecoveredPer = (recoveredPer) => ({
53+
content: chalk.greenBright(recoveredPer),
54+
hAlign: 'right',
55+
});
56+
57+
e.getEmoji = (countryCode) => {
58+
if (countryCode && emojiFlags.countryCode(countryCode)) {
59+
return emojiFlags.countryCode(countryCode).emoji;
60+
}
61+
return '';
62+
};
63+
64+
e.calActive = ({ confirmed, recovered, deaths }) => confirmed - (recovered + deaths);
65+
e.calMortalityPer = ({ confirmed, deaths }) => ((deaths / confirmed) * 100).toFixed(2);
66+
e.calRecoveredPer = ({ confirmed, recovered }) => ((recovered / confirmed) * 100).toFixed(2);
67+
68+
/**
69+
historyObj = {
70+
"1/22/20": 0,
71+
"1/23/20": 1,
72+
"1/24/20": 4,
73+
"1/25/20": 7,
74+
}
75+
Returns sorted arr of above elements - [0, 1, 4, 7]
76+
*/
77+
e.historyObjToArr = (historyObj) => {
78+
const sortedTimestampArr = _.sortBy(
79+
Object.keys(historyObj).map(date => new Date(date).getTime()),
80+
Number
81+
);
82+
return sortedTimestampArr.map(timestamp => {
83+
const dateFormatted = moment(timestamp).format('M/D/YY');
84+
return historyObj[dateFormatted];
85+
});
86+
};
87+
88+
/**
89+
* Given both arr1 and arr2 has same number of elements
90+
* Returns -> sum[n] = arr1[n] + arr2[n]
91+
*
92+
*/
93+
e.addArr = (arr1, arr2) => {
94+
if (arr1.length === 0 ) {
95+
return arr2;
96+
}
97+
if (arr2.length === 0) {
98+
return arr1;
99+
}
100+
return arr1.map((val, index) => arr1[index] + arr2[index]);
101+
};
102+
103+
e.getOneDayChange = ({ confirmedByDay }) => {
104+
const present = confirmedByDay.length - 1;
105+
const dailyChange = confirmedByDay[present] - confirmedByDay[present - 1];
106+
return {
107+
content: `${h(dailyChange)}🔺`,
108+
hAlign: 'right',
109+
};
110+
};
111+
112+
e.getOneWeekChange = ({ confirmedByDay }) => {
113+
const present = confirmedByDay.length - 1;
114+
const weeklyChange = confirmedByDay[present] - confirmedByDay[present - 7];
115+
return {
116+
content: `${h(weeklyChange)}🔺`,
117+
hAlign: 'right',
118+
};
119+
};
120+
121+
e.getRateOfGrowth = ( { confirmedByDay }) => {
122+
return confirmedByDay[0];
123+
};
124+
125+
e.getTotalStats = (countryData) => {
126+
const worldStats = countryData.reduce((acc, countryObj) => {
127+
acc.confirmed += countryObj.confirmed;
128+
acc.recovered += countryObj.recovered;
129+
acc.deaths += countryObj.deaths;
130+
acc.confirmedByDay = e.addArr( acc.confirmedByDay, countryObj.confirmedByDay);
131+
acc.recoveredByDay = e.addArr( acc.recoveredByDay, countryObj.recoveredByDay);
132+
acc.deathsByDay = e.addArr( acc.deathsByDay, countryObj.deathsByDay);
133+
return acc;
134+
}, {
135+
confirmed: 0,
136+
recovered: 0,
137+
deaths: 0,
138+
confirmedByDay: [],
139+
recoveredByDay: [],
140+
deathsByDay: [],
141+
});
142+
worldStats.active = e.calActive(worldStats);
143+
worldStats.recoveredPer = e.calRecoveredPer(worldStats);
144+
worldStats.mortalityPer = e.calMortalityPer(worldStats);
145+
return worldStats;
146+
}

readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Track coronavirus from cli
44

55
## Screenshot
66

7-
<img src="./screenshot.png" width="960" height="720">
7+
<img src="https://i.ibb.co/wYyB8XG/screenshot.png" width="960" height="720">
88

99
### Prerequisites
1010

@@ -32,6 +32,6 @@ corona
3232

3333
## License
3434

35-
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
35+
This project is licensed under the MIT License
3636

3737

screenshot.png

-972 KB
Loading

0 commit comments

Comments
 (0)