<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=9">
<title>Popular Names</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: sans-serif;
font-size: 16px;
}
#tooltip {
color: black;
opacity: .9;
background: #333;
padding: 5px;
border: 1px solid lightgrey;
border-radius: 5px;
position: absolute;
z-index: 10;
visibility: hidden;
white-space: nowrap;
pointer-events: none;
}
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;
}
.container
{
width:960px;
height:100px;
}
.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/births/popular-names/index.html">National Records of Scotland (NRS) data on popular names (NRS website)</a>
<br>
(ties resolved alphabetically)</span>
</div>
<br>
<div id="svgHolder"></div>
<div class="container" 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>
//Design params you may wish to change
//Color setup; choose options for g/b colorsets from below
//D3 built-in 20 colour palette
//var color = d3.scale.category20b();
//20 shades of pink (presumably colourblind safe; can substitute any alternative palette here)
var gcolorset = ["#FCD4D5","#FCCED2","#FBC8CE","#FBC2CA","#FBBCC7","#FBB6C3","#FAB0BF","#FAAABC","#FAA4B8","#FA9FB5",
"#F593B1","#F087AD","#EB7BA9","#E66FA5","#E163A1","#DD579D","#D84B99","#D33F95","#CE3391","#C9278D"];
var bcolorset= ["#A6BDDB","#9DB6D4","#94AFCD","#8CA8C6","#83A1BF","#7A9AB8","#7293B1","#698CAA","#6085A3","#587E9C",
"#4F7796","#47708F","#3E6988","#356281","#2D5B7A","#245473","#1B4D6C","#134665","#0A3F5E","#023858"];
//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 targetWidth=960;
var targetHeight=700;
//Parse data (next line specifies file location) and launch viz
d3.json("boys_top20_noclash.json", function(json){
//File read
initData=json;
startYear= initData.startYear;
endYear= initData.endYear;
minRank=initData.minRank;
gender=initData.gender;
if(gender=="girls")
color = d3.scale.ordinal().domain(d3.range(0,30)).range(gcolorset);
else
color = d3.scale.ordinal().domain(d3.range(0,30)).range(bcolorset);
d3.select("#mapTitle").text("Top "+minRank+" "+gender+" names, "+startYear+" - "+endYear);
dataSet=initData.dataSet;
//Got the data, let's start the interactive components!
runViz();
}); //Done with file parse
function runViz(){
var activeYear = startYear;
var playing =0;
$(function() {
$( "#slider" ).slider({
value:startYear,
min: startYear,
max: endYear,
step: 1,
slide: function( event, ui ) {
activeYear=ui.value;
update();
} //closes slide function def
});//closes slider def
});
//chart Width and height
var w = targetWidth+50;
var h = targetHeight-50;
var padding = 50;
//Create scale functions
var xScale = d3.scale.linear().domain([startYear-1,endYear+1]).range([padding, w - padding * 2]);
var yScale = d3.scale.linear().domain([minRank+1,0]).range([h - padding, padding]);
var rScale = d3.scale.linear().domain([0, 1]).range([0, (h-padding)/(2*minRank)-3]);
//Define X axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(endYear-startYear)
.tickFormat(d3.format("d"));;
//Define Y axis
var yAxis = d3.svg.axis().scale(yScale).orient("left");
var yticks=[];
ytick=minRank;
while (ytick >0) {
yticks.push(ytick);
ytick-=5;
}
yticks.push(1);
yAxis.tickValues(yticks);
//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);
//Create Y axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
//Render data
svg.selectAll("circle")
.data(dataSet)
.enter()
.append("circle")
.on("mouseover",mouseOver)
.on("mouseout", function (d) { d3.select("#tooltip").style("visibility", "hidden") })
.attr("fill",function(d,i){ return color(i);})
.attr("cx", function(d) {return xScale(activeYear);})
.attr("cy", function(d) {
return yScale(Math.min(minRank,d[1][activeYear-startYear]));
})
.attr("r",function(d) {
if(d[1][activeYear-startYear]>minRank) return rScale(0);
return rScale(1);
})
svg.selectAll(".labelText")
.data(dataSet)
.enter()
.append("text")
.attr("class","labelText")
.attr("font-family","sans-serif")
.attr("x",xScale(activeYear)+1.5*rScale(1))
.attr("y", function(d) {return yScale(Math.min(minRank,d[1][activeYear-startYear]))+rScale(1)/2;})
.attr("fill",function(d,i){ return color(i);})
.attr("font-size",function(d) {
if(d[1][activeYear-startYear]>minRank) return 0;
return 2+rScale(1);}
)
.text(function(d){return d[0]});
//Add playback controls and year indicator
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",20)
.attr("y",30)
.attr("font-family","sans-serif")
.attr("fill","#3c0050")
.attr("font-size",22)
.text(activeYear);
//Animation controls
setInterval(function(){takeStep()},3000);
function takeStep()
{
if(playing==1&&activeYear<endYear)
{
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"});
}
function update(){
svg.selectAll("circle").transition()
.duration(2500)
.attr("cx", function(d) {
return xScale(activeYear);
})
.attr("cy", function(d) {
return yScale(Math.min(minRank,d[1][activeYear-startYear]));
})
.attr("r",function(d) {
if(d[1][activeYear-startYear]>minRank) return rScale(0);
return rScale(1);
});
yearSVG.select("#yearLabel").transition()
.duration(2500)
.text(activeYear);
svg.selectAll(".labelText").transition()
.duration(2500)
.attr("x",xScale(activeYear)+1.5*rScale(1))
.attr("y", function(d) {return yScale(Math.min(minRank,d[1][activeYear-startYear]))+rScale(1)/2;})
.attr("font-size",function(d) {
if(d[1][activeYear-startYear]>minRank) return 0;
return 2+rScale(1);}
);
} //Closes update code
//tooltip
function mouseOver(d,i) {
d3.select("#tooltip")
.style("visibility", "visible")
.style("background",function(){return color(i)})
.html(function() {return d[1][activeYear-startYear]+": "+d[0];})
.style("top", function () { return (d3.event.pageY - 40)+"px"})
.style("left", function () { return (d3.event.pageX - 65)+"px";});
}
} //end of runViz
</script>
<div id="tooltip"></div>
</body>
</html>