Skip to content

Instantly share code, notes, and snippets.

@daniilS
Last active January 27, 2017 23:02
Show Gist options
  • Save daniilS/0eb8ea9130822b1ff7c4eef64b53f2f5 to your computer and use it in GitHub Desktop.
Save daniilS/0eb8ea9130822b1ff7c4eef64b53f2f5 to your computer and use it in GitHub Desktop.
Cambridge application statistics analyser
// ==UserScript==
// @name Cambridge application statistics analyser
// @namespace https://gist.github.com/daniilS/
// @description Go to the application statistics page, select courses or colleges, and press the button!
// @author daniilS
// @version 2
// @updateURL https://gist.github.com/daniilS/0eb8ea9130822b1ff7c4eef64b53f2f5/raw/cambridge_stats.user.js
// @match http://www.undergraduate.study.cam.ac.uk/apply/statistics
// @require https://code.highcharts.com/highcharts.js
// @require https://code.highcharts.com/modules/exporting.js
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @run-at document-idle
// ==/UserScript==
var count = GM_getValue("CambridgeStatCounter", 0);
var data = GM_getValue("CambridgeStatData", []);
var firstYear = GM_getValue("CambridgeStatFirstYear", parseInt(document.getElementById("edit-year")[document.getElementById("edit-year").length - 1].value));
var lastYear = parseInt(document.getElementById("edit-year")[0].value);
function addButton(){
var button = document.getElementById("edit-submit").cloneNode();
button.value = "Collect statistics";
button.style.margin = "0px 5px";
button.addEventListener("click", function(e){
e.preventDefault();
firstYear = parseInt(document.getElementById("yearInput").value);
GM_setValue("CambridgeStatFirstYear", firstYear);
document.getElementById("edit-period-year").click();
document.getElementById("edit-year").value = firstYear.toString();
document.getElementById("edit-app-applications").checked = true;
document.getElementById("edit-open-open").checked = false;
document.getElementById("edit-off-offers").checked = true;
document.getElementById("edit-winter-winter").checked = true;
document.getElementById("edit-acc-acceptances").checked = false;
count++;
GM_setValue("CambridgeStatCounter", count);
document.getElementById("edit-submit").click();
return false;
});
var yearInput = document.getElementById("edit-year").cloneNode(true);
yearInput.id = "yearInput";
yearInput.value = firstYear.toString();
var yearLabel = document.createElement("label");
yearLabel.setAttribute("for", yearInput);
yearLabel.innerHTML = "Collect statistics starting from:";
document.getElementById("edit-submit").parentNode.appendChild(button);
document.getElementById("edit-submit").parentNode.appendChild(yearLabel);
document.getElementById("edit-submit").parentNode.appendChild(yearInput);
}
function processData(data){
var offersSummed = [];
data.forEach(function(yearData){ //sum direct and pool offers
var processedYearData = [];
processedYearData.push(yearData[0]);
processedYearData.push(yearData[1]);
var accepted = [];
for(var x = 0; x < yearData[2].length; x++){
accepted.push(yearData[2][x]+yearData[3][x]);
}
processedYearData.push(accepted);
offersSummed.push(processedYearData);
});
var average = [];
for(var college = 0; college < offersSummed[offersSummed.length - 1][0].length; college++){ //calculate average applications and offers, then divide
var name = offersSummed[offersSummed.length - 1][0][college];
var applicationsSum = 0;
var offersSum = 0;
offersSummed.forEach(function(year){
var index = year[0].findIndex(function(e){ //to ensure only colleges that offered the course last year are taken into account
return e == name;
});
if(index != -1){
applicationsSum += year[1][index];
offersSum += year[2][index];
}
});
if(applicationsSum !== 0 && offersSum !== 0){
average.push([name, applicationsSum/offersSum]);
}
}
average.sort(function(collegeA, collegeB){
return collegeA[1] - collegeB[1];
});
average.forEach(function(college, index, array){
array[index][0] = college[0].replace(" College", "");
});
return average;
}
function drawChart(chartData){
var options;
if(document.getElementById("edit-group-college").checked === true){ //grouped by college
options = document.getElementsByClassName("chosen-choices")[1];
}
else{ //grouped by course
options = document.getElementsByClassName("chosen-choices")[0];
}
var title = "Applicants per offered place";
if(options.children.length == 2){ //only one college/course selected, so add it to the graph title
title += " (" + options.children[0].innerText + ")";
if(document.getElementById("edit-group-course").checked === true){
alert("Warning: this data does not include offers made by other colleges. Consider grouping by college instead, or not selecting any specific college.");
}
}
if(firstYear != lastYear){
title += "—average of " + firstYear + "–" + lastYear;
}
Highcharts.chart("highcharts-0", {
chart: {
height: 600,
spacingLeft: 50,
type: "column"
},
title: {
text: title
},
xAxis: {
type: "category",
labels: {
rotation: -45,
style: {
fontSize: "13px",
fontFamily: "Verdana, sans-serif"
}
}
},
yAxis: {
min: 0,
title: {
text: null
}
},
legend: {
enabled: false
},
tooltip: {
pointFormat: "Applicants per offered place: <b>{point.y:.1f}</b>"
},
series: [{
data: chartData
}]
});
}
if(!count){
addButton();
}
else{
var thisData = [];
var colleges = [];
for(var college of unsafeWindow.Highcharts.charts[0].series[0].data){
colleges.push(college.category);
}
thisData.push(colleges);
if(unsafeWindow.Highcharts.charts[0].series.length == 4){ //grouped by college
[0, 1, 3].forEach(function(x){ //total applications, direct offers, pool offers from other colleges
thisData.push(unsafeWindow.Highcharts.charts[0].series[x].processedYData);
});
}
else{ //grouped by course
[0, 1, 2].forEach(function(x){ //total applications, direct offers, pool offers
thisData.push(unsafeWindow.Highcharts.charts[0].series[x].processedYData);
});
}
data.push(thisData);
var nextYear = firstYear + count;
if(nextYear > lastYear){
chartData = processData(data);
drawChart(chartData);
count = 0;
GM_deleteValue("CambridgeStatCounter");
GM_deleteValue("CambridgeStatData");
GM_deleteValue("CambridgeStatFirstYear");
firstYear = parseInt(document.getElementById("edit-year")[document.getElementById("edit-year").length - 1].value);
addButton();
}
else{
document.getElementById("edit-year").value = nextYear.toString();
count++;
GM_setValue("CambridgeStatData", data);
GM_setValue("CambridgeStatCounter", count);
document.getElementById("edit-submit").click();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment