import { useMemo } from 'react'
import { useSelector } from 'react-redux'
import {
findIn,
getDateLists,
getDataForBins,
getFetchParams,
findSecondaryMonth,
getClosestIndex,
onlyUniqueArray,
} from '../utils'
import useGetTable from './useGetTable'
import { paramsSelectors } from '../stores/paramsStore'
import { dataSelectors } from '../stores/dataStore'
const { selectGeojsonData } = dataSelectors
const {
selectCurrentData,
selectDataParams,
selectDatasets,
selectTables,
selectVariables,
} = paramsSelectors
const dateLists = getDateLists()
/**
* Hook to get a variable, returning a 1 dimensional array of values. Arguments
* use predefined variable names, dataset selection, and date index.
*
* @category Hooks
* @param {Object} props
* @param {string} props.variable - Name of the variable to get data for
* @param {string} props.dataset - Name of the geojson dataset to use when using
* a multi-dataset variable (cases and deaths)
* @param {number} props.dateIndex - Index of the date to use -- days since
* 01/21/2020
* @returns {Array} - A 1 dimensional array of data for the variable, ordered by
* the geojson features
*/
function useGetVariable({
variable,
// priorityLoad = false,
dataset = false,
dateIndex = false,
}) {
const canLoadInBackground = useSelector(
({ data }) => data.canLoadInBackground
)
// pieces of redux state
const stateDataset = useSelector(selectCurrentData)
const currentData = dataset || stateDataset
const geojsonData = useSelector(selectGeojsonData(currentData))
const dataParams = useSelector(selectDataParams)
const datasets = useSelector(selectDatasets)
const tables = useSelector(selectTables)
const variables = useSelector(selectVariables)
// current state data params
const params = findIn(variables, 'variableName', variable)
const currDataset = findIn(datasets, 'file', currentData)
const [nIsTimeSeries, dIsTimeSeries] = [
params?.nType && params.nType.includes('time'),
params?.dType && params.dType.includes('time'),
]
const isTimeSeries = nIsTimeSeries || dIsTimeSeries
const [defaultNumeratorParams, defaultDenominatorParams] = [
params,
params,
].map((dataParams, i) =>
getFetchParams({
dataParams,
tables,
currDataset,
predicate: i === 1 ? 'denominator' : 'numerator',
dateList: dateLists['isoDateList'],
})
)
const currIndex = isTimeSeries
? getClosestIndex(
dateIndex || dataParams.nIndex || dataParams.dIndex,
defaultNumeratorParams.name || ''
) || 30
: null
const currRangeIndex = currIndex - (dataParams.nRange || dataParams.dRange)
const currTimespans = [currIndex, currRangeIndex]
.map((index) => [
!currIndex || dateLists.isoDateList.length - index < 30
? 'latest'
: dateLists.isoDateList[index]?.slice(0, 7),
!currIndex || dateLists.isoDateList.length - index < 30
? false
: findSecondaryMonth(index, dateLists.isoDateList),
])
.flat()
.filter((f) => !!f)
.filter(onlyUniqueArray)
const fetchParams = [defaultNumeratorParams, defaultDenominatorParams].map(
(params) =>
currTimespans.map((timespan, i) => ({
...params,
timespan,
}))
)
const [[numData, numReady], [denData, denReady]] = [
useGetTable({
filesToFetch: fetchParams[0],
shouldFetch: canLoadInBackground,
dateLists,
}),
useGetTable({
filesToFetch: fetchParams[1],
shouldFetch: canLoadInBackground,
dateLists,
}),
]
const data = useMemo(
() =>
getDataForBins({
numeratorData:
params.numerator === 'properties'
? geojsonData?.properties
: numData?.data,
denominatorData:
params.denominator === 'properties'
? geojsonData?.properties
: denData?.data,
dataParams: params,
binIndex: currIndex,
fixedOrder:
geojsonData?.order?.indexOrder &&
Object.values(geojsonData.order.indexOrder),
dataReady: numReady && denReady,
}),
[numReady && denReady && JSON.stringify(params)]
)
// if (numReady && denReady && variable === 'Adult Obesity') {
// debugger
// }
return data
}
export default useGetVariable
Source