|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> |
|
|
|
<style id="jsbin-css"> |
|
.zipcode { |
|
stroke: black; |
|
stroke-width: 1px; |
|
fill: none; |
|
} |
|
|
|
.tooltip { |
|
position: absolute; |
|
background: beige; |
|
padding: 5px; |
|
border: 1px solid black; |
|
} |
|
</style> |
|
</head> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script> |
|
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.5/d3-legend.min.js"></script> |
|
<body> |
|
|
|
<div class="container"> |
|
<svg width="650" height="650" id="svg"></svg> |
|
</div> |
|
|
|
<script id="jsbin-javascript"> |
|
var ZIPCODE_URL = |
|
"https://raw.githubusercontent.com/lingyielia/D3-visual/master/data/nyc_zip.geojson"; |
|
var rodent_URL = "https://raw.githubusercontent.com/lingyielia/D3-visual/master/data/rodent_byzip.json"; |
|
|
|
d3.queue() |
|
.defer(d3.json, ZIPCODE_URL) |
|
.defer(d3.json, rodent_URL) |
|
.await(makemap); |
|
|
|
function makemap(error, zipcodes, dataset) { |
|
var svg = d3.select("#svg"), |
|
gMap = svg.append("g"), |
|
canvasSize = [650,650], |
|
projection = d3.geoMercator() |
|
.scale(Math.pow(2, 10.66 + 5.34)) |
|
.center([-73.975, 40.7]) |
|
.translate([canvasSize[0]/2, canvasSize[1]/2]), |
|
path = d3.geoPath() |
|
.projection(projection); |
|
|
|
var countbyzip = {}, |
|
boroughbyzip = {}, |
|
counts = dataset.map(d => d.count), |
|
data = Object.entries(counts), |
|
maxCount = d3.max(data, d => d[1]), |
|
color = d3.scaleThreshold() |
|
.domain(d3.range(0, maxCount, maxCount/5)) |
|
.range(d3.schemePurples[5]); |
|
|
|
var tooltip = d3.select("body") |
|
.append("div") |
|
.attr("class", "tooltip"); |
|
|
|
dataset.forEach(function (d) { |
|
countbyzip[d.zipcode] = +d.count; |
|
}); |
|
|
|
dataset.forEach(function (d) { |
|
boroughbyzip[d.zipcode] = d.borough; |
|
}); |
|
|
|
gMap.selectAll(".zipcode") |
|
.data(zipcodes.features) |
|
.enter().append("path") |
|
.attr("class", "zipcode") |
|
.attr("d", path) |
|
.style("fill", function(d) {return color(countbyzip[d.properties.zipcode]);}) |
|
.on("mouseenter", function(d) { |
|
d3.select(this) |
|
.style("fill", "Tomato"); |
|
tooltip.html("<table>"+ |
|
"<tr><td>Zipcode</td><td>"+(d.properties.zipcode)+"</td></tr>"+ |
|
"<tr><td>Counts</td><td>"+(countbyzip[d.properties.zipcode])+"</td></tr>"+ |
|
"<tr><td>Borough</td><td>"+(boroughbyzip[d.properties.zipcode])+"</td></tr>"+ |
|
"</table>") |
|
.style("opacity", 0.9) |
|
.style("left", (d3.event.pageX + 30) + "px") |
|
.style("top", (d3.event.pageY + 10) + "px"); |
|
}) |
|
.on("mousemove", function(d) { |
|
return tooltip |
|
.style("top", d3.event.pageY+30 + "px") |
|
.style("left", d3.event.pageX+10 + "px") |
|
}) |
|
.on("mouseout", function(d) { |
|
d3.select(this) |
|
.style("fill", function(d) {return color(countbyzip[d.properties.zipcode]);}); |
|
tooltip.style("opacity", 0); |
|
}); |
|
|
|
// legend |
|
var linear = d3.scaleLinear() |
|
.domain([0,maxCount]) |
|
.range(["#C5C2DF", "#482581"]); |
|
|
|
gMap.append("g") |
|
.attr("class", "legendLinear") |
|
.attr("transform", "translate(15,100)"); |
|
|
|
var legendLinear = d3.legendColor() |
|
.title("Number of Rodent Complaints") |
|
.labelAlign("end") |
|
.labelFormat(".2s") |
|
.shapeHeight(5) |
|
.shapeWidth(60) |
|
.cells(4) |
|
.orient('horizontal') |
|
.scale(linear); |
|
|
|
gMap.select(".legendLinear") |
|
.call(legendLinear); |
|
|
|
} |
|
|
|
|
|
</script> |
|
|
|
</body> |
|
</html> |