xxxxxxxxxx
<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>
https://d3js.org/d3.v3.min.js