Source

src/utils/dataFunction.js

/**
 * General data function for fast decision tree with a numerator and
 * denominator. Calculates for a single geography.
 *
 * @category Utils/Data
 * @example
 *     const numeratorData = {
 *         cases: 500,
 *     }
 *     const denominatorData = {
 *         population: 100,
 *     }
 *     const dataParams = {
 *         nProperty: 'cases',
 *         dProperty: 'population',
 *         scale: 1000,
 *     }
 *     const result = dataFunction(numeratorData, denominatorData, dataParams) // 5000
 *
 * @param {DataRow} numeratorData - Object with data values for a single row.
 *   The numerator data, see DataRow {@link src/stores/dataStore/types.ts}
 * @param {DataRow} denominatorData - Object with data values for a single row.
 *   The denomiantor data, see DataRow {@link src/stores/dataStore/types.ts}
 * @param {Object} dataParams - Parameters for the data function, see
 *   VariableSpec {@link src/stores/paramsStore/types.ts}
 */
const dataFn = (numeratorData, denominatorData, dataParams) => {
    const { nProperty, nIndex, dProperty, dIndex, nType, dType, scale } =
        dataParams

    const nRange = nIndex <= dataParams.nRange ? nIndex : dataParams.nRange
    const dRange = dIndex <= dataParams.dRange ? dIndex : dataParams.dRange

    if (numeratorData === undefined || denominatorData === undefined) {
        return null
    }

    if (
        (nProperty !== null &&
            (numeratorData[nProperty] === undefined ||
                numeratorData[nProperty] === null)) ||
        (nIndex !== null &&
            nProperty === null &&
            (numeratorData[nIndex] === undefined ||
                numeratorData[nIndex] === null))
    ) {
        return null
    }

    if (nType === 'time-series' && dType === 'time-series') {
        if ((nRange === null) & (dRange === null)) {
            return (numeratorData[nIndex] / denominatorData[dIndex]) * scale
        } else {
            return (
                ((numeratorData[nIndex] - numeratorData[nIndex - nRange]) /
                    nRange /
                    ((denominatorData[dIndex] -
                        denominatorData[dIndex - dRange]) /
                        dRange)) *
                scale
            )
        }
    }

    if (dProperty === null && nRange === null) {
        // whole count or number -- no range, no normalization
        return (numeratorData[nProperty] || numeratorData[nIndex]) * scale
    }

    if (dProperty === null && nRange !== null) {
        // range number, daily or weekly count -- no normalization
        return (
            ((numeratorData[nIndex] - numeratorData[nIndex - nRange]) /
                nRange) *
            scale
        )
    }

    if (dProperty !== null && nRange === null) {
        // whole count or number normalized -- no range
        return (
            ((numeratorData[nProperty] || numeratorData[nIndex]) /
                (denominatorData[dProperty] || denominatorData[dIndex])) *
            scale
        )
    }

    if (dProperty !== null && nRange !== null && dRange === null) {
        // range number, daily or weekly count, normalized to a single value
        return (
            ((numeratorData[nIndex] - numeratorData[nIndex - nRange]) /
                nRange /
                (denominatorData[dProperty] || denominatorData[dIndex])) *
            scale
        )
        // } else if (dProperty!==null&&nRange!==null&&dRange!==null){ // range number, daily or weekly count, normalized to a range number, daily or weekly count
        //   console.log('getting the right col')
        //   return (
        //     (numeratorData[nIndex]-numeratorData[nIndex-nRange])/nRange)
        //     /
        //     ((denominatorData[dIndex]-denominatorData[dIndex-dIndex])/dIndex)
        //     *scale
    }

    return null
}

export default dataFn

// Pretty sweet branchless variant
// const dataFn = (numeratorData, numeratorProperty, index, range, denominatorData, denominatorProperty, denominatorIndex, denominatorRange, scale)  => {

//     return (
//       (
//         (
//           (
//             (numeratorData[index]||numeratorData[numeratorProperty])
//             -
//             ((range!==null)&&(numeratorData[index-range]))
//           )

//           /
//           (range+(range===null))
//         )
//       /
//         (
//           (
//             (
//               (denominatorData[denominatorIndex]||denominatorData[denominatorProperty])
//               -
//               ((denominatorRange!==null)&&(denominatorData[denominatorIndex-denominatorRange]))
//             )
//             /
//             (denominatorRange+(denominatorRange===null))
//           )
//           ||
//             (denominatorData[denominatorProperty])
//           ||
//           1
//         )
//       )
//       *
//       scale
//     )
// }