|
<!--Level of Education vs Work Value (normalized) |
|
|
|
We notice that the standard deviation is high, meaning that the mean is not reliable |
|
--> |
|
<!DOCTYPE html> |
|
<html> |
|
<meta charset="utf-8"> |
|
|
|
<!-- Example based on http://bl.ocks.org/mbostock/3887118 --> |
|
<!-- Tooltip example from http://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html --> |
|
|
|
<style> |
|
body { |
|
font: 11px sans-serif; |
|
} |
|
|
|
.axis path, |
|
.axis line { |
|
fill: none; |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
.dot { |
|
stroke: #000; |
|
} |
|
|
|
.tooltip { |
|
position: absolute; |
|
width: 200px; |
|
height: 28px; |
|
pointer-events: none; |
|
} |
|
</style> |
|
<body> |
|
<script src="http://d3js.org/d3.v4.min.js"></script> |
|
<!-- |
|
<button id="2AHisto" value="2AHisto">Average Income Histogram</button><button id="2JHisto">Median Income Histogram</button><br> |
|
|
|
<button id="2ALine" value="2ALine">Average Income Line</button><button id="2JLine">Median Income Line</button><br> |
|
|
|
<button id="2ABars" value="2ABars">Average Income, Earnings, months worked </button><button id="2JBars">Median Income, Earnings, months worked</button><br> |
|
|
|
<svg id="svg"></svg> |
|
<script type="text/javascript" src=csv.js> |
|
d3.select("#2AHisto").on("click", function(d,i) |
|
{ |
|
table2AHisto(); |
|
}) |
|
d3.select("#2JHisto").on("click", function(d,i) |
|
{ |
|
table2JHisto(); |
|
}) |
|
d3.select("#2ALine").on("click", function(d,i) |
|
{ |
|
table2ALine(); |
|
}) |
|
d3.select("#2JLine").on("click", function(d,i) |
|
{ |
|
table2JLine(); |
|
}) |
|
d3.select("#2ABars").on("click", function(d,i) |
|
{ |
|
table2ABars(); |
|
}) |
|
d3.select("#2JBars").on("click", function(d,i) |
|
{ |
|
table2JBars(); |
|
}) |
|
table2JHisto(); |
|
|
|
</script> |
|
--> |
|
<script> |
|
|
|
// set the dimensions and margins of the graph |
|
var margin = {top: 20, right: 20, bottom: 30, left: 40}, |
|
width = 960 - margin.left - margin.right, |
|
height = 500 - margin.top - margin.bottom; |
|
|
|
// set the ranges |
|
var x = d3.scaleBand() |
|
.range([0, width]) |
|
.padding(0.1); |
|
var y = d3.scaleLinear() |
|
.range([height, 0]); |
|
|
|
// append the svg object to the body of the page |
|
// append a 'group' element to 'svg' |
|
// moves the 'group' element to the top left margin |
|
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 + ")"); |
|
|
|
// get the data |
|
d3.csv("Table_2A.csv", function(error, data) { |
|
if (error) throw error; |
|
|
|
// format the data: divide income by percentage of time worked |
|
data.forEach(function(d) { |
|
d["Total income"] = +Number(d["Total income"].replace(/[^0-9\.]+/g,"")); |
|
d["Months worked"] = +d["Months worked"]; |
|
}); |
|
|
|
var maxIncome = d3.max(data, function(d) { return d["Total income"]; }) |
|
var minIncome = d3.min(data, function(d) { return d["Total income"]; }) |
|
|
|
var maxTime = d3.max(data, function(d) { return d["Months worked"]; }) |
|
data.forEach(function(d) { |
|
d.time = d["Months worked"] / maxTime; |
|
d.incomeNorm = d["Total income"] / maxIncome; |
|
d.net = d.incomeNorm / d.time; |
|
}); |
|
|
|
//for line of regression |
|
var max = d3.max(data, function(d) { return d.net; }) |
|
var min = d3.min(data, function(d) { return d.net; }) |
|
|
|
|
|
// Scale the range of the data in the domains |
|
x.domain(data.map(function(d) { return d["Highest level completed"]; })); |
|
y.domain([0, d3.max(data, function(d) { return d.net; })]); |
|
|
|
// append the rectangles for the bar chart |
|
svg.selectAll(".bar") |
|
.data(data) |
|
.enter().append("rect") |
|
.attr("class", "bar") |
|
.attr("x", function(d) { return x(d["Highest level completed"]); }) |
|
.attr("width", x.bandwidth()) |
|
.attr("y", function(d) { return y(d.net); }) |
|
.attr("height", function(d) { return height - y(d.net); }); |
|
|
|
|
|
|
|
|
|
// add the x Axis |
|
svg.append("g") |
|
.attr("transform", "translate(0," + height + ")") |
|
.call(d3.axisBottom(x)); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(" + (width / 2) + " ," + (height + margin.bottom) + ")") |
|
.style("text-anchor", "middle") |
|
.style("font-weight", "bold") |
|
.text("Level of Education"); |
|
|
|
// add the y Axis |
|
svg.append("g") |
|
.call(d3.axisLeft(y)); |
|
|
|
svg.append("text") |
|
.attr("transform", "rotate(-90)") |
|
.attr("y", 0 - margin.left) |
|
.attr("x",0 - (height / 2)) |
|
.attr("dy", "1em") |
|
.style("text-anchor", "middle") |
|
.style("font-weight", "bold") |
|
.text("Value (income/months worked)"); |
|
|
|
//code taken from http://stackoverflow.com/questions/20507536/d3-js-linear-regression |
|
function linearRegression(y,x){ |
|
|
|
var lr = {}; |
|
var n = y.length; |
|
var sum_x = 0; |
|
var sum_y = 0; |
|
var sum_xy = 0; |
|
var sum_xx = 0; |
|
var sum_yy = 0; |
|
|
|
for (var i = 0; i < y.length; i++) { |
|
|
|
sum_x += x[i]; |
|
sum_y += y[i]; |
|
sum_xy += (x[i]*y[i]); |
|
sum_xx += (x[i]*x[i]); |
|
sum_yy += (y[i]*y[i]); |
|
} |
|
|
|
lr['slope'] = (n * sum_xy - sum_x * sum_y) / (n*sum_xx - sum_x * sum_x); |
|
lr['intercept'] = (sum_y - lr.slope * sum_x)/n; |
|
lr['r2'] = Math.pow((n*sum_xy - sum_x*sum_y)/Math.sqrt((n*sum_xx-sum_x*sum_x)*(n*sum_yy-sum_y*sum_y)),2); |
|
|
|
return lr; |
|
|
|
}; |
|
|
|
/* |
|
* Source: http://stevegardner.net/2012/06/11/javascript-code-to-calculate-the-pearson-correlation-coefficient/ |
|
*/ |
|
function getPearsonCorrelation(x, y) { |
|
var shortestArrayLength = 0; |
|
|
|
if(x.length == y.length) { |
|
shortestArrayLength = x.length; |
|
} else if(x.length > y.length) { |
|
shortestArrayLength = y.length; |
|
console.error('x has more items in it, the last ' + (x.length - shortestArrayLength) + ' item(s) will be ignored'); |
|
} else { |
|
shortestArrayLength = x.length; |
|
console.error('y has more items in it, the last ' + (y.length - shortestArrayLength) + ' item(s) will be ignored'); |
|
} |
|
|
|
var xy = []; |
|
var x2 = []; |
|
var y2 = []; |
|
|
|
for(var i=0; i<shortestArrayLength; i++) { |
|
xy.push(x[i] * y[i]); |
|
x2.push(x[i] * x[i]); |
|
y2.push(y[i] * y[i]); |
|
} |
|
|
|
var sum_x = 0; |
|
var sum_y = 0; |
|
var sum_xy = 0; |
|
var sum_x2 = 0; |
|
var sum_y2 = 0; |
|
|
|
for(var i=0; i< shortestArrayLength; i++) { |
|
sum_x += x[i]; |
|
sum_y += y[i]; |
|
sum_xy += xy[i]; |
|
sum_x2 += x2[i]; |
|
sum_y2 += y2[i]; |
|
} |
|
|
|
var step1 = (shortestArrayLength * sum_xy) - (sum_x * sum_y); |
|
var step2 = (shortestArrayLength * sum_x2) - (sum_x * sum_x); |
|
var step3 = (shortestArrayLength * sum_y2) - (sum_y * sum_y); |
|
var step4 = Math.sqrt(step2 * step3); |
|
var answer = step1 / step4; |
|
|
|
return answer; |
|
} |
|
|
|
var lr = linearRegression(y,x); |
|
|
|
var incomes = []; |
|
var monthsWorked = []; |
|
data.forEach(function(d) { |
|
incomes.push(d["Total income"]) |
|
monthsWorked.push(d["Months worked"]) |
|
}); |
|
var pcc = getPearsonCorrelation(incomes, monthsWorked); |
|
|
|
//append the mean as a red dashed line |
|
var mean = d3.mean(data,function(d) { return y(d.net)}) |
|
|
|
svg.append("line") |
|
.attr("x1", 0) |
|
.attr("y1", mean) |
|
.attr("x2", width) |
|
.attr("y2", mean) |
|
.style("stroke-dasharray", ("5, 5")) |
|
.attr("stroke-width", 3) |
|
.attr("stroke", "red"); |
|
|
|
svg.append("line") |
|
.attr("x1", x(0)) |
|
.attr("y1", y(min)) |
|
.attr("x2", width) |
|
.attr("y2", y( (max * lr.slope) + lr.intercept )) |
|
.style("stroke-dasharray", ("10, 15")) |
|
.attr("stroke-width", 3) |
|
.attr("stroke", "blue"); |
|
|
|
std = d3.deviation(data, function(d) { return d.net; }); |
|
|
|
svg.append("line") |
|
.attr("x1", 0) |
|
.attr("y1", mean + std*height) |
|
.attr("x2", width) |
|
.attr("y2", mean + std*height) |
|
.style("stroke-dasharray", ("1, 3")) |
|
.attr("stroke-width", 3) |
|
.attr("stroke", "green"); |
|
|
|
svg.append("line") |
|
.attr("x1", 0) |
|
.attr("y1", mean - std*height) |
|
.attr("x2", width) |
|
.attr("y2", mean - std*height) |
|
.style("stroke-dasharray", ("1, 3")) |
|
.attr("stroke-width", 3) |
|
.attr("stroke", "green"); |
|
|
|
svg.append("text") |
|
.attr("x", margin.left * 0.8) |
|
.attr("y", height /6) |
|
.attr("text-anchor", "left") |
|
.style("font-size", "12px") |
|
.style('fill', 'black') |
|
.text("Pearson Correlation of income vs time worked: " + pcc); |
|
|
|
|
|
}); |
|
|
|
svg.append("text") |
|
.attr("x", (width / 2)) |
|
.attr("y", 0 - (margin.top /20)) |
|
.attr("text-anchor", "middle") |
|
.style("font-size", "25px") |
|
.style("text-decoration", "bold") |
|
.text("Level of Education vs Work Value (normalized)"); |
|
|
|
svg.append("text") |
|
.attr("x", margin.left * 0.8) |
|
.attr("y", height /35) |
|
.attr("text-anchor", "left") |
|
.style("font-size", "12px") |
|
.style('fill', 'red') |
|
.text("Red line = Mean"); |
|
|
|
svg.append("text") |
|
.attr("x", margin.left * 0.8) |
|
.attr("y", height /9) |
|
.attr("text-anchor", "left") |
|
.style("font-size", "12px") |
|
.style('fill', 'blue') |
|
.text("Blue line = Line of Regression"); |
|
|
|
svg.append("text") |
|
.attr("x", margin.left * 0.8) |
|
.attr("y", height /15) |
|
.attr("text-anchor", "left") |
|
.style("font-size", "12px") |
|
.style('fill', 'green') |
|
.text("Green lines = Standard Deviation (From Mean)"); |
|
|
|
|
|
|
|
|
|
</script> |
|
|
|
</body> |
|
</html> |