var width = 960, height = 500, active = d3.select(null); var projection = d3.geo.albersUsa() .scale(1000) .translate([width / 2, height / 2]); var path = d3.geo.path() .projection(projection); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); svg.append("rect") .attr("class", "background") .attr("width", width) .attr("height", height) .on("click", reset); var g = svg.append("g") .style("stroke-width", "1.5px"); d3.json("us.json", function(error, us) { if (error) throw error; g.selectAll("path") .data(topojson.feature(us, us.objects.states).features) .enter().append("path") .attr("d", path) .attr("class", "feature") .on("click", clicked); g.append("path") .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })) .attr("class", "mesh") .attr("d", path); }); d3.json("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson", function(raw) { // strips the data into a much simpler flat format and removes // data points outside the US (ie. outside the clipping bounds of the projection) var data = raw["features"].map(function(d) { return {"magnitude": d["properties"]["mag"], "coordinates": d["geometry"]["coordinates"].slice(0,-1)} }).filter(function(d) { return projection(d.coordinates) !== null; }) var scale = d3.scale.linear() .domain([1,10]) .range([0,60]); var circles = svg.selectAll("circle") .data(data) .enter().append("circle"); circles .attr("cx", function(d,i) { return projection(d.coordinates)[0]; }) .attr("cy", function(d,i) { return projection(d.coordinates)[1]; }) .attr("r", function(d,i) { return scale(d.magnitude); }) .style("fill", "steelblue") .style("fill-opacity", 0.5); }); function clicked(d) { if (active.node() === this) return reset(); active.classed("active", false); active = d3.select(this).classed("active", true); var bounds = path.bounds(d), dx = bounds[1][0] - bounds[0][0], dy = bounds[1][1] - bounds[0][1], x = (bounds[0][0] + bounds[1][0]) / 2, y = (bounds[0][1] + bounds[1][1]) / 2, scale = .9 / Math.max(dx / width, dy / height), translate = [width / 2 - scale * x, height / 2 - scale * y]; g.transition() .duration(750) .style("stroke-width", 1.5 / scale + "px") .attr("transform", "translate(" + translate + ")scale(" + scale + ")"); } function reset() { active.classed("active", false); active = d3.select(null); g.transition() .duration(750) .style("stroke-width", "1.5px") .attr("transform", ""); }