Skip to content

Instantly share code, notes, and snippets.

@alansmithy
Last active November 1, 2015 19:14
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 alansmithy/2b8023afe570bbf3bab2 to your computer and use it in GitHub Desktop.
Save alansmithy/2b8023afe570bbf3bab2 to your computer and use it in GitHub Desktop.
The Costner Effect
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<title>The Costner Effect</title>
<style>
body{font-family:sans-serif;background-color:#dedede}
#container {
width: 800px;
margin-left: auto;
margin-right: auto;
margin-top: 30px;
background-color: white;
box-shadow: 2px 2px 4px 5px #ccc;
}
.yaxis path{fill:none;stroke:none;}
.yaxis line{
fill: none;
stroke: #333333;
stroke-width: 0.1%
}
.yaxis text{
font-size:12px;
}
.xaxis path,line{fill:none;stroke:none;}
.xaxis text{
font-size:10px;
}
g.bar {
cursor:pointer;
}
g.bar text {
fill:#fff;
font-size:10px;
text-anchor:middle;
opacity:0;
}
g.bar:hover rect {
fill: skyblue;
}
g.bar:hover text {
opacity: 1;
}
g.lines {
pointer-events:none;
fill:none;
stroke-width:6px;
stroke:white;
stroke-linecap:round;
stroke-linejoin:round;
}
.titles {
font-weight:bold;
fill-opacity:0.2;
}
</style>
</head>
<body>
<div id="container">
</div>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var w = 700;
var h = 300;
var margin={'left':50,
'right':20,
'top':70,
'bottom':50};
var parseDate = d3.time.format("%Y").parse;
d3.csv("kevin.csv", function(error, data) {
//parse the data
data.forEach(function(d) {
d.babies=+d.babies;
d.gross=+d.gross;
});
var dates = data.map(function(d){return d.date});
//extent,scales,axes
//var xDomain = d3.extent(data, function(d) {return d.date;});
var max = d3.max([d3.max(data, function(d) {return d.babies;}),d3.max(data, function(d) {return d.gross;})]);
var yDomain = [0,max]
var xScale = d3.scale.ordinal()
.domain(dates)
.rangeRoundBands([0,w],0.05)
var yScale = d3.scale.linear()
.domain(yDomain)
.range([h,0])
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(4)
//document structure
var svg = d3.select("#container").append("svg")
.attr("width",function(){
return margin.left+w+margin.right;
})
.attr("height",function(){
return margin.top+h+margin.bottom;
})
//call y axis
svg.append("g").attr("class","yaxis").attr("transform",function(){
return "translate("+margin.left+","+margin.top+")";
}).call(yAxis);
svg.append("g").attr("class","xaxis").attr("transform",function(){
return "translate("+margin.left+","+(margin.top+h)+")";
}).call(xAxis);
//create groups with bars for baby births
var groups = svg.append("g").attr("transform",function(){
return "translate(+"+margin.left+",0)"
}).selectAll("g").data(data).enter().append("g")
.attr("class","bar").attr("transform",function(d,i){
return "translate("+xScale(d.date)+",0)"
});
var rects = groups.append("rect")
.attr("height",function(d){
return 0;
//return h-yScale(d.babies)
})
.attr("width",xScale.rangeBand)
.attr("y",function(d){
return h+margin.top
//return (h+margin.top)-(h-yScale(d.babies))
})
.attr("fill","steelblue");
groups.append("text")
.attr("x",function(d){
return xScale.rangeBand()/2
})
.attr("y",function(d){
return (h+margin.top)-15;
})
.text(function(d){
return d.babies;
})
.append("tspan")
.attr("x",function(d){
return xScale.rangeBand()/2
})
.attr("dy",12)
.text("Kevs")
//line generator
var lineGen = d3.svg.line()
.x(function(d) {
return xScale.rangeBand()/2+(xScale(d.date));
})
.y(function(d) {
return yScale(d.gross);
})
//annotations
svg.append("text")
.attr("id","babyText")
.attr("fill-opacity",0)
.attr("x",260)
.attr("y",215)
.attr("fill","steelblue")
.text("babies called Kevin")
.append("tspan")
.attr("x",260)
.attr("dy",20)
.text("born in Zurich");
//annotations
svg.append("text")
.attr("id","grossText")
.attr("fill-opacity",0)
.attr("text-anchor","end")
.attr("x",margin.left+w)
.attr("y",285)
.attr("fill","orange")
.text("Costner's box office Gross")
.append("tspan")
.attr("x",margin.left+w)
.attr("dy",20)
.text("($m)");
//prepare data for line
var lineData=[];
lineData[0] = data.map(function(d){return{ "date":d.date,"gross":d.gross}});
//create group and append line
var lineGroup = svg.append("g").attr("class","lines").attr("transform",function(){
return "translate("+margin.left+","+margin.top+")";
})
var line1 = lineGroup.selectAll("path").data(lineData).enter().append("path").attr('d', function(d){ return lineGen(d); });
lineGroup.append("path").attr("d",function(){
return line1.attr("d");
}).attr("stroke","orange").attr("stroke-width","4px")
//hide line till animation
var lineLen = line1.node().getTotalLength()*2;
lineGroup.attr("stroke-dasharray",lineLen + ", "+lineLen).attr("stroke-dashoffset",lineLen);
var titles = svg.append("g").attr("class","titles");
titles.append("text")
.attr("x",margin.left)
.attr("y",30)
.attr("font-size",24)
.attr("font-weight","normal")
.text("The")
titles.append("text")
.attr("x",margin.left+10)
.attr("y",60)
.attr("font-size",48)
.text("Costner");
titles.append("text")
.attr("x",margin.left)
.attr("y",85)
.attr("font-size",36)
.attr("font-weight","normal")
.text("Effect");
//source
svg.append("text")
.attr("x",margin.left)
.attr("y",margin.top+h+margin.bottom-5)
.attr("font-size",12)
.attr("fill","#aaa")
.text("Source: canton of Zurich, TheNumbers.com");
//mouseover text
var mousetext = svg.append("text")
.attr("x",margin.left+w-10)
.attr("y",margin.top+20)
.attr("text-anchor","end")
.attr("fill","#aaa")
.text("")
var mouseinfo =svg.append("text")
.attr("x",margin.left+w-10)
.attr("y",margin.top+50)
.attr("style","fill:orange;font-size:24px;font-weight:bold")
.attr("text-anchor","end")
.text("")
groups.on("mouseover",function(d){
mousetext.text("Kevin's highlights this year:");
mouseinfo.text(d.highlights)
})
groups.on("mouseout",function(d){
mousetext.text("")
mouseinfo.text("")
})
//transitions
rects.transition()
.duration(500)
.delay(function(d,i){
return i*100;
})
.attr("height",function(d){
return h-yScale(d.babies)
})
.attr("y",function(d){
return (h+margin.top)-(h-yScale(d.babies))
})
d3.select("#babyText").transition().duration(500).delay(2500).attr("fill-opacity",1)
lineGroup.transition()
.duration(4000)
.delay(3000)
.attr("stroke-dashoffset", 0);
d3.select("#grossText").transition().duration(500).delay(5500).attr("fill-opacity",1)
});//end data load
</script>
</body>
</html>
We can make this file beautiful and searchable if this error is corrected: It looks like row 13 should actually have 4 columns, instead of 3. in line 12.
date,babies,gross,highlights
1987,41,111.78,The Untouchables
1988,62,50.8887,Bull Durham
1989,92,64.4316,Field of Dreams
1990,110,199.854,Dances With Wolves
1991,168,235.899,JFK/Robin Hood
1992,115,122.007,The Bodyguard
1993,101,31.131,A Perfect World
1994,77,41.9806,Wyatt Earp
1995,61,88.2462,Waterworld
1996,67,53.8546,Tin Cup
1997,51,17.6262,The Postman
1998,49,0
1999,46,88.0687,Play it to the Bone
2000,54,34.5921,Thirteen Days
2001,37,15.75,3000 miles to Graceland
2002,39,30.3234,Dragonfly
2003,34,58.3313,Open Range
2004,36,0
2005,27,43.0003,The Upside of Anger/Rumour Has It
2006,24,55.029,The Guardian
2007,23,28.5493,Mr. Brooks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment