Skip to content

Instantly share code, notes, and snippets.

@Tedables
Last active February 10, 2017 04:22
Show Gist options
  • Save Tedables/f52b5660eeb090cd65707ca4cb711c69 to your computer and use it in GitHub Desktop.
Save Tedables/f52b5660eeb090cd65707ca4cb711c69 to your computer and use it in GitHub Desktop.
Homework 1
license: mit

These visulizations are built on top of the Scatterplot and Bar chart examples presented on Piazza. This was originally forked from asielen's block: Reusable Line Chart v2, an implementation of a reusable responsive multiline chart, but it largely wasn't used

Contents:

  • Reusable modular design
  • Responsive design, chart size adjusts with screen size
  • Customizable options
    • Chart Size
    • Margins
    • Div Selector
    • Chart Colors
    • Axis labels
  • Toggleable series (click on the legend to toggle series)

forked from Tedables's block: Homework 1

//Makes a histogram of Table_2J.csv
var table2JHisto = function(){
// 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_2J.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d["Total income"] = +Number(d["Total income"].replace(/[^0-9\.]+/g,""));
});
// 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["Total income"]; })]);
// 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["Total income"]); })
.attr("height", function(d) { return height - y(d["Total income"]); });
//append the mean as a red dashed line
var mean = d3.mean(data,function(d) { return y(d["Total income"])})
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");
// add the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the y Axis
svg.append("g")
.call(d3.axisLeft(y));
//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;
};
var lr = linearRegression(y,x);
var max = d3.max(data, function(d) { return d["Total income"]; })
var min = d3.min(data, function(d) { return d["Total income"]; })
var myLine = svg.append("line")
.attr("x1", x(0))
.attr("y1", y(lr.intercept))
.attr("x2", x(max))
.attr("y2", y( (max * lr.slope) + lr.intercept ))
.attr("stroke-width", 3)
.style("stroke", "green");
svg.append("line")
.attr("x1", (0))
.attr("y1", (500))
.attr("x2", width)
.attr("y2", (500))
.style("stroke-dasharray", ("5, 5"))
.attr("stroke-width", 3)
.attr("stroke", "green");
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", ("5, 5"))
.attr("stroke-width", 3)
.attr("stroke", "blue");
});
svg.append("text")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top /2))
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("text-decoration", "bold")
.text("Value vs Date Graph");
}
//Grouped bars representation
var table2JBars = function(){
// get the data
d3.csv("Table_2J.csv", function(error, data) {
if (error) throw error;
// format the data
//TODO: more variables
data.forEach(function(d) {
d["Total income"] = +Number(d["Total income"].replace(/[^0-9\.]+/g,""));
});
bars(data);
}
)};
//Line graph
var table2JLine = function(){
// get the data
d3.csv("Table_2J.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d["Total income"] = +Number(d["Total income"].replace(/[^0-9\.]+/g,""));
});
line(data);
}
)};
//Makes a histogram of Table_2A.csv
var table2AHisto = function(){
// get the data
d3.csv("Table_2A.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d["Total income"] = +Number(d["Total income"].replace(/[^0-9\.]+/g,""));
});
histo(data);
}
)};
//Grouped bars representation
var table2ABars = function(){
// get the data
d3.csv("Table_2A.csv", function(error, data) {
if (error) throw error;
// format the data
//TODO: more variables
data.forEach(function(d) {
d["Total income"] = +Number(d["Total income"].replace(/[^0-9\.]+/g,""));
});
bars(data);
}
)};
//Line graph
var table2ALine = function(){
// get the data
d3.csv("Table_2A.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d["Total income"] = +Number(d["Total income"].replace(/[^0-9\.]+/g,""));
});
line(data);
}
)};
<!--Level of Education vs Time spent Working
built largely on top of example linked in piazza:
https://bl.ocks.org/d3noob/402dd382a51a4f6eea487f9a35566de0
From previous graphs, it is clear that you get more money with a higher degree, but you also likely spend much more time working!
-->
<!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])
// define the line
var valueline = d3.line()
.x(function(d) { return x(d["Highest level completed"]); })
.y(function(d) { return y(d["Months worked"]); });
// 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 = 4;
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["Months worked"]; })
var min = d3.min(data, function(d) { return d["Months worked"]; })
// Scale the range of the data in the domains
x.domain(data.map(function(d) { return d["Highest level completed"]; }));
y.domain([d3.min(data, function(d) { return d["Months worked"]; }), d3.max(data, function(d) { return d["Months worked"]; })+0.3]);
//add the line
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 6)
.attr("d", valueline);
// 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("Months worked (of last 4)");
//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;
}
//append the mean as a red dashed line
var mean = d3.mean(data,function(d) { return y(d["Months worked"])})
//MEAN
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");
//REGRESSION
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);
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", 2)
.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 Time spent Working");
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', 'green')
.text("Green line = Line of Regression");
</script>
</body>
</html>
<!--LEVEL OF EDUCATION VS MEDIAN INCOME
(using Table_2J.csv)-->
<!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: 59},
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_2J.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d["Total income"] = +Number(d["Total income"].replace(/[^0-9\.]+/g,""));
});
// 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["Total income"]; })]);
// 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["Total income"]); })
.attr("height", function(d) { return height - y(d["Total income"]); });
//append the mean as a red dashed line
var mean = d3.mean(data,function(d) { return y(d["Total income"])})
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");
// 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("Income over Last Four Months ($)");
//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;
};
var lr = linearRegression(y,x);
var max = d3.max(data, function(d) { return d["Total income"]; })
var min = d3.min(data, function(d) { return d["Total income"]; })
var myLine = svg.append("line")
.attr("x1", x(0))
.attr("y1", y(lr.intercept))
.attr("x2", x(max))
.attr("y2", y( (max * lr.slope) + lr.intercept ))
.attr("stroke-width", 3)
.style("stroke", "green");
svg.append("line")
.attr("x1", (0))
.attr("y1", (500))
.attr("x2", width)
.attr("y2", (500))
.style("stroke-dasharray", ("5, 5"))
.attr("stroke-width", 3)
.attr("stroke", "green");
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");
});
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 Income");
svg.append("text")
.attr("x", margin.left * 0.8)
.attr("y", height /15)
.attr("text-anchor", "left")
.style("font-size", "12px")
.style('fill', 'red')
.text("Red line = Mean Income");
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");
</script>
</body>
</html>
<!--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>
<!--Level of Education vs Time spent Working
built largely on top of example linked in piazza:
https://bl.ocks.org/d3noob/402dd382a51a4f6eea487f9a35566de0
From previous graphs, it is clear that you get more money with a higher degree, but you also likely spend much more time working!
-->
<!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])
// define the line
var valueline = d3.line()
.x(function(d) { return x(d["Highest level completed"]); })
.y(function(d) { return y(d["Months worked"]); });
// 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 = 4;
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["Months worked"]; })
var min = d3.min(data, function(d) { return d["Months worked"]; })
// Scale the range of the data in the domains
x.domain(data.map(function(d) { return d["Highest level completed"]; }));
y.domain([d3.min(data, function(d) { return d["Months worked"]; }), d3.max(data, function(d) { return d["Months worked"]; })+0.3]);
//add the line
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 6)
.attr("d", valueline);
// 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("Months worked (of last 4)");
//code found on 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);
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", 2)
.attr("stroke", "green");
});
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 Time spent Working");
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', 'green')
.text("Green line = Line of Regression");
</script>
</body>
</html>
// 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;
var histo = function(data){
// set the ranges
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
// 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["Total income"]; })]);
// 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("#barchart").selectAll("rect.bar")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// 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["Total income"]); })
.attr("height", function(d) { return height - y(d["Total income"]); });
//append the mean as a red dashed line
var mean = d3.mean(data,function(d) { return y(d["Total income"])})
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");
// add the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the y Axis
svg.append("g")
.call(d3.axisLeft(y));
});
function init()
{
//setup the svg
var svg = d3.select("#svg")
.attr("width", w+100)
.attr("height", h+100)
console.log("svg", svg)
svg.append("svg:rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("stroke", "#000")
.attr("fill", "none")
svg.append("svg:g")
.attr("id", "barchart")
.attr("transform", "translate(50,50)")
}
}
Highest level completed Number of people Total income Earnings (FT) Earnings (All) Months worked
Elementary 12,002 $1,166 $2,136 $1,813 1.7
Some high school 18,260 $1,205 $2,434 $1,840 1.8
High school graduate 57,880 $1,960 $3,179 $2,631 2.3
Some college 35,337 $2,204 $3,598 $2,789 2.6
Vocational certificate* 24,709 $2,400 $3,538 $2,945 2.6
Associate's degree 18,429 $3,001 $4,166 $3,562 3
Bachelor's degree 38,782 $4,259 $5,445 $5,034 3
Master's degree 15,132 $5,564 $6,731 $6,243 3.1
Professional degree 3,232 $9,501 $11,927 $11,071 3.3
Doctorate degree 2,486 $7,466 $8,434 $8,116 3.2
We can make this file beautiful and searchable if this error is corrected: Any value after quoted field isn't allowed in line 2.
Highest level completed,Number of people,Total income,Earnings (FT),Earnings (All),Months worked
Elementary,"12,002","$914" ,"$1,732 ","$1,516 ",1.7
Some high school,"18,260","$880" ,"$2,000 ","$1,472 ",1.8
High school graduate,"57,880","$1,458","$2,550 ","$2,078 ",2.3
Some college,"35,337","$1556 ","$2,917 ","$2,130 ",2.6
Vocational certificate*,"24,709","$1,898 ","$2,950 ","$2,400 ",2.6
Associate's degree,"18,429","$2,408 ","$3,456 ","$2,923 ",3
Bachelor's degree,"38,782","$3,188 ","$4,355 ","$3,874 ",3
Master's degree,"15,132","$4,508 ","$5,417 ","$5,000 ",3.1
Professional degree,"3,232","$6,125 ","$7,417 ","$7,128 ",3.3
Doctorate degree,"2,486","$5,756 ","$6,833 ","$6,260 ",3.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment