Skip to content

Instantly share code, notes, and snippets.

@yan2014
Last active October 22, 2015 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yan2014/d16824924ae2143e88ff to your computer and use it in GitHub Desktop.
Save yan2014/d16824924ae2143e88ff to your computer and use it in GitHub Desktop.
Week4: Heatmap table
<!--Make a table like the one in d3_table_heatmap.html for your data. It should be sortable using stupidtable.js. Make a color scale for one of your numeric columns. You can use the scale on a font or the background. Same rules as above:
Week4: Heatmap table
Style it (with CSS or in d3).
Make the column names nice ones for people to read in the table.
Sort the data in javascript for a default sort order that's sensible.
Make sure the headers have a cursor that looks like it's a pointer, that indicates you can click.
Be sure to add text identifying source and explaining the data.
Send me the gist: "Week4: Heatmap table"-->
<!--http://data.unicef.org/education/overview.html-->
<!DOCTYPE html>
<html>
<head>
<title>Survival rate to last grade of primary education</title>
<link rel="stylesheet" type="text/css" href="main.css"> </head>
<body>
<h1>The Reverse Gender Gap?</h1>
<p>In 2010, it seems that the percentage for female who had finished primary education is slightly larger than the percentage for male in the world. Then, what's the fact in less developed countries (Yemen, Guinea, etc)?</p>
<p>This table shows survival rate (percentage) to last grade of primary education from 2008 to 2011. </p>
<p>Data source: http://data.unicef.org/education/overview.html</p>
<div id="table"></div>
</body>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="stupidtable.js"></script>
<script type="text/javascript" src="main.js"></script>
</html>
table {
margin-left: 40px;
padding: 10px;
}
th {
cursor: pointer;
}
/**
* Created by shiyan on 9/17/15.
*/
//Load in contents of CSV file, and do things to the data.
d3.csv("primary education.csv", function(error, myData) {
if (error) {
console.log("Had an error loading file.");
}
// We'll be using simpler data as values, not objects.
var myArray = [];
// this is a new variable, to make it easier to do a color scale.
// alternately, you could extract these values with a map function.
var allDifferences = [];
myData.forEach(function(d, i){
// now we add another data object value, a calculated value.
d.mfdifference = d.male - d.female;
// Add an array to the empty array with the values of each:
myArray.push([d.countries, d.timePeriod,d.male, d.female, d.mfdifference]);
// this is just a convenience, another way would be to use a function to get the values in the d3 scale.
allDifferences.push(d.mfdifference);
});
console.log(allDifferences);
var table = d3.select("#table").append("table");
var header = table.append("thead").append("tr");
// Made some objects to construct the header in code:
// The sort_type is for the Jquery sorting function.
var headerObjs = [
{ label: "Countries", sort_type: "string" },
{ label: "Time Period", sort_type: "string" },
{ label: "Male", sort_type: "int" },
{ label: "Female", sort_type: "int" },
{ label: "Difference", sort_type: "int" }
];
header
.selectAll("th")
.data(headerObjs)
.enter()
.append("th")
.attr("data-sort", function (d) { return d.sort_type; })
.text(function(d) { return d.label; });
var tablebody = table.append("tbody");
rows = tablebody
.selectAll("tr")
.data(myArray)
.enter()
.append("tr");
var colorScale = d3.scale.linear()
.domain(d3.extent(allDifferences))
.range(["#E6F5FF", "#0099FF"]);
cells = rows.selectAll("td")
// each row has data associated; we get it and enter it for the cells.
.data(function(d) {
return d;
})
.enter()
.append("td")
.style("background-color", function(d,i) {
// for the last element in the row, we color the background:
if (i === 4) {
return colorScale(d);
}
})
.text(function(d) {
return d;
});
// jquery sorting applied to it - could be done with d3 and events.
$("table").stupidtable();
});
ISO_Code countries timePeriod total male female
ALB Albania 2010 98 98 98
DZA Algeria 2010 95 94 95
AGO Angola 2009 32 37 27
ARG Argentina 2009 95 95 96
ARM Armenia 2010 96 96 96
AUT Austria 2010 99 99 100
AZE Azerbaijan 2010 97 99 96
BHS Bahamas 2009 89 91 88
BHR Bahrain 2010 98 97 98
BGD Bangladesh 2009 66 62 71
BLR Belarus 2010 98 97 100
BEL Belgium 2009 97 95 98
BLZ Belize 2010 91 93 89
BEN Benin 2010 56 58 53
BTN Bhutan 2011 95 91 99
BOL Bolivia 2009 85 85 85
BIH Bosnia and Herzegovina 2010 81 81 80
BWA Botswana 2008 93 91 95
BGR Bulgaria 2009 97 98 97
BFA Burkina Faso 2011 69 66 73
BDI Burundi 2010 51 47 54
CPV Cabo Verde 2010 89 90 89
KHM Cambodia 2010 61 61 62
CMR Cameroon 2010 57 57 57
CAF Central African Republic 2010 46 49 44
TCD Chad 2010 49 51 47
CHL Chile 2010 98 98 98
COL Colombia 2010 87 88 87
CRI Costa Rica 2010 91 90 93
CIV Cote d'Ivoire 2008 61 62 59
HRV Croatia 2009 99 99 100
CUB Cuba 2010 95 94 96
CZE Czech Republic 2010 99 99 99
COD Democratic Republic of the Congo 2010 54 60 49
DNK Denmark 2009 99 99 99
DJI Djibouti 2008 64 64 64
DMA Dominica 2010 91 85 96
ECU Ecuador 2010 92 91 93
EGY Egypt 2010 99 99 99
SLV El Salvador 2010 84 82 86
GNQ Equatorial Guinea 2010 55 53 58
ERI Eritrea 2009 69 71 67
EST Estonia 2009 98 97 98
ETH Ethiopia 2010 41 40 42
FJI Fiji 2008 91 93 88
FIN Finland 2010 100 100 99
GMB Gambia 2010 63 60 66
GEO Georgia 2009 96 94 99
DEU Germany 2009 96 96 97
GHA Ghana 2008 72 76 69
GTM Guatemala 2009 68 68 68
GIN Guinea 2011 59 65 52
GUY Guyana 2008 83 85 82
HND Honduras 2010 75 72 78
HUN Hungary 2008 98 98 98
ISL Iceland 2009 98 97 99
IRN Iran (Islamic Republic of) 2010 98 98 98
ITA Italy 2009 100 99 100
JAM Jamaica 2009 95 94 96
JPN Japan 2009 100 100 100
KAZ Kazakhstan 2011 100 99 100
KWT Kuwait 2009 96 96 96
KGZ Kyrgyzstan 2010 95 95 96
LAO Lao People's Democratic Republic 2010 68 67 69
LVA Latvia 2010 93 93 93
LBN Lebanon 2010 90 88 94
LSO Lesotho 2010 66 58 76
LBR Liberia 2008 68 73 62
LIE Liechtenstein 2009 79 81 78
LTU Lithuania 2010 96 96 97
MDG Madagascar 2010 40 39 40
MWI Malawi 2010 51 50 52
MYS Malaysia 2009 99 99 100
MLI Mali 2010 75 77 74
MLT Malta 2008 80 83 76
MHL Marshall Islands 2008 83 87 80
MRT Mauritania 2008 81 80 82
MUS Mauritius 2010 97 97 98
MEX Mexico 2010 95 94 96
MNG Mongolia 2010 93 92 94
MNE Montenegro 2011 80 80 81
MAR Morocco 2011 88 89 88
MOZ Mozambique 2011 31 32 29
MMR Myanmar 2009 75 72 77
NAM Namibia 2009 84 82 87
NER Niger 2010 69 71 67
NGA Nigeria 2009 80 77 83
NOR Norway 2009 99 99 99
PAK Pakistan 2010 52 53 51
PAN Panama 2010 94 92 96
PRY Paraguay 2009 83 81 84
PER Peru 2010 82 82 81
PHL Philippines 2008 76 72 80
POL Poland 2009 99 99 100
KOR Republic of Korea 2009 99 99 99
MDA Republic of Moldova 2010 95 96 95
ROU Romania 2009 97 97 97
RWA Rwanda 2009 37 35 39
KNA Saint Kitts and Nevis 2009 74 78 70
LCA Saint Lucia 2010 92 90 94
WSM Samoa 2010 77 74 79
SEN Senegal 2010 59 59 60
SRB Serbia 2010 98 98 98
SYC Seychelles 2010 94 95 93
SGP Singapore 2008 99 99 99
SVK Slovakia 2010 98 98 98
SVN Slovenia 2010 99 99 98
ESP Spain 2010 98 98 97
LKA Sri Lanka 2010 97 100 95
SUR Suriname 2008 90 82 100
SWE Sweden 2010 96 96 96
SYR Syrian Arab Republic 2010 96 95 96
TJK Tajikistan 2010 99 99 99
TLS Timor-Leste 2010 84 82 85
TGO Togo 2010 52 55 48
TTO Trinidad and Tobago 2009 89 87 92
TUN Tunisia 2008 95 94 95
TUR Turkey 2009 99 98 100
UGA Uganda 2010 25 25 25
UKR Ukraine 2010 98 98 99
ARE United Arab Emirates 2010 84 85 84
TZA United Republic of Tanzania 2009 81 76 87
URY Uruguay 2009 95 94 96
UZB Uzbekistan 2010 98 98 98
VUT Vanuatu 2008 71 74 69
VEN Venezuela 2010 95 92 98
YEM Yemen 2010 76 82 68
ZMB Zambia 2008 53 55 52
MACRO Sub-Saharan Africa 2010 57 58 57
MACRO Eastern and Southern Africa 2010 49 48 49
MACRO West and Central Africa 2010 66 67 65
MACRO Middle East and North Africa 2010 88 89 88
MACRO South Asia 2010 63 61 65
MACRO East Asia and Pacific 2010 89 89 89
MACRO Latin America and Caribbean 2010 84 82 86
MACRO CEE/CIS 2010 98 97 98
MACRO Least developed countries 2010 57 57 58
MACRO World 2010 75 74 76
/**
* Created by shiyan on 9/17/15.
*/
// Stupid jQuery table plugin.
(function($) {
$.fn.stupidtable = function(sortFns) {
return this.each(function() {
var $table = $(this);
sortFns = sortFns || {};
sortFns = $.extend({}, $.fn.stupidtable.default_sort_fns, sortFns);
$table.data('sortFns', sortFns);
$table.on("click.stupidtable", "thead th", function() {
$(this).stupidsort();
});
});
};
// Expects $("#mytable").stupidtable() to have already been called.
// Call on a table header.
$.fn.stupidsort = function(force_direction){
var $this_th = $(this);
var th_index = 0; // we'll increment this soon
var dir = $.fn.stupidtable.dir;
var $table = $this_th.closest("table");
var datatype = $this_th.data("sort") || null;
// No datatype? Nothing to do.
if (datatype === null) {
return;
}
// Account for colspans
$this_th.parents("tr").find("th").slice(0, $(this).index()).each(function() {
var cols = $(this).attr("colspan") || 1;
th_index += parseInt(cols,10);
});
var sort_dir;
if(arguments.length == 1){
sort_dir = force_direction;
}
else{
sort_dir = force_direction || $this_th.data("sort-default") || dir.ASC;
if ($this_th.data("sort-dir"))
sort_dir = $this_th.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC;
}
$table.trigger("beforetablesort", {column: th_index, direction: sort_dir});
// More reliable method of forcing a redraw
$table.css("display");
// Run sorting asynchronously on a timout to force browser redraw after
// `beforetablesort` callback. Also avoids locking up the browser too much.
setTimeout(function() {
// Gather the elements for this column
var column = [];
var sortFns = $table.data('sortFns');
var sortMethod = sortFns[datatype];
var trs = $table.children("tbody").children("tr");
// Extract the data for the column that needs to be sorted and pair it up
// with the TR itself into a tuple. This way sorting the values will
// incidentally sort the trs.
trs.each(function(index,tr) {
var $e = $(tr).children().eq(th_index);
var sort_val = $e.data("sort-value");
// Store and read from the .data cache for display text only sorts
// instead of looking through the DOM every time
if(typeof(sort_val) === "undefined"){
var txt = $e.text();
$e.data('sort-value', txt);
sort_val = txt;
}
column.push([sort_val, tr]);
});
// Sort by the data-order-by value
column.sort(function(a, b) { return sortMethod(a[0], b[0]); });
if (sort_dir != dir.ASC)
column.reverse();
// Replace the content of tbody with the sorted rows. Strangely
// enough, .append accomplishes this for us.
trs = $.map(column, function(kv) { return kv[1]; });
$table.children("tbody").append(trs);
// Reset siblings
$table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc");
$this_th.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir);
$table.trigger("aftertablesort", {column: th_index, direction: sort_dir});
$table.css("display");
}, 10);
return $this_th;
};
// Call on a sortable td to update its value in the sort. This should be the
// only mechanism used to update a cell's sort value. If your display value is
// different from your sort value, use jQuery's .text() or .html() to update
// the td contents, Assumes stupidtable has already been called for the table.
$.fn.updateSortVal = function(new_sort_val){
var $this_td = $(this);
if($this_td.is('[data-sort-value]')){
// For visual consistency with the .data cache
$this_td.attr('data-sort-value', new_sort_val);
}
$this_td.data("sort-value", new_sort_val);
return $this_td;
};
// ------------------------------------------------------------------
// Default settings
// ------------------------------------------------------------------
$.fn.stupidtable.dir = {ASC: "asc", DESC: "desc"};
$.fn.stupidtable.default_sort_fns = {
"int": function(a, b) {
return parseInt(a, 10) - parseInt(b, 10);
},
"float": function(a, b) {
return parseFloat(a) - parseFloat(b);
},
"string": function(a, b) {
return a.localeCompare(b);
},
"string-ins": function(a, b) {
a = a.toLocaleLowerCase();
b = b.toLocaleLowerCase();
return a.localeCompare(b);
}
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment