D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
samirrayani
Full window
Github gist
income by country
<!DOCTYPE html> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="spinner.css"> <style type="text/css"> body { background: #ffffff; /*transform: scale(1.05);*/ } svg { overflow: visible; /*margin-bottom:50px;*/ /*border:1px solid pink;*/ } h2 { font-family: sans-serif; text-align:center; font-size: 13px; margin-left:15px; } h3 { font-size:9px; font-family: sans-serif; text-align:center; margin-left:15px; text-transform: uppercase; font-weight: 100; } div.wrapper { width:1050px; margin: 0 auto; position:relative; } div.description { width:650px; position:absolute; top:15px; left:15px; /*margin:10px auto;*/ display:none; z-index: 10000; } div.description p { color: #666; font-size:13px; font-family: sans-serif; margin-bottom:30px; } div.description p a { color: teal; } div.container { width: 1050px; height: 450px; margin: 50px auto; } div.intro { font-size: 13px; font-family: sans-serif; text-align: center; } div.cutoff-container { display:inline-block; margin-right:20px; } .country-line { fill: none; stroke: #dedede; stroke-width:2px; } .country-line.hover { /*stroke-width:3px;*/ stroke: #666; } .country-line.united-states { stroke: #885ead; stroke-width:3px; } path.domain { fill:none; } .axis { font-family: sans-serif; } .x.axis text { font-size:12px; fill: #888; } .y.axis text { fill: none; font-size:12px; } .x.axis path.domain{ stroke-width:1px; stroke: #222; } .last-y-axis text{ fill: #888 !important; } .tick line{ fill: none; stroke: #888; stroke-dasharray: 2px 3px; shape-rendering: crispEdges; stroke-width: 1px; opacity:.75; } label { font-family: sans-serif; font-size: 13px; font-weight: 200; -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Chrome/Safari/Opera */ -khtml-user-select: none; /* Konqueror */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* IE/Edge */ user-select: none; } h1 { font-family: serif; line-height: 30px; font-size: 26px; font-weight:200; } h4 { font-family: sans-serif; font-size:16px; margin:-10px 0 10px 0; } span.legend-bar{ width: 40px; height:3px; background:#666; display:inline-block; margin-right:10px; position:relative; top:-3px; } div.legend ul li { margin-bottom:10px; } div.legend ul li span.text { font-size:16px; font-family: sans-serif; font-weight: 200; } div.legend ul { list-style: none; margin:30px 0; padding:0; } li.row { display:none; } li.row.show { display:block; } span.legend-bar.us { background:#885ead; } </style> <body> <div class="wrapper"> <div class="description"> <p>The following is a recreation of a visualization by Kevin Quealy <br/>found in <a href="https://www.nytimes.com/2014/04/23/upshot/the-american-middle-class-is-no-longer-the-worlds-richest.html" target="_blank">this</a> article published by the NY Times on April 22, 2014</p> <h1>American Incomes Are Losing Their Edge, <br/>Except at the Top</h1> <h4>Inflation-adjusted, after-tax income over time</h4> <input type="checkbox" id="smooth" /> <label for="smooth">Remove smoothing</label> <div class="legend"> <ul> <li><span class="legend-bar us"></span><span class="text">United States</span></li> <li class="row"><span class="legend-bar hover-legend"></span><span class="text hover-legend">Rest of World</span></li> </ul> </div> </div> <div class="container"> <div id="cssload-pgloading"> <div class="cssload-loading"></div> </div> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> <script> var container = d3.select("div.container"); var margin = {top: 20, right: 50, bottom: 25, left: 10}; var width = container.node().getBoundingClientRect().width - margin.left - margin.right - 220, height = container.node().getBoundingClientRect().height - margin.top - margin.bottom; var incomeData = false; var svg = clean = function(d) { d.year = +d.year; d.val = +d.val; return d; }; drawChart = function(data){ d3.select("div.description").style("display","block"); container.html(""); var incomeCutoffAndCountry = d3.nest() .key(function(d) { return d.cutoff; }) .key(function(d) { return d.country; }) .entries(data); var cutoffContainer = container.selectAll(".cutoff-container") .data(incomeCutoffAndCountry, function(d) { return d.key; }); cutoffContainer.enter() .append("div") .attr("class", function(d) { return "cutoff-container"; }) .style("height", height) .style("width", width/incomeCutoffAndCountry.length); cutoffContainer.exit().remove(); var lineWidth = width/incomeCutoffAndCountry.length; var xScale = d3.scale.linear() .range([0, lineWidth]) .domain([1980,2010]); var yScale = d3.scale.linear() .range([height,0]) .domain([0, 80000]); var line = d3.svg.line() .x(function(d) { return xScale(d.year); }) .y(function(d) { return yScale(d.val); }); var svg = cutoffContainer.append("svg") .attr("width", lineWidth) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform","translate(" + margin.left + "," + margin.top + ")"); var yAxis = d3.svg.axis() .scale(yScale) .orient("right") .tickFormat(d3.format("$,")) .innerTickSize(lineWidth) .outerTickSize(0) .tickValues(function(d){ return [10000,20000,30000,40000,50000,60000,70000,80000]; }); var dateFormat = d3.time.format("%y"); var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .tickValues(function(d){ return [1980,2010]; }) .tickFormat(function(d){ return "'"+(""+d).substring(2); }); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0,"+(height+5)+")") .call(xAxis); var y = svg.append("g") .attr("class", "y axis") .classed("last-y-axis", function(d){ return d.key==="cop95"; }) .attr("width", lineWidth) .call(yAxis); var numLinesByIndex = [1,1,2,2,2,2,3,4,5,6,8]; y.selectAll("g.tick").forEach(function(d,i){ d.forEach(function(l,j){ if( (j+1) > numLinesByIndex[i] ) { l.remove(); } }) }); var countryLines = svg.selectAll(".country-line") .data(function(d){ return d.values; }, function(d){ return d.key; }); countryLines.enter() .append("path") .attr("class", function(d){ return "country-line " + d.key.replace(" ","-").toLowerCase(); }) .attr("d", function(d) { var values = smoothLines ? [d.values[0],d.values[d.values.length-1]] : d.values; return line(values); }) .on('mouseover',function(d){ // console.log(d); d3.select("span.text.hover-legend ").html(d.key); d3.select("li.row").classed("show",true); d3.selectAll("."+this.className.baseVal.replace(" ",".")) .classed("hover",true); d3.selectAll(".hover") .each(function(){ this.parentElement.appendChild(this); }); }) .on('mouseout',function(){ d3.select("span.text.hover-legend ").html("Rest of World"); d3.select("li.row").classed("show",false); d3.selectAll(".hover") .classed("hover",false); d3.selectAll(".united-states") .each(function(){ this.parentElement.appendChild(this); }); }); countryLines.exit().remove(); cutoffContainer.append("h2") .text(function(d){ return d.key=='cop50' ? "Median" : d.key.substring(3) + "th"; }); cutoffContainer.append("h3") .text("percentile") .style("color", function(d){ return d.key=='cop50' ? "white" : "#333" }); }; var smoothLines = true; ready = function(err, data) { d3.selectAll("#smooth").on("change", function() { smoothLines = !this.checked; drawChart(data); }); d3.select("#cssload-pgloading").remove(); drawChart(data); }; d3.csv("incomes.csv", clean, ready); </script> </body>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js