D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
mph006
Full window
Github gist
Historical Income by Country and Income Percentile - D3 update
<!DOCTYPE html> <meta charset="utf-8"> <style type="text/css"> body { font-family: arial, sans; font-size: 13px; margin: 10px auto; width:1220px; } .line { fill:none; } .axis text { font-size: 12px; fill: #777; } .axis path { display: none; } .axis line { stroke-width:.3px; stroke: #dedede; /*stroke-dasharray: 2px 2px;*/ } .country-container { display: inline-block; margin-right:10px; } .info{ position: absolute; top: 10px; left: 250px; } .country-label{ position: absolute; top:15px; left:150px; } #countrySelect{ position: absolute; top: 30px; left:500px; } #decileSelect{ position: absolute; top: 30px; left:650px; } </style> <body> <div class="info"></div> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> <script type="text/javascript"> var margin = {top: 20, right: 50, bottom: 20, left: 80}; var mapData; var width = 900 - margin.left - margin.right, height = 600 - margin.top - margin.bottom; var xScale = d3.scale.linear() .range([0,width]); var yScale = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(xScale) .tickSize(-height) .tickPadding(8) .tickFormat(d3.round) .orient("bottom"); var yAxis = d3.svg.axis() .scale(yScale) .tickSize(-width) .tickPadding(8) .orient("left"); var container = d3.select("body") .append("div") .attr("class", "country-container"); var svg = container.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 + ")"); function fetchInt(string){ return +string.replace(",",""); } function updateData(){ var countrySelect = document.getElementById('countrySelect'); var decileSelect = document.getElementById('decileSelect'); var country = countrySelect.options[countrySelect.selectedIndex].value; var decile = decileSelect.options[decileSelect.selectedIndex].value; var line = d3.svg.line() .x(function(d) { return xScale(d.year); }) .y(function(d) { return yScale(d[decile]); }); d3.select(".country-label") .text("Country: "+country+" : "+decile); svg.selectAll(".line") .datum(mapData[country]) .transition().duration(500) .attr("d", line); var circleData = svg.selectAll(".circle-container") //Missing object constency here... .data(mapData[country]) .attr("class","circle-container update"); circleData.enter() .append("circle") .attr("class","circle-container enter") .attr("r",4) svg.selectAll(".circle-container") .style("fill","steelblue") .transition() .duration(500) .attr("cx",function(d){return xScale(d.year); }) .attr("cy",function(d){return yScale(d[decile]); }) .style("opacity",1); //Must know the svg element things are coming from (.svg), not a blanket d3.select() //Must seperate data and enter and exit variables circleData.exit() .attr("class","circle-container exit") .transition() .duration(200) .style("opacity",0) .remove(); } d3.tsv("all-countries.tsv", ready); function ready(error, data) { if (error) return console.warn(error); data.forEach(function(d){ d.cop5 = fetchInt(d.cop5); d.cop10 = fetchInt(d.cop10); d.cop20 = fetchInt(d.cop20); d.cop30 = fetchInt(d.cop30); d.cop40 = fetchInt(d.cop40); d.cop50 = fetchInt(d.cop50); d.cop60 = fetchInt(d.cop60); d.cop70 = fetchInt(d.cop70); d.cop80 = fetchInt(d.cop80); d.cop90 = fetchInt(d.cop90); d.cop95 = fetchInt(d.cop95); d.year = +d.dataset.split(" ")[d.dataset.split(" ").length-1]; d.country = d.dataset.replace(/[0-9]/g, "").replace("LIS - ","").trim(); }); xScale.domain(d3.extent(data,function(d){return d.year;})); yScale.domain([d3.extent(data,function(d){return d.cop5;})[0],d3.extent(data,function(d){return d.cop95;})[1]]); mapData = d3.nest() .key(function(d){ return d.country;}) .map(data); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + (height) + ")") .call(xAxis) .selectAll("g"); svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" +10+ ",0)") .call(yAxis); var countryList = d3.set(data.map(function(d) { return d.country; })).values(); decileList = []; for(var k in data[0]) (k.indexOf("cop")>-1)?decileList.push(k):"do nothing!"; d3.select("body") .append("select") .attr("class","drop-down-selector") .attr("id","countrySelect") .on("change",updateData) .selectAll("option") .data(countryList) .enter().append("option") .text(function(d) {return d;}); d3.select("body") .append("select") .attr("class","drop-down-selector") .attr("id","decileSelect") .on("change",updateData) .selectAll("option") .data(decileList) .enter().append("option") .text(function(d) {return d;}); container.append("h2") .attr("class","country-label"); svg.append("path") .attr("class", "line") .style("stroke","steelblue"); updateData(); } </script>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js