Created
February 20, 2019 23:07
-
-
Save phocks/06fe6f5ea02d776e4be23a1dda94ba7b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useEffect } from "react"; | |
import styles from "./styles.scss"; | |
import { feature } from "topojson"; | |
const d3 = Object.assign({}, require("d3-geo")); | |
/** | |
* OK this is some documentation | |
* @param {*} props | |
*/ | |
const GeoMap = React.memo(props => { | |
let projection; | |
let path; | |
// Set up component props | |
const { | |
width = 800, | |
height = 600, | |
mapFileLocation = __webpack_public_path__ + "topo/australia.json", | |
focusPoint = [133.15399233370441, -24.656909465155994], | |
margin = 64, | |
fill = "#ddd", | |
...restProps | |
} = props; | |
// Set up component state | |
const [geo, setGeo] = useState(null); | |
// Component did mount? | |
const componentDidMount = () => { | |
return componentDidUnmount; | |
}; | |
// Component did unmount? | |
const componentDidUnmount = () => {}; | |
// Side effect after first mount | |
useEffect(componentDidMount, []); | |
// Used to rotate the projection | |
const invertLongLat = longlat => { | |
return [-longlat[0], -longlat[1]]; | |
}; | |
const loadJson = async fileLocation => { | |
const data = await fetch(fileLocation); | |
const topo = await data.json(); | |
const objects = Object.values(topo.objects); // Get array of objects so we don't need the name | |
const geoJsonObject = feature(topo, objects[0]); | |
setGeo(geoJsonObject); | |
}; | |
// Load map file if not already loaded | |
if (!geo) loadJson(mapFileLocation); | |
else { | |
projection = d3 | |
.geoMercator() | |
.rotate(invertLongLat(focusPoint)) | |
.fitExtent( | |
// Auto zoom | |
[[margin, margin], [width - margin, height - margin]], | |
geo | |
); | |
path = d3.geoPath().projection(projection); | |
} | |
return ( | |
<div className={styles.root}> | |
<svg className={styles.svg} width={width} height={height}> | |
{geo && ( | |
<g className={styles.group}> | |
{geo.features.map((data, iteration) => ( | |
<path | |
key={`path-${iteration}`} | |
d={path(data)} | |
className={styles.feature} | |
fill={fill} | |
stroke="white" | |
strokeWidth={0.5} | |
/> | |
))} | |
</g> | |
)} | |
</svg> | |
</div> | |
); | |
}); | |
export default GeoMap; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment