|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
text { |
|
font-family: Verdana, Arial, sans-serif; |
|
font-size: 0.6em; |
|
font-stretch: condensed; |
|
fill: darkgrey; |
|
} |
|
|
|
text.years { |
|
font-size: 0.55em; |
|
font-stretch: extra-condensed; |
|
} |
|
text.hover { |
|
font-weight: bold; |
|
fill: black; |
|
|
|
} |
|
.legend text { |
|
fill: black; |
|
|
|
} |
|
|
|
div.tooltip { |
|
font-family: Verdana, Arial, sans-serif; |
|
font-size: 0.6em; |
|
position: absolute; |
|
text-align: center; |
|
padding: 1px; |
|
background: lightsteelblue; |
|
border: 0px; |
|
border-radius: 4px; |
|
pointer-events: none; |
|
} |
|
</style> |
|
<div id="viz"></div> |
|
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> |
|
<script> |
|
var width = 960, |
|
height = 500; |
|
var padding = 10; |
|
var rasterw = 750-padding, |
|
rasterh = height-3*padding; |
|
var svg = d3.select("#viz").append("svg") |
|
.attr("width",width) |
|
.attr("height",height) |
|
.append("g") |
|
.attr("transform","translate("+padding+","+padding+")");; |
|
|
|
var colours = ["#4575b4","#91bfdb","#e0f3f8", "#ffffbf", "#fee090", "#fc8d59"].reverse(); |
|
|
|
var heatmapColour = d3.scale.linear() |
|
.domain(d3.range(0, 1, 1.0 / (colours.length - 1))) |
|
.range(colours); |
|
|
|
var div = d3.select("body").append("div") |
|
.attr("class", "tooltip") |
|
.style("opacity", 0); |
|
|
|
d3.tsv("birds.tsv", function(error, _data) { |
|
|
|
_data.sort(function(a,b) {return a[2014]-b[2014]}); |
|
years = Object.keys(_data[0]); |
|
years.forEach(function(d,i) { |
|
if (d == "naam") { |
|
years.splice(i, 1);} |
|
}); |
|
var data = []; |
|
_data.forEach(function(d,i) { |
|
data.push({ |
|
naam: d.naam, |
|
values: years.map(function(o){ |
|
return [o,d[o]];}), |
|
extent: d3.extent(years.map(function(o){return parseInt(d[o]);})) |
|
}); |
|
}); |
|
|
|
var cn = years.length, |
|
rn = data.length; |
|
|
|
var bw = rasterw/cn, |
|
bh = rasterh/rn; |
|
|
|
var birds = svg.selectAll("birds") |
|
.data(data) |
|
.enter().append("g") |
|
.attr("transform",function(d,i) {return "translate(0,"+i*bh+")";}); |
|
|
|
birds.append("text") |
|
.text(function(d) {return d.naam}) |
|
.attr("class",function(d) {return "b"+d.naam}) |
|
.attr("transform",function(d,i) {return "translate("+(rasterw+3)+","+(bh-2)+")";}); |
|
|
|
var blocks = birds.selectAll("blocks") |
|
.data(function(d) {return d.values;}) |
|
.enter().append("rect") |
|
.attr("class",function(d) { |
|
p = d3.select(this.parentNode).datum(); |
|
return "y"+d[0]+" b"+p.naam}) |
|
.attr("width",bw) |
|
.attr("height",bh) |
|
.style("fill",function(d) { |
|
p = d3.select(this.parentNode).datum(); |
|
c = d3.scale.linear().domain(p.extent).range([0,1]); |
|
return heatmapColour(c(d[1])); |
|
}) |
|
.attr("transform",function(d,i) {return "translate("+i*bw+",0)";}) |
|
.on("mouseover", function(d) { |
|
d3.selectAll(".hover").classed("hover", false); |
|
d3.selectAll(".y"+d[0]).classed("hover", true); |
|
p = d3.select(this.parentNode).datum(); |
|
p = p.naam; |
|
d3.selectAll(".b"+p.replace(" ",".")).classed("hover", true); |
|
div.transition() |
|
.duration(200) |
|
.style("opacity", .7); |
|
div .html("Eerste eilegdatum <br>"+p+"<br>"+d[0] + ": "+dateFromDay(d[0], d[1])) |
|
.style("left", (d3.event.pageX+10) + "px") |
|
.style("top", (d3.event.pageY +10) + "px"); |
|
}) |
|
.on("mouseout", function(d) { |
|
div.transition() |
|
.duration(500) |
|
.style("opacity", 0); |
|
}); |
|
|
|
var years = svg.selectAll("years") |
|
.data(years) |
|
.enter().append("text") |
|
.text(function(d,i) {return d}) |
|
.style("text-anchor","middle") |
|
.attr("class",function(d) {return "years y"+d}) |
|
.attr("transform",function(d,i) {return "translate("+(i*bw+bw/2)+"," + (height-2*padding) + ")";}) |
|
|
|
var legenddata = [[0,"vroeger"],[1,""],[2,""],[3,""],[4,"later"],[5,""]]; |
|
|
|
var legend = svg.append("g") |
|
.attr("class","legend") |
|
.attr("transform", function(d,i) {return "translate(865,460)"});; |
|
|
|
var lblocks = legend.selectAll("legend") |
|
.data(legenddata) |
|
.enter().append("g") |
|
.attr("transform", function(d,i) {return "translate(" + i*bw/2 + ",0)"}); |
|
|
|
lblocks.append("rect") |
|
.attr("width",bw/2) |
|
.attr("height",bh) |
|
.style("fill",function(d) { |
|
c = d3.scale.linear().domain([0,5]).range([0,1]); |
|
return heatmapColour(c(d[0])); |
|
}); |
|
|
|
lblocks.append("text") |
|
.text(function(d) { |
|
return d[1] |
|
}) |
|
.attr("transform", "translate(0,20)");; |
|
|
|
legend.append("text") |
|
.text("Wanneer werd") |
|
.attr("transform", "translate(0,-30)"); |
|
|
|
legend.append("text") |
|
.text("het eerste") |
|
.attr("transform", "translate(0,-20)"); |
|
|
|
legend.append("text") |
|
.text("ei gelegd:") |
|
.attr("transform", "translate(0,-10)"); |
|
|
|
}); |
|
|
|
function dateFromDay(year, day){ |
|
var date = new Date(year, 0); |
|
var options = { month: 'long', day: 'numeric' }; |
|
return new Date(date.setDate(day)).toLocaleDateString('nl-NL', options); |
|
} |
|
</script> |