block by nbremer 0324ec7eb18f64ac0ce1b294126f1c6c

Simplified Baby Names Chart - I

Full Screen

A simplified version of my Top 10 Baby names since 1880 project looking only at the main chart

Built with blockbuilder.org

index.html

<!DOCTYPE html>
	<meta charset="utf-8">

	<!-- Google fonts -->
	<link href='//fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet' type='text/css'>
	
	<!-- D3 -->
	<script src="//d3js.org/d3.v3.min.js"></script>
	<!-- Data -->
	<script src="girl_names_us.js"></script>
	
	<!-- Styling -->
	<style>
		body {
		  font-family: 'Open Sans', sans-serif;
		  font-size: 11px;
		  font-weight: 300;
		  fill: #4A4A4A;
		}

		#chart{
			padding: 30px 20px;
		}

		.axis path,
		.axis line {
		  fill: none;
		  stroke: #000;
		  shape-rendering: crispEdges;
		}

		.x.axis path, .y.axis path {
		  display: none;
		}

		.x.axis text, .y.axis text {
		  font: 10px;
		}

		.line {
		  fill: none;
		}

		.popUpName text {
		  text-anchor: middle;
		  text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
		}

		.voronoi path {
		  fill: none;
		  pointer-events: all;
		}
	</style>
	
<body>
	<div id="chart"></div>
	<script src="babynames.js"></script>
</body>

babynames.js

//Brush is the higher focus chart, All is the smaller context chart	
var margin = {top: 20, right: 30, bottom: 30, left: 50},
    width = document.body.clientWidth - margin.left - margin.right - 10,
    height = 500 - margin.top - margin.bottom;

var startYear = 1970,
	endYear = 2014,
	yearRange = endYear - startYear;
	
//Stroke width per max position
var strokeWidth = [12,8,8,6,6,4,4,2,2,2];

////////////////////////////////////////////////////////////// 
/////////////////////////// Girls ////////////////////////////
////////////////////////////////////////////////////////////// 	

allGirlNames = [];
namesByID = [];
girls.forEach(function(d,i) {
    allGirlNames[i] = d.name;
	namesByID[d.name] = i;
});
var color = d3.scale.ordinal()
		.range(["#FFC600", "#FEC606", "#FEC60B", "#FDC710", "#FDC716", "#FCC61B", "#FCC61F", "#FCC523", "#FBC427", 
		"#FBC22B", "#FBC02D", "#FBBD2F", "#FBBA31", "#FBB632", "#FBB132", "#FCAC31", "#FCA730", "#FDA12F", "#FD9B2D", 
		"#FE952C", "#FE8F2A", "#FF8929", "#FF8428", "#FF7E27", "#FF7927", "#FF7527", "#FF7128", "#FE6E29", "#FE6A2B", 
		"#FD682D", "#FC652F", "#FB6330", "#FA6032", "#F95E33", "#F85C34", "#F65A34", "#F55733", "#F35432", "#F15230", 
		"#F04F2D", "#EE4B2A", "#EC4827", "#EA4524", "#E84221", "#E63E1F", "#E43B1D", "#E2381C", "#E0351C", "#DD321E", 
		"#DB3020", "#D92E25", "#D62C2B", "#D42A31", "#D22939", "#CF2841", "#CD274A", "#CB2754", "#C8275D", "#C62866", 
		"#C4296F", "#C22A77", "#BF2C7F", "#BD2E86", "#BB308C", "#B93391", "#B73596", "#B5389A", "#B33B9D", "#B13EA0", 
		"#AE41A2", "#AC43A3", "#A946A4", "#A648A4", "#A349A4", "#9F4AA3", "#9B4BA2", "#974BA1", "#934B9F", "#8E4A9D", 
		"#8A499A", "#854897", "#804795", "#7B4692", "#76448E", "#71438B", "#6C4188"])
		.domain(allGirlNames);
		
////////////////////////////////////////////////////////////// 
///////////////////// Scales & Axes ////////////////////////// 
////////////////////////////////////////////////////////////// 

var xScale = d3.scale.linear().domain([startYear, endYear]).range([0, width]),
	yScale= d3.scale.linear().domain([0.5,10.5]).range([0, height]);

var xAxis = d3.svg.axis().scale(xScale).orient("bottom").tickFormat(d3.format("d")).tickSize(0),
	yAxis = d3.svg.axis().scale(yScale).orient("left").tickSize(0);
	
var line = d3.svg.line()
	.interpolate("monotone") //Slight rounding without too much deviation
    .x(function(d) { return xScale(d.year); })
    .y(function(d) { return yScale(d.position); });

////////////////////////////////////////////////////////////// 
//////////////////////// Create chart //////////////////////// 
////////////////////////////////////////////////////////////// 

//Create focus SVG
var focus = d3.select("#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  	.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

//Append clippath to focus chart
focus.append("defs").append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", width)
    .attr("height", height);	

//Append x axis to focus chart	
focus.append("g")
  .attr("class", "x axis")
  .style("font-size", 13)
  .attr("transform", "translate(0," + (height + 9) + ")")
  .call(xAxis);
  
//Append y axis to focus chart	
focus.append("g")
  .attr("class", "y axis")
  .attr("transform", "translate(-10,0)")
  .call(yAxis)
.append("text")
  .attr("class", "titles")
  .attr("transform", "rotate(-90)")
  .attr("x", -(height/2))
  .attr("y", -35)
  .attr("dy", ".71em")
  .style("font-size", 14)
  .style("text-anchor", "middle")
  .text("Position in Top 10");

////////////////////////////////////////////////////////////// 
///////////////////////// Voronoi //////////////////////////// 
////////////////////////////////////////////////////////////// 

 //Create a flat data version for the Voronoi
/*************************************************************/
var flatData = [];
for (k in girls) {
		var k_data = girls[k];
		k_data.values.forEach(function(d) {  
			if (d.position <= 10) flatData.push({name: k_data.name, year: d.year, position: d.position});                               
		});
}//for k
var maxPosition = d3.nest()
	.key(function(d) { return d.name; })
	.rollup(function(d) {return d3.min(d, function(g) {return g.position;});})
	.entries(flatData);
	
var nestedFlatData = d3.nest().key(function(d) { return d.name; }).entries(flatData);
/*************************************************************/

//Initiate the voronoi function
var voronoi = d3.geom.voronoi()
    .x(function(d) { return xScale(d.year); })
    .y(function(d) { return yScale(d.position); })
    .clipExtent([[-margin.left, -margin.top], [width + margin.right, height + margin.bottom]]);
	
//Initiate the voronoi group element	
var voronoiGroup = focus.append("g")
	.attr("class", "voronoi");

voronoiGroup.selectAll("path")
	.data(voronoi(flatData.filter(function(d) {return d.year >= xScale.domain()[0] &  d.year <= xScale.domain()[1]; })))
	.enter().append("path")
	.attr("d", function(d) { return "M" + d.join("L") + "Z"; })
	.datum(function(d) { return d.point; })
	.attr("class", "voronoiCells")
	.on("mouseover", mouseover)
	.on("mouseout", mouseout);

//Voronoi mouseover and mouseout functions	
function mouseover(d) {
    focus.selectAll(".focus").style("opacity", 0.1);
    focus.selectAll("."+d.name).style("opacity", 0.8);
	//Move the tooltip to the front
	d3.select(".popUpName").moveToFront();
	//Change position, size of circle and text of tooltip
    popUpName.attr("transform", "translate(" + xScale(d.year) + "," + yScale(d.position) + ")");
	var circleSize = parseInt(d3.selectAll(".focus." + d.name).selectAll(".line").style("stroke-width"));
	popUpName.select(".tooltipCircle").style("fill", color(d.name)).attr("r", circleSize);
    popUpName.select("text").text(d.name);
}//mouseover

function mouseout(d) {
    focus.selectAll(".focus").style("opacity", 0.7);
	popUpName.attr("transform", "translate(-100,-100)");
}//mouseout

//Move selected element to the front
d3.selection.prototype.moveToFront = function() {
  return this.each(function(){
    this.parentNode.appendChild(this);
  });
};

////////////////////////////////////////////////////////////// 
//////////////////////// Create lines //////////////////////// 
////////////////////////////////////////////////////////////// 

var focusData = focus.selectAll(".focus")
	.data(girls)
	.enter().append("g")
	.attr("class", function(d) {return "focus " + d.name ;})
	.append("path")
		.attr("class", "line")
		.attr("clip-path", "url(#clip)")
		.style("pointer-events", "none")
		.style("stroke-linejoin", "round")
		.style("opacity", 0)
		.attr("d", function(d) { return line(d.values); })
		.style("stroke-width", function(d) {return strokeWidth[maxPosition[namesByID[d.name]].values - 1]; })
		.style("stroke", function(d) {return color(d.name); })
		.transition().duration(750).delay(500)
		.style("opacity", 0.7);

////////////////////////////////////////////////////////////// 
//////////////////////// Tooltip ///////////////////////////// 
////////////////////////////////////////////////////////////// 
 
var popUpName = focus.append("g")
    .attr("transform", "translate(-100,-100)")
    .attr("class", "popUpName")
	.style("pointer-events", "none");

popUpName.append("circle")
	.attr("class", "tooltipCircle")
    .attr("r", 3.5);

popUpName.append("text")
	.style("font-size", 12)
	.attr("class", "titles")
    .attr("y", -15);