A variation of this map. The SwissMap
component gets passed a url
property with which it attempts to load the map data. When the loading callback fires it updates its state and gets re-rendered. Reload the page if the loading fails (the URL has a 30 % chance to be invalid).
Last active
March 23, 2016 15:04
-
-
Save jstcki/9238916 to your computer and use it in GitHub Desktop.
React Map Component
This file contains 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
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
font: 12px Helvetica, sans-serif; | |
position: relative; | |
width: 960px; | |
height: 500px; | |
} | |
.message { | |
position: relative; | |
text-align: center; | |
top: 50%; | |
margin: -15px auto 0 auto; | |
line-height: 30px; | |
width: 500px; | |
} | |
.message--error { | |
color: red; | |
} | |
.country { | |
fill: #222; | |
} | |
.canton-boundaries { | |
fill: none; | |
stroke: #fff; | |
stroke-width: 1; | |
} | |
.municipality-boundaries { | |
fill: none; | |
stroke: #fff; | |
stroke-width: .3; | |
} | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="http://d3js.org/topojson.v1.min.js"></script> | |
<script src="http://fb.me/react-0.9.0.min.js"></script> | |
<script> | |
var SwissMap = React.createClass({ | |
getInitialState: function() { | |
return { | |
ch: null, | |
error: null | |
}; | |
}, | |
componentDidMount: function() { | |
// Artificially delay the loading, so the loading state stays visible for a while. | |
setTimeout(this.loadData, 2000); | |
}, | |
loadData: function() { | |
d3.json(this.props.url, this.dataLoaded); | |
}, | |
dataLoaded: function(err, data) { | |
if (err) return this.setState({error: err}); | |
this.setState({data: data}); | |
}, | |
render: function() { | |
if (this.state.error) return React.DOM.div({className: 'message message--error'}, 'Whoops! ' + this.props.url + ' does not exist. Reload the page to try again.'); | |
if (!this.state.data) return React.DOM.div({className: 'message'}, 'Loading ' + this.props.url); | |
var ch = this.state.data, | |
country = topojson.feature(ch, ch.objects.country), | |
municipalityBoundaries = topojson.mesh(ch, ch.objects.municipalities, function(a, b) { return a !== b; }), | |
cantonBoundaries = topojson.mesh(ch, ch.objects.cantons, function(a, b) { return a !== b; }); | |
var path = d3.geo.path() | |
.projection(null); | |
return React.DOM.svg({width: this.props.width, height: this.props.height}, | |
React.DOM.path({ | |
className: 'country', | |
d: path(country) | |
}), | |
React.DOM.path({ | |
className: 'municipality-boundaries', | |
d: path(municipalityBoundaries) | |
}), | |
React.DOM.path({ | |
className: 'canton-boundaries', | |
d: path(cantonBoundaries) | |
}) | |
); | |
} | |
}); | |
React.renderComponent( | |
SwissMap({ | |
url: Math.random() > 0.3 ? 'ch.json' : 'not-there.json', | |
width: 960, | |
height: 500 | |
}), | |
document.body | |
); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment