Initial work on health conditions report.

This commit is contained in:
Joshua Bemenderfer
2021-12-31 18:01:49 -05:00
parent be2a75a579
commit b02aa6e0b3
8 changed files with 163 additions and 11 deletions

1
components.d.ts vendored
View File

@@ -59,6 +59,7 @@ declare module 'vue' {
TrendRiskAge: typeof import('./src/components/charts/risk/age/TrendRiskAge.vue')['default']
TrendRiskCasesAge: typeof import('./src/components/charts/risk/age/TrendRiskCasesAge.vue')['default']
'TrendRiskCasesAge copy': typeof import('./src/components/charts/risk/age/TrendRiskCasesAge copy.vue')['default']
TrendRiskHealthConditions: typeof import('./src/components/charts/risk/health-conditions/TrendRiskHealthConditions.vue')['default']
TrendTotalCases: typeof import('./src/components/charts/overall/cases/TrendTotalCases.vue')['default']
TrendTotalCasesPerCapita: typeof import('./src/components/charts/overall/cases/TrendTotalCasesPerCapita.vue')['default']
TrendTotalDeaths: typeof import('./src/components/charts/overall/deaths/TrendTotalDeaths.vue')['default']

View File

@@ -9,6 +9,7 @@ import OverallHospitalizations from './parser/overall/hospitalizations.js'
import OverallDeaths from './parser/overall/deaths.js'
import RiskAge from './parser/risk/age.js'
import RiskHealthConditions from './parser/risk/health-conditions.js'
async function main() {
const sources = await fg(['./data/raw/*.zip'])
@@ -27,6 +28,7 @@ async function main() {
await OverallDeaths(zips, counties)
await RiskAge(zips)
await RiskHealthConditions(zips)
}
main()

View File

@@ -0,0 +1,46 @@
import mkdirp from 'mkdirp'
import path from 'path'
import fsp from 'fs/promises'
import Papa from 'papaparse'
import { getCounty } from '../../util.js'
async function processSingleZip ({ date, zip }) {
const output = {
directory: `./public/data/risk/health-conditions/`,
file: `health-conditions.json`
}
try {
await fsp.rm(output.directory, { recursive: true })
} catch (e) {}
const csv = await zip.entryData('comorbidities_sum.csv').then(res => res.toString())
const rows = Papa.parse(csv, {
header: true
}).data
const results = rows.map(row => {
return {
health_condition: row.comorbidity,
sex: row.sex,
cases: +row.cases,
deaths: +row.deaths
}
}).filter(row => !!row.health_condition)
const data = {
segment: { },
headers: Object.keys(results[0]),
rows: results.map(row => Object.values(row))
}
await mkdirp(output.directory)
await fsp.writeFile(path.join(output.directory, output.file), JSON.stringify(data))
}
function process (zips) {
return processSingleZip(zips.at(-1))
}
export default process

View File

@@ -0,0 +1 @@
{"segment":{},"headers":["health_condition","sex","cases","deaths"],"rows":[["Any Chronic Condition","Female",160346,6087],["Any Chronic Condition","Male",125662,6987],["Any Chronic Condition","Total",286274,13077],["Any Chronic Condition","Unknown",266,3],["Any Disability","Female",11801,1587],["Any Disability","Male",9456,1434],["Any Disability","Total",21276,3021],["Any Disability","Unknown",19,0],["Cardiovascular Disease","Female",29854,3071],["Cardiovascular Disease","Male",27385,3746],["Cardiovascular Disease","Total",57273,6819],["Cardiovascular Disease","Unknown",34,2],["Chronic Liver Disease","Female",1819,163],["Chronic Liver Disease","Male",1577,257],["Chronic Liver Disease","Total",3397,420],["Chronic Liver Disease","Unknown",1,0],["Chronic Lung Disease","Female",43275,1738],["Chronic Lung Disease","Male",27761,1763],["Chronic Lung Disease","Total",71106,3502],["Chronic Lung Disease","Unknown",70,1],["Chronic Renal Disease","Female",6815,1345],["Chronic Renal Disease","Male",6600,1669],["Chronic Renal Disease","Total",13421,3016],["Chronic Renal Disease","Unknown",6,2],["Currently Pregnant","Female",8779,22],["Currently Pregnant","Male",0,0],["Currently Pregnant","Total",8783,22],["Currently Pregnant","Unknown",4,0],["Diabetes Mellitus","Female",36341,2519],["Diabetes Mellitus","Male",30965,3055],["Diabetes Mellitus","Total",67365,5576],["Diabetes Mellitus","Unknown",59,2],["Hypertension/High blood pressure","Female",32438,1660],["Hypertension/High blood pressure","Male",25379,1829],["Hypertension/High blood pressure","Total",57879,3489],["Hypertension/High blood pressure","Unknown",62,0],["ICU","Female",6345,2682],["ICU","Male",7999,3559],["ICU","Total",14367,6244],["ICU","Unknown",23,3],["Immunocompromised Condition","Female",9333,550],["Immunocompromised Condition","Male",5405,612],["Immunocompromised Condition","Total",14746,1162],["Immunocompromised Condition","Unknown",8,0],["Missing/Unknown status on all conditions","Female",363168,1173],["Missing/Unknown status on all conditions","Male",329985,1327],["Missing/Unknown status on all conditions","Total",701056,2502],["Missing/Unknown status on all conditions","Unknown",7903,2],["None of the above conditions","Female",386415,10347],["None of the above conditions","Male",305984,11906],["None of the above conditions","Total",693561,22253],["None of the above conditions","Unknown",1162,0],["Obesity (BMI>40)","Female",11896,421],["Obesity (BMI>40)","Male",6482,387],["Obesity (BMI>40)","Total",18389,808],["Obesity (BMI>40)","Unknown",11,0],["Other Chronic Diseases","Female",38442,2488],["Other Chronic Diseases","Male",25104,2527],["Other Chronic Diseases","Total",63599,5015],["Other Chronic Diseases","Unknown",53,0],["Smoker","Female",38238,967],["Smoker","Male",45056,1801],["Smoker","Total",83347,2768],["Smoker","Unknown",53,0],["Total with completed information","Female",400790,11146],["Total with completed information","Male",316997,12774],["Total with completed information","Total",718978,23923],["Total with completed information","Unknown",1191,3]]}

View File

@@ -0,0 +1,66 @@
<template>
<Card v-for="chart of charts" :key="chart.health_condition">
<h2 class="mb-2 text-xl text-indigo-900 flex justify-between items-center">
{{chart.health_condition}}
</h2>
<JSCharting :options="chart.options"></JSCharting>
</Card>
</template>
<script setup>
import { ref, computed } from 'vue'
import { col } from '@/components/charts/util'
import store from '@/components/charts/risk/health-conditions/store.js'
const data = store.data
const rows = computed(() => {
if (!data.value) return []
return data.value.rows.filter(r => {
return !['Missing/Unknown status on all conditions','Total with completed information'].includes(col(data, r, 'health_condition'))
})
})
const charts = computed(() => {
if (!rows.value) return {}
const dataSet = rows.value.reduce((obj, r) => {
const sex = col(data, r, 'sex')
if (sex !== 'Total') return obj
const health_condition = col(data, r, 'health_condition')
const cases = col(data, r, 'cases')
const deaths = col(data, r, 'deaths')
console.log(cases, deaths)
if (!obj[health_condition]) obj[health_condition] = {
health_condition,
points: [
{ name: 'Cases', y: cases },
{ name: 'Deaths', y: deaths }
]
}
return obj
}, {})
return Object.values(dataSet).map(({ health_condition, points }) => {
return {
health_condition,
options: {
type: 'column',
legend_visible: true,
debug: true,
// yAxis: { scale: { type: 'logarithmic', logBase: 10 } },
legend_position: 'bottom',
defaultSeries_type: 'column',
series: [{
palette: 'default',
points: points
}]
}
}
})
})
</script>

View File

@@ -0,0 +1,15 @@
import { reactive, ref, watch } from 'vue'
const store = {
data: ref(null)
}
async function refreshData() {
store.data.value = await fetch(`/data/risk/health-conditions/health-conditions.json`).then(res => res.json())
}
if (globalThis.window) {
refreshData()
}
export default store

View File

@@ -64,20 +64,24 @@
</router-link>
</li>
<li>
<router-link :to="{path: '/risk/gender'}" class="text-base rounded-lg flex items-center p-2 mr-3 hover:bg-violet-100 group" active-class="bg-violet-800 text-white hover:bg-violet-800">
<icon-mdi-gender-male-female class="mr-2"></icon-mdi-gender-male-female> by gender?
</router-link>
</li>
<li>
<router-link :to="{path: '/risk/ethnicity'}" class="text-base rounded-lg flex items-center p-2 mr-3 hover:bg-violet-100 group" active-class="bg-violet-800 text-white hover:bg-violet-800">
<icon-mdi-web class="mr-2"></icon-mdi-web> by ethnicity?
</router-link>
</li>
<li>
<router-link :to="{path: '/risk/health-condition'}" class="text-base rounded-lg flex items-center p-2 mr-3 hover:bg-violet-100 group" active-class="bg-violet-800 text-white hover:bg-violet-800">
<router-link :to="{path: '/risk/health-conditions'}" class="text-base rounded-lg flex items-center p-2 mr-3 hover:bg-violet-100 group" active-class="bg-violet-800 text-white hover:bg-violet-800">
<icon-healthicons-clinical-f-outline class="mr-2"></icon-healthicons-clinical-f-outline> by health condition?
</router-link>
</li>
<li class="flex items-center justify-between">
<!-- <router-link :to="{path: '/risk/gender'}" class="text-base rounded-lg flex items-center p-2 mr-3 hover:bg-violet-100 group" active-class="bg-violet-800 text-white hover:bg-violet-800"> -->
<a href="#" class="text-base rounded-lg flex items-center p-2 mr-3 group opacity-50">
<icon-mdi-gender-male-female class="mr-2"></icon-mdi-gender-male-female> by gender?
</a>
<span class="rounded-lg bg-violet-700 text-white text-sm px-2 py-1 mr-3">Soon</span>
</li>
<li class="flex items-center justify-between">
<!-- <router-link :to="{path: '/risk/ethnicity'}" class="text-base rounded-lg flex items-center p-2 mr-3 hover:bg-violet-100 group" active-class="bg-violet-800 text-white hover:bg-violet-800"> -->
<a href="#" class="text-base rounded-lg flex items-center p-2 mr-3 group opacity-50">
<icon-mdi-web class="mr-2"></icon-mdi-web> by ethnicity?
</a>
<span class="rounded-lg bg-violet-700 text-white text-sm px-2 py-1 mr-3">Soon</span>
</li>
</ul>
</li>
</ul>

View File

@@ -0,0 +1,17 @@
---
title: Who is most at risk by health condition?
---
<Card class="col-span-1" prose={true}>
# Who is most at risk by condition?
## What is this report useful for?
This report provides charts indicating the number of cases and deaths for a number of tracked medical conditions.
You may find it useful for assessing the relative risk of COVID to yourself or others.
</Card>
<div class="grid gap-2 lg:gap-4 grid-cols-1 xl:grid-cols-4">
<TrendRiskHealthConditions client:load/>
</div>