Based on Mike Bostock's Non-contiguous cartogram example.
Data obtained from the Government of Canada's Open Data Portal.
xxxxxxxxxx
<html>
<head>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/queue.v1.js"></script>
<script src="https://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>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/queue.v1.js to a secure url
Modified http://d3js.org/topojson.v0.js to a secure url
https://d3js.org/d3.v3.min.js
https://d3js.org/queue.v1.js
https://d3js.org/topojson.v0.js