This is the end result of this tutorial.
React-simple-maps is a react component library to help make SVG mapping with d3-geo, TopoJSON, and React easier. One of the strengths of using react-simple-maps
is that it gives React full control over the DOM and does not treat the SVG map as a black box. This means that react-simple-maps
can easily take advantage of the entire React ecosystem and all the good things that come with it.
React-simple-maps
was partially inspired by the declarative api of Victory
charts. If you haven’t heard about Victory
, take a look on github, or see the examples and guides on their website.
The great thing about Victory
charts is that it does not have to be used standalone, but that it can be embedded in already existing SVG containers. This makes it possible to combine Victory
charts with any SVG visual, e.g. a map ;)
This tutorial will go over how to combine the two libraries and create the map shown on the cover of this article. If you are just interested in the final code, head on over to the github repo.
Here’s what this tutorial will cover:
<VictoryPie />
inside <Marker />
componentsLet’s get started.
The visualisation for this tutorial shows the language distribution in Switzerland by canton. Even though Switzerland has a population of slightly more than 8 million, it has four official languages: German, French, Italian, and Romansh. This results in Switzerland being divided into three distinct linguistic regions, each with its own culture. Romansh constitutes a special case, as it is only spoken by 0.5% of the Swiss population, mostly in the canton of Graubünden.
While most cantons will identify predominantly with one language, there are some (Fribourg, Valais, Bern, and Graubünden) that have quite a diverse linguistic environment.
In order to simplify the setup for this tutorial, I will be using next.js to create an app scaffold. To get started, install these dependencies:
$ npm install react react-dom react-simple-maps victory next --save
In terms of scaffolding, here’s what the app structure will look like:
┬ app├─┬ data│ └── index.js├─┬ pages│ └── index.js├─┬ static│ └── cantons.json├── node_modules└── package.json
Don’t forget to add the next dev
script in package.json
.
// ./package.json...scripts: {"dev": "next",...}...
Every mapping visualisation starts with a good base map, and a solid TopoJSON file. If you are new to TopoJSON, check out the docs here. If you are new to creating your own TopoJSON files, you can check out my article on How to convert and prepare TopoJSON files for interactive mapping with d3.
The original shapefile used to create the TopoJSON file came from gadm.org.
The projection for the map of Switzerland was derived from this block, made by Mike Bostock. In order to use the Albers projection with react-simple-maps
, we need to load in d3-geo. Since react-simple-maps
uses d3-geo internally, it should already be installed. Using geoAlbers
from d3-geo, you can easily create a custom projection, and pass it into the projection
prop of <ComposableMap />
.
You can now run the app. Just type $ npm run dev
in the terminal, and go to [http://localhost:3000](http://localhost:3000/)
.
The dataset for this tutorial comes from the Swiss Federal Statistics Office. In order to not mess with asynchronous data loading, this small dataset can be easily converted into a javascript object, and loaded in as a normal script. Here’s an excerpt:
// ./data/index.js
export const cantons = [{id: 25,canton: "Zurich",coordinates: [ 8.6356, 47.3595 ],languages: [{ name: "German", value: 83.1 },{ name: "French", value: 3 },{ name: "Italian", value: 5.9 },{ name: "Romansh", value: 0.4 },]},...
The data can now be easily imported into the app:
// ./pages/index.js
import { cantons } from "../data"...
The final step is now to use the data to render out react-simple-maps
<Marker />
components and render <VictoryPie />
charts into those markers.
Note: The two <circle />
elements added on lines 67-68
, are just for decorative purposes.
This tutorial covered how to use react-simple-maps
together with Victory
charts to create a nice little map of Switzerland’s language distribution by canton. The two libraries play well together, so give it a try. Thanks for reading, and happy mapping! ;)
For the complete code example, see this github repo.
For more information on declarative mapping, check out How to create pure react SVG maps with topojson and d3-geo.
For information on how to convert shapefiles into TopoJSON to use with react-simple-maps
, or d3, check out How to convert and prepare TopoJSON files for interactive mapping with d3.
More information about react-simple-maps
More information about Victory.
Thanks to the folks at Formidable, for creating the awesomeness that is Victory
and of course Mike Bostock, and Jason Davies for their work on d3 and for being a continuous source of inspiration.