finished fixing coding bootcamp cost calculator

This commit is contained in:
Quincy Larson
2015-06-24 09:51:44 -07:00
parent 09656a0f34
commit ca5cef08bf
3 changed files with 299 additions and 4 deletions

View File

@ -1108,6 +1108,29 @@ hr {
} }
} }
// Calculator styles
.initially-hidden {
display: none;
}
.chart rect {
fill: steelblue;
}
.chart text {
font-size: 14px;
text-anchor: end;
}
.axis path,
.axis line {
fill: none;
stroke: #121401;
stroke-width: 2px;
shape-rendering: crispEdges;
}
//uncomment this to see the dimensions of all elements outlined in red //uncomment this to see the dimensions of all elements outlined in red
//* { //* {
// border-color: red; // border-color: red;

272
public/js/calculator.js Normal file
View File

@ -0,0 +1,272 @@
$(document).ready(function () {
var bootcamps = ''
$.getJSON('/coding-bootcamp-cost-calculator.json', function(data) {
bootcamps = data;
});
var city = "";
$("body").data("state", "stacked");
$('#city-buttons').on("click", "button", function () {
$(this).addClass('animated pulse');
city = $(this).attr("id");
$('#chosen').text('Coming from ' + city.replace(/-/g, ' ').replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}) + ', and making $_______, your true costs will be:');
setTimeout(function () {
$('#city-buttons').hide();
$('#income').addClass('animated fadeIn').show();
}, 1000);
});
$('#income').on("click", "button", function () {
$(this).addClass('animated pulse');
setTimeout(function () {
$('#income').hide();
$('#chart').addClass('animated fadeIn').show();
$('#chart-controls').addClass('animated fadeIn').show();
$('#explanation').addClass('animated fadeIn').show();
}, 1000);
var lastYearsIncome = parseInt($(this).attr("id"));
$('#chosen').text('Coming from ' + city.replace(/-/g, ' ').replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}) + ', and making $' + lastYearsIncome.toString().replace(/0000$/, '0,000') + ', your true costs will be:');
var categoryNames = ['Lost Wages', 'Financing Cost', 'Housing Cost', 'Tuition'];
bootcamps.forEach(function (camp) {
var x0 = 0;
if (camp.cities.indexOf(city) > -1) {
weeklyHousing = 0;
} else {
weeklyHousing = +camp.housing;
}
camp.mapping = [{
name: camp.name,
label: 'Tuition',
value: +camp.cost,
x0: x0,
x1: x0 += +camp.cost
}, {
name: camp.name,
label: 'Financing Cost',
value: +Math.floor(camp.cost * .09519),
x0: +camp.cost,
x1: camp.finance ? x0 += +Math.floor(camp.cost * .09519) : 0
}, {
name: camp.name,
label: 'Housing Cost',
value: +weeklyHousing * camp.weeks,
x0: camp.finance ? +Math.floor(camp.cost * 1.09519) : camp.cost,
x1: x0 += weeklyHousing * camp.weeks
}, {
name: camp.name,
label: 'Lost Wages',
value: +(Math.floor(camp.weeks * lastYearsIncome / 50)),
x0: camp.finance ? +(Math.floor(camp.cost * 1.09519) + weeklyHousing * camp.weeks) : +camp.cost + weeklyHousing * camp.weeks,
x1: x0 += +(Math.floor(camp.weeks * lastYearsIncome / 50))
}];
camp.total = camp.mapping[camp.mapping.length - 1].x1;
});
bootcamps.sort(function (a, b) {
return a.total - b.total;
});
maxValue = 0;
bootcamps.forEach(function (camp) {
camp.mapping.forEach(function (elem) {
if (elem.value > maxValue) {
maxValue = elem.value;
}
});
});
var xStackMax = d3.max(bootcamps, function (d) {
return d.total;
}), //Scale for Stacked
xGroupMax = bootcamps.map(function (camp) {
return camp.mapping.reduce(function (a, b) {
return a.value > b.value ? a.value : b.value;
});
}).reduce(function (a, b) {
return a > b ? a : b;
});
var margin = {
top: 30,
right: 60,
bottom: 50,
left: 140
},
width = 800 - margin.left - margin.right,
height = 1200 - margin.top - margin.bottom;
var barHeight = 20;
var xScale = d3.scale.linear()
.domain([0, xStackMax])
.rangeRound([0, width]);
var y0Scale = d3.scale.ordinal()
.domain(bootcamps.map(function (d) {
return d.name;
}))
.rangeRoundBands([0, height], .1);
var y1Scale = d3.scale.ordinal()
.domain(categoryNames).rangeRoundBands([0, y0Scale.rangeBand()]);
var color = d3.scale.ordinal()
.range(["#215f1e", "#5f5c1e", "#1e215f", "#5c1e5f"])
.domain(categoryNames);
var svg = d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var selection = svg.selectAll(".series")
.data(bootcamps)
.enter().append("g")
.attr("class", "series")
.attr("transform", function (d) {
return "translate(0," + y0Scale(d.name) + ")";
});
var rect = selection.selectAll("rect")
.data(function (d) {
return d.mapping;
})
.enter().append("rect")
.attr("x", 0)
.attr("width", 0)
.attr("height", y0Scale.rangeBand())
.style("fill", function (d) {
return color(d.label);
})
.style("stroke", "white")
.on("mouseover", function (d) {
showPopover.call(this, d);
})
.on("mouseout", function (d) {
removePopovers();
});
rect.transition()
.delay(function (d, i) {
return i * 10;
})
.attr("x", function (d) {
return xScale(d.x0);
})
.attr("width", function (d) {
return xScale((d.x1) - (d.x0));
});
d3.selectAll("#transform").on("click", function () {
$('#transform').addClass('animated pulse');
change();
setTimeout(function () {
$('#transform').removeClass('animated pulse');
}, 1000);
});
d3.selectAll("#chart").on("click", function () {
change();
});
function change() {
if ($("body").data("state") === "stacked") {
transitionGrouped();
$("body").data("state", "grouped");
} else {
transitionStacked();
$("body").data("state", "stacked");
}
}
function transitionGrouped() {
xScale.domain = ([0, xGroupMax]);
rect.transition()
.duration(500)
.delay(function (d, i) {
return i * 10;
})
.attr("width", function (d) {
return xScale((d.x1) - (d.x0));
})
.transition()
.attr("y", function (d) {
return y1Scale(d.label);
})
.attr("x", 0)
.attr("height", y1Scale.rangeBand())
}
function transitionStacked() {
xScale.domain = ([0, xStackMax]);
rect.transition()
.duration(500)
.delay(function (d, i) {
return i * 10;
})
.attr("x", function (d) {
return xScale(d.x0);
})
.transition()
.attr("y", function (d) {
return y0Scale(d.label);
})
.attr("height", y0Scale.rangeBand())
}
//axes
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y0Scale)
.orient("left");
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", 300)
.attr("y", 35)
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text("Cost in $USD");
//tooltips
function removePopovers() {
$('.popover').each(function () {
$(this).remove();
});
}
function showPopover(d) {
$(this).popover({
title: d.name,
placement: 'auto top',
container: 'body',
trigger: 'manual',
html: true,
content: function () {
return d.label +
"<br/>$" +
d3.format(",")(d.value ? d.value : d.x1 - d.x0);
}
});
$(this).popover('show')
}
//legends
var legend = svg.selectAll(".legend")
.data(categoryNames.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function (d, i) {
return "translate(30," + i * y0Scale.rangeBand() * 1.1 + ")";
});
legend.append("rect")
.attr("x", width - y0Scale.rangeBand())
.attr("width", y0Scale.rangeBand())
.attr("height", y0Scale.rangeBand())
.style("fill", color)
.style("stroke", "white");
legend.append("text")
.attr("x", width - y0Scale.rangeBand() * 1.2)
.attr("y", 12)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function (d) {
return d;
});
});
});

View File

@ -1,6 +1,6 @@
extends ../layout-wide extends ../layout-wide
block content block content
script(src="../../../js/calculator.js") script(src="/js/calculator.js")
.row .row
.col-xs-12.col-sm-10.col-md-8.col-lg-6.col-sm-offset-1.col-md-offset-2.col-lg-offset-3 .col-xs-12.col-sm-10.col-md-8.col-lg-6.col-sm-offset-1.col-md-offset-2.col-lg-offset-3
h1.text-center Coding Bootcamp Cost Calculator h1.text-center Coding Bootcamp Cost Calculator
@ -104,9 +104,9 @@ block content
li.large-li Free Code Camp. We don't charge tuition or garnish wages. We're fully online so you don't have to move. We're self-paced so you don't have to quit your job. Thus, your true cost of attending Free Code Camp will be $0. li.large-li Free Code Camp. We don't charge tuition or garnish wages. We're fully online so you don't have to move. We're self-paced so you don't have to quit your job. Thus, your true cost of attending Free Code Camp will be $0.
.spacer .spacer
.row .row
.col-xs-12.col-sm-4.col-md-3 .col-xs-12.col-sm-5.col-md-5
img.img-responsive.testimonial-image(src='https://www.evernote.com/l/AHRIBndcq-5GwZVnSy1_D7lskpH4OcJcUKUB/image.png') img.testimonial-image(src='https://www.evernote.com/l/AHRIBndcq-5GwZVnSy1_D7lskpH4OcJcUKUB/image.png')
.col-xs-12.col-sm-8.col-md-9 .col-xs-12.col-sm-7.col-md-7
h3 Built by Suzanne Atkinson h3 Built by Suzanne Atkinson
p.large-p Suzanne is an emergency medicine physician, triathlon coach and web developer from Pittsburgh. You should &thinsp; p.large-p Suzanne is an emergency medicine physician, triathlon coach and web developer from Pittsburgh. You should &thinsp;
a(href='https://twitter.com/intent/user?screen_name=SteelCityCoach' target='_blank') follow her on Twitter a(href='https://twitter.com/intent/user?screen_name=SteelCityCoach' target='_blank') follow her on Twitter