JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script src="https://bsouthga.github.io/d3-exploder/d3-exploder.js"></script>
<h1>Click a state!</h1>
<div id="map"></div>
CSS
#states path {
fill : #000;
stroke : #fff;
}
#explode-states path {
fill : rgba(0,0,0,0);
stroke : rgba(0,0,0,0);
}
#explode-states:hover {
cursor:pointer;
}
#explode-states path.highlighted-state {
fill: red;
}
JavaScript
// need to use jquery to get json from a different url
$.getJSON({
url: "https://bsouthga.github.io/d3-exploder/us.json",
success: makeMap
});
// map making code goes in here
function makeMap(us) {
/*
First we need to create the actual d3 map
*/
// a good h/w ratio for this map;
var ratio = 500/960;
var width = 400,
height = width*ratio;
var projection = d3.geoAlbersUsa()
.scale(width)
.translate([width/2, height/2]);
var path = d3.geoPath()
.projection(projection);
var svg = d3.select("#map").append("svg")
.attr("width", width + 200)
.attr("height", height);
var g = svg.append("g");
var state_features = topojson.feature(
us, us.objects.states
).features;
// add states which will form the static map
var states = g.append("g")
.attr("id", "states")
.selectAll("path")
.data(state_features)
.enter().append("path")
.attr('id', function(d) { return "fips_" + d.id; })
.attr("d", path);
// add states we will explode! (these stay
// add states which will form the static map
var explode_states = g.append("g")
.attr("id", "explode-states")
.selectAll("path")
.data(state_features)
.enter().append("path")
.attr('id', function(d) { return "fips_" + d.id; })
.attr("d", path);
// Here is the magic!
// This exploder will create a grid of the states
// when called on a featurelist selection
var exploder = d3.exploder()
// use the same projection as the map
.projection(projection)
// size the state to have an area of 150 pixels
.size(function(d, i) { return 100; })
// position the center of the state 3/4 of the width and 1/2 the height
.position(function(d, i) {
return [500, height/2];
})
var...