D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
P7h
Full window
Github gist
Life expectancy at birth - Module 5 exercise [slopegraph]
<!DOCTYPE html> <html> <head> <title>Life Expectancy Slope Graph: 1960 – 2011</title> <script type="text/javascript" src="https://d3js.org/d3.v3.js"></script> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style> body { color: #444; background: #f3f3f3; font: normal 12px "Adobe Garamond Pro", "Palatino", serif; margin: 2em; } header { margin: 0 0 20px 220px; border-bottom: 0px solid #6c6c6c; width: 360px; position: relative; } /*h1 { font-size: 16px; font-weight: normal; text-shadow: #fff 0 1px 0; margin: 0 0 0 0; padding: 0; } small { color: #a3a3a3; font-size: 10px; position: absolute; top: 0.6em; right: 0;}*/ a { color: #a3a3a3; } text.label { fill: #444; } text.label.start { text-anchor: end; } line.slope { stroke: #444; stroke-width: 1; } .missing text.label { display: none; } .missing line.slope { display: none; } .over text.label { fill: #bb2629; font-size: 14px !important; font-weight: bold; } .over line.slope { stroke: #bb2629; stroke-width: 2; } </style> </head> <body> <header> <h1>Life Expectancy (1960 — 2012)</h1> <h3>With data from <a href="https://data.worldbank.org/indicator/SP.DYN.LE00.IN">WorldBank</a></h2> </header> <div id="chart"></div> </body> <script> data = null; d3.csv("LifeExpectancyAtBirth.csv", function(csv) { data = csv; var // Extract years from the dataset years = d3.keys(csv[0]).filter( function(d) { return d.match(/^\d/) }), // Return numerical keys // Extract names of countries from the dataset countries = csv.map( function(d) { return d["CountryName"] }), // Set "from" and "to" years to display from = "1960", to = "2012", // Extract country names and start/end values from the dataset data = csv .map( function(d) { var r = { label: d["CountryName"], start: parseFloat(d[from]), end: parseFloat(d[to]) }; return r; }) //Require countries to have both values present .filter(function(d) { return (!isNaN(d.start) && !isNaN(d.end)); }), // Extract the values for every country for both years in the dataset for the scale values = data .map( function(d) { return d3.round(d.start, 1); }) .filter( function(d) { return d; } ) .concat( data .map( function(d) { return d3.round(d.end, 1); } ) .filter( function(d) { return d; } ) ) .sort() .reverse(), // Return true for countries without start/end values missing = function(d) { return !d.start || !d.end; }, // Format values for labels label_format = function(value) { return d3.format(".1f")(d3.round(value, 1)); }, font_size = 12, margin = 20, width = 800, height = countries.length * font_size*1.5 + margin, // height = 50000, chart = d3.select("#chart").append("svg") .attr("width", width) .attr("height", height); // Scales and positioning var slope = d3.scale.ordinal() .domain(values) .rangePoints([margin, height]); //Go through the list of countries in order, adding additional space as necessary. var min_h_spacing = 1.2 * font_size, // 1.2 is standard font height:line space ratio previousY = 0, thisY, additionalSpacing; //Preset the Y positions (necessary only for the lower side) //These are used as suggested positions. data.forEach(function(d) { d.startY = slope(d3.round(d.start,1)); d.endY = slope(d3.round(d.end,1)); }); //Loop over the higher side (right) values, adding space to both sides if there's a collision data .sort(function(a,b) { if (a.end == b.end) return 0; return (a.end < b.end) ? -1 : +1; }) .forEach(function(d) { thisY = d.endY; //position "suggestion" additionalSpacing = d3.max([0, d3.min([(min_h_spacing - (thisY - previousY)), min_h_spacing])]); //Adjust all Y positions lower than this end's original Y position by the delta offset to preserve slopes: data.forEach(function(dd) { if (dd.startY >= d.endY) dd.startY += additionalSpacing; if (dd.endY >= d.endY) dd.endY += additionalSpacing; }); previousY = thisY; }); //Loop over the lower side (left) values, adding space to both sides if there's a collision previousY = 0; data .sort(function(a,b) { if (a.startY == b.startY) return 0; return (a.startY < b.startY) ? -1 : +1; }) .forEach(function(d) { thisY = d.startY; //position "suggestion" additionalSpacing = d3.max([0, d3.min([(min_h_spacing - (thisY - previousY)), min_h_spacing])]); //Adjust all Y positions lower than this start's original Y position by the delta offset to preserve slopes: data.forEach(function(dd) { if (dd.endY >= d.startY) dd.endY += additionalSpacing; if (dd.label != d.label && dd.startY >= d.startY) dd.startY += additionalSpacing; }); previousY = thisY; }); // Countries var country = chart.selectAll("g.country") .data( data ) .enter() .append("g") .attr("class", "country") .classed("missing", function(d) { return missing(d); }); country .on("mouseover", function(d,i) { return d3.select(this).classed("over", true); }) .on("mouseout", function(d,i) { return d3.select(this).classed("over", false); }); // ** Left column country .append("text") .classed("label start", true) .attr("x", 200) .attr("y", function(d) {return d.startY;}) .attr("xml:space", "preserve") .style("font-size", font_size) .text(function(d) { return d.label+ " " + label_format(d.start); }); // ** Right column country .append("text") .classed("label end", true) .attr("x", width-100) .attr("y", function(d) {return d.endY;}) .attr("xml:space", "preserve") .style("font-size", font_size) .text(function(d) { return label_format(d.end) + " " + d.label; }); // ** Slope lines country .append("line") .classed("slope", function(d) { return d.start || d.end; }) .attr("x1", 210) .attr("x2", width-110) .attr("y1", function(d,i) { return d.start && d.end ? d.startY - font_size/2 + 2 : null; }) .attr("y2", function(d,i) { return d.end && d.end ? d.endY - font_size/2 + 2 : null; }); return chart; }); </script> </html>
Modified
http://d3js.org/d3.v3.js
to a secure url
https://d3js.org/d3.v3.js