block by armollica b3009dc6f46647e4c56c385094f3ed61

NYC Ancestry

Full Screen

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

index.html

<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>