The number of people in New York faceted by self-reported ancestry. Click the “Open” button to the right to see it fullscreen.
Data from the U.S. Census Bureau
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Raleway:300' rel='stylesheet' type='text/css'>
<style>
html {
font-family: 'Raleway', sans-serif;
}
.map {
display: inline-block;
position: relative;
padding-top: 50px;
}
.map h3 {
text-align: center;
position: absolute;
top: 10px;
left: 10px;
width: 200px;
margin-top: 0px;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var width = 300,
height = width;
var fontSizeScale = d3.scale.pow().exponent(0.15)
.domain([0, 1000000])
.range([0, 50]);
var areaScale = d3.scale.linear()
.domain([0, 1000])
.range([0, width]);
var projection = d3.geo.mercator()
.center([-73.98, 40.70])
.scale(30000)
.translate([width/2, height/2]);
var path = d3.geo.path()
.projection(projection);
var container = d3.select("body").append("div")
.attr("class", "container");
d3.json("nyc.json", function(error, nyc) {
if (error) throw error;
console.log(nyc);
var ancestries = nyc.tracts.properties.ancestries;
ancestries.sort(function(a, b) {
return d3.ascending(a.ancestry_name, b.ancestry_name);
});
var maps = container.selectAll(".map")
.data(ancestries)
.enter().append("div")
.attr("class", "map");
maps.append("h3")
.style("font-size", function(d) {
return fontSizeScale(d.people / d.ancestry_name.length);
})
.text(function(d) { return d.ancestry_name; });
//// Draw maps
// Do it this way so it starts rendering maps sequentially
// instead of holding off and rendering only after all maps
// are ready. There's got to be a better way...
var canvases = maps.append("canvas")
.attr("width", width)
.attr("height", height)[0];
var timer = d3.timer(function(t) {
var canvas = canvases.shift();
if (canvas !== undefined) {
var context = canvas.getContext("2d"),
ancestry_id = canvas.__data__.ancestry_id;
path.context(context);
draw(context, ancestry_id);
}
else { return true; }
});
function draw(context, ancestry_id) {
// Draw the boroughs
context.lineWidth = 0.2;
context.beginPath();
path(nyc.boroughs);
context.stroke();
// Draw the bubbles
context.save();
context.globalAlpha = 0.7;
context.lineWidth = 0.1;
nyc.tracts.features.forEach(function(d) {
var p = projection(d.geometry.coordinates),
people = d.properties.ancestry[ancestry_id] || 0,
area = areaScale(people),
radius = Math.sqrt(area / Math.PI);
context.beginPath();
context.arc(p[0], p[1], radius, 0, 2*Math.PI);
context.stroke();
});
context.restore();
}
});
</script>
</body>
</html>