Last active
October 27, 2015 22:00
-
-
Save hmader/a78a061a0e4a85d69413 to your computer and use it in GitHub Desktop.
Week 9: Stacked Bars Transition
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Country | Year | Age | Any method | Any modern method | Female Sterilization | Male Sterilization | Pill | Injectable | IUD | Male condom | Vaginal barrier methods | Implant | Other modern methods | Any traditional method | Rhythm | Withdrawal | Other traditional methods | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Burkina Faso | 2014 | 15-49 | 17 | 17 | 0 | 0 | 2 | 7 | 0.1 | 0 | 0 | 7.8 | 0.1 | 0 | 0 | 0 | 0 | |
Cambodia | 2014 | 15-49 | 56.3 | 38.8 | 3 | 0.1 | 17.8 | 9.1 | 4.4 | 2.1 | 2.2 | 0.1 | 17.5 | 3 | 14.5 | 0.1 | ||
Cuba | 2014 | 15-49 | 73.7 | 72.2 | 24.5 | 0 | 7.3 | 0.6 | 23.8 | 15.5 | 0.2 | 0 | 0.3 | 1.5 | 1.5 | |||
Democratic Republic of the Congo | 2013-2014 | 15-49 | 20.4 | 7.5 | 0.7 | 0.1 | 0.7 | 1.2 | 0.2 | 3.4 | 0.4 | 0.7 | 0 | 12.9 | 7.5 | 4.5 | 0.9 | |
Dominican Republic | 2013 | 15-49 | 71.9 | 68.4 | 40.9 | 0.2 | 16.6 | 5.7 | 1.7 | 2.6 | 0.5 | 0.2 | 3.5 | 1.2 | 1.8 | 0.5 | ||
Egypt | 2014 | 15-49 | 58.5 | 56.9 | 1.2 | 0 | 16 | 8.5 | 30.1 | 0.5 | 0.1 | 0.5 | 0 | 1.6 | 0.3 | 0.3 | 1 | |
Ethiopia | 2014 | 15-49 | 35 | 33.8 | 0.3 | 0 | 1.6 | 23.8 | 0.7 | 0.2 | 0 | 7.2 | 0 | 1.2 | 1.2 | |||
Gambia | 2013 | 15-49 | 9 | 8.1 | 0.6 | 2.1 | 3.9 | 0.3 | 0.6 | 0.6 | 0.9 | 0.2 | 0.3 | 0.4 | ||||
Ghana | 2014 | 15-49 | 19.5 | 17.7 | 0 | 0 | 4.3 | 7.3 | 0.4 | 0.8 | 0 | 3.2 | 1.7 | 1.8 | 0 | 0 | 1.8 | |
Kenya | 2014 | 15-49 | 55.7 | 55.4 | 1.6 | 7.3 | 29.1 | 3.4 | 1.8 | 11.1 | 0.8 | 0.2 | 0.2 | |||||
Kyrgyzstan | 2014 | 15-49 | 42 | 38.5 | 1.3 | 0 | 4.1 | 0.2 | 22.4 | 10.4 | 0 | 0 | 0 | 3.4 | 0.7 | 1.1 | 1.6 | |
Lesotho | 2014 | 15-49 | 60.2 | 59.8 | 1.7 | 0.1 | 14.2 | 24 | 1.3 | 16.9 | 1.4 | 0.2 | 0.4 | 0.2 | 0.2 | |||
Liberia | 2013 | 15-49 | 20.2 | 19.1 | 0.3 | 5 | 11.2 | 0.4 | 2.1 | 0.2 | 1.1 | 1.1 | 0 | 0 | ||||
Malawi | 2013-2014 | 15-49 | 58.6 | 57.4 | 10.2 | 0.1 | 2.2 | 32.2 | 1 | 2 | 9.4 | 0.3 | 1.2 | 0.5 | 0.3 | 0.5 | ||
Montenegro | 2013 | 15-49 | 23.3 | 15.4 | 0.1 | 2.7 | 5.6 | 6.9 | 7.8 | 0.3 | 7.4 | 0.1 | ||||||
Namibia | 2013 | 15-49 | 56.1 | 55.2 | 6.4 | 0.3 | 7 | 26.8 | 1.2 | 12 | 0 | 0.2 | 1.3 | 0.9 | 0.2 | 0.3 | 0.5 | |
Nepal | 2014 | 15-49 | 49.6 | 47.1 | 18 | 4.7 | 4.7 | 13 | 1.7 | 3.7 | 0.1 | 1.3 | 2.5 | 0.2 | 2.2 | 0.1 | ||
Nigeria | 2013 | 15-49 | 15.1 | 9.4 | 0.3 | 0 | 1.8 | 3.2 | 1.1 | 2.1 | 0 | 0.4 | 0.3 | 5.8 | 2.3 | 2.5 | 1.1 | |
Panama | 2013 | 15-49 | 62.8 | 59.9 | 25 | 0.5 | 11.4 | 16.3 | 2.4 | 3.7 | 0.6 | 0.2 | 2.9 | 0.9 | 1.1 | 0.7 | ||
Peru | 2013 | 15-49 | 74 | 51.2 | 8.8 | 0.3 | 9.1 | 17.4 | 2.5 | 12.6 | 0.2 | 0.2 | 0 | 22.7 | 13.9 | 7.9 | 0.9 | |
Philippines | 2013 | 15-49 | 55.1 | 36.9 | 8.5 | 0.1 | 19.1 | 3.7 | 3.5 | 1.9 | 0.1 | 18.2 | 5.3 | 12.1 | 0.7 | |||
Serbia | 2014 | 15-49 | 58.4 | 18.4 | 0.4 | 0 | 3.3 | 0 | 2.2 | 12.4 | 0 | 0 | 0.1 | 40 | 4.9 | 35 | 0.1 | |
Sierra Leone | 2013 | 15-49 | 16.6 | 14.6 | 0.5 | 3.9 | 7.5 | 0.1 | 0.2 | 2.4 | 0 | 2 | 0.1 | 0.1 | 1.8 | |||
Togo | 2013-2014 | 15-49 | 19.9 | 17.3 | 0.3 | 2.2 | 7.1 | 0.8 | 2.1 | 4.7 | 0 | 2.6 | 2.2 | 0.3 | 0.1 | |||
Turkey | 2013 | 15-49 | 73.5 | 47.3 | 9.4 | 0 | 4.6 | 0.6 | 16.8 | 15.8 | 0.1 | 0 | 0 | 26 | 0.3 | 25.5 | 0.2 | |
Uganda | 2014 | 15-49 | 27.2 | 25.5 | 1.9 | 0 | 2.1 | 15 | 0.8 | 1.9 | 0 | 3.3 | 0.6 | 1.6 | 0 | 0 | 1.6 | |
Vanuatu | 2013 | 15-49 | 49 | 36.4 | 11 | 0.6 | 10.5 | 9.7 | 2.4 | 2.1 | 12.5 | 6.5 | 4.7 | 1.3 | ||||
Viet Nam | 2013-2014 | 15-49 | 75.7 | 56.9 | 2.8 | 0.1 | 11.9 | 1.7 | 28.2 | 11.8 | 0 | 0.2 | 0.2 | 18.8 | 13.4 | 5.4 | 0 | |
Yemen | 2013 | 15-49 | 33.5 | 25.2 | 2.3 | 0.1 | 11.6 | 4.2 | 5.9 | 0.5 | 0 | 0.6 | 0 | 8.3 | 1.6 | 2.6 | 4.1 | |
Zambia | 2013-2014 | 15-49 | 49 | 43.9 | 1.9 | 11.8 | 19.3 | 1.2 | 4 | 5.5 | 0.2 | 5.2 | 0.8 | 3.2 | 1.2 | |||
Zimbabwe | 2014 | 15-49 | 66.9 | 66.3 | 0.9 | 0 | 43.9 | 9 | 0.4 | 3.3 | 0.2 | 8.4 | 0.2 | 0.6 | 0.1 | 0.3 | 0.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var margin = { | |
top: 20, | |
right: 150, | |
bottom: 100, | |
left: 40 | |
}, | |
width = 1150 - margin.left - margin.right, | |
height = 600 - margin.top - margin.bottom; | |
var xScale = d3.scale.ordinal() | |
.rangeRoundBands([0, width], .5); | |
var yScale = d3.scale.linear() | |
.rangeRound([height, 0]); | |
//var color = d3.scale.category20c(); | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient("bottom") | |
.innerTickSize([0]); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient("left") | |
.tickFormat(d3.format(".2s")); // for the stacked totals version | |
var stack = d3.layout | |
.stack(); // default view is "zero" for the count display. | |
var svg = d3.select("#chart").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var myTooltip = d3.select("body") | |
.append("div") | |
.attr("class", "myTooltip"); | |
var percentClicked = false; | |
d3.csv("Contraceptive-Types-select-countries-2013-2014.csv", function (error, data) { | |
if (error) { | |
console.log(error); | |
} | |
data.sort(function (a, b) { | |
return b["Any method"] - a["Any method"]; | |
}); | |
// how would we sort by largest total bar? what would we have to calculate? | |
var methods = d3.keys(data[0]).filter(function (d) { | |
return (d !== "Country" && d !== "Year" && d !== "Age" && d !== "Any method" && d !== "Any modern method" && d !== "Any traditional method"); | |
}); | |
var color = d3.scale.ordinal() | |
.domain(methods) | |
.range(['#fd8d3c', '#e6550d', ' #c6dbef', '#9ecae1', '#6baed6', '#1797E5', '#3182bd', '#2956A8', '#19344F','#31a354', '#74c476', '#a1d99b', '#c7e9c0']); | |
console.log("methods", methods); | |
var stacked = stack(makeData(methods, data)); // needed for default view | |
xScale.domain(data.map(function (d) { | |
return d.Country; | |
})); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis) | |
.selectAll("text") | |
.attr("dy", ".5em") | |
.attr("transform", "rotate(-30)") | |
.style("text-anchor", "end"); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis) | |
.append("text") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 6) | |
.attr("dy", ".71em") | |
.style("text-anchor", "end") | |
.text("Contraceptive Prevalence"); | |
var country = svg.selectAll(".country") | |
.data(stacked) | |
.enter().append("g") | |
.attr("class", "country") | |
.style("fill", function (d, i) { | |
// console.log("method method", d[i].method); | |
return color(d[i].method); | |
}); | |
console.log("country", country); | |
var rectangles = country.selectAll("rect") | |
.data(function (d) { | |
// console.log("array for a rectangle", d); | |
return d; | |
}) // this just gets the array for bar segment. | |
.enter().append("rect") | |
.attr("width", xScale.rangeBand()); | |
// this just draws them in the default way, now they're appended. | |
transitionCount(); | |
drawLegend(); | |
d3.selectAll("input").on("change", handleFormClick); | |
// All the functions for stuff above! | |
function handleFormClick() { | |
if (this.value === "bypercent") { | |
percentClicked = true; | |
transitionPercent(); | |
} else { | |
percentClicked = false; | |
transitionCount(); | |
} | |
} | |
function makeData(methods, data) { | |
return methods.map(function (method) { | |
return data.map(function (d) { | |
return { | |
x: d["Country"], | |
y: +d[method], | |
method: method | |
}; | |
}) | |
}); | |
} | |
function transitionPercent() { | |
yAxis.tickFormat(d3.format("%")); | |
stack.offset("expand"); // use this to get it to be relative/normalized! | |
var stacked = stack(makeData(methods, data)); | |
// call function to do the bars, which is same across both formats. | |
transitionRects(stacked); | |
} | |
function transitionCount() { | |
yAxis.tickFormat(d3.format(".2s")); // for the stacked totals version | |
stack.offset("zero"); | |
var stacked = stack(makeData(methods, data)); | |
transitionRects(stacked); | |
console.log("stacked", stacked); | |
} | |
function transitionRects(stacked) { | |
// this domain is using the last of the stacked arrays, which is the last illness, and getting the max height. | |
yScale.domain([0, d3.max(stacked[stacked.length - 1], function (d) { | |
return d.y0 + d.y; | |
})]); | |
// attach new fixed data | |
var country = svg.selectAll(".country") | |
.data(stacked); | |
// same on the rects | |
country.selectAll("rect") | |
.data(function (d) { | |
console.log("array for a rectangle"); | |
return d; | |
}) // this just gets the array for bar segment. | |
svg.selectAll("g.country rect") | |
.transition() | |
.duration(250) | |
.attr("x", function (d) { | |
return xScale(d.x); | |
}) | |
.attr("y", function (d) { | |
return yScale(d.y0 + d.y); | |
}) // | |
.attr("height", function (d) { | |
return yScale(d.y0) - yScale(d.y0 + d.y); | |
}); // height is base - tallness | |
svg.selectAll(".y.axis").transition().call(yAxis); | |
} | |
/*====================================================================== | |
Legend | |
======================================================================*/ | |
// Building a legend by hand, based on http://bl.ocks.org/mbostock/3886208 | |
function drawLegend() { | |
var legend = svg.selectAll(".legend") | |
.data(color.domain().slice()) // what do you think this does? | |
.enter().append("g") | |
.attr("class", "legend") | |
.attr("transform", function (d, i) { | |
return "translate(0," + i * 20 + ")"; | |
}); | |
legend.append("rect") | |
.attr("x", width) | |
.attr("width", 18) | |
.attr("height", 18) | |
.style("fill", color); | |
legend.append("text") | |
.attr("x", width + 24) | |
.attr("y", 9) | |
.attr("dy", ".35em") | |
.style("text-anchor", "start") | |
.text(function (d, i) { | |
return methods[i]; | |
}); | |
} | |
/*====================================================================== | |
Mouse Events | |
======================================================================*/ | |
rectangles | |
.on("mouseover", mouseoverFunc) | |
.on("mousemove", mousemoveFunc) | |
.on("mouseout", mouseoutFunc); | |
function mouseoverFunc(d) { | |
console.log("moused over", d.x); | |
if(percentClicked) { | |
myTooltip | |
.style("display", null) | |
.html("<p><span class='tooltipHeader'>" + d.x + "</span><br>"+ d.method + ": " + d3.format("%")(d.y) + "</p>"); | |
} else { | |
console.log("method", d.method, "percent", d.y); | |
myTooltip | |
.style("display", null) | |
.html("<p><span class='tooltipHeader'>" + d.x + "</span><br>"+ d.method + ": " +d.y + "%</p>"); | |
} | |
} | |
function mousemoveFunc(d) { | |
myTooltip | |
.style("top", (d3.event.pageY - 5) + "px") | |
.style("left", (d3.event.pageX + 10) + "px"); | |
} | |
function mouseoutFunc(d) { | |
return myTooltip.style("display", "none"); // this sets it to invisible! | |
} | |
/*====================================================================== | |
======================================================================*/ | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<!-- Modification of an example by Scott Murray from Knight D3 course --> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Stacked Bar</title> | |
<link href='https://fonts.googleapis.com/css?family=Roboto:400,400italic,700,700italic|Lora:400,400italic,700,700italic' rel='stylesheet' type='text/css'> | |
<link rel="stylesheet" type="text/css" href="main.css"> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> | |
<body> | |
<h1 class="header">Types of Contraception Used in Select Countries</h1> | |
<h2 class="header"></h2> | |
<p id="sources" class="header">Source: <a href="http://www.un.org/en/development/desa/population/publications/dataset/contraception/wcu2015.shtml">United Nations, Department of Economic and Social Affairs</a>. Only countries with complete data from the years 2013-2014 are represented.</p> | |
<div class="header" id="form"> | |
<label><input type="radio" name="mode" value="bycount" checked>% Contraceptive Use by Country</label> | |
<label><input type="radio" name="mode" value="bypercent">Percent Breakdown of Overall Use</label> | |
</div> | |
<div id="chart"></div> | |
<script type="text/javascript" src="contraceptives.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
box-sizing: border-box; | |
} | |
svg { | |
/* padding: 1em;*/ | |
background-color: rgb(255, 255, 255); | |
} | |
svg rect:hover { | |
opacity: .3; | |
} | |
svg circle:hover { | |
opacity: .3; | |
} | |
svg g { | |
fill: #ACACAC; | |
} | |
svg g text.label, | |
svg g text.ylabel { | |
fill: #2A2A2A; | |
} | |
svg { | |
background-color: white; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #D3D3D3; | |
stroke-width: 1px; | |
} | |
.line { | |
stroke: #FF9900; | |
fill: none; | |
stroke-opacity: 25%; | |
stroke-width: 1px; | |
} | |
.unfocused { | |
stroke-opacity: 25%; | |
} | |
.focused { | |
stroke-width: 2px; | |
stroke-opacity: 100%; | |
} | |
.MDG { | |
stroke: #2A2A2A; | |
fill: none; | |
stroke-opacity: 100%; | |
stroke-width: 1px; | |
} | |
.axis text, .legend text, | |
.aside { | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
.header { | |
width: 70%; | |
margin-left: 16px; | |
} | |
h1 { | |
font-family: 'Roboto', sans-serif; | |
font-size: 1.75em; | |
margin-top: 1em; | |
font-weight: 700; | |
color: #0099FF; | |
text-transform: uppercase; | |
} | |
h2 { | |
font-family: 'Roboto', sans-serif; | |
text-align: justify; | |
line-height: 1.25em; | |
font-weight: 700; | |
font-size: 1em; | |
} | |
p { | |
font-family: 'Lora', serif; | |
font-size: 15px; | |
line-height: 1.25em; | |
text-align: justify; | |
} | |
#sources { | |
font-size: 12px; | |
font-style: italic; | |
color: rgb(0, 0, 0); | |
font-style: italic; | |
} | |
a { | |
color: #0099FF; | |
text-decoration: none; | |
} | |
a:hover { | |
color: rgb(255, 0, 153); | |
} | |
.sans { | |
font-family: sans-serif; | |
} | |
.orange { | |
color: #FF9900; | |
} | |
.blue { | |
color: #0099FF; | |
} | |
.red { | |
color: red; | |
} | |
.myTooltip { | |
position: absolute; | |
z-index: 10; | |
} | |
.myTooltip p { | |
font-family: 'Roboto', sans-serif; | |
background-color: rgba(255, 255, 255, 1); | |
padding: .5em 1em; | |
font-size: 12px; | |
line-height: 17px; | |
color: black; | |
} | |
.tooltipHeader { | |
font-weight: 700; | |
font-size: 12.5px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment