react-uzbekistan-map
v0.1.0
Published
Customizable SVG map of Uzbekistan for React — 14 regions and 199 districts (tumans) with built-in metadata, choropleth support, and drill-down.
Maintainers
Readme
react-uzbekistan-map
A customizable SVG map of Uzbekistan for React — all 14 regions (viloyatlar, the Republic of Karakalpakstan, and Tashkent city) and all 199 districts (tumanlar), with built-in metadata, choropleth support, tooltips, and region drill-down. TypeScript-first, zero runtime dependencies.
npm install react-uzbekistan-map| Population choropleth | Drill-down into a region |
| --- | --- |
| |
|
All three images are actual component output, generated by
scripts/generate-previews.mjs from the shipped geometry.
Quick start
import { UzbekistanMap } from 'react-uzbekistan-map';
export function App() {
return (
<UzbekistanMap
language="uz"
onRegionClick={(region) => console.log(region.id, region.capital.uz)}
/>
);
}That renders the country divided into its 14 first-level divisions with localized labels and a built-in tooltip.
Features
- Accurate geometry — derived from the geoBoundaries UZB ADM2 dataset (UN OCHA), so region borders nest exactly with district borders.
- Built-in data — every region ships with its ISO 3166-2 code, names in
4 locales (
uz,uz-Cyrl,ru,en), capital, population estimate, and area. - Choropleth — pass
data={{ 'UZ-FA': 42, ... }}and values are mapped to colors (default blue scale, or bring your owncolorScale). - Drill-down —
focusRegion="UZ-FA"zooms into Fergana and shows its districts; other regions stay visible but dimmed. - Districts view —
view="districts"draws all 199 tumans country-wide. - Fully stylable —
themefor global colors,regionStyle/districtStylefor per-unit SVG props,renderLabelto completely replace label rendering, customtooltipcontent. - Responsive by default — pure
viewBox-based SVG that scales to its container at any width while keeping its aspect ratio; labels scale with the map. - Custom markers — children render inside the SVG; use
projectPoint(lon, lat)to convert real coordinates into map space. - Accessible — clickable units are keyboard-focusable buttons with
localized
aria-labels.
Examples
Population choropleth
import { UzbekistanMap, regions } from 'react-uzbekistan-map';
const population = Object.fromEntries(regions.map((r) => [r.id, r.population]));
<UzbekistanMap data={population} language="en" />;Drill-down into a region
function DrillDownMap() {
const [focus, setFocus] = useState<RegionId | null>(null);
return (
<>
{focus && <button onClick={() => setFocus(null)}>← Back</button>}
<UzbekistanMap
focusRegion={focus}
onRegionClick={(r) => setFocus(r.id)}
onDistrictClick={(d) => console.log(d.id)}
/>
</>
);
}Custom styling
<UzbekistanMap
theme={{ fill: '#0f172a', stroke: '#1e293b', hoverFill: '#38bdf8' }}
regionStyle={(region) =>
region.id === 'UZ-QR' ? { fill: 'goldenrod' } : undefined
}
/>Markers at real coordinates
import { UzbekistanMap, projectPoint } from 'react-uzbekistan-map';
const [x, y] = projectPoint(69.2401, 41.2995); // Tashkent
<UzbekistanMap>
<circle cx={x} cy={y} r={6} fill="crimson" />
</UzbekistanMap>;Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| view | 'regions' \| 'districts' | 'regions' | Admin level to draw. |
| focusRegion | RegionId \| null | null | Zoom into one region and show its districts. |
| language | 'uz' \| 'uz-Cyrl' \| 'ru' \| 'en' | 'uz' | Label/tooltip language. |
| showLabels | boolean | auto | Name labels (on for regions view). |
| data | Record<string, number> | — | Choropleth values by region/district id. |
| colorScale | (value, min, max) => string | blue scale | Value → fill color. |
| theme | Partial<MapTheme> | — | Global colors, stroke, label font. |
| regionStyle | (region) => SVGProps | — | Per-region overrides. |
| districtStyle | (district) => SVGProps | — | Per-district overrides. |
| selectedId | string \| null | null | Controlled selection highlight. |
| onRegionClick | (region, event) => void | — | Also enables pointer cursor + keyboard activation. |
| onDistrictClick | (district, event) => void | — | Same, for districts. |
| onHover | (unit \| null) => void | — | Hovered unit changed. |
| tooltip | boolean \| (unit) => ReactNode | true | Built-in or custom tooltip. |
| renderLabel | (unit, {x, y, fontSize}) => ReactNode | — | Replace label rendering entirely (return null to hide one). |
| children | ReactNode | — | Rendered inside the SVG (markers etc.). |
Also exported: regionData, regions, getRegion(id), regionShapes,
districtShapes, projectPoint, MAP_VIEWBOX, COUNTRY_PATH, and all types.
Data notes
- Region population figures are approximate official estimates (early 2024). Corrections via PR are very welcome.
- District names currently ship in English transliteration only; localized district names are on the roadmap.
- Boundary geometry: geoBoundaries UZB ADM2 (source: UN OCHA ROCCA, CC BY 3.0 IGO), cleaned and simplified. Boundaries are suitable for data visualization, not for legal/cadastral use.
Development
npm install
npm run geodata # rebuild src/data/geo/* from raw GeoJSON in geodata/
npm run dev # demo playground (Vite)
npm run typecheck
npm run build # ESM + CJS + d.ts into dist/Roadmap
- Localized district names (uz / uz-Cyrl / ru) + per-district metadata
- Bundle-size optimization: shared-arc encoding, lazy-loaded district chunks
- Animated zoom transitions for drill-down
- SSR snapshot tests, visual regression tests
- Optional city/capital markers layer
License
MIT — see LICENSE. Map data © geoBoundaries / UN OCHA ROCCA (CC BY 3.0 IGO).
