Skip to content

Instantly share code, notes, and snippets.

@umcrcooke
Last active December 18, 2015 01:19
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 umcrcooke/5703304 to your computer and use it in GitHub Desktop.
Save umcrcooke/5703304 to your computer and use it in GitHub Desktop.
Sortable Heatmap
<!DOCTYPE html>
<meta charset="utf-8">
<head>
</head>
<style>
.q0-11 {fill: rgba(215, 48, 39, 0.8);}
.q1-11 {fill: rgba(244, 109, 67, 0.8);}
.q2-11 {fill: rgba(253, 174, 97, 0.8);}
.q3-11 {fill: rgba(254, 224, 144, 0.8);}
.q4-11 {fill: rgba(255, 255, 191, 0.8);}
.q5-11 {fill: rgba(224, 243, 248, 0.8);}
.q6-11 {fill: rgba(171, 217, 233, 0.8);}
.q7-11 {fill: rgba(116, 173, 209, 0.8);}
.q8-11 {fill: rgba(69, 117, 180, 0.8);}
.cell_label, .row_label{
font-family: sans-serif;
font-size: 10px;
line-height: 10px;
}
.col_label {
font-family: sans-serif;
font-size: 12px;
line-height: 10px;
font-weight: bold;
}
.col_label:hover {
fill: blue;
font-size: 14px;
line-height: 10px;
font-weight: bold;
cursor: default;
}
.col_label:active {
fill: orange;
font-size: 14px;
line-height: 10px;
font-weight: bold;
cursor: default;
}
.cell_label {
pointer-events: none;
}
#chart {
margin-left: 400px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<div id="chart"></div>
<script>
var dataset = [ { "2003": "1", "2004": "1", "2005": "1", "2006": "1", "2007": "1", "2008": "1", "2009": "1", "Country Name": "USA" },
{ "2003": "2", "2004": "2", "2005": "2", "2006": "2", "2007": "3", "2008": "4", "2009": "6", "Country Name": "Canada" },
{ "2003": "3", "2004": "3", "2005": "3", "2006": "3", "2007": "2", "2008": "3", "2009": "3", "Country Name": "Italy" },
{ "2003": "4", "2004": "4", "2005": "4", "2006": "4", "2007": "4", "2008": "2", "2009": "2", "Country Name": "France" },
{ "2003": "5", "2004": "6", "2005": "6", "2006": "6", "2007": "6", "2008": "6", "2009": "7", "Country Name": "Ireland" },
{ "2003": "6", "2004": "5", "2005": "5", "2006": "5", "2007": "5", "2008": "5", "2009": "4", "Country Name": "Germany" }];
var years = d3.keys(dataset[0]).filter(function(key) {
return key != "Country Name";
});
console.log(years);
var empty={};
var output=[];
for(i=parseInt(years[0]); i<=parseInt(years[years.length-1]); i++){
empty = {};
var newyear = years;
empty[newyear.shift()] = dataset.sort(function (a,b) {return a[i]-b[i];}).map(function (d) {return d["Country Name"];});
output.push(empty);
}
var sortOrder={};
for (var i=0; i<=output.length; i++) {
var row=output[i];
for (yr in row) {
sortOrder[yr] = sortOrder[yr] || {};
sortOrder[yr] = row[yr]
}
}
data = [];
dataset.sort(function (a,b) {
return (a[2003]-b[2003]);
})
dataset.forEach(function(d){
for (year = 2003; year < 2010; year++){
data.push({"year": year, "Country": d["Country Name"], "value": d[year]});
}
});
//var countryOrder = ["USA", "France", "Italy", "Germany", "Canada", "Ireland"];
var cell = {size: 20, width: 30, height: 20, border: 3}
var margin = {top: 100, right: 40, bottom: 10, left: 440},
height = 4800,
width = 800;
var color = d3.scale.quantize()
.domain([0, 6])
.range(d3.range(9).map(function(d) { return "q" + d + "-11"; }));
/*var grid = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "chart");
*/
var grid = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("margin-left", -margin.left + "px")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var cells = grid.append("g").attr("class", "grid_cells").selectAll("rect")
.data(data)
.enter().append("svg:rect")
.attr("class", function(d){ return color(d.value); })
.attr("x", function(d) { return (d.year - 2003)*cell.width ; })
.attr("y", function(d) { return (/*countryOrder*/sortOrder["2003"].indexOf(d.Country))*cell.height; })
.attr("width", cell.width - cell.border)
.attr("height", cell.height- cell.border)
.on('mouseover', function() {d3.select(this)
.style('fill', 'white');
})
.on('mouseout', function() {
d3.select(this)
.style('fill', '');
})
.on('click', function() {
console.log(d3.select(this));
})
.style("stroke", '#555');
var celltext = grid.append("g").attr("class", "cell_labels").selectAll(".cell_label")
.data(data)
.enter().append("svg:text")
.attr("x", function(d) { return (d.year - 2003)*cell.width + (cell.width-cell.border)/2 ;})
.attr("y", function(d) { return (/*countryOrder*/sortOrder["2003"].indexOf(d.Country))*cell.height + (cell.height-cell.border)/2; })
.attr("text-anchor","middle")
.attr("dy",".35em")
.attr("class", "cell_label")
.text(function(d) {return d.value;});
var rowtext = grid.append("g").attr("class", "row_labels").selectAll(".row_label")
.data(dataset).sort(function(a, b) {
return d3.ascending(+a[2003], +b[2003]);
})
.enter().append("svg:text")
.attr("x", -6)
.attr("y", function(d, i) { return (i*cell.height) + (cell.height-cell.border)/2; })
.attr("class", "row_label")
.text(function (d){return d["Country Name"];})
.attr('dy', '.25em')
.attr('text-anchor', 'end');
var years = d3.keys(dataset[0]).filter(function(key) {
return key != "Country Name";
});
var coltext = grid.append("g").attr("class", "col_labels").selectAll(".col_label")
.data(years)
.enter().append("svg:text")
.attr("x", function(d, i) { return (i*cell.width) + (cell.width-cell.border)/2; })
.attr("y", -15)
.attr("class", "col_label")
.attr("id", function (d) { return "col_" + d + " ";})
.text(function (d){return d;})
.attr('dx', '1.5em')
.attr('text-anchor', 'end')
.attr('transform', function (d,i) {return "rotate(-50," + ((i*cell.width) + (cell.width-cell.border)/2) + ", -15)";})
.on("click", function(d,i) { update(d);});
function update(year) {
grid.selectAll('rect')
.transition()
.duration(2500)
.attr("y", function(d) { return (sortOrder[year].indexOf(d.Country))*cell.height; })
grid.selectAll(".cell_label")
.transition()
.duration(2500)
.attr("y", function(d) { return (sortOrder[year].indexOf(d.Country))*cell.height + (cell.height-cell.border)/2; })
d3.selectAll(".row_label")
.sort(function(a, b) {
return d3.ascending(+a[year], +b[year]);
})
.transition()
.duration(2500)
.attr("y", function(d, i) { return (i*cell.height) + (cell.height-cell.border)/2; });
d3.selectAll(".col_label").attr("fill", "black").style("font-size", 12);
d3.select("#col_"+year).attr("fill", "red").style("font-size", 14);
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment