Skip to content

Commit

Permalink
Implement CountyMap
Browse files Browse the repository at this point in the history
  • Loading branch information
Swizec committed Oct 28, 2018
1 parent 4e09024 commit 4c9ba22
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/App.js
Expand Up @@ -64,7 +64,7 @@ class App extends Component {
y={0}
width={500}
height={500}
zoom={1}
zoom={null}
/>
</svg>
</div>
Expand Down
42 changes: 42 additions & 0 deletions src/components/CountyMap/County.js
@@ -0,0 +1,42 @@
import React, { Component } from "react";
import _ from "lodash";

const ChoroplethColors = _.reverse([
"rgb(247,251,255)",
"rgb(222,235,247)",
"rgb(198,219,239)",
"rgb(158,202,225)",
"rgb(107,174,214)",
"rgb(66,146,198)",
"rgb(33,113,181)",
"rgb(8,81,156)",
"rgb(8,48,107)"
]);
const BlankColor = "rgb(240,240,240)";

class County extends Component {
shouldComponentUpdate(nextProps, nextState) {
const { zoom, value } = this.props;

return zoom !== nextProps.zoom || value !== nextProps.value;
}

render() {
const { value, geoPath, feature, quantize } = this.props;

let color = BlankColor;

if (value) {
color = ChoroplethColors[quantize(value)];
}

return (
<path
d={geoPath(feature)}
style={{ fill: color }}
title={feature.id}
/>
);
}
}
export default County;
104 changes: 104 additions & 0 deletions src/components/CountyMap/CountyMap.js
@@ -0,0 +1,104 @@
import React from "react";
import * as d3 from "d3";
import * as topojson from "topojson";
import _ from "lodash";

import County from "./County";

class CountyMap extends React.Component {
constructor(props) {
super(props);

const projection = d3.geoAlbersUsa().scale(1280);

this.state = {
geoPath: d3.geoPath().projection(projection),
quantize: d3.scaleQuantize().range(d3.range(9)),
projection
};
}

static getDerivedStateFromProps(props, state) {
let { projection, quantize, geoPath } = state;

projection
.translate([props.width / 2, props.height / 2])
.scale(props.width * 1.3);

if (props.zoom && props.usTopoJson) {
const us = props.usTopoJson,
USstatePaths = topojson.feature(us, us.objects.states).features,
id = _.find(props.USstateNames, { code: props.zoom }).id;

projection.scale(props.width * 4.5);

const centroid = geoPath.centroid(_.find(USstatePaths, { id: id })),
translate = projection.translate();

projection.translate([
translate[0] - centroid[0] + props.width / 2,
translate[1] - centroid[1] + props.height / 2
]);
}

if (props.values) {
quantize.domain([
d3.quantile(props.values, 0.15, d => d.value),
d3.quantile(props.values, 0.85, d => d.value)
]);
}

return {
...state,
projection,
quantize
};
}

render() {
const { usTopoJson, values, zoom } = this.props,
{ geoPath, quantize } = this.state;

if (!usTopoJson) {
return null;
} else {
const us = usTopoJson,
USstatesMesh = topojson.mesh(
us,
us.objects.states,
(a, b) => a !== b
),
counties = topojson.feature(us, us.objects.counties).features;

const countyValueMap = _.fromPairs(
values.map(d => [d.countyID, d.value])
);

return (
<g>
{counties.map(feature => (
<County
geoPath={geoPath}
feature={feature}
zoom={zoom}
key={feature.id}
quantize={quantize}
value={countyValueMap[feature.id]}
/>
))}

<path
d={geoPath(USstatesMesh)}
style={{
fill: "none",
stroke: "#fff",
strokeLineJoin: "round"
}}
/>
</g>
);
}
}
}

export default CountyMap;
1 change: 1 addition & 0 deletions src/components/CountyMap/index.js
@@ -0,0 +1 @@
export { default } from "./CountyMap";

0 comments on commit 4c9ba22

Please sign in to comment.