Skip to content

Instantly share code, notes, and snippets.

@phocks
Created February 20, 2019 23:07
Show Gist options
  • Save phocks/06fe6f5ea02d776e4be23a1dda94ba7b to your computer and use it in GitHub Desktop.
Save phocks/06fe6f5ea02d776e4be23a1dda94ba7b to your computer and use it in GitHub Desktop.
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