index.html
<!DOCTYPE html>
<meta charset="utf-8">
<style type="text/css">
body {
font: 12px sans-serif;
}
.cutoff-chart-container {
display: inline-block;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
stroke-opacity: .3;
stroke-dasharray: 2,2;
stroke-width: .5;
}
.countryLine {
stroke: #000;
stroke-opacity: .5;
}
.United-States {
stroke: steelblue;
stroke-opacity: 1;
}
p {
padding: 0px;
margin: 0px;
}
</style>
<body>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script>
var margin = {top: 10, right: 2, bottom: 20, left: 2};
var width = 80 - margin.left - margin.right,
height = 400 - 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)
.orient("bottom")
.ticks(0);
var formatCurrency = d3.format("$,f");
var yAxis = d3.svg.axis()
.scale(yScale)
.innerTickSize(-width)
.outerTickSize(0)
.tickPadding(10)
.orient("right")
.tickFormat(function(d) { return formatCurrency(d); });
var generateLine = d3.svg.line()
.x(function(d) { return xScale(d.year); })
.y(function(d) { return yScale(d.val); })
.interpolate("cardinal");
var color = d3.scale.category20();
d3.csv("incomes.csv", ready);
function ready(error, data) {
if (error) throw "error loading data";
data.forEach(function(d) {
d.val = +d.val;
d.year = +d.year;
});
var vals = data.map(function(d) { return d.val; });
yScale.domain([0, d3.max(vals)]);
xScale.domain(d3.extent(data, function(d) { return d.year; }));
incomebyCutoffAndCountry = d3.nest()
.key(function(d) { return d.cutoff; })
.key(function(d) { return d.country })
.entries(data);
var cutoffChartContainer = d3.select("body")
.selectAll(".cutoff-chart-container")
.data(incomebyCutoffAndCountry, function(d) { return d.key })
.enter().append("div")
.attr("class", "cutoff-chart-container")
.attr("id", function(d) { return d.key; });
cutoffChartContainer.append("h5")
.style("font","12px sans-serif")
.style("text-align","center")
.text(function(d) { return d.key.substring(5,3) + "%" })
.append("p")
.text("Percentile")
var svg = cutoffChartContainer.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.selectAll("body")
.append("div")
.attr("class", "cutoff-chart-container")
.append("svg")
.attr("width", 60)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append("g")
.attr("class","y axis")
.call(yAxis);
svg.append("g")
.attr("class","y axis")
.attr("transform","translate(" + width + ",0)")
.call(yAxis)
.selectAll("path")
.style("stroke-opacity",0)
.style("stroke-dasharray",0);
svg.append("g")
.attr("class", "x axis")
.attr("transform","translate(0," + height + ")")
.call(xAxis)
.selectAll("path")
.style("stroke-opacity",1)
.style("stroke-dasharray",0);
var countryLine = svg.selectAll(".countryLine")
.data(function(d) { return d.values; })
.enter().append("path")
.attr("class", function(d) { return "countryLine " + d.key.replace(' ','-') });
countryLine
.transition()
.duration(500)
.ease("linear")
.delay(function(d,i) { return i * 500; })
.attr("d",function(d) { return generateLine(d.values); })
.style("fill","none");
d3.selectAll(".countryLine")
.on("mouseenter", function() {
var selectedClass = d3.select(this).attr("class").split(" ")[1];
d3.selectAll("." + selectedClass)
.style("stroke-width",5);
})
.on("mouseleave", function() {
var selectedClass = d3.select(this).attr("class").split(" ")[1];
d3.selectAll("." + selectedClass)
.style("stroke-width",1);
})
}
</script>