added yesterday, rolling average
This commit is contained in:
		
							parent
							
								
									0a72c63cdc
								
							
						
					
					
						commit
						df22e3c79f
					
				
							
								
								
									
										40
									
								
								generate.js
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								generate.js
									
									
									
									
									
								
							| @ -442,6 +442,18 @@ const processGlobalDeaths = async () => { | |||||||
| 			}), | 			}), | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
|  | 		stateItem.rollingAverageDaily = stateItem.timeSeriesDaily.map((item, i, arr) => { | ||||||
|  | 			const prevValues = arr.slice(Math.max(0, i - 6), i); | ||||||
|  | 			const valueAverage = (item.value + prevValues.reduce((sum, next) => sum + next.value, 0)) / (1 + prevValues.length); | ||||||
|  | 			const deltaAverage = (item.delta + prevValues.reduce((sum, next) => sum + next.delta, 0)) / (1 + prevValues.length); | ||||||
|  | 
 | ||||||
|  | 			return { | ||||||
|  | 				key: item.key, | ||||||
|  | 				value: Math.round(valueAverage), | ||||||
|  | 				delta: Math.round(deltaAverage), | ||||||
|  | 			}; | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
| 		stateItem.deathGrowthRate = getGrowthRate(stateItem); | 		stateItem.deathGrowthRate = getGrowthRate(stateItem); | ||||||
| 
 | 
 | ||||||
| 		// insert into states array for the country
 | 		// insert into states array for the country
 | ||||||
| @ -480,13 +492,25 @@ const processGlobalDeaths = async () => { | |||||||
| 			}), | 			}), | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
|  | 		countryItem.rollingAverageDaily = countryItem.timeSeriesDaily.map((item, i, arr) => { | ||||||
|  | 			const prevValues = arr.slice(Math.max(0, i - 6), i); | ||||||
|  | 			const valueAverage = (item.value + prevValues.reduce((sum, next) => sum + next.value, 0)) / (1 + prevValues.length); | ||||||
|  | 			const deltaAverage = (item.delta + prevValues.reduce((sum, next) => sum + next.delta, 0)) / (1 + prevValues.length); | ||||||
|  | 
 | ||||||
|  | 			return { | ||||||
|  | 				key: item.key, | ||||||
|  | 				value: Math.round(valueAverage), | ||||||
|  | 				delta: Math.round(deltaAverage), | ||||||
|  | 			}; | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
| 		countryItem.deathGrowthRate = getGrowthRate(countryItem); | 		countryItem.deathGrowthRate = getGrowthRate(countryItem); | ||||||
| 		return countryItem; | 		return countryItem; | ||||||
| 	}); | 	}); | ||||||
| 
 | 
 | ||||||
| 	const worldData = { | 	const worldData = { | ||||||
| 		name: 'The World', | 		name: 'Worldwide', | ||||||
| 		safeName: 'the-world', | 		safeName: 'worldwide', | ||||||
| 		total: 0, | 		total: 0, | ||||||
| 		countries: countryArr, | 		countries: countryArr, | ||||||
| 		timeSeriesDaily: {}, | 		timeSeriesDaily: {}, | ||||||
| @ -530,6 +554,18 @@ const processGlobalDeaths = async () => { | |||||||
| 		}; | 		}; | ||||||
| 	}); | 	}); | ||||||
| 
 | 
 | ||||||
|  | 	worldData.rollingAverageDaily = worldData.timeSeriesDaily.map((item, i) => { | ||||||
|  | 		const prevValues = worldData.timeSeriesDaily.slice(Math.max(0, i - 6), i); | ||||||
|  | 		const valueAverage = (item.value + prevValues.reduce((sum, next) => sum + next.value, 0)) / (1 + prevValues.length); | ||||||
|  | 		const deltaAverage = (item.delta + prevValues.reduce((sum, next) => sum + next.delta, 0)) / (1 + prevValues.length); | ||||||
|  | 
 | ||||||
|  | 		return { | ||||||
|  | 			key: item.key, | ||||||
|  | 			value: Math.round(valueAverage), | ||||||
|  | 			delta: Math.round(deltaAverage), | ||||||
|  | 		}; | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
| 	worldData.deathGrowthRate = getGrowthRate(worldData); | 	worldData.deathGrowthRate = getGrowthRate(worldData); | ||||||
| 	worldData.population = 7781841000; | 	worldData.population = 7781841000; | ||||||
| 	worldData.deathsPerMillion = worldData.total / worldData.population * 1000000; | 	worldData.deathsPerMillion = worldData.total / worldData.population * 1000000; | ||||||
|  | |||||||
| @ -16,6 +16,10 @@ html | |||||||
| 			.table-sm { | 			.table-sm { | ||||||
| 				font-size: 80%; | 				font-size: 80%; | ||||||
| 			} | 			} | ||||||
|  | 			.table-sm code { | ||||||
|  | 				font-size: 110%; | ||||||
|  | 				color: inherit; | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 		script. | 		script. | ||||||
| 			const charts = { | 			const charts = { | ||||||
| @ -30,12 +34,12 @@ html | |||||||
| 				const chart = new Chart(canvas.getContext('2d'), { | 				const chart = new Chart(canvas.getContext('2d'), { | ||||||
| 					type: 'line', | 					type: 'line', | ||||||
| 					data: { | 					data: { | ||||||
| 						labels: [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14], | 						labels: new Array(data.length), | ||||||
| 						datasets: [{ | 						datasets: [{ | ||||||
| 							data: data, | 							data: data, | ||||||
| 							borderColor: 'rgb(53,120,193)', | 							borderColor: 'rgb(53, 120, 193)', | ||||||
| 							borderWidth: 1, | 							borderWidth: 1, | ||||||
| 							backgroundColor: 'rgba(148,193,250,0.51)', | 							backgroundColor: 'rgba(148, 193, 250, 0.50)', | ||||||
| 						}], | 						}], | ||||||
| 					}, | 					}, | ||||||
| 					options: { | 					options: { | ||||||
| @ -55,9 +59,12 @@ html | |||||||
| 							yAxes: [ | 							yAxes: [ | ||||||
| 								{ | 								{ | ||||||
| 									display: false, | 									display: false, | ||||||
|  | 									type: 'logarithmic', | ||||||
| 									ticks: { | 									ticks: { | ||||||
| 										precision: 0, | 										precision: 0, | ||||||
| 										beginAtZero: true, | 										beginAtZero: true, | ||||||
|  | 										max: Math.pow(10, Math.ceil(Math.log10(maxValue))), | ||||||
|  | 										callback: value => Number(value.toString()), | ||||||
| 									} | 									} | ||||||
| 								}, | 								}, | ||||||
| 							], | 							], | ||||||
| @ -103,7 +110,7 @@ html | |||||||
| 
 | 
 | ||||||
| 				charts.trends.forEach((data) => { | 				charts.trends.forEach((data) => { | ||||||
| 					const axis = data.chart.options.scales.yAxes[0]; | 					const axis = data.chart.options.scales.yAxes[0]; | ||||||
| 					if (axis.type === 'linear') { | 					if (type === 'logarithmic') { | ||||||
| 						axis.type = 'logarithmic'; | 						axis.type = 'logarithmic'; | ||||||
| 						const maxLogPower = Math.ceil(Math.log10(data.maxValue)); | 						const maxLogPower = Math.ceil(Math.log10(data.maxValue)); | ||||||
| 						axis.ticks.max = Math.pow(10, maxLogPower); | 						axis.ticks.max = Math.pow(10, maxLogPower); | ||||||
| @ -118,7 +125,7 @@ html | |||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			function makeHeroChart(id, title, labels, totalDeaths, newDeaths) { | 			function makeHeroChart(id, title, labels, totalDeaths, newDeaths, rollingAverage) { | ||||||
| 				const canvas = document.getElementById(id); | 				const canvas = document.getElementById(id); | ||||||
| 
 | 
 | ||||||
| 				charts.heroMaxValue = totalDeaths[totalDeaths.length - 1]; | 				charts.heroMaxValue = totalDeaths[totalDeaths.length - 1]; | ||||||
| @ -129,20 +136,27 @@ html | |||||||
| 						labels: labels, | 						labels: labels, | ||||||
| 						datasets: [ | 						datasets: [ | ||||||
| 							{ | 							{ | ||||||
| 								label: 'Total Deaths', | 								label: 'Cumulative', | ||||||
| 								data: totalDeaths, | 								data: totalDeaths, | ||||||
| 								fill: true, | 								fill: '1', | ||||||
| 								borderColor: 'rgb(196, 64, 64)', | 								borderColor: 'rgb(196, 64, 64)', | ||||||
| 								borderWidth: 1, | 								borderWidth: 1, | ||||||
| 								backgroundColor: 'rgba(196, 128, 128, 0.25)', | 								backgroundColor: 'rgba(196, 128, 128, 0.25)', | ||||||
| 							}, | 							}, | ||||||
| 							{ | 							{ | ||||||
| 								label: 'New Deaths', | 								label: 'New (rolling)', | ||||||
| 								data: newDeaths, | 								data: rollingAverage, | ||||||
| 								fill: true, | 								fill: 'origin', | ||||||
| 								borderColor: 'rgb(64, 64, 64)', | 								borderColor: 'rgb(20,24,59)', | ||||||
|  | 								borderWidth: 1, | ||||||
|  | 								backgroundColor: 'rgba(96, 96, 164, 0.25)', | ||||||
|  | 							}, | ||||||
|  | 							{ | ||||||
|  | 								label: 'New', | ||||||
|  | 								data: newDeaths, | ||||||
|  | 								fill: false, | ||||||
|  | 								borderColor: 'rgb(96, 96, 96, 0.25)', | ||||||
| 								borderWidth: 1, | 								borderWidth: 1, | ||||||
| 								backgroundColor: 'rgba(128, 128, 128, 0.75)', |  | ||||||
| 							} | 							} | ||||||
| 						], | 						], | ||||||
| 					}, | 					}, | ||||||
| @ -163,9 +177,13 @@ html | |||||||
| 							yAxes: [ | 							yAxes: [ | ||||||
| 								{ | 								{ | ||||||
| 									display: true, | 									display: true, | ||||||
|  | 									type: 'logarithmic', | ||||||
| 									ticks: { | 									ticks: { | ||||||
| 										precision: 0, | 										precision: 0, | ||||||
| 										beginAtZero: true, | 										beginAtZero: true, | ||||||
|  | 										min: 0, | ||||||
|  | 										max: Math.pow(10, Math.ceil(Math.log10(charts.heroMaxValue))), | ||||||
|  | 										callback: value => Number(value.toString()) | ||||||
| 									}, | 									}, | ||||||
| 									afterBuildTicks: (axis, ticks) => { | 									afterBuildTicks: (axis, ticks) => { | ||||||
| 										if (axis.type === 'logarithmic') { | 										if (axis.type === 'logarithmic') { | ||||||
| @ -212,19 +230,22 @@ html | |||||||
| 								type="button" | 								type="button" | ||||||
| 								onclick="setAxisType('linear')" | 								onclick="setAxisType('linear')" | ||||||
| 								autocomplete="off" | 								autocomplete="off" | ||||||
| 								disabled |  | ||||||
| 							) Linear | 							) Linear | ||||||
| 							button.btn.btn-secondary.btn-sm.set-axis-logarithmic( | 							button.btn.btn-secondary.btn-sm.set-axis-logarithmic( | ||||||
| 								type="button" | 								type="button" | ||||||
| 								onclick="setAxisType('logarithmic')" | 								onclick="setAxisType('logarithmic')" | ||||||
| 								autocomplete="off" | 								autocomplete="off" | ||||||
|  | 								disabled | ||||||
| 							) Logarithmic | 							) Logarithmic | ||||||
| 					canvas.mx-auto(id="main-chart" width="800" height="450") | 					canvas.mx-auto(id="main-chart" width="800" height="450") | ||||||
| 					- | 					- | ||||||
| 						const growthRate = '+' + (data.deathGrowthRate * 100).toFixed(2) + '%'; | 						const growthRate = '+' + (data.deathGrowthRate * 100).toFixed(2) + '%'; | ||||||
| 						const population = 'pop. ' + data.population.toLocaleString(); | 						const population = 'pop. ' + data.population.toLocaleString(); | ||||||
| 						const deathsPerMillion = Math.round(data.deathsPerMillion) + '/million'; | 						const deathsPerMillion = Math.round(data.deathsPerMillion).toLocaleString() + '/MM'; | ||||||
| 						const heroTitle = data.name + ` (${population}, ${deathsPerMillion}, ${growthRate})`; | 						const heroTitle = [ | ||||||
|  | 							'Covid-19 Deaths: ' + data.name, | ||||||
|  | 							`${population} | ${deathsPerMillion} | ${growthRate}` | ||||||
|  | 						]; | ||||||
| 					script. | 					script. | ||||||
| 						makeHeroChart( | 						makeHeroChart( | ||||||
| 							'main-chart', | 							'main-chart', | ||||||
| @ -232,6 +253,7 @@ html | |||||||
| 							!{JSON.stringify(data.timeSeriesDaily.map(x => x.key))}, | 							!{JSON.stringify(data.timeSeriesDaily.map(x => x.key))}, | ||||||
| 							!{JSON.stringify(data.timeSeriesDaily.map(x => x.value))}, | 							!{JSON.stringify(data.timeSeriesDaily.map(x => x.value))}, | ||||||
| 							!{JSON.stringify(data.timeSeriesDaily.map(x => x.delta))}, | 							!{JSON.stringify(data.timeSeriesDaily.map(x => x.delta))}, | ||||||
|  | 							!{JSON.stringify(data.rollingAverageDaily.map(x => x.delta))}, | ||||||
| 						); | 						); | ||||||
| 
 | 
 | ||||||
| 		mixin dataTable(items, label, type) | 		mixin dataTable(items, label, type) | ||||||
| @ -246,9 +268,10 @@ html | |||||||
| 						th.text-center(data-col="million"): +sortableLinks("million") per 1M | 						th.text-center(data-col="million"): +sortableLinks("million") per 1M | ||||||
| 					th.text-center(data-col="total"): +sortableLinks("total") Total | 					th.text-center(data-col="total"): +sortableLinks("total") Total | ||||||
| 					th.text-center.sorted(data-col="today"): +sortableLinks("today") Today | 					th.text-center.sorted(data-col="today"): +sortableLinks("today") Today | ||||||
| 					th.text-center(data-col="last7"): +sortableLinks("last7") Last 7 days | 					th.text-center(data-col="yesterday"): +sortableLinks("yesterday") Yesterday | ||||||
| 					th.text-center(data-col="last30"): +sortableLinks("last30") Last 30 days | 					th.text-center(data-col="last7"): +sortableLinks("last7") Last 7 | ||||||
| 					th.text-center(data-col="growth"): +sortableLinks("growth") Growth Rate | 					th.text-center(data-col="last30"): +sortableLinks("last30") Last 30 | ||||||
|  | 					th.text-center(data-col="growth"): +sortableLinks("growth") Growth | ||||||
| 					th.text-center Trend | 					th.text-center Trend | ||||||
| 
 | 
 | ||||||
| 				- | 				- | ||||||
| @ -267,6 +290,7 @@ html | |||||||
| 						const getValue = offset => (item.timeSeriesDaily[item.timeSeriesDaily.length - offset] || {}).value || 0; | 						const getValue = offset => (item.timeSeriesDaily[item.timeSeriesDaily.length - offset] || {}).value || 0; | ||||||
| 						const getDelta = offset => (item.timeSeriesDaily[item.timeSeriesDaily.length - offset] || {}).delta || 0; | 						const getDelta = offset => (item.timeSeriesDaily[item.timeSeriesDaily.length - offset] || {}).delta || 0; | ||||||
| 						const today = getDelta(1); | 						const today = getDelta(1); | ||||||
|  | 						const yesterday = getDelta(2); | ||||||
| 						const last7 = getValue(1) - getValue(7); | 						const last7 = getValue(1) - getValue(7); | ||||||
| 						const last30 = getValue(1) - getValue(30); | 						const last30 = getValue(1) - getValue(30); | ||||||
| 					tr( | 					tr( | ||||||
| @ -276,6 +300,7 @@ html | |||||||
| 						data-total=item.total | 						data-total=item.total | ||||||
| 						data-million=item.deathsPerMillion | 						data-million=item.deathsPerMillion | ||||||
| 						data-today=today | 						data-today=today | ||||||
|  | 						data-yesterday=yesterday | ||||||
| 						data-last7=last7 | 						data-last7=last7 | ||||||
| 						data-last30=last30 | 						data-last30=last30 | ||||||
| 						data-growth=item.deathGrowthRate | 						data-growth=item.deathGrowthRate | ||||||
| @ -287,6 +312,7 @@ html | |||||||
| 							td.text-right: code: +formatNumber(Math.round(item.deathsPerMillion)) | 							td.text-right: code: +formatNumber(Math.round(item.deathsPerMillion)) | ||||||
| 						td.text-right: code: +formatNumber(item.total) | 						td.text-right: code: +formatNumber(item.total) | ||||||
| 						td.text-right.sorted: code: +formatNumber(today) | 						td.text-right.sorted: code: +formatNumber(today) | ||||||
|  | 						td.text-right: code: +formatNumber(yesterday) | ||||||
| 						td.text-right: code: +formatNumber(last7) | 						td.text-right: code: +formatNumber(last7) | ||||||
| 						td.text-right: code: +formatNumber(last30) | 						td.text-right: code: +formatNumber(last30) | ||||||
| 						td.text-right: code= Number(item.deathGrowthRate * 100).toFixed(2) + '%' | 						td.text-right: code= Number(item.deathGrowthRate * 100).toFixed(2) + '%' | ||||||
| @ -396,6 +422,7 @@ html | |||||||
| 							break; | 							break; | ||||||
| 						case 'total': | 						case 'total': | ||||||
| 						case 'today': | 						case 'today': | ||||||
|  | 						case 'yesterday': | ||||||
| 						case 'last7': | 						case 'last7': | ||||||
| 						case 'last30': | 						case 'last30': | ||||||
| 						case 'population': | 						case 'population': | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user