Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend: Update CHR provider to handle historical data and fallbacks #3892

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions frontend/src/data/config/DatasetMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ export type DatasetId =
| 'cdc_wonder_data-alls_state_historical'
| 'census_pop_estimates-race_and_ethnicity'
| 'chr_data-race_and_ethnicity_county_current'
| 'chr_data-race_and_ethnicity_county_historical'
| 'chr_data-alls_county_current'
| 'chr_data-alls_county_historical'
| 'covid_tracking_project-cases_by_race_state'
| 'covid_tracking_project-deaths_by_race_state'
| 'covid_tracking_project-hospitalizations_by_race_state'
Expand Down Expand Up @@ -913,6 +916,24 @@ export const DatasetMetadataMap: Record<DatasetId, DatasetMetadata> = {
contains_nh: true,
source_id: 'chr',
},
'chr_data-race_and_ethnicity_county_historical': {
name: 'Prevalence of multiple chronic disease, behavioral health, and social determinants of health by county, with race/ethnicity breakdowns for some topics.',
original_data_sourced: '2016-2021',
contains_nh: true,
source_id: 'chr',
},
'chr_data-alls_county_current': {
name: 'Prevalence of multiple chronic disease, behavioral health, and social determinants of health by county.',
original_data_sourced: '2021',
contains_nh: true,
source_id: 'chr',
},
'chr_data-alls_county_historical': {
name: 'Prevalence of multiple chronic disease, behavioral health, and social determinants of health by county.',
original_data_sourced: '2016-2021',
contains_nh: true,
source_id: 'chr',
},
the_unitedstates_project: {
name: '@unitedstates is a shared commons of data and tools for the United States. Made by the public, used by the public. Featuring work from people with the Sunlight Foundation, GovTrack.us, the New York Times, the Electronic Frontier Foundation, and the internet.',
original_data_sourced: '1915-2023',
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/data/providers/AhrProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getDataFetcher,
resetCacheDebug,
} from '../../utils/globals'
import type { ScrollableHashId } from '../../utils/hooks/useStepObserver'
import {
type DatasetId,
type DatasetIdWithStateFIPSCode,
Expand All @@ -21,10 +22,10 @@ async function ensureCorrectDatasetsDownloaded(
ahrDatasetId: DatasetId,
baseBreakdown: Breakdowns,
demographicType: DemographicType,
cardId?: ScrollableHashId,
) {
const ahrProvider = new AhrProvider()
const specificId = appendFipsIfNeeded(ahrDatasetId, baseBreakdown)

dataFetcher.setFakeDatasetLoaded(specificId, [])

// Evaluate the response with requesting "All" field
Expand All @@ -34,9 +35,9 @@ async function ensureCorrectDatasetsDownloaded(
baseBreakdown.addBreakdown(demographicType),
'suicide',
'current',
cardId,
),
)

expect(dataFetcher.getNumLoadDatasetCalls()).toBe(1)

const consumedDatasetIds: Array<DatasetId | DatasetIdWithStateFIPSCode> = [
Expand Down Expand Up @@ -115,9 +116,10 @@ describe('AhrProvider', () => {

test('County and Sex Breakdown (should just get the ALLs)', async () => {
await ensureCorrectDatasetsDownloaded(
'chr_data-race_and_ethnicity_county_current',
'chr_data-alls_county_current',
Breakdowns.forFips(new Fips('01001')),
SEX,
'rates-over-time', // need to mock a call from a card that should get fallbacks
)
})
})
150 changes: 40 additions & 110 deletions frontend/src/data/providers/AhrProvider.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { getParentDropdownFromDataTypeId } from '../../utils/MadLibs'
import { getDataManager } from '../../utils/globals'
import type { DatasetId } from '../config/DatasetMetadata'
import type { DropdownVarId } from '../config/DropDownIds'
import { BEHAVIORAL_HEALTH_CATEGORY_DROPDOWNIDS } from '../config/MetricConfigBehavioralHealth'
import type { DataTypeId, MetricId } from '../config/MetricConfigTypes'
import type {
Breakdowns,
DemographicBreakdownKey,
TimeView,
} from '../query/Breakdowns'
import { type MetricQuery, MetricQueryResponse } from '../query/MetricQuery'
import type { Breakdowns } from '../query/Breakdowns'
import {
type MetricQuery,
MetricQueryResponse,
resolveDatasetId,
} from '../query/MetricQuery'
import { appendFipsIfNeeded } from '../utils/datasetutils'
import VariableProvider from './VariableProvider'

Expand Down Expand Up @@ -139,95 +138,15 @@ class AhrProvider extends VariableProvider {
])
}

getDatasetId(
breakdowns: Breakdowns,
dataTypeId?: DataTypeId,
timeView?: TimeView,
): DatasetId | undefined {
const currentDropdown: DropdownVarId | undefined =
dataTypeId && getParentDropdownFromDataTypeId(dataTypeId)
const isBehavioralHealth =
currentDropdown &&
BEHAVIORAL_HEALTH_CATEGORY_DROPDOWNIDS.includes(currentDropdown as any)

if (breakdowns.geography === 'national') {
if (timeView === 'current') {
if (breakdowns.hasOnlyRace())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_race_and_ethnicity_national_current'
: 'graphql_ahr_data-non-behavioral_health_race_and_ethnicity_national_current'
if (breakdowns.hasOnlySex())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_sex_national_current'
: 'graphql_ahr_data-non-behavioral_health_sex_national_current'
if (breakdowns.hasOnlyAge())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_age_national_current'
: 'graphql_ahr_data-non-behavioral_health_age_national_current'
}

if (timeView === 'historical') {
if (breakdowns.hasOnlyRace())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_race_and_ethnicity_national_historical'
: 'graphql_ahr_data-non-behavioral_health_race_and_ethnicity_national_historical'
if (breakdowns.hasOnlySex())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_sex_national_historical'
: 'graphql_ahr_data-non-behavioral_health_sex_national_historical'
if (breakdowns.hasOnlyAge())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_age_national_historical'
: 'graphql_ahr_data-non-behavioral_health_age_national_historical'
}
}
if (breakdowns.geography === 'state') {
if (timeView === 'current') {
if (breakdowns.hasOnlyRace())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_race_and_ethnicity_state_current'
: 'graphql_ahr_data-non-behavioral_health_race_and_ethnicity_state_current'
if (breakdowns.hasOnlySex())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_sex_state_current'
: 'graphql_ahr_data-non-behavioral_health_sex_state_current'
if (breakdowns.hasOnlyAge())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_age_state_current'
: 'graphql_ahr_data-non-behavioral_health_age_state_current'
}

if (timeView === 'historical') {
if (breakdowns.hasOnlyRace())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_race_and_ethnicity_state_historical'
: 'graphql_ahr_data-non-behavioral_health_race_and_ethnicity_state_historical'
if (breakdowns.hasOnlySex())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_sex_state_historical'
: 'graphql_ahr_data-non-behavioral_health_sex_state_historical'
if (breakdowns.hasOnlyAge())
return isBehavioralHealth
? 'graphql_ahr_data-behavioral_health_age_state_historical'
: 'graphql_ahr_data-non-behavioral_health_age_state_historical'
}
}
// some county data is available via CHR
if (
breakdowns.geography === 'county' &&
dataTypeId &&
CHR_DATATYPE_IDS.includes(dataTypeId)
) {
if (breakdowns.hasExactlyOneDemographic())
return 'chr_data-race_and_ethnicity_county_current'
}
}

async getDataInternal(
metricQuery: MetricQuery,
): Promise<MetricQueryResponse> {
const { breakdowns, dataTypeId, timeView } = metricQuery
const datasetId = this.getDatasetId(breakdowns, dataTypeId, timeView)
const { isChr, categoryPrefix } = getDatasetDetails(metricQuery)
const { datasetId, isFallbackId, breakdowns } = resolveDatasetId(
isChr ? 'chr_data' : 'graphql_ahr_data',
isChr ? '' : categoryPrefix,
metricQuery,
)

if (!datasetId) {
return new MetricQueryResponse([], [])
Expand All @@ -241,25 +160,13 @@ class AhrProvider extends VariableProvider {
df = this.filterByGeo(df, breakdowns)
df = this.renameGeoColumns(df, breakdowns)

if (
breakdowns.geography === 'county' &&
dataTypeId &&
CHR_DATATYPE_IDS.includes(dataTypeId) &&
!breakdowns.hasOnlyRace()
) {
let requestedDemographic: DemographicBreakdownKey = 'race_and_ethnicity'
// CHR: treat the "All" rows from by race as "All" for sex/age
df = df.filter((row) => row['race_and_ethnicity'] === 'All')
if (breakdowns.hasOnlySex()) requestedDemographic = 'sex'
if (breakdowns.hasOnlyAge()) requestedDemographic = 'age'
df = df.renameSeries({
race_and_ethnicity: requestedDemographic,
})
if (isFallbackId) {
df = this.castAllsAsRequestedDemographicBreakdown(df, breakdowns)
} else {
df = this.applyDemographicBreakdownFilters(df, breakdowns)
df = this.removeUnrequestedColumns(df, metricQuery)
}

df = this.applyDemographicBreakdownFilters(df, breakdowns)
df = this.removeUnrequestedColumns(df, metricQuery)

return new MetricQueryResponse(df.toArray(), consumedDatasetIds)
}

Expand All @@ -281,3 +188,26 @@ class AhrProvider extends VariableProvider {
}

export default AhrProvider

function getDatasetDetails(metricQuery: MetricQuery) {
const { dataTypeId, breakdowns } = metricQuery
if (
dataTypeId &&
CHR_DATATYPE_IDS.includes(dataTypeId) &&
breakdowns.geography === 'county'
)
return { isChr: true, categoryPrefix: '' }

const currentDropdown: DropdownVarId | undefined =
dataTypeId && getParentDropdownFromDataTypeId(dataTypeId)

const isBehavioralHealth =
currentDropdown &&
BEHAVIORAL_HEALTH_CATEGORY_DROPDOWNIDS.includes(currentDropdown as any)

const categoryPrefix = isBehavioralHealth
? 'behavioral_health_'
: 'non-behavioral_health_'

return { isChr: false, categoryPrefix }
}
Loading