These code examples are my work for the course “Data Visualization and Infographics with D3,” taught by Alberto Cairo and Scott Murray, and offered through the Knight Center for Journalism in the Americas at UT Austin.
For this exercise, I'm using a dataset on food. It includes indicators on undernourishment, underweight children, food prices, food price volatility, diabetes rates and obesity rates.
The bar chart displays the country's overall Food Index score. This score is a combination of data along many dimensions. The colors represent the dimension that each country is doing best at and worst at.
I'm still working on learning how to set up the legend and buttons to be responsive.
This dataset combines data from three large organizations: Food and Agriculture Organization on the United Nations (FAO), International Labour Organization (ILO) and the World Health Organization (WHO).
I combined this data with a few basic indicators from the World Bank on the economic level of each country. As we work, I expect to add several more WB indicators on Aid levels, specifically for food, and political volatility levels.
The .raw data is just that. The standardized data controls for different scares in measuring the countries. The min/max rescaling method was used to generate re-scaled values of -=100 where 0 points is the minimum (best) and 100 points is the maximim (worst). So it's not really a ranking, but close to it conceptually.
For the purposes of this exercise, I only included countries with no missing data.
I'm interested in using this data to explore the patterns of hunger, issues of access, overconsumption, and misuse of resources.
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8">
<title>Global Food Index Bar Chart</title>
<script type="text/javascript" src="https://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
body {
background-color: white;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
}
.headline{
font-size: 15px;
color:#d95f0e;
}
.axis path,
.axis line {
fill:none;
stroke:gray;
stroke-width: 0.5px;
shape-rendering: crispEdges;;
}
.axis text {
font-family: Arial, sans-serif;
font-size: 8px;
}
.y.axis path {
display: none;
}
.legend { list-style: none; }
.legend li { float: left; margin-right: 0px; }
.legend span { border: 1px solid #ccc; float: left; width: 9px; height: 9px; margin: 2px; }
.legend .enoughtoeat { background-color: #7fbc41; }
.legend .foodquality { background-color: #f1b6da; }
.legend .healthyeating { background-color: #005824; }
.legend .notenough { background-color: #8c510a; }
.legend .foodafford { background-color: #253494; }
.legend .poorquality { background-color: #dfc27d; }
.legend .unhealthy { background-color: #80cdc1; }
ul{
position: absolute;
right: 190px;
top: 60px;
width: 800px;
}
form {
position: absolute;
right: 650px;
top: 40px;
}
</style>
</head>
<body>
<form>
<label><input type="radio" name="mode" value="best" checked> What's the country best at?</label>
<label><input type="radio" name="mode" value="worst"> What's the country worst at?</label>
</form>
<ul class="legend">
<li><span class="enoughtoeat"></span> Enough to Eat</li>
<li><span class="foodquality"></span> Quality Food</li>
<li><span class="healthyeating"></span> Healthy Eating</li>
<li><span class="notenough"></span> Not Enough Food</li>
<li><span class="foodafford"></span> Unaffordable Food</li>
<li><span class="poorquality"></span> Poor Quality Food</li>
<li><span class="unhealthy"></span> Unhealthy Eating</li>
</ul>
<script type="text/javascript">
d3.select("body")
.append("p")
.text("Global Food Index Scores by Country: Where is it best to eat?")
.attr("class", "headline")
;
var w = 700;
var h = 1750;
var padding = [ 5, 10, 20, 100]; //Top, right, bottom, left
var widthScale = d3.scale.linear()
.range([ 0, w - padding[1] - padding[3] ]);
var heightScale = d3.scale.ordinal()
.rangeRoundBands([ padding[0], h - padding[2] ], 0.15);
var xAxis = d3.svg.axis()
.scale(widthScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(heightScale)
.orient("left");
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
d3.csv("FoodDataFinal.csv", function(data) {
data.sort(function(a, b) {
return d3.descending(a.ScoreReversedHighGood, b.ScoreReversedHighGood);
});
widthScale.domain([ 0, d3.max(data, function(d) {
return +d.ScoreReversedHighGood;
}) ]);
heightScale.domain(data.map(function(d) { return d.Country; } ));
var rects = svg.selectAll("rect")
.data(data)
.enter()
.append("rect");
rects.attr("x", padding[3])
.attr("y", function(d) {
return heightScale(d.Country);
})
.attr("width", function(d) {
return widthScale(d.ScoreReversedHighGood);
})
.attr("height", heightScale.rangeBand())
.attr("fill", "#fec44f")
.attr("stroke", "#fe9929")
.append("title")
.text(function(d) {
return d.Country + "'s Food Index score is " + d.ScoreReversedHighGood + " and they are best at " + d.DriverBestF;
});
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + padding[3] + "," + (h - 55) + ")")
.call(xAxis)
;
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + 100 + ",0)")
.call(yAxis)
;
d3.selectAll("input").on("change", change);
var timeout = setTimeout(function() {
d3.select("input[value=\"best\"]").property("checked", true).each(change);
}, 8000);
function change() {
clearTimeout(timeout);
if (this.value === "best") transitionBest();
else transitionWorst();
}
function transitionBest() {
rects.transition()
.transition()
.duration(1000)
.delay(1000)
.attr("fill", function(d) {
if(d.DriverBestF == "Enough to Eat") {return "#7fbc41"}
if(d.DriverBestF == "Food Quality") {return "#f1b6da"}
else {return "#005824"}
;})
.attr("stroke", "#bababa")
}
function transitionWorst() {
rects.transition()
.transition()
.duration(1000)
.delay(1000)
.attr("fill", function(d) {
if(d.DriverWorstF == "Not Enough to Eat") {return "#8c510a"}
if(d.DriverWorstF == "Poor Food Quality") {return "#dfc27d"}
if(d.DriverWorstF == "Unhealthy Eating") {return "#80cdc1"}
else {return "#253494"}
;})
.attr("stroke", "#bababa")
}
});
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js