<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=9">
<title>Scottish Fertility</title>
<link rel="stylesheet" href="../jquery-ui.css">
<script src="../jquery-1.10.2.js"></script>
<script src="../jquery-ui.js"></script>
<script src="../d3.v3.min.js"></script>
<style>#slider {
margin-top: 10px;
}
.ui-slider-horizontal {
height: 20px;
width: 760px;
}
.ui-slider .ui-slider-handle {
height: 25px;
width: 10px;
padding-left: 5px;
}
axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: arial,sans-serif;
font-size: 16px;
}
#tooltip {
color: black;
opacity: .9;
background: white;
padding: 5px;
border: 1px solid lightgrey;
border-radius: 5px;
position: absolute;
z-index: 10;
visibility: hidden;
white-space: nowrap;
pointer-events: none;
font-family:arial,sans-serif;
}
body{
font: 100% "Arial", sans-serif;
margin: 20px;
color:#3c0050;
}
#imgLinks
{
position:absolute;
left:10px;
top:5px;
}
#mapTitle
{
position:absolute;
left:260px;
top:-5px;
height:25px;
width:700px;
}
#sourceData
{
position:absolute;
left:260px;
top:45px;
height:20px;
width:700px;
}
.column-center
{
display: inline-block;
width:760px;
height:100px;
}
.column-left
{
float: left;
width:100px;
height:100px;
}
.column-right
{
float:right;
width: 95px;
height:100px;
}
</style>
</head>
<body>
<div id="imgLinks">
<a href="http://www.nrscotland.gov.uk/" target="_blank"><img src="../NRS_smalllogo.png" border = "0" alt="NRS Home Page"/></a></div>
<h3 id="mapTitle"></h3>
<div id="sourceData">
<span id="sourceText">Source: <a href="http://www.gro-scotland.gov.uk/statistics/theme/vital-events/general/ref-tables/2012/section-3-births.html">National Records of Scotland (NRS) data on births (NRS website)</a>,
<br>Table 3.6 (<a href="http://www.gro-scotland.gov.uk/files2/stats/ve-ref-tables-2012/rev-table-3-6.xls" target="_blank">Excel</a> <a href="http://www.gro-scotland.gov.uk/files2/stats/ve-ref-tables-2012/rev-table-3-6.csv" target="_blank">CSV</a> <a href="http://www.gro-scotland.gov.uk/files2/stats/ve-ref-tables-2012/rev-table-3-6.pdf" target="_blank">PDF</a>)
<br>(Hover or tap on individual dots for exact rates.)</span>
</div>
<br><br>
<div id="svgHolder"></div>
<div class="container" style="width:960px;height:100px" id="controls">
<div class="column-center" id="controlC" ><div id="slider"></div></div>
<div class="column-left" id="controlL"></div>
<div class="column-right" id="controlR"></div>
</div>
<script type="text/javascript">
//Design params you may wish to change
//Color setup; choose an option from below
//D3 built-in 20 colour palette
//var color = d3.scale.category20b();
//30 distinct, equal chroma/luminance colours
/*
q = 30; offset = 0;chroma = 40;luminance = 70; delta = 360/q;
var colorset = []
for (var hue = 0; hue < q; hue++) {colorset.push(d3.hcl((hue*delta+offset)%360,chroma,luminance));}
*/
//Interpolation of colorbrewer 5-class RdYlBu (colourblind safe)
var colorset = ["#D7191C","#DB2923","#DF3A2B","#E34A33","#E75B3A","#EC6B42","#F07C4A","#F48C51","#F89D59","#FDAE61",
"#FDBB70","#FDC980","#FED690","#FEE49F","#FEF1AF","#FFFFBF","#EEF7C7","#DDEFCF","#CCE8D8","#BBE0E0",
"#ABD9E9","#9CCEE3","#8EC4DD","#80B9D8","#72AFD2","#64A4CC","#569AC7","#488FC1","#3A85BB","#2C7BB6"];
//The following command should be used if you chose either of the previous 2 options
var color = d3.scale.ordinal().domain(d3.range(0,30)).range(colorset);
//Dimensions of the visualisation
//Unfortunately changes to these will probably also require adjustments to the css given in header
var w = 960;
var h = 500;
var padding = 50;
var dotRadius =13;
//Detect touch environments
var isMobile = false;
var agent = navigator.userAgent.toLowerCase();
if( agent.indexOf('iphone') >= 0 || agent.indexOf('ipad') >= 0){
isMobile = true;
}
if(agent.indexOf("android") > -1) isMobile=true;
//Parse data (next line specifies file location) and launch viz
d3.json("fertility.json", function(json){
//File read
initData=json;
startYear=initData.startYear;
endYear=initData.endYear;
d3.select("#mapTitle").text("Age-specific Birth rates, per 1,000 female population, Scotland, "+startYear+ " to "+endYear);
dataSet=initData.dataSet;
yearAverages=initData.yearAverages;
//Got the data, let's start the interactive components!
runViz();
}); //Done with file parse
function runViz(){
activeDot=0; //for persistent tooltip, tracks which dot has been selected, 0 for none.
activeYear=startYear; //Specifies which year should display on startup
var playing =0;
var activeIndex=0;
$(function() {
$( "#slider" ).slider({
value:activeYear,
min: startYear,
max: endYear,
step: 1,
slide: function( event, ui ) {
activeYear=ui.value;
activeIndex=activeYear-startYear;
update();
} //closes slide function def
});//closes slider def
$( "#amount" ).val( $( "#slider" ).slider( "value" ) );
});
var cohorts = d3.range(startYear-44,endYear-15);
//Create scale functions
var xScale = d3.scale.linear().domain([15,45]).range([padding, w - padding * 2]);
var yScale = d3.scale.linear().domain([0, 175]).range([h - padding, padding]);
var rScale = d3.scale.linear().domain([0, 1]).range([0, dotRadius]);
//Define X axis
var xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(5);
//Define Y axis
var yAxis = d3.svg.axis().scale(yScale).orient("left").ticks(5);
//Create SVG element
var svg = d3.select("#svgHolder").append("svg").attr("width", w).attr("height", h);
//Create X axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
svg.append("text").attr("id","yLabel").attr("font-family","Arial,sans-serif").attr("font-size",15).attr("stroke","gray")
.attr("x",xScale(27)).attr("y",yScale(0)+40)
.text("Age of mother at birth");
//Create Y axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
svg.append("text").attr("id","yLabel").attr("font-family","Arial,sans-serif").attr("font-size",15).attr("stroke","gray")
.attr("x",11).attr("y",yScale(45)).attr("transform",function(){return "rotate(270 "+11+","+yScale(45)+")"})
.text("Birth rate (per 1000 female population)");
//Create data circles
svg.selectAll("circle")
.data(cohorts)
.enter()
.append("circle")
.on("mouseover",function(d){
if(!isMobile) mouseOver(d);
})
.on("mouseout", function (d) {
if(!isMobile) d3.select("#tooltip").style("visibility", "hidden")
})
.on("click",function(d){
if(isMobile){
if(activeDot==d){d3.select("#tooltip").style("visibility", "hidden"); activeDot=0;}
else {activeDot=d; mouseOver(d);}
}
})
.attr("fill",function(d){ return color(d)})
.attr("cx", function(d) {
return xScale(Math.max(15.5,Math.min(44.5,0.5+activeYear-d)));
})
.attr("cy", function(d) {
if(activeYear-d>=15&&activeYear-d<=44) return yScale(dataSet[activeYear-d-15][activeIndex]);
if(activeYear-d<15) return yScale(dataSet[0][activeIndex]);
if(activeYear-d>44) return yScale(dataSet[29][activeIndex]);
})
.attr("r",function(d) {
if(activeYear-d>=15&&activeYear-d<=44) return rScale(1);
return rScale(0);
});
svg.append("line").attr("id","allAgeLine").attr("x1",xScale(yearAverages[activeIndex])).attr("x2",xScale(yearAverages[activeIndex]))
.attr("y1",yScale(0)).attr("y2",yScale(175))
.attr("stroke","gray").attr("stroke-dasharray","10,10");
svg.append("text").attr("id","aveText").attr("font-family","arial,sans-serif").attr("font-size",15).attr("stroke","gray")
.attr("x",xScale(yearAverages[activeIndex])-5).attr("y",yScale(30)).attr("transform",function(){return "rotate(270 "+(xScale(yearAverages[activeIndex])-5)+","+yScale(30)+")"})
.text("Average age of mother at childbirth");
svg.append("text").attr("id","aveVal").attr("font-family","arial,sans-serif").attr("font-size",15).attr("stroke","gray")
.attr("x",xScale(yearAverages[activeIndex])).attr("y",h-padding)
.text(yearAverages[activeIndex]);
var playSVG = d3.select("#controlL")
.append("svg")
.attr("width", 100)
.attr("height", 50);
var yearSVG = d3.select("#controlR")
.append("svg")
.attr("width", 100)
.attr("height", 50);
playSVG.append("image")
.attr("id","playControl")
.attr("height","37")
.attr("width","37")
.attr("x",30)
.attr("y",0)
.on("click",togglePlay)
.attr("xlink:href","../play.png");
yearSVG.append("text")
.attr("id","yearLabel")
.attr("x",10)
.attr("y",30)
.attr("font-family","sans-serif")
.attr("fill","#3c0050")
.attr("font-size",22)
.text(activeYear);
function update(){
yearSVG.select("#yearLabel").transition()
.duration(1000)
.text(activeYear);
svg.selectAll("circle").transition()
.duration(1000)
.attr("cx", function(d) {
return xScale(Math.max(15.5,Math.min(44.5,0.5+activeYear-d)));
})
.attr("cy", function(d) {
if(activeYear-d>=15&&activeYear-d<=44) return yScale(dataSet[activeYear-d-15][activeIndex]);
if(activeYear-d<15) return yScale(dataSet[0][activeIndex]);
if(activeYear-d>44) return yScale(dataSet[29][activeIndex]);
})
.attr("r",function(d) {
if(activeYear-d>=15&&activeYear-d<=44) return rScale(1);
return rScale(0);
});
svg.selectAll("#allAgeLine").transition().duration(1000).attr("x1",xScale(yearAverages[activeIndex])).attr("x2",xScale(yearAverages[activeIndex]));
svg.selectAll("#aveText")
.transition().duration(1000).attr("x",xScale(yearAverages[activeIndex])-5).attr("y",yScale(30))
.attr("transform",function(){return "rotate(270 "+(xScale(yearAverages[activeIndex])-5)+","+yScale(30)+")"});
svg.selectAll("#aveVal")
.transition().duration(1000).attr("x",xScale(yearAverages[activeIndex]))
.text(yearAverages[activeIndex]);
}; //end of update function
function mouseOver(d,i) {
d3.select("#tooltip")
.style("visibility", "visible")
.html(
function() {
return "Birth rate in "+activeYear+" for women aged "+(activeYear-d)+"<br>(born in "+d+") was "+dataSet[activeYear-d-15][activeIndex]+ " per thousand.";
}
)
.style("background",function(){ return color(d)})
.style("top", function () { return (d3.event.pageY - 40)+"px"})
.style("left", function () { return (d3.event.pageX - 65)+"px";})
}
setInterval(function(){takeStep()},1000); //Specifies how long between year changes (in ms)
function takeStep()
{
if(playing==1&&activeYear<endYear)
{
activeIndex+=1;
activeYear+=1;
$("#slider").slider('value',activeYear);
update();
}
}
function togglePlay()
{
playing=1-playing;
playSVG.select("#playControl").attr("xlink:href",function(){return (playing==1)?"../pause.png":"../play.png"});
}
}; //end runViz definition
</script>
<div id="tooltip"></div>
</body>
</html>