import { t } from '@/i18n'; import { formatValue } from '@/lib/format'; import { classIndex, isoLookupFromCountries, worldPaths } from '@/lib/map-geo'; import type { CountrySummary, MapResponse } from '@/lib/types'; import { ChoroplethView, type ChoroplethFeature } from './choropleth-view'; /** * Server component: joins the world geometry with `/indicators/{slug}/map` values and the country list * (for slugs and the ISO-numeric lookup), computes 5–7 quantile classes from the API legend, and hands * plain data to the interactive client view. Sequential single-hue ramp (light → dark = low → high). */ export function Choropleth({ map, countries, height, compact = false, className, title, }: { map: MapResponse; countries: CountrySummary[]; height?: number; compact?: boolean; className?: string; title?: string; }) { const { paths, sphere } = worldPaths(); const byId = new Map(countries.map((c) => [c.id, c])); // Registry numeric → ISO3 lookup (when the API exposes iso_numeric on the summary); static table otherwise. const numeric = isoLookupFromCountries(countries as Array<{ id: string; iso_numeric?: string | null }>); const breaks = (map.legend?.breaks ?? []).slice(0, 6); const k = breaks.length + 1; // classes const features: ChoroplethFeature[] = paths.map((p) => { // Prefer registry numeric lookup when the static table has no code. const iso3 = p.iso3 ?? (p.numeric ? numeric.get(p.numeric) ?? null : null); const c = iso3 ? byId.get(iso3) : undefined; const v = iso3 ? map.values[iso3] : undefined; return { iso3, name: c?.name ?? p.name, slug: c?.slug ?? null, flag: c?.flag ?? null, d: p.d, value: typeof v === 'number' ? v : null, cls: typeof v === 'number' ? classIndex(v, breaks) : null, }; }); const spec = map.indicator; const legendItems = Array.from({ length: k }, (_, i) => { const lo = i === 0 ? map.legend.min : breaks[i - 1]!; const hi = i === k - 1 ? map.legend.max : breaks[i]!; return { cls: i, label: `${formatValue(lo, spec)} – ${formatValue(hi, spec)}` }; }); const year = map.year_used ?? map.year ?? ''; const summary = t('chart.summary.map', { name: spec.name, year, n: map.n, min: formatValue(map.legend.min, spec), max: formatValue(map.legend.max, spec) }); return ( ); }