|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<title>Afghanistan Troops</title> |
|
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> |
|
<style type="text/css"> |
|
body { |
|
font: 10px sans-serif; |
|
} |
|
|
|
.title{ |
|
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif; |
|
font-size: 18px; |
|
color: #073E71; |
|
} |
|
|
|
svg { |
|
width: 960px; |
|
height: 500px; |
|
border: solid 1px #ccc; |
|
font: 10px sans-serif; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
.Afghan rect:hover { |
|
fill: green; |
|
} |
|
|
|
rect:hover { |
|
fill: purple; |
|
} |
|
|
|
.Other Foreign rect:hover { |
|
fill: purple; |
|
} |
|
|
|
#tooltip { |
|
position: absolute; |
|
width: 200px; |
|
height: auto; |
|
padding: 10px; |
|
background-color: white; |
|
.transparent { |
|
zoom: 1; |
|
filter: alpha(opacity=50); |
|
opacity: 0.5; |
|
} |
|
-webkit-border-radius: 10px; |
|
-moz-border-radius: 10px; |
|
border-radius: 10px; |
|
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); |
|
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); |
|
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); |
|
pointer-events: none; |
|
} |
|
|
|
#tooltip.hidden { |
|
display: none; |
|
} |
|
|
|
#tooltip p { |
|
margin: 0; |
|
font-family: sans-serif; |
|
font-size: 16px; |
|
line-height: 20px; |
|
opacity:1; |
|
} |
|
|
|
.nonopaque { |
|
opacity: 1; |
|
} |
|
|
|
.semiopaque { |
|
opacity: 0.5; |
|
} |
|
|
|
|
|
</style> |
|
</head> |
|
<body> |
|
<div id="tooltip" class="hidden"> |
|
<p><strong><span id="tipdate">Month and year go here</span></strong></p> |
|
<p><span id="tipcat">Heading</span></p> |
|
<p><span id="tipval">100</span></p> |
|
</div> |
|
|
|
<div> |
|
<span class="title">Troops and Security forces in Afghanistan 2001-2012</span> |
|
</div> |
|
<script type="text/javascript"> |
|
|
|
var w = 960, |
|
h = 500, |
|
p = [20, 50, 30, 20], |
|
x = d3.scale.ordinal().rangeRoundBands([0, w - p[1] - p[3]]), |
|
y = d3.scale.linear().range([0, h - p[0] - p[2]]), |
|
z = d3.scale.ordinal().range(["darkblue", "blue", "lightblue"]), |
|
cats = d3.scale.ordinal().range(["Afghan","US", "OtherForeign"]), |
|
interpolated = d3.scale.ordinal().range(["nonopaque","semiopaque"]), |
|
parse = d3.time.format("%B-%y").parse, |
|
format = d3.time.format("%y") |
|
tipformat = d3.time.format("%B-%y"); |
|
|
|
var svg = d3.select("body").append("svg:svg") |
|
.attr("width", w) |
|
.attr("height", h) |
|
.append("svg:g") |
|
.attr("transform", "translate(" + p[3] + "," + (h - p[2]) + ")"); |
|
|
|
|
|
var gmouseover = function() { |
|
|
|
|
|
|
|
|
|
var troopCat = String(d3.select(this).attr("data-measure")); |
|
|
|
|
|
d3.select("#tooltip") |
|
.select("#tipcat") |
|
.text(function(d){ return troopCat}); |
|
|
|
|
|
//Show the tooltip |
|
// d3.select("#tooltip").classed("hidden", false); |
|
}; |
|
|
|
|
|
/*var gmouseout= function(d) { |
|
var rect=d3.select(this); |
|
Hide the tooltip |
|
d3.select("#tooltip").classed("hidden", true) |
|
};*/ |
|
|
|
|
|
|
|
var rectmouseover = function() { |
|
|
|
|
|
|
|
|
|
//Get this bar's x/y values, then augment for the tooltip |
|
var xPosition = parseFloat(d3.select(this).attr("x")) + 100; |
|
var yPosition = parseFloat(d3.select(this).attr("y")) + h; |
|
var theDate = (d3.select(this).attr("title")); |
|
var numTroops = d3.format(",.0f")(d3.select(this).attr("class")); |
|
// |
|
//Update the tooltip position and value |
|
|
|
|
|
d3.select("#tooltip") |
|
.select("#tipdate") |
|
.text(function(d){ return theDate}); |
|
|
|
|
|
|
|
/*d3.select("#tooltip") |
|
.select("#tipcat") |
|
.text(function(d){ return troopCat});*/ |
|
|
|
|
|
d3.select("#tooltip") |
|
.style("left", xPosition + "px") |
|
.style("top", yPosition + "px") |
|
.select("#tipval") |
|
.text(function(d){ return numTroops}); |
|
|
|
|
|
|
|
|
|
|
|
//Show the tooltip |
|
d3.select("#tooltip").classed("hidden", false); |
|
}; |
|
|
|
|
|
var rectmouseout= function(d) { |
|
var rect=d3.select(this); |
|
rect.transition().duration(100) |
|
.style("fill", function(d) { return color(d.name); }) |
|
.style("stroke", "none"); |
|
//Hide the tooltip |
|
d3.select("#tooltip").classed("hidden", true) |
|
}; |
|
|
|
var data= d3.csv("index.csv", function(afghan) { |
|
|
|
|
|
/* var troopNames= d3.keys(data[0]).filter(function(key) { return key !==mydate; }); |
|
console.log(troopNames);*/ |
|
// Transpose the data into layers by tnum. |
|
var trooptypes = d3.layout.stack()(["Afghan Security Forces","U.S. Troops", "Other Foreign Troops" ].map(function(tnum) { |
|
return afghan.map(function(d) { |
|
return {x: parse(d.mydate), y: +d[tnum]}; |
|
}); |
|
})) |
|
|
|
//.attr("class", function(troopNames, i){return d(i);}); |
|
// .values(function(d) { return d.tnum; }); |
|
console.log(trooptypes); |
|
|
|
var interp = d3.layout.stack()(["afghaninterpolated","usinterpolated", "otherinterpolated" ].map(function(tinterp) { |
|
return afghan.map(function(d) { |
|
return {inter: +d[tinterp]}; |
|
}); |
|
})) |
|
console.log(interp); |
|
var thedata = data; |
|
|
|
|
|
|
|
// Compute the x-domain (by date) and y-domain (by top). |
|
x.domain(trooptypes[0].map(function(d) { return d.x; })); |
|
y.domain([0, d3.max(trooptypes[trooptypes.length - 1], function(d) { return d.y0 + d.y; })]); |
|
|
|
// Add a group for each tnum. |
|
var tnum = svg.selectAll("g.tnum") |
|
.data(trooptypes) |
|
.enter().append("svg:g") |
|
//.attr("class", (function(thedata) { return d[0]; })) |
|
.style("fill", function(d, i) { return z(i); }) |
|
.attr("data-measure", function(d, i) { return cats(i); }) |
|
.on("mouseover", gmouseover); |
|
// .on("mouseout", gmouseout); |
|
|
|
// Add a rect for each date. |
|
var rect = tnum.selectAll("rect") |
|
.data(Object) |
|
.enter().append("svg:rect") |
|
.attr("x", function(d) { return x(d.x); }) |
|
.attr("y", function(d) { return -y(d.y0) - y(d.y); }) |
|
.attr("height", function(d) { return y(d.y); }) |
|
.attr("width", x.rangeBand()) |
|
.attr("title", function(d) { return d.x; }) |
|
.attr("data-measure", function(d) { return d.y; }) |
|
/*.style("fill", function(d, i) { if (d.int == 1) {return "red"} // if close is less than 400 fill = red |
|
else { return ;}})*/ |
|
// .text(function(d){return d.parentNode.attr("class")}) |
|
.on("mouseover", rectmouseover) |
|
.on("mouseout", rectmouseout); |
|
|
|
|
|
var interp = rect.selectAll("rect") |
|
.data(interp) |
|
.enter().append("svg:g") |
|
.style("fill", "white") |
|
.attr("class", function(d) {return interpolated(d.inter); }); |
|
|
|
// |
|
// Add a label per date. |
|
var label = svg.selectAll("text") |
|
.data(x.domain()) |
|
.enter().append("svg:text") |
|
.attr("x", function(d) { return x(d) + x.rangeBand() / 2; }) |
|
.attr("y", 6) |
|
.attr("text-anchor", "middle") |
|
.attr("dy", ".71em") |
|
.text(format); |
|
|
|
// Add y-axis rules. |
|
var rule = svg.selectAll("g.rule") |
|
.data(y.ticks(5)) |
|
.enter().append("svg:g") |
|
.attr("class", "rule") |
|
.attr("transform", function(d) { return "translate(0," + -y(d) + ")"; }); |
|
|
|
rule.append("svg:line") |
|
.attr("x2", w - p[1] - p[3]) |
|
.style("stroke", function(d) { return d ? "#fff" : "#000"; }) |
|
.style("stroke-opacity", function(d) { return d ? .7 : null; }); |
|
|
|
rule.append("svg:text") |
|
.attr("x", w - p[1] - p[3] + 6) |
|
.attr("dy", ".35em") |
|
.text(d3.format(",d")); |
|
}); |
|
|
|
</script> |
|
</body> |
|
</html> |