forked from sunnyuxuan‘s block: Week4 homework1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Week3 homework</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 style="color:#007fff; text-align: center;">TOP 10 Places of Origin of International Students</h1>
<p>According to the Open Doors International Student data portal, <strong style="color:#007fff;">974,926</strong>
international students studied at U.S. colleges and universities in 2014-2015. Among these international students, <strong style="color:#007fff;">58%</strong> of them are come from China, India, South Korea and Saudi Arabia.</p>
<div id="table" style="
margin: auto;"> </div>
<p style="color:grey;">Source: Institute of International Education. (2001). "Leading Places of Origin of International Students, 2013-2014." Open Doors Report on International Educational Exchange. Retrieved from //www.iie.org/opendoors</p>
</body>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="stupidtable.js"></script>
<script type="text/javascript">
d3.csv("week4.csv", function(error, myData) {
if (error) {
console.log("Loading file has errors.");
}
var myArray = [];
var allPercent = [];
myData.forEach(function(d, i){
d.Percent = d.Year2014 / d.Total ;
d.Percent = d.Percent * 100;
d.Percent = d3.round(d.Percent,1);
myArray.push([d.Place, d.Year2013, d.Year2014, d.Percent]);
allPercent.push(d.Percent);
});
console.log(allPercent);
var table = d3.select("#table").append("table");
var header = table.append("thead").append("tr");
var headerObjs = [
{ label: "Place", sort_type: "string" },
{ label: "Year2013", sort_type: "int" },
{ label: "Year2014", sort_type: "int" },
{ label: "Percent", sort_type: "float" },
];
myArray.sort(function(a,b){
return +b.Percent - +a.Percent
});
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");
table.attr("style","margin: auto","padding:10px;");
var rows = tablebody
.selectAll("tr")
.data(myArray)
.enter()
.append("tr");
var color3 = d3.scale.linear().domain(d3.extent(allPercent)).range(["#0052cc",
"#cce0ff"]);
var cells = rows.selectAll("td")
.data(function(d){return d;})
.enter()
.append("td")
.style("background-color",function(d,i){
if (i === 3){
return color3(d);
}
})
.text(function(d) { return d; });
$("table").stupidtable();
});
</script>
</html>
Make a table like the one in d3_table_heatmap.html for your data. You can modify your existing table if you want. 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.
// 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);
table{
border-collapse: collapse;
width:100%;
}
table,th,td {
text-align: center;
border: 1px solid #b3d9ff;
}
th:nth-child(n+1){
background:#99c2ff;
color:white;
font-size:15px;
font-style: normal;
}
tr:hover {
background-color: #99c2ff;
color:white;
}
th{
cursor:pointer;
}
Place,Year2013,Year2014,Total
China,274439,304040,974926
India,102673,132888,974926
South Korea,68047,63710,974926
Saudi Arabia,53919,59945,974926
Canada,28304,27240,974926
Brazil,13286,23675,974926
Taiwan,21266,20993,974926
Japan,19334,19064,974926
Vietnam,16579,18722,974926
Mexico,14779,17052,974926