/** * Shared key format and coverage check for the per-group posterior draws * returned by `useDrawDistribution`. Both the hook (which builds the map) and * the charts (which read it, and decide whether to claim "real draws") go * through here so the key format lives in exactly one place. */ /** Canonical key for one race×sex group in a `drawsByGroup` map. */ export function groupKey(race, sex) { return `${race}_${sex}` } /** * True only when *every* group in `groups` has a non-empty draw array. * * `useDrawDistribution`'s `status` is an any-group signal: it reports 'ready' * as soon as one group has real draws. Charts fall back per-group, so the * chart-wide "these are real posterior draws" note/caption must be gated on * complete coverage instead — a group can be missing because its enrollment is * falsy or because its (LEAID, RACE, SEX) isn't in the parquet shard. * * Returns false for an empty group list (nothing rendered means nothing to * claim) and for a null map (loading, or the fetch failed outright). * * @param {Record | null | undefined} drawsByGroup * @param {Array<{race: string, sex: string}>} groups - the groups a chart is * actually rendering, not everything the API returned. * @returns {boolean} */ export function hasDrawsForAll(drawsByGroup, groups) { if (!drawsByGroup || !groups?.length) return false return groups.every((g) => (drawsByGroup[groupKey(g.race, g.sex)]?.length ?? 0) > 0) }