Skip to content

Instantly share code, notes, and snippets.

@tmaybe
Forked from tommaybe/LICENSE.md
Last active December 20, 2015 11:39
Show Gist options
  • Save tmaybe/6124823 to your computer and use it in GitHub Desktop.
Save tmaybe/6124823 to your computer and use it in GitHub Desktop.
Heat Grid Showing Survey Results
Absolutes Total: Male Female 18-24 y.o. 25-34 y.o. 35-44 y.o. 45-54 y.o. over 55 y.o. Villages Urban Pashtun Tajik Uzbek Hazara Other Less than 2,000 Afs 2,001 - 3,000 Afs 3,001 - 5,000 Afs (incl. refused and DK) 5,001 - 10,000 Afs 10,001+ Afs Never went to school (incl. refused and DK) 1-6 grade 7-9 grade 10+ grade Central/Kabul Eastern South East South Western Western North East Central/Hazarjat North West
Base: All Respondents 6348 3638 2710 1572 1724 1512 945 594 4983 1365 2620 2009 553 695 471 551 1066 1240 1991 1500 3675 970 581 1122 1428 617 680 708 856 927 222 910
Right direction 2933 1698 1235 723 775 715 429 291 2392 541 1170 935 253 349 226 281 540 536 888 688 1721 444 266 502 511 283 266 362 400 508 131 472
Wrong direction 2200 1340 859 549 607 521 325 197 1623 576 976 683 183 190 167 174 348 419 710 548 1202 350 213 434 666 264 226 234 252 251 46 262
Some in right, some in wrong direction (vol.) 1084 531 554 267 307 242 175 93 857 228 425 345 100 143 71 76 156 250 363 240 658 165 90 171 228 65 170 109 170 151 32 160
Refused (vol.) 6 3 3 0 3 3 0 0 5 1 2 3 0 1 0 0 2 2 0 2 5 0 0 1 2 0 0 0 2 2 0 0
Don't know (vol.) 125 65 59 33 32 31 16 13 106 19 47 44 15 11 8 19 20 33 31 22 88 11 12 13 20 6 19 4 33 15 13 16
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
rect.bordered {
stroke: #E6E6E6;
stroke-width: 2px;
}
text.mono {
font-size: 9pt;
font-family: Consolas, courier;
fill: #aaa;
}
text.axis {
fill: #000;
}
</style>
<script src="http://d3js.org/d3.v3.js" type="text/javascript"></script>
<title></title>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript">
var parsedata = [],
margin = {
top: 175,
right: 0,
bottom: 100,
left: 165
},
width = 990 - margin.left - margin.right,
height = 430 - margin.top - margin.bottom,
gridSize = Math.floor(width / 36),
legendElementWidth = gridSize * 2,
buckets = 9,
colors = ["#fff7ec", "#fee8c8", "#fdd49e", "#fdbb84", "#fc8d59", "#ef6548", "#d7301f", "#b30000", "#7f0000"],
// alternatively colorbrewer.YlGnBu[9]
fullanswers = ["Right direction", "Wrong direction", "Some in right, some in wrong direction (vol.)", "Refused (vol.)", "Don't know (vol.)"],
answers = ["Right", "Wrong", "Some Right, Some Wrong", "Refused to Answer", "Don't Know"],
categories = ["total", "gendermale", "genderfemale", "age18to24", "age25to34", "age35to44", "age45to54", "age55plus", "settlementvillages", "settlementurban", "ethnicitypashtun", "ethnicitytajik", "ethnicityuzbek", "ethnicityhazara", "ethnicityother", "incomeunder2k", "income2kto3k", "income3kto5k", "income5kto10k", "income10kplus", "edunone", "edu1to6", "edu7to9", "edu10plus", "regionkabul", "regione", "regionse", "regionsw", "regionw", "regionne", "regionhazarjat", "regionnw"],
categorylabels = ["Everybody", "Male", "Female", "Age 18-24", "Age 25-34", "Age 35-44", "Age 45-54", "Age 55+", "Villages", "Urban", "Pashtun", "Tajik", "Uzbek", "Hazara", "Other Ethnicity", "Income <2K", "Income 2K-3K", "Income 3K-5K", "Income 5K-10K", "Income 10K+", "No Education", "Grades 1-6", "Grades 7-9", "Grades 10+", "Kabul", "East", "South East", "South West", "West", "North East", "Hazarjat", "North West"];
d3.tsv("data.tsv", function(d) {
return {
answer: d["Absolutes"],
total: +d["Total:"],
gendermale: +d["Male"],
genderfemale: +d["Female"],
age18to24: +d["18-24 y.o."],
age25to34: +d["25-34 y.o."],
age35to44: +d["35-44 y.o."],
age45to54: +d["45-54 y.o."],
age55plus: +d["over 55 y.o."],
settlementvillages: +d["Villages"],
settlementurban: +d["Urban"],
ethnicitypashtun: +d["Pashtun"],
ethnicitytajik: +d["Tajik"],
ethnicityuzbek: +d["Uzbek"],
ethnicityhazara: +d["Hazara"],
ethnicityother: +d["Other"],
incomeunder2k: +d["Less than 2,000 Afs"],
income2kto3k: +d["2,001 - 3,000 Afs"],
income3kto5k: +d["3,001 - 5,000 Afs (incl. refused and DK)"],
income5kto10k: +d["5,001 - 10,000 Afs"],
income10kplus: +d["10,001+ Afs"],
edunone: +d["Never went to school (incl. refused and DK)"],
edu1to6: +d["1-6 grade"],
edu7to9: +d["7-9 grade"],
edu10plus: +d["10+ grade"],
regionkabul: +d["Central/Kabul"],
regione: +d["Eastern"],
regionse: +d["South East"],
regionsw: +d["South Western"],
regionw: +d["Western"],
regionne: +d["North East"],
regionhazarjat: +d["Central/Hazarjat"],
regionnw: +d["North West"]
}
}, function(error, data) {
// reference to the first row of data, with the totals
var totalsobj = data[0];
// step through the remaining rows
for (row = 1; row < data.length; row++) {
var rowobj = data[row];
for (var key in rowobj) {
// verify that this is the object's own property
if (rowobj.hasOwnProperty(key) && key != "answer") {
// get percentages by dividing the value by the total respondants
var roundedpercent = Math.round((rowobj[key] / totalsobj[key]) * 10000) / 100;
var gridobj = {answer: rowobj['answer'], category: key, percent: roundedpercent, people: rowobj[key] };
parsedata.push(gridobj);
}
}
}
var colorScale = d3.scale.quantile()
.domain([0, buckets - 1, d3.max(parsedata, function (d) { return d.percent; })])
.range(colors);
var svg = d3.select("#chart").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 + ")");
svg.append("text")
.text("Generally speaking, do you think things in Afghanistan today are going in the right direction,")
.attr("x", 0).attr("y", -margin.top + 25);
svg.append("text")
.text("or do you think they are going in the wrong direction?")
.attr("x", 0).attr("y", -margin.top + 45);
var answerLabels = svg.selectAll(".ansLabel")
.data(answers)
.enter().append("text")
.text(function(d) { return d; })
.attr("x", 0).attr("y", function(d, i) { return i * gridSize; })
.style("text-anchor", "end")
.attr("transform", "translate(-6," + gridSize / 1.5 + ")")
.attr("class", "mono axis");
var categoryLabels = svg.selectAll(".catLabel")
.data(categorylabels)
.enter().append("text")
.text(function(d) { return d; })
.style("text-anchor", "beginning")
.attr("transform", function(d, i) { return "translate(" + ((i * gridSize) + (gridSize / 2)) + ", -6) rotate(-65)" })
.attr("class", "mono axis");
var heatMap = svg.selectAll(".gridsquare")
.data(parsedata)
.enter()
.append("rect")
.attr("x", function(d) { return (categories.indexOf(d.category)) * gridSize; })
.attr("y", function(d) { return (fullanswers.indexOf(d.answer)) * gridSize; })
.attr("rx", 4)
.attr("ry", 4)
.attr("class", "bordered")
.attr("width", gridSize)
.attr("height", gridSize)
.style("fill", colors[0]);
heatMap.transition().duration(1000)
.style("fill", function(d) { return colorScale(d.percent); });
heatMap.append("title").text(function(d) { return d.percent + "% (" + d.people + " people)"; });
var legend = svg.selectAll(".legend")
.data([0].concat(colorScale.quantiles()), function(d) { return d; })
.enter().append("g");
legend.append("rect")
.attr("x", function(d, i) { return legendElementWidth * i; })
.attr("y", height)
.attr("width", legendElementWidth)
.attr("height", gridSize / 2)
.style("fill", function(d, i) { return colors[i]; });
legend.append("text")
.attr("class", "mono")
.text(function(d) { return "≥ " + Math.round(d); })
.attr("x", function(d, i) { return legendElementWidth * i; })
.attr("y", height + gridSize);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment