Getting started
This quickstart guide will walk you through the process of creating either a world map or a state map of the US with React Simple Maps. The process for both is quite similar, but the US map will focus more on the use of custom projections (Albers USA). This can be applied to any other non-global map chart you can make with SVG.
In order to get started with React Simple Maps, you will need two things:
- A working react app (check out the react guide, or next.js)
- A TopoJSON or GeoJSON map file
If you are using React Simple Maps with next.js, be sure to create a client component for the map itself.
Install
npm install react-simple-mapsThe package ships three entry points. Importing from react-simple-maps gives you everything; the subpaths let you skip the d3-zoom/d3-selection code if you do not need pan and zoom.
import { ComposableMap, Geographies } from "react-simple-maps" // everything
import { ComposableMap, Geographies } from "react-simple-maps/core" // no zoom code
import { ZoomableGroup } from "react-simple-maps/zoom" // zoom onlyWorld Map
Everything is composed inside a ComposableMap, which sets up the projection and shares it with its descendants through context. Geographies, markers, lines and annotations all read that projection to place themselves, so you only configure the projection once.
By default maps are rendered in the Equal Earth projection. You can pass other projections to projection to change this. Read the guide on projections for more information on this.
import { ComposableMap, Geographies, Geography } from "react-simple-maps"
// Path to your map file (TopoJSON, GeoJSON)
const geoUrl = "/your-world-map-topo.json"
// Simple world map using the equalEarth projection
const WorldMap = () => (
<ComposableMap>
<Geographies geography={geoUrl}>
{({ geographies }) =>
geographies.map((geo) => <Geography key={geo.rsmKey} geography={geo} />)
}
</Geographies>
</ComposableMap>
)The above code will render a map with each geography rendered in black by default (paths render in black by default in SVG). The SVG code will look like this:
<svg class="rsm-svg" viewBox="...">
<g class="rsm-geographies">
<path class="rsm-geography" d="..." />
<path class="rsm-geography" d="..." />
<path class="rsm-geography" d="..." />
...
</g>
</svg>Note that there are no width and height attributes on the svg element. ViewBox handles the aspect ratio, and the map will scale to fill its parent container by default. This way you get a "responsive" map out of the box without having to set any CSS properties.
Out of the box, the scale of the map might not be correct for your use case. If you see parts of New Zealand cut off at the edge, you can fix this by setting the scale of the projection via projectionConfig.
Borders
You can render borders in two ways. First, you could just add a stroke to each geography:
<Geography key={geo.rsmKey} geography={geo} stroke="#FFF" strokeWidth={0.5} />There is however a better way, and that is to use the borders returned alongside geographies from the Geographies component.
<Geographies geography="...">
{({ geographies, borders }) => (
<>
{geographies.map((geo) => (
<Geography key={geo.rsmKey} geography={geo} />
))}
<path
d={borders?.svgPath || ""}
fill="none"
stroke="#FFF"
strokeWidth={0.5}
/>
</>
)}
</Geographies>This way, the borders path renders one big path element for all the borders, avoiding overlaps and outlines. The outline is returned separately alongside geographies and borders.
Note that borders is a property that only gets returned if the input to geography is TopoJSON. If you are passing GeoJSON, borders and outline will not be computed and will therefore be returned as undefined. This means that you need to provide a fallback option, hence borders?.svgPath || "".
To give your map some context you can use the Sphere and Graticule components. The graticule renders steps of 10° by default, but you can modify this via the step prop to render any kind of graticule (you can even render multiple graticules). The graticule component renders a path, so any SVG path properties like stroke and strokeWidth work out of the box for styling.
<ComposableMap>
<Graticule />
<Sphere />
<Geographies geography="...">...</Geographies>
</ComposableMap>To make the map interactive and enable users to zoom in and out of geographies, you can wrap your Graticule, Sphere, and Geographies in a ZoomableGroup component.
import { ZoomableGroup } from "react-simple-maps"
const InteractiveMap = () => (
<ComposableMap>
<ZoomableGroup>
<Graticule />
<Sphere />
<Geographies geography="...">...</Geographies>
</ZoomableGroup>
</ComposableMap>
)Make sure that all of your map components are inside ZoomableGroup. Otherwise the zoom and pan functionality will only be applied on parts of your map, which will lead to strange behaviour.
Note that if you are using the ZoomableGroup component, your map will by default render at coordinates [0, 0], regardless of what rotate property you set in projectionConfig. This is expected. If you rotate your map projection, you need to adjust for that rotation via the center prop on ZoomableGroup.
<ComposableMap projectionConfig={{ rotate: [-60, 0, 0] }}>
<ZoomableGroup center={[60, 0]}>...</ZoomableGroup>
</ComposableMap>US states map
For the US states map we can keep everything the same as the world map. The only difference is that we need to change the path to the map file (in this case to a map file containing US states) and the projection (geoAlbersUSA).
import { ComposableMap, Geographies, Geography } from "react-simple-maps"
// Path to your map file (TopoJSON, GeoJSON)
const geoUrl = "/your-us-state-map-topo.json"
// Simple US map using the albersUSA projection
const UsStatesMap = () => (
<ComposableMap projection="geoAlbersUsa">
<Geographies geography={geoUrl}>
{({ geographies }) =>
geographies.map((geo) => (
<Geography
key={geo.rsmKey}
geography={geo}
fill="#06F"
opacity={Math.random()}
/>
))
}
</Geographies>
</ComposableMap>
)In the above map, opacity gets a random value between 0 and 1. This simulates a choropleth map without having to load any data for this test example.
Adding data
Both the world map and the US states map do not currently display any data. In order to show data, you would have to import a separate dataset, or embed the data in your topojson properties and then add a color scale to visualize the data.
Read the working with data guide to see the various ways in which you can visualize data in React Simple Maps using external data files.
You can also explore some of the components that come with React Simple Maps, such as Markers, Lines, and Annotations.