Skip to content

Instantly share code, notes, and snippets.

@hotzeplotz
Forked from anonymous/cities.csv
Last active August 29, 2015 14:06
Show Gist options
  • Select an option

  • Save hotzeplotz/30b2e03e484b2f8a829c to your computer and use it in GitHub Desktop.

Select an option

Save hotzeplotz/30b2e03e484b2f8a829c to your computer and use it in GitHub Desktop.
ID METRO CITY_POP METRO_POP_MIN METRO_POP_MAX CITY_AS_PERCENT_OF_METRO
1 Lagos 21.5 21.5 21.5 100
2 Istanbul 14.1 14.1 14.1 100
3 Hong Kong 7.2 7.2 7.2 100
4 Kinshasa 9.5 9.2 10.7 89
5 Lima 8.6 9.5 10.2 84
6 Beijing 19.6 19.9 23.7 83
7 Riyadh 5.2 5.7 6.3 83
8 Bogotá 7.6 7.8 9.3 82
9 Shanghai 23.0 23.8 29.6 78
10 Tianjin 10.4 10.5 14.1 74
11 Moscow 11.7 11.7 16.7 70
12 Berlin 3.4 3.5 5.8 59
13 Tehran 8.1 7.4 12.4 65
14 Mumbai 12.4 18.7 22.6 55
15 São Paulo 11.1 20.3 21.7 51
16 Rio De Janeiro 6.4 12.1 12.7 50
17 Johannesburg 4.4 8.1 8.8 50
18 Cairo 8.9 16.4 18.0 49
19 Delhi 16.6 17.6 25.3 66
20 Bangkok 6.4 8.7 14.9 43
21 Dhaka 7.0 15.9 16.7 42
22 Karachi 9.3 14.3 23.2 40
23 Mexico City 8.9 19.0 22.2 40
24 London 8.4 10.1 21.8 40
25 Guangzhou 14.0 18.3 32.6 43
26 Seoul 10.1 9.8 25.6 39
27 New York 8.4 18.5 21.8 39
28 Jakarta 10.1 27.0 30.0 34
29 Tokyo 13.2 36.7 39.4 34
30 Kolkata 4.5 14.2 15.8 28
31 Los Angeles 3.9 12.3 17.3 23
32 Paris 2.3 10.7 12.4 19
33 Buenos Aires 2.9 13.6 15.7 18
34 Osaka 2.7 17.8 19.7 14
35 Manila 1.7 11.9 22.5 8
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="//cdnjs.cloudflare.com/ajax/libs/foundation/5.3.3/css/foundation.min.css" rel="stylesheet" type="text/css">
<link href='//fonts.googleapis.com/css?family=Anton' rel='stylesheet' type='text/css'>
<link href='//fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
.ui-sort {
margin-bottom: 3rem;
}
.city h1 {
font-family: 'Open Sans',"Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 1rem;
text-transform: uppercase;
text-align: center;
line-height: 1;
margin-bottom: 0;
}
.population-figures {
text-align: center;
font-size: 0.8rem;
}
.metro-pop-max {
fill: #939598;
}
.metro-pop-min {
fill: #c7c8ca;
}
.city-pop {
fill: #d2334b;
}
.percent-label {
stroke: #d2334b;
font-size: 0.75rem;
}
svg.pop {
margin-top: 1rem;
display: block;
margin-left: auto;
margin-right: auto;
}
div.tooltip {
position: absolute;
display: block;
text-align: center;
width: 60px;
height: 16px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 1px;
pointer-events: none;
}
</style>
</head>
<body>
<div class="row">
<div class="large-12 columns" role="content">
<article>
<div class="ui-sort">
Sort by:
<ul>
<li>City population: <a class="sortby" data-sortby="city-pop" data-sort="asc">Smallest first</a> | <a class="sortby" data-sortby="city-pop" data-sort="desc">Largest first</a></li>
<li>Metropolitan region population (minimum estimate) <a class="sortby" data-sortby="metro-pop-min" data-sort="asc">Smallest first</a> | <a class="sortby" data-sortby="metro-pop-min" data-sort="desc">Largest first</a></li>
<li>Metropolitan region population (maximum estimate): <a class="sortby" data-sortby="metro-pop-max" data-sort="asc">Smallest first</a> | <a class="sortby" data-sortby="metro-pop-max" data-sort="desc">Largest first</a></li>
<li>Ratio of city population to metropolitan region population: <a class="sortby" data-sortby="percent" data-sort="asc">Smallest first</a> | <a class="sortby" data-sortby="percent" data-sort="desc">Largest first</a></li>
</ul>
</div>
<div>
<ul class="cities small-block-grid-2 medium-block-grid-4 large-block-grid-6"></ul>
</div>
</article>
</div>
</div>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script>
$(function() {
$('.sortby').on('click', function() {
var $wrapper = $('ul.cities'),
sortby = this.getAttribute('data-sortby'),
sort = this.getAttribute('data-sort');
$wrapper.find('.city').sort(function (a, b) {
var order = +a.getAttribute('data-' + sortby) - +b.getAttribute('data-' + sortby);
return (sort == 'asc') ? order : -order;
})
.appendTo( $wrapper );
});
});
var width = height = 150,
chart_width = width - 40, // make space for percent figure
chart_selector = '.cities';
function dotSides(d, max_pop, range_width) {
var
size = d3.scale.linear()
.domain([0,max_pop])
.range([0,range_width]),
metro_pop_min,
metro_pop_max,
city_pop;
metro_pop_max = size(d.METRO_POP_MAX);
metro_pop_min = size(d.METRO_POP_MIN);
city_pop = size(d.CITY_POP);
return { metro_pop_max: metro_pop_max, metro_pop_min: metro_pop_min, city_pop: city_pop };
}
d3.csv('cities.csv', function(data) {
var
cities_list = d3.select(chart_selector),
cities,
max_pop = d3.max(data, function(d) { return +d.METRO_POP_MAX; });
div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
cities = cities_list.selectAll("li")
.data(data)
.enter()
.append('li')
.attr('id', function(d) { return 'city' + d.ID; })
.attr('data-city-pop', function(d) { return d.CITY_POP; })
.attr('data-metro-pop-min', function(d) { return d.METRO_POP_MIN; })
.attr('data-metro-pop-max', function(d) { return d.METRO_POP_MAX; })
.attr('data-percent', function(d) { return d.CITY_AS_PERCENT_OF_METRO; })
.attr('class', 'city');
cities
.append('h1')
.text(function(d) { return d.METRO;});
cities
.append('div')
.attr('class', 'population-figures')
.html(function(d) {
if(! (d.CITY_POP === d.METRO_POP_MAX)) {
return d.CITY_POP + 'm&mdash;' + d.METRO_POP_MAX + 'm';
} else {
return d.CITY_POP + 'm';
}
})
cities
.append('svg')
.attr('class', 'pop')
.attr('width', width)
.attr('height', height)
.each(function(d,i) {
var sizes = dotSides(d, max_pop, chart_width),
metro_pop_min = sizes.metro_pop_min,
metro_pop_max = sizes.metro_pop_max,
city_pop = sizes.city_pop,
side_diff = Math.abs(metro_pop_max - city_pop) / 2,
city_container = d3.select(this);
city = d3.select(this)
.append('g')
.attr('class', 'city-pops')
.attr('transform', 'translate(' + (((chart_width - metro_pop_max) / 2) + (width - chart_width)) + ')');
city.append('text')
.attr('class', 'percent-label')
.attr('transform', 'translate(-2,10)') // move percent label to left of top-left corner
.attr('text-anchor', 'end')
.text(d.CITY_AS_PERCENT_OF_METRO + '%');
city.append('rect')
.attr('class', 'metro-pop-max')
.attr('height', metro_pop_max)
.attr('width', metro_pop_max)
.on('mouseover', function(d) {
div.transition()
.style('opacity', 0.9);
div.html(d3.round(d.METRO_POP_MAX, 2) + "m")
.style('left', (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 16) + "px");
})
.on('mouseout', function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
city.append('rect')
.attr('class', 'metro-pop-min')
.attr('height', metro_pop_min)
.attr('width', metro_pop_min)
.on('mouseover', function(d) {
div.transition()
.style('opacity', 0.9);
div.html(d3.round(d.METRO_POP_MIN, 2) + "m")
.style('left', (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 16) + "px");
})
.on('mouseout', function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
city.append('rect')
.attr('class', 'city-pop')
.attr('height', city_pop)
.attr('width', city_pop)
.on('mouseover', function(d) {
div.transition()
.style('opacity', 0.9);
div.html(d3.round(d.CITY_POP, 2) + "m")
.style('left', (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 16) + "px");
})
.on('mouseout', function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
})
});
});
</script>
</body>
</html>
Metro vs City population
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment