Visualising the results of Imperial's Staff Survey for Felix.
Last active
January 1, 2020 08:33
-
-
Save tlfrd/6e20a23a1479b46dcfdc50efec51ee3b to your computer and use it in GitHub Desktop.
Heat Map II
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.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; } | |
div.tooltip{ | |
position: absolute; | |
text-align: center; | |
padding: 5px; | |
font-size: 12px; | |
font-family: 'Open Sans', sans-serif; | |
background-color: white; | |
border: 1px #b7b7b7 solid; | |
pointer-events: none; | |
width: 50px; | |
} | |
text { | |
font-family: 'Open Sans', sans-serif; | |
font-size: 12px; | |
} | |
.title { | |
font-size: 20px; | |
} | |
rect { | |
stroke: white; | |
} | |
</style> | |
</head> | |
<body> | |
<script> | |
var margin = {top: 125, right: 100, bottom: 100, left: 275}; | |
var width = 900 - margin.left - margin.right, | |
height = 500 - 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 + ")"); | |
d3.csv("staffsurvey.csv", (error, data) => { | |
if (error) throw error; | |
var formattedData = formatData(data); | |
var extent = getExtent(formattedData); | |
// Create colour scale | |
var colourScale = d3.scaleLinear(); | |
colourScale.range(["#f9f9ff", "#0000FF"]) | |
colourScale.domain([extent[1], extent[0]]); | |
drawHeatMap(formattedData, {height: height, width: width, xLength: formattedData[0].facultyResults.length, rowLabelXPadding: 10, columnLabelYPadding: 10}, colourScale); | |
}); | |
// Get extent of percentage | |
function getExtent(data) { | |
var minPercentage = d3.min(data, d => { | |
return d3.min(d.facultyResults, d1 => { | |
if (d1.percentage) { | |
return d1.percentage; | |
} else { | |
return 100; | |
} | |
}); | |
}); | |
var maxPercentage = d3.max(data, d => { | |
return d3.max(d.facultyResults, d1 => { | |
if (d1.percentage) { | |
return d1.percentage; | |
} else { | |
return 0; | |
} | |
}); | |
}); | |
return [minPercentage, maxPercentage]; | |
} | |
// Format data into nice arrays | |
function formatData(data) { | |
var questions = []; | |
data.forEach(d => { | |
var facultiesArray = []; | |
for (var faculty in d) { | |
if (faculty != "Question Class") { | |
facultiesArray.push({ | |
faculty: faculty, | |
percentage: d[faculty].slice(0, -1) | |
}); | |
} | |
} | |
questions.push({ | |
questionClass: d["Question Class"], | |
facultyResults: facultiesArray | |
}); | |
}); | |
return questions; | |
} | |
// Refactor and pass position of label via config | |
function showLabel(d) { | |
var coords = [d3.event.clientX, d3.event.clientY]; | |
var top = coords[1] + 30, | |
left = coords[0] - 50; | |
d3.select(".tooltip") | |
.style("top", top + "px") | |
.style("left", left + "px") | |
.transition() | |
.duration(200) | |
.style("opacity", 1) | |
d3.select(".tooltip") | |
.html(d.percentage + "%") | |
} | |
function moveLabel() { | |
var coords = [d3.event.clientX, d3.event.clientY]; | |
var top = coords[1] + 30, | |
left = coords[0] - 50; | |
d3.select(".tooltip") | |
.style("top", top + "px") | |
.style("left", left + "px"); | |
} | |
function hideLabel(d) { | |
d3.select(".tooltip") | |
.transition() | |
.duration(200) | |
.style("opacity", 0); | |
} | |
// Draw the heatmap | |
function drawHeatMap(data, config, colourScale) { | |
var rectWidth = config.width / config.xLength, | |
rectHeight = config.height / data.length; | |
var rowGroups = svg.selectAll("g") | |
.data(data).enter() | |
.append("g") | |
.attr("class", "row-group") | |
.attr("transform", (d, i) => "translate(" + [0, i * rectHeight] + ")"); | |
var rects = rowGroups.selectAll("rect") | |
.data(d => d.facultyResults).enter() | |
.append("rect") | |
.attr("class", "row") | |
.attr("width", rectWidth) | |
.attr("height", rectHeight) | |
.attr("x", (d, i) => i * rectWidth) | |
.style("fill", d => colourScale(d.percentage)) | |
.on("mouseover", showLabel) | |
.on("mousemove", moveLabel) | |
.on("mouseout", hideLabel); | |
// Refactor | |
var title = svg.append("text") | |
.attr("y", -50) | |
.attr("x", width / 2) | |
.attr("text-anchor", "middle") | |
.attr("class", "title") | |
.text("Percentage of Postitive Responses for Question Classes by Department") | |
// Refactor | |
var rowLabels = rowGroups.append("text") | |
.attr("x", -config.rowLabelXPadding) | |
.attr("y", rectHeight / 1.5) | |
.attr("text-anchor", "end") | |
.text(d => d.questionClass); | |
// Refactor | |
var columnLabels = svg.append("g") | |
.attr("class", "columnLabels") | |
.selectAll("text") | |
.data(data[0].facultyResults).enter() | |
.append("text") | |
.attr("text-anchor", "middle") | |
.attr("x", (d, i) => i * rectWidth + (rectWidth / 2)) | |
.attr("y", -config.columnLabelYPadding) | |
.text(d => d.faculty); | |
var legend = svg.append("g") | |
.attr("class", "legend") | |
.attr("transform", "translate(" + [0, height + rectHeight] + ")") | |
var legendLinear = d3.legendColor() | |
.shapeWidth(rectWidth) | |
.shapeHeight(rectHeight) | |
.shapePadding(0) | |
.orient('horizontal') | |
.scale(colourScale) | |
.labelFormat(d => Math.round(d) + "%"); | |
legend.call(legendLinear); | |
var div = d3.select("body").append("div") | |
.attr("class", "tooltip") | |
.style("opacity", 0); | |
} | |
</script> | |
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Question Class | Overall | Aero | Bioeng | Chem Eng | Civil | Computing | ESE | EEE | Materials | Mech Eng | Dyson | Business | Medicine | CEP | Chem | Life Science | Maths | Physics | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Your Role | 71% | 64% | 73% | 70% | 71% | 67% | 76% | 72% | 70% | 76% | 69% | 72% | 68% | 70% | 70% | 68% | 75% | 70% | |
Your Development | 61% | 55% | 66% | 65% | 61% | 57% | 72% | 65% | 65% | 65% | 70% | 61% | 56% | 51% | 64% | 54% | 72% | 62% | |
Reward and Recognition | 59% | 48% | 57% | 52% | 48% | 44% | 57% | 52% | 55% | 62% | 59% | 60% | 55% | 58% | 46% | 52% | 58% | 52% | |
Safety | 88% | 80% | 88% | 85% | 91% | 82% | 92% | 92% | 86% | 86% | 82% | 86% | 88% | 82% | 92% | 93% | 86% | 92% | |
Health and Wellbeing | 68% | 63% | 65% | 66% | 71% | 58% | 72% | 68% | 68% | 67% | 59% | 67% | 65% | 63% | 63% | 66% | 64% | 67% | |
Your Line Manager | 69% | 53% | 69% | 78% | 71% | 65% | 75% | 75% | 72% | 74% | 77% | 69% | 65% | 61% | 72% | 62% | 79% | 66% | |
Your Department | 66% | 50% | 72% | 63% | 62% | 64% | 68% | 64% | 67% | 61% | 68% | 70% | 55% | 59% | 64% | 56% | 70% | 63% | |
Your Faculty | 40% | 31% | 47% | 43% | 33% | 33% | 44% | 34% | 44% | 37% | 55% | 48% | 32% | 41% | 42% | 33% | 34% | 31% | |
College Senior Leadership | 41% | 27% | 42% | 44% | 48% | 26% | 44% | 37% | 40% | 40% | 47% | 51% | 30% | 35% | 44% | 34% | 36% | 35% | |
Communication | 52% | 45% | 54% | 54% | 58% | 45% | 54% | 47% | 49% | 46% | 62% | 48% | 47% | 51% | 54% | 46% | 43% | 44% | |
Equality, Diversity, and Inclusion | 74% | 63% | 67% | 70% | 72% | 65% | 67% | 67% | 75% | 76% | 69% | 79% | 67% | 70% | 74% | 71% | 74% | 73% | |
Perceptions of the College | 74% | 73% | 77% | 75% | 83% | 70% | 77% | 83% | 76% | 78% | 80% | 79% | 68% | 74% | 69% | 66% | 77% | 74% | |
Next Steps | 53% | 33% | 61% | 57% | 53% | 46% | 50% | 55% | 50% | 50% | 64% | 49% | 45% | 61% | 53% | 50% | 55% | 56% |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Question Class | Overall | Business School | Engineering | Medicine | FoNS | |
---|---|---|---|---|---|---|
Your Role | 71% | 72% | 72% | 69% | 71% | |
Your Development | 61% | 61% | 64% | 59% | 61% | |
Reward and Recognition | 59% | 60% | 54% | 57% | 55% | |
Safety | 88% | 86% | 87% | 88% | 91% | |
Health and Wellbeing | 68% | 67% | 67% | 67% | 66% | |
Your Line Manager | 69% | 69% | 72% | 68% | 68% | |
Your Department | 66% | 70% | 65% | 61% | 63% | |
Your Faculty | 40% | 48% | 41% | 39% | 37% | |
College Senior Leadership | 41% | 51% | 40% | 37% | 37% | |
Communication | 52% | 48% | 51% | 51% | 48% | |
Equality, Diversity, and Inclusion | 74% | 79% | 77% | 71% | 72% | |
Perceptions of the College | 74% | 79% | 77% | 71% | 72% | |
Next Steps | 53% | 49% | 53% | 51% | 55% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment