...

/

Render a choropleth map of the US

Render a choropleth map of the US

Now that we have our data, it’s time to start drawing pictures - a choropleth map. That’s a map that uses colored geographical areas to encode data.

In this case, we’re going to show the delta between median household salary in a statistical county and the average salary of a single tech worker on a visa. The darker the blue, the higher the difference.

widget

There’s a lot of gray on this map because the shortened dataset doesn’t span that many counties. There’s going to be plenty in the full choropleth too, but not as much as there is here.

Turns Out™ immigration visa opportunities for techies aren’t evenly distributed throughout the country. Who knew?

Just like before, we’re going to start with changes in our App component, then build the new bit. This time, a CountyMap component spread into three files:

  • CountyMap/index.js, to make imports easier
  • CountyMap/CountyMap.js, for overall map logic
  • CountyMap/County.js, for individual county polygons

Step 1: Prep App.js

You might guess the pattern already: add an import, add a helper method or two, update render.

Press + to interact
// src/App.js
import Preloader from './components/Preloader';
import { loadAllData } from './DataHandling';
// markua-start-insert
import CountyMap from './components/CountyMap';
// markua-end-insert

That imports the CountyMap component from components/CountyMap/. Until we’re done, your browser should show an error overlay about some file or another not existing.

In the App class itself, we add a countyValue method. It takes a county entry and a map of tech salaries, and it returns the delta between median household income and a single tech salary.

Press + to interact
// src/App.js
countyValue(county, techSalariesMap) {
const medianHousehold = this.state.medianIncomes[county.id],
salaries = techSalariesMap[county.name];
if (!medianHousehold || !salaries) {
return null;
}
const median = d3.median(salaries, d => d.base_salary);
return {
countyID: county.id,
value: median - medianHousehold.medianIncome
};
}

We use this.state.medianIncomes to get the median household salary and the techSalariesMap input to get salaries for a specific census area. Then we use d3.median to calculate the median value for salaries and return a two-element dictionary with the result.

countyID specifies the county and value is the delta that our choropleth displays.

In the render method, we’ll do three things:

  • prep a list of county values
  • remove the “data loaded” indicator
  • render the map
Press + to interact
// src/App.js
render() {
if (this.state.techSalaries.length < 1) {
return (
<Preloader />
);
}
// markua-start-insert
const filteredSalaries = this.state.techSalaries,
filteredSalariesMap = _.groupBy(filteredSalaries, 'countyID'),
countyValues = this.state.countyNames.map(
county => this.countyValue(county, filteredSalariesMap)
).filter(d => !_.isNull(d));
let zoom = null;
// markua-end-insert
return (
<div className="App container">
// markua-start-delete
<h1>Loaded {this.state.techSalaries.length} salaries</h1>
// markua-end-delete
// markua-start-insert
<svg width="1100" height="500">
<CountyMap usTopoJson={this.state.usTopoJson}
USstateNames={this.state.USstateNames}
values={countyValues}
x={0}
y={0}
width={500}
height={500}
zoom={zoom} />
</svg>
// markua-end-insert
</div>
);
}

We call our dataset ...

Access this course and 1400+ top-rated courses and projects.