|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400, 600" rel="stylesheet"> |
|
<style> |
|
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } |
|
|
|
text { |
|
font-family: 'Open Sans', sans-serif; |
|
} |
|
|
|
.title { |
|
font-size: 17px; |
|
opacity: 0.7; |
|
font-weight: 600; |
|
} |
|
|
|
.outline { |
|
fill: none; |
|
} |
|
|
|
.below-bar { |
|
fill: #a0448c; |
|
} |
|
|
|
.eq-bar { |
|
fill: #b5b6b9; |
|
} |
|
|
|
.above-bar { |
|
fill: #adce49; |
|
} |
|
|
|
.legend-label { |
|
font-size: 14px; |
|
opacity: 0.7; |
|
} |
|
|
|
.y-axis text { |
|
font-size: 12px; |
|
opacity: 0.7; |
|
} |
|
|
|
.bar-groups text { |
|
fill: white; |
|
font-weight: 600; |
|
} |
|
|
|
.annotation { |
|
font-size: 12px; |
|
opacity: 0.7; |
|
} |
|
|
|
</style> |
|
</head> |
|
|
|
<body> |
|
<script> |
|
var margin = {top: 150, right: 100, bottom: 125, left: 200}; |
|
|
|
var width = 960 - margin.left - margin.right, |
|
height = 700 - margin.top - margin.bottom; |
|
|
|
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 + ")"); |
|
|
|
function getValues(d) { |
|
for (var i = 1; i <= 27; i++) { |
|
d[i] = +d[i]; |
|
} |
|
return d; |
|
} |
|
|
|
var x = d3.scaleLinear() |
|
.range([0, width]); |
|
|
|
var y = d3.scaleBand() |
|
.range([0, height]) |
|
.padding(0.2); |
|
|
|
d3.csv("nss-results.csv", getValues, function(error, results) { |
|
if (error) throw error; |
|
|
|
var englandAverage = results[results.length - 2], |
|
imperialAverage = results[results.length - 1]; |
|
|
|
results = results.slice(0, -2); |
|
|
|
results.forEach(function(d) { |
|
var eng = [], |
|
imp = []; |
|
for (var i = 1; i <= 27; i++) { |
|
eng[i - 1] = (d[i] - englandAverage[i]).toPrecision(2); |
|
imp[i - 1] = (d[i] - imperialAverage[i]).toPrecision(2); |
|
} |
|
d.englandAvgDiff = eng; |
|
d.imperialAvgDiff = imp; |
|
}); |
|
|
|
results.forEach(function(d) { |
|
var above = 0, |
|
equal = 0, |
|
below = 0; |
|
|
|
for (var x in d.englandAvgDiff) { |
|
if (+d.englandAvgDiff[x] < 0) { |
|
below++; |
|
} else if (+d.englandAvgDiff[x] > 0) { |
|
above++; |
|
} else { |
|
equal++; |
|
} |
|
} |
|
|
|
d.above = above; |
|
d.equal = equal; |
|
d.below = below; |
|
}); |
|
|
|
results.sort(function(a, b) { |
|
if (a.below < b.below) return 1; |
|
if (a.below > b.below) return -1; |
|
return 0; |
|
}) |
|
|
|
x.domain([0, results[0].englandAvgDiff.length]); |
|
y.domain(results.map(d => d.department)); |
|
|
|
var title = svg.append("g") |
|
.attr("class", "title") |
|
.attr("transform", "translate(" + [0, -margin.top / 2] + ")"); |
|
|
|
title.append("text") |
|
.attr("text-anchor", "stat") |
|
.text("No. of NSS Questions with Scores Above or Below the England Average"); |
|
|
|
|
|
var legend = svg.append("g") |
|
.attr("transform", "translate(" + [0, -margin.top / 4] + ")"); |
|
|
|
legend.selectAll("rect") |
|
.data(["below-bar", "eq-bar", "above-bar"]) |
|
.enter().append("rect") |
|
.attr("class", d => d) |
|
.attr("x", (d, i) => (width / 4) * i) |
|
.attr("width", d => 20) |
|
.attr("height", y.bandwidth()); |
|
|
|
legend.append("rect") |
|
.attr("class", "outline") |
|
.attr("width", width) |
|
.attr("height", y.bandwidth()); |
|
|
|
legend.selectAll("text") |
|
.data(["Below Average", "Equal To Average", "Above Average"]) |
|
.enter().append("text") |
|
.attr("class", "legend-label") |
|
.attr("x", (d, i) => (width / 4) * i + 30) |
|
.attr("y", y.bandwidth() / 2) |
|
.attr("dy", 5) |
|
.text(d => d); |
|
|
|
var annotation = svg.append("g") |
|
.attr("transform", "translate(" + [0, height + margin.bottom / 3] + ")"); |
|
annotation.append("text") |
|
.attr("class", "annotation") |
|
.text("*Molecular Biology, Biophysics, and Biochemisty") |
|
|
|
var yAxisGroup = svg.append("g") |
|
.attr("class", "y-axis-group"); |
|
|
|
var yAxis = yAxisGroup.append("g") |
|
.attr("class", "y-axis") |
|
.call(d3.axisLeft(y).tickSize(0)); |
|
yAxis.attr("transform", "translate(" + [-10, -1] + ")") |
|
yAxis.select(".domain").style("opacity", 0); |
|
|
|
var xAxisGroup = svg.append("g") |
|
.attr("class", "x-axis-group") |
|
.attr("transform", "translate(" + [0, height] + ")") |
|
|
|
var barGroups = svg.append("g") |
|
.attr("class", "bar-groups") |
|
.selectAll("g") |
|
.data(results) |
|
.enter().append("g") |
|
.attr("class", "bar-group") |
|
.attr("transform", d => "translate(" + [0, y(d.department)] + ")") |
|
|
|
var lowerBars = barGroups.append("rect") |
|
.attr("class", "below-bar") |
|
.attr("x", 0) |
|
.attr("width", d => x(d.below)) |
|
.attr("height", y.bandwidth()); |
|
|
|
var lowerLabels = barGroups.append("text") |
|
.attr("x", d => x(d.below) / 2) |
|
.attr("y", y.bandwidth()) |
|
.attr("text-anchor", "middle") |
|
.text(d => d.below > 0 ? d.below : ""); |
|
|
|
var eqBars = barGroups.append("rect") |
|
.attr("class", "eq-bar") |
|
.attr("x", d => x(d.below)) |
|
.attr("width", d => x(d.equal)) |
|
.attr("height", y.bandwidth()); |
|
|
|
var eqLabels = barGroups.append("text") |
|
.attr("x", d => x(d.below) + x(d.equal) / 2) |
|
.attr("y", y.bandwidth()) |
|
.attr("text-anchor", "middle") |
|
.text(d => d.equal > 0 ? d.equal : ""); |
|
|
|
var aboveBars = barGroups.append("rect") |
|
.attr("class", "above-bar") |
|
.attr("x", d => x(d.below + d.equal)) |
|
.attr("width", d => x(d.above)) |
|
.attr("height", y.bandwidth()); |
|
|
|
var aboveLabels = barGroups.append("text") |
|
.attr("x", d => x(d.below) + x(d.equal) + x(d.above) / 2) |
|
.attr("y", y.bandwidth()) |
|
.attr("text-anchor", "middle") |
|
.text(d => d.above > 0 ? d.above : ""); |
|
|
|
barGroups.selectAll("text") |
|
.attr("dy", -y.bandwidth() * 0.225) |
|
.style("font-size", y.bandwidth() * 0.7) |
|
|
|
var outlines = barGroups.append("rect") |
|
.attr("class", "outline") |
|
.attr("width", width + 1) |
|
.attr("height", y.bandwidth()); |
|
|
|
}); |
|
|
|
</script> |
|
</body> |