Skip to content

Instantly share code, notes, and snippets.

@tnightingale
Last active December 12, 2015 03:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tnightingale/4704168 to your computer and use it in GitHub Desktop.
Save tnightingale/4704168 to your computer and use it in GitHub Desktop.
Non-contiguous cartogram: Canada
province seats_min population_2006 national_quotient base_seats_rounded additional_seats allocated_seats next_election_allocated_seats electoral_quotient
Ontario 95 12160282 113308 106 0 106 121 114720
Quebec 75 7546131 113308 68 7 75 78 100615
British Columbia 28 4113487 113308 36 0 36 42 114264
Alberta 21 3290350 113308 28 0 28 34 117513
Manitoba 14 1148401 113308 10 4 14 14 82029
Saskatchewan 14 968157 113308 9 5 14 14 69154
Nova Scotia 11 913462 113308 8 3 11 11 83042
New Brunswick 10 729997 113308 7 3 10 10 73000
Newfoundland and Labrador 7 505469 113308 5 2 7 7 72209
Prince Edward Island 4 135851 113308 1 3 4 4 33963
Northwest Territories 1 41464 1 1 41464
Yukon 1 30372 1 1 30372
Nunavut 1 29474 1 1 29474
Geo_Code Prov_Name Topic Characteristic Note Total Flag_Total Male Flag_Male Female Flag_Female
13 New Brunswick Population and dwelling counts Population in 2011 1 751171 0 ... 0 ...
60 Yukon Population and dwelling counts Population in 2011 1 33897 0 ... 0 ...
11 Prince Edward Island Population and dwelling counts Population in 2011 1 140204 0 ... 0 ...
48 Alberta Population and dwelling counts Population in 2011 1 3645257 + 0 ... 0 ...
35 Ontario Population and dwelling counts Population in 2011 1 12851821 + 0 ... 0 ...
10 Newfoundland and Labrador Population and dwelling counts Population in 2011 1 514536 0 ... 0 ...
24 Quebec Population and dwelling counts Population in 2011 1 7903001 + 0 ... 0 ...
61 Northwest Territories Population and dwelling counts Population in 2011 1 41462 0 ... 0 ...
12 Nova Scotia Population and dwelling counts Population in 2011 1 921727 0 ... 0 ...
47 Saskatchewan Population and dwelling counts Population in 2011 1 1033381 + 0 ... 0 ...
46 Manitoba Population and dwelling counts Population in 2011 1 1208268 + 0 ... 0 ...
59 British Columbia Population and dwelling counts Population in 2011 1 4400057 + 0 ... 0 ...
62 Nunavut Population and dwelling counts Population in 2011 1 31906 0 ... 0 ...
<!DOCTYPE html>
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/queue.v1.js"></script>
<script src="http://d3js.org/topojson.v0.js"></script>
<script type="text/javascript" src="non-contiguous-cartogram-chart.js"></script>
<style type="text/css">
body {
font-family: Arial, sans-serif;
}
.container {
float: left;
width: 400px;
margin: 20px 40px;
}
p.caption { text-align: center }
.land {
fill: #fff;
stroke: lightgray;
stroke-width: 2;
}
.area {
fill: orange;
stroke: darkgray;
}
.area:hover {
fill: red;
}
</style>
</head>
<body data-provinces="prov_4326_simple.topo.json"
data-profile="census-profile.csv"
data-seats="canada_house_commons_electoral_seats.csv">
<div class="container" id="population"></div>
<div class="container" id="seats"></div>
<script type="text/javascript">
(function () {
var container = d3.select('body').node(),
data = container.dataset;
queue()
.defer(d3.json, data.provinces)
.defer(d3.csv, data.profile)
.defer(d3.csv, data.seats)
.await(ready);
function ready(err, canada, profile, seats) {
var census = d3.map(),
commons = d3.map(),
total_population = d3.sum(profile, get_population),
total_seats = d3.sum(seats, get_allocated_seats);
profile.forEach(function (d) {
census.set(d["Prov_Name"], { population: get_population(d) });
});
seats.forEach(function (d) {
commons.set(d["province"], { allocated_seats: get_allocated_seats(d) });
});
canada.objects.provinces.geometries.forEach(function (d) {
var census_item = census.get(d.properties.PRENAME),
commons_item = commons.get(d.properties.PRENAME);
d.properties.population_percentage = census_item.population / total_population;
d.properties.seats_percentage = commons_item.allocated_seats / total_seats;
return d;
});
var population = cartogram('provinces', 'population_percentage')
.width(400).height(300)
.zoom(d3.behavior.zoom().translate([-20,180]).scale(0.4));
d3.select("#population").datum(canada).call(population)
.append("p").attr("class", "caption")
.text("Percentage of population");
var seat_allocation = cartogram('provinces', 'seats_percentage')
.width(400).height(300)
.zoom(d3.behavior.zoom().translate([-20,180]).scale(0.4));
d3.select("#seats").datum(canada).call(seat_allocation)
.append("p").attr("class", "caption")
.text("Percentage of seats allocated in the House of Commons");
}
/**
* Property accessor functions.
*/
function get_population(d) {
return +d["Total"];
}
function get_allocated_seats(d) {
return +d["allocated_seats"];
}
}());
</script>
</body>
</html>
var cartogram = function (objects_key, scale_key) {
var margin = {top: 20, right: 20, bottom: 20, left: 20},
width = 960,
height = 500,
proj = d3.geo.albers(),
scale = d3.scale.linear(),
zoom = d3.behavior.zoom().translate([0,300]).scale(0.7);
function cartogram(selection) {
selection.each(function (d) {
var svg = d3.select(this).selectAll("svg").data([d]);
var gEnter = svg.enter().append("svg")
.attr("width", width)
.attr("height", height);
var path = d3.geo.path().projection(proj);
var g = svg.append("g")
.attr("transform", "translate(" + zoom.translate() + ")" +
"scale(" + [zoom.scale(), zoom.scale()] + ")");
var land = g.append("path")
.attr("class", "land")
.datum(topojson.object(d, d.objects[objects_key]))
.attr("d", path);
var areas = g.selectAll(".area")
.data(topojson.object(d, d.objects[objects_key]).geometries)
.enter().append("path")
.attr("class", "area")
.attr("d", path)
.attr("transform", function (d) {
var centroid = path.centroid(d),
x = centroid[0],
y = centroid[1];
return "translate(" + x + "," + y + ")"
+ "scale(" + Math.sqrt(d.properties[scale_key] * 5 || 0) + ")"
+ "translate(" + -x + "," + -y + ")";
})
.style("stroke-width", function(d) {
return 1 / Math.sqrt(d.properties[scale_key] * 5 || 1);
});;
});
}
cartogram.width = function (value) {
if (!arguments.length) return width;
width = value;
return cartogram;
};
cartogram.height = function (value) {
if (!arguments.length) return height;
height = value;
return cartogram;
};
cartogram.zoom = function (value) {
if (!arguments.length) return zoom;
zoom = value;
return cartogram;
};
return cartogram;
};
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment