Completed overall testing and cases dashboard.

This commit is contained in:
Joshua Bemenderfer
2021-12-31 12:57:47 -05:00
parent bbaef02acb
commit e37988dd2f
518 changed files with 17463 additions and 285 deletions

View File

@@ -0,0 +1,109 @@
<template>
<StatCard>
<template v-slot:heading>Total Tests Performed</template>
<template v-slot:value v-if="chips.total_tests">
{{chips.total_tests.toLocaleString()}}
</template>
<template v-slot:meta v-if="chips.total_tests">
PCR + Antigen
</template>
</StatCard>
<StatCard>
<template v-slot:heading>Highest Testing Day</template>
<template v-slot:value v-if="chips.tests">
{{chips.tests.date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}}
</template>
<template v-slot:meta v-if="chips.tests">
<span class="text-indigo-500 font-bold">{{chips.tests.value.toLocaleString()}}</span> tests performed
</template>
</StatCard>
<StatCard>
<template v-slot:heading>Highest Positive Day</template>
<template v-slot:value v-if="chips.positive">
<span class="text-red-800">{{chips.positive.date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}}</span>
</template>
<template v-slot:meta v-if="chips.positive">
<span class="text-red-800 font-bold">{{chips.positive.value.toLocaleString()}}</span> new cases
</template>
</StatCard>
<StatCard>
<template v-slot:heading>7-Day Percent Positive</template>
<template v-slot:value v-if="chips.percent_positive">
<span :class="{
'text-green-600': chips.percent_positive < 2,
'text-yellow-500': chips.percent_positive >= 2 && chips.percent_positive < 5,
'text-orange-500': chips.percent_positive >= 5 && chips.percent_positive < 20,
'text-red-800': chips.percent_positive > 20
}">
{{chips.percent_positive}}<span class="font-light">%</span>
</span>
</template>
<template v-slot:meta v-if="chips.positive">
<div class="inline-flex flex-wrap text-xs -mx-1">
<div class="flex-1">
<div class="px-1 text-green-600 font-medium whitespace-nowrap">Low: &lt; 2%</div>
<div class="px-1 text-yellow-600 font-medium whitespace-nowrap">Moderate &lt; 5%</div>
</div>
<div class="flex-1">
<div class="px-1 text-orange-600 font-medium whitespace-nowrap">High &lt; 20%</div>
<div class="px-1 text-red-700 font-medium whitespace-nowrap">Very high &gt; 20%</div>
</div>
</div>
<a class="link block mt-2 text-xs" href="https://www.who.int/publications/i/item/considerations-in-adjusting-public-health-and-social-measures-in-the-context-of-covid-19-interim-guidanceLow">
Source, see p. 18
</a>
</template>
</StatCard>
</template>
<script setup>
import { reactive, computed } from 'vue'
import { col } from '@/components/charts/util'
import store from '@/components/charts/overall/testing/store.js'
const data = store.data
const chips = reactive({
total_tests: computed(() => {
if (!data.value) return null
const r = data.value.rows.at(-1)
return col(data, r, 'combined_performed_running_total')
}),
tests: computed(() => {
if (!data.value) return null
return data.value.rows.reduce((prev, r) => {
const date = new Date(col(data, r, 'report_date'))
const value = +col(data, r, 'combined_performed')
if (prev && prev.value > value) return prev
else return { date, value }
})
}),
positive: computed(() => {
if (!data.value) return null
return data.value.rows.reduce((prev, r) => {
const date = new Date(col(data, r, 'report_date'))
const value = +col(data, r, 'combined_positive')
if (prev && prev.value > value) return prev
else return { date, value }
})
}),
percent_positive: computed(() => {
if (!data.value) return null
const r = data.value.rows.at(-1)
return col(data, r, 'seven_day_percent_positive')
})
})
</script>

View File

@@ -0,0 +1,9 @@
<template>
<SliceSelector :parameters="parameters"></SliceSelector>
</template>
<script setup lang='ts'>
import store from '@/components/charts/overall/testing/store.js'
const parameters = store.parameters
</script>

View File

@@ -0,0 +1,68 @@
<template>
<Card>
<h2 class="mb-6 text-xl text-indigo-900 flex justify-between items-center">
Daily Positive Antigen Results
<select v-model="chart" class="text-base m-0">
<option value="calendar">Calendar</option>
<option value="line">Line Chart</option>
</select>
</h2>
<JSCharting v-if="chart === 'calendar'" :options="calendarOptions"></JSCharting>
<JSCharting v-if="chart === 'line'" :options="areaOptions"></JSCharting>
</Card>
</template>
<script setup>
import { ref, computed } from 'vue'
import { col, colors } from '@/components/charts/util'
import store from '@/components/charts/overall/testing/store.js'
const chart = ref('calendar')
const column = 'antigen_positive'
const parameters = store.parameters
const data = store.data
const rows = computed(() => {
if (!data.value || !parameters.value) return []
return data.value.rows
.filter(r => {
return col(data, r, 'report_date') >= parameters.value.start && col(data, r, 'report_date') <= parameters.value.end
})
})
const calendarOptions = computed(() => {
return {
type: 'calendar month solid',
palette: { colors },
calendar_initial: parameters.value ? parameters.value.end : null,
data: rows.value.map(r => ([
`${col(data, r, 'report_date')} 12:00:00`,
col(data, r, column)
]))
}
})
const areaOptions = computed(() => {
return {
type: 'lineSpline',
legend_visible: false,
xAxis: { crosshair_enabled: true, scale_type: 'time' },
palette: { colors },
defaultSeries: {
shape_opacity: 0.55,
color: colors[Math.round(colors.length / 2)],
defaultPoint_marker_visible: false
},
series: [
{
points: rows.value.map(r => ([
`${col(data, r, 'report_date')} 12:00:00`,
col(data, r, column)
]))
}
]
}
})
</script>

View File

@@ -0,0 +1,67 @@
<template>
<Card>
<h2 class="mb-6 text-xl text-indigo-900 flex justify-between items-center">
Daily Antigen Tests Performed
<select v-model="chart" class="text-base m-0">
<option value="calendar">Calendar</option>
<option value="line">Line Chart</option>
</select>
</h2>
<JSCharting v-if="chart === 'calendar'" :options="calendarOptions"></JSCharting>
<JSCharting v-if="chart === 'line'" :options="areaOptions"></JSCharting>
</Card>
</template>
<script setup>
import { ref, computed } from 'vue'
import { col, colors } from '@/components/charts/util'
import store from '@/components/charts/overall/testing/store.js'
const chart = ref('calendar')
const column = 'antigen_performed'
const parameters = store.parameters
const data = store.data
const rows = computed(() => {
if (!data.value || !parameters.value) return []
return data.value.rows
.filter(r => {
return col(data, r, 'report_date') >= parameters.value.start && col(data, r, 'report_date') <= parameters.value.end
})
})
const calendarOptions = computed(() => {
return {
type: 'calendar month solid',
palette: { colors },
calendar_initial: parameters.value ? parameters.value.end : null,
data: rows.value.map(r => ([
`${col(data, r, 'report_date')} 12:00:00`,
col(data, r, column)
]))
}
})
const areaOptions = computed(() => {
return {
type: 'lineSpline',
legend_visible: false,
xAxis: { crosshair_enabled: true, scale_type: 'time' },
palette: { colors },
defaultSeries: {
shape_opacity: 0.55,
color: colors[Math.round(colors.length / 2)],
defaultPoint_marker_visible: false
},
series: [
{
points: rows.value.map(r => ([
`${col(data, r, 'report_date')} 12:00:00`,
col(data, r, column)
]))
}
]
}
})
</script>

View File

@@ -0,0 +1,68 @@
<template>
<Card>
<h2 class="mb-6 text-xl text-indigo-900 flex justify-between items-center">
Daily Positive PCR Results
<select v-model="chart" class="text-base m-0">
<option value="calendar">Calendar</option>
<option value="line">Line Chart</option>
</select>
</h2>
<JSCharting v-if="chart === 'calendar'" :options="calendarOptions"></JSCharting>
<JSCharting v-if="chart === 'line'" :options="areaOptions"></JSCharting>
</Card>
</template>
<script setup>
import { ref, computed } from 'vue'
import { col, colors } from '@/components/charts/util'
import store from '@/components/charts/overall/testing/store.js'
const chart = ref('calendar')
const column = 'pcr_positive'
const parameters = store.parameters
const data = store.data
const rows = computed(() => {
if (!data.value || !parameters.value) return []
return data.value.rows
.filter(r => {
return col(data, r, 'report_date') >= parameters.value.start && col(data, r, 'report_date') <= parameters.value.end
})
})
const calendarOptions = computed(() => {
return {
type: 'calendar month solid',
palette: { colors },
calendar_initial: parameters.value ? parameters.value.end : null,
data: rows.value.map(r => ([
`${col(data, r, 'report_date')} 12:00:00`,
col(data, r, column)
]))
}
})
const areaOptions = computed(() => {
return {
type: 'lineSpline',
legend_visible: false,
xAxis: { crosshair_enabled: true, scale_type: 'time' },
palette: { colors },
defaultSeries: {
shape_opacity: 0.55,
color: colors[Math.round(colors.length / 2)],
defaultPoint_marker_visible: false
},
series: [
{
points: rows.value.map(r => ([
`${col(data, r, 'report_date')} 12:00:00`,
col(data, r, column)
]))
}
]
}
})
</script>

View File

@@ -0,0 +1,68 @@
<template>
<Card>
<h2 class="mb-6 text-xl text-indigo-900 flex justify-between items-center">
Daily PCR Tests Performed
<select v-model="chart" class="text-base m-0">
<option value="calendar">Calendar</option>
<option value="line">Line Chart</option>
</select>
</h2>
<JSCharting v-if="chart === 'calendar'" :options="calendarOptions"></JSCharting>
<JSCharting v-if="chart === 'line'" :options="areaOptions"></JSCharting>
</Card>
</template>
<script setup>
import { ref, computed } from 'vue'
import { col, colors } from '@/components/charts/util'
import store from '@/components/charts/overall/testing/store.js'
const chart = ref('calendar')
const column = 'pcr_performed'
const parameters = store.parameters
const data = store.data
const rows = computed(() => {
if (!data.value || !parameters.value) return []
return data.value.rows
.filter(r => {
return col(data, r, 'report_date') >= parameters.value.start && col(data, r, 'report_date') <= parameters.value.end
})
})
const calendarOptions = computed(() => {
return {
type: 'calendar month solid',
palette: { colors },
calendar_initial: parameters.value ? parameters.value.end : null,
data: rows.value.map(r => ([
`${col(data, r, 'report_date')} 12:00:00`,
col(data, r, column)
]))
}
})
const areaOptions = computed(() => {
return {
type: 'lineSpline',
legend_visible: false,
xAxis: { crosshair_enabled: true, scale_type: 'time' },
palette: { colors },
defaultSeries: {
shape_opacity: 0.55,
color: colors[Math.round(colors.length / 2)],
defaultPoint_marker_visible: false
},
series: [
{
points: rows.value.map(r => ([
`${col(data, r, 'report_date')} 12:00:00`,
col(data, r, column)
]))
}
]
}
})
</script>

View File

@@ -0,0 +1,29 @@
import { reactive, ref, watch } from 'vue'
import { formatDate } from '@/components/charts/util.js'
const today = new Date()
const end = new Date()
const start = new Date(today.valueOf() - 2592000000)
const store = {
parameters: ref({
county: '-- All --',
start: formatDate(start),
end: formatDate(end)
}),
data: ref(null)
}
async function refreshData() {
store.data.value = await fetch(`/data/state/testing/by-county/${store.parameters.value.county}.json`).then(res => res.json())
}
watch(() => store.parameters.value.county, () => {
refreshData()
})
if (globalThis.window) {
refreshData()
}
export default store