components/InteractiveGlobe/countryColors.jsjavascript
import { countryMetaByCca3, countriesByContinent } from "./countryMeta";
/**
* Resolves value-partnership-globe-countries.json's continent-keyed and
* per-country config into the ccn3-keyed color map InteractiveGlobe's
* polygon layer needs. `continents` is applied first (colors every country
* in that continent), then `countries` (pre-populated with every ISO
* country, `{cca3, name, state}` - only `cca3`/`state` are read here, `name`
* is an editor-facing label) on top as per-country overrides - so e.g.
* continents.Europe="highlight" plus a DEU entry with state "hide"
* highlights all of Europe except Germany.
*
* "normal" entries are treated as "no explicit choice" and skipped in both
* loops rather than written into the map - `countries` is pre-populated with
* all ~250 countries at "normal" by default (so an editor only has to change
* the ones they care about), and since "normal" is also the ultimate
* fallback color (`defaultCountryColor`), those untouched entries would
* otherwise silently overwrite a continent-level highlight/hide for every
* country in it.
*
* Shared between the 3D globe (GlobePage.jsx) and the print map
* (PrintMap.jsx) so both render the exact same country colors from the same
* content.
*
* @param {Object} [countryDisplay] - `content.valuePartnership.countryDisplay`.
* @param {string} fallbackColor - Used as `defaultCountryColor` when
* `countryDisplay.colors.normal` isn't set (config-schema.js's
* `globeFallbackCountryColor`).
* @returns {{defaultCountryColor: string, countryColorByCcn3: Map<string,string>}}
*/
export function resolveCountryColors(countryDisplay, fallbackColor) {
const defaultCountryColor = countryDisplay?.colors?.normal ?? fallbackColor;
const countryColorByCcn3 = new Map();
if (!countryDisplay) return { defaultCountryColor, countryColorByCcn3 };
const { colors } = countryDisplay;
for (const [continent, state] of Object.entries(countryDisplay.continents ?? {})) {
if (state === "normal") continue;
const color = colors?.[state];
if (!color) continue;
for (const meta of countriesByContinent(continent)) countryColorByCcn3.set(meta.ccn3, color);
}
for (const { cca3, state } of countryDisplay.countries ?? []) {
if (state === "normal") continue;
const color = colors?.[state];
const meta = countryMetaByCca3(cca3);
if (color && meta) countryColorByCcn3.set(meta.ccn3, color);
}
// sub-national areas (currently just Alaska) that don't have an ISO
// country code and so can't go through the `countries` loop above - see
// ALASKA_REGION_ID.
for (const { id, state } of countryDisplay.regions ?? []) {
if (state === "normal") continue;
const color = colors?.[state];
if (color) countryColorByCcn3.set(id, color);
}
return { defaultCountryColor, countryColorByCcn3 };
}