block by nbremer d4ab393602780d6aa83a

New Year's Card - Life expectancy

Full Screen

The D3.js code that I used as the base for the Life Expectancy New Year’s card that I designed. You can see the end result of all 4 cards and read about the design process in my blog Saying “Happy new year” with data

You can find the design of the two other cards here

index.html

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

body {
  font: 10px sans-serif;
}

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

.axis path {
  display: none;
}

.line {
  fill: none;
  stroke-width: 1px;
  opacity: 0.4;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>

var margin = {top: 60, right: 80, bottom: 60, left: 80},
    width = 1000 - margin.left - margin.right,
    height = 460 - margin.top - margin.bottom;

var x = d3.scale.linear()
    .range([0, width])
	.domain([1950,2015]);

var y = d3.scale.linear()
    .range([height, 0])
	.domain([65,85]);

var color = d3.scale.ordinal()
	.range(["#8A9B0F", "#C82026"])
	.domain(["men", "women"]);
	
var colorRange = ['#8a9b0f','#939213','#9b8917','#a3801a','#a9771c','#af6d1e',
	'#b56320','#ba5622','#bf4924','#c43725','#c82026'];
var colorSeq = d3.scale.ordinal()
	.range(colorRange)
	.domain([d3.range(colorRange.length)]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
	.tickFormat(d3.format("d"));

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
	.ticks(5)
	.tickSize(-width, 0, 0);

var line = d3.svg.line()
    .interpolate("cardinal")
    .x(function(d) { return x(d.year); })
    .y(function(d) { return y(d.gender); });

var svg = d3.select("body").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 + ")");

d3.csv("lifeExpectancy.csv", function(error, data) {
  if (error) throw error;
  
  data.forEach(function (d,i) {
	  d.year = +d.year;
	  d.men = +d.men;
	  d.women = +d.women;
	  d.diff = d.women - d.men;
  })

  var rScale = d3.scale.linear()
	.domain([1, Math.round(d3.max(data, function(d) { return d.diff; })) ])
	.range([3, 40]);
	
  var keys = d3.keys(data[0]).filter(function(key) { return key !== "year" && key !== "diff"; });

  var genderLines = keys.map(function(name) {
    return {
      name: name,
      values: data.map(function(d) {
        return {
			year: d.year, 
			gender: d[name]};
      })
    };
  });

  //Append axes
  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);

	//Wrapper for the background circles
	var strokes = svg.append("g").attr("class","strokeWrapper");

  	//Append difference circles
  	data.forEach(function(d,index) {
	  	var numLoops = Math.round(d.diff);
	  	  
	  	for(var j = 1; j < (numLoops+1); j++) {
		  	strokes.append("circle")
			  	.attr("cx", x(d.year))
			  	.attr("cy", y(Math.random() * (d.men*0.95 - d.women*1.05) + d.women*1.05).toFixed(4))
			  	.attr("r", rScale(j))
			  	.style("stroke", colorSeq(randomIntFromInterval(0,colorRange.length)))
				.style("stroke-width", (Math.random() * (0.5 - 6) + 6).toFixed(1))
				.style("opacity", (Math.random() * (0.05 - 0.1) + 0.1).toFixed(1))
			  	.style("fill", "none");
	  	  }//for j
  	})
  
  	//Append the two lines
  	var lines = svg.selectAll(".lines")
      	.data(genderLines)
    	.enter().append("g")
      	.attr("class", "lines");

	lines.append("path")
	      	.attr("class", "line")
	      	.attr("d", function(d) { return line(d.values); })
	      	.style("stroke", function(d) { return color(d.name); });
	  
  	//Append circles
  	var circles = svg.selectAll(".circleWrapper")
		  .data(data)
		  .enter().append("g")
		  .attr("class","circleWrapper")
		  .attr("transform", function(d) { return "translate(" + x(d.year) + ")"; });
	  
  	//Append men
	circles.append("circle")
		  .attr("class", "circleWoman")
		  .attr("cy", function(d) { return y(d.men); })
		  .attr("r", 8)
		  .style("fill", color("men"))
		  .style("fill-opacity", 0.1);

	 circles.append("circle")
		  .attr("class", "circleMen")
		  .attr("cy", function(d) { return y(d.men); })
		  .attr("r", 3)
		  .style("fill", color("men"))
		  .style("stroke", color("men"))
		  .style("stroke-width", 3)
		  .style("stroke-opacity", 0.3);
	
	//Append women
	circles.append("circle")
		  .attr("class", "circleWoman")
		  .attr("cy", function(d) { return y(d.women); })
		  .attr("r", 8)
		  .style("fill", color("women"))
		  .style("fill-opacity", 0.1);
		    
	circles.append("circle")
		  .attr("class", "circleWoman")
		  .attr("cy", function(d) { return y(d.women); })
		  .attr("r", 3)
		  .style("fill", color("women"))
		  .style("stroke", color("women"))
		  .style("stroke-width", 3)
		  .style("stroke-opacity", 0.3);

});

function randomIntFromInterval(min,max) {
    return Math.floor(Math.random()*(max-min+1)+min);
}


</script>

lifeExpectancy.csv

year,men,women
1950,70.29,72.58
1951,70.24,72.75
1952,70.96,73.29
1953,70.41,72.97
1954,70.96,73.83
1955,70.94,74.08
1956,70.97,74.1
1957,71.39,74.58
1958,71.46,74.84
1959,71.24,75.16
1960,71.39,75.3
1961,71.45,75.74
1962,70.95,75.56
1963,71.02,75.77
1964,71.27,76.27
1965,71.12,76.14
1966,71.03,76.12
1967,71.17,76.57
1968,70.92,76.44
1969,70.92,76.29
1970,70.81,76.5
1971,70.99,76.77
1972,70.81,76.79
1973,71.3,77.13
1974,71.61,77.61
1975,71.45,77.71
1976,71.53,77.92
1977,72.08,78.52
1978,71.95,78.5
1979,72.46,78.93
1980,72.48,79.19
1981,72.71,79.32
1982,72.75,79.44
1983,72.93,79.56
1984,72.96,79.67
1985,73.07,79.66
1986,73.09,79.61
1987,73.51,80.06
1988,73.69,80.24
1989,73.67,79.93
1990,73.84,80.11
1991,74.05,80.15
1992,74.3,80.28
1993,73.98,80
1994,74.58,80.31
1995,74.59,80.36
1996,74.66,80.35
1997,75.17,80.55
1998,75.19,80.69
1999,75.34,80.45
2000,75.54,80.58
2001,75.8,80.71
2002,75.99,80.69
2003,76.23,80.93
2004,76.87,81.44
2005,77.19,81.6
2006,77.63,81.89
2007,78.01,82.31
2008,78.32,82.28
2009,78.53,82.65
2010,78.77,82.72
2011,79.18,82.85
2012,79.14,82.82
2013,79.41,83.04
2014,79.87,83.29