Skip to content

Instantly share code, notes, and snippets.

@zanarmstrong
Last active February 8, 2017 04:28
Show Gist options
  • Save zanarmstrong/da5321c6b195ff69c442abaf9550e332 to your computer and use it in GitHub Desktop.
Save zanarmstrong/da5321c6b195ff69c442abaf9550e332 to your computer and use it in GitHub Desktop.
Non-Contiguous Cartogram
license: gpl-3.0

Unlike choropleth maps, cartograms encode data using area rather than color, resulting in distorted geographic boundaries. In this example, states are shown as circles centered arond their geographic position. The size of the circle is based on teh 2015 GDP as reported on Wikipedia.

This is forked from mbostock's block: Non-Contiguous Cartogram. The original was inspired by Zachary Johnson. Non-continguous cartogram design invented by Judy Olsen. U.S. state and county boundaries from the U.S. Census Bureau, simplified using GDAL and MapShaper.

<!DOCTYPE html>
<meta charset="utf-8">
<title>Non-Contiguous Cartogram</title>
<style>
.land {
fill: #fff;
stroke: #ccc;
}
.state {
stroke: #666;
opacity: .5;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var path = d3.geo.path();
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 500);
// set up pie chart
var radius = 130;
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var sortSlices = function(a,b){
if(a.include == b.include) {
return b.GDP - a.GDP
}
return +b.include - +a.include
}
var updatePie = function(data){
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return +d.GDP; });
svg.selectAll(".arc").data([]).exit().remove()
var g = svg.selectAll(".arc")
.data(pie(data.sort(sortSlices)), function(d){return d.data.State})
console.log(pie(data.sort(sortSlices)))
g.enter().append("g")
.attr("transform", "translate(950,300)")
.attr("class", "arc")
.append("path")
.attr("class", 'stateArc');
d3.selectAll(".stateArc").attr("d", arc).style("fill", colorSelectedArc);
}
d3.csv('namesToId.csv', function(error, stateNamesIds){
var stateAbbrLookup = {}
var stateIdLookup = stateNamesIds.reduce(function(map, obj) {
map[obj.id] = obj.name
stateAbbrLookup[obj.id] = obj.abb
return map;
}, {});
d3.csv('stateGDP2015.csv', function(error, gdp){
var max = d3.max(gdp, function(d) { return +d.GDP;} );
var gdpByStateLookup = gdp.reduce(function(map, obj) {
if(obj.GDP > max){
max = obj.GDP
}
map[obj.State] = {'gdp': +obj.GDP, 'include': +obj.include};
return map;
}, {});
d3.json("https://gist.githubusercontent.com/mbostock/4090846/raw/d534aba169207548a8a3d670c9c2cc719ff05c47/us.json", function(error, us) {
if (error) throw error;
// outline of US
svg.append("path")
.datum(topojson.feature(us, us.objects.land))
.attr("class", "land")
.attr("d", path);
// function to use include boolean to decide color
colorSelected = function(d){
var data = gdpByStateLookup[stateIdLookup[d.id]];
if(data && data.include) {
return "#9fc2c6"
}
return "#ccc"
}
colorSelectedArc = function(d) {
return +d.data.include ? '#9fc2c6' : '#ddd'
}
var state = svg.selectAll(".state")
.data(topojson.feature(us, us.objects.states).features, function(d){return d.id})
.enter().append("g")
.attr("transform", function(d){
var center = path.centroid(d);
return "translate(" + center[0] + "," + center[1] + ")"
})
state.append("text")
.attr("transform", function(d){return "translate(-11,5)"})
.attr("fill", "lightgrey")
.text(
function(d){
return stateAbbrLookup[d.id]
}
)
state.append("circle")
.attr("class", "state")
.attr("r", function(d){
var data = gdpByStateLookup[stateIdLookup[d.id]];
return data ? Math.sqrt(data.gdp / max) * 50 : 0
})
.style("fill", colorSelected)
.on('click', function(d){
gdpByStateLookup[stateIdLookup[d.id]].include = !gdpByStateLookup[stateIdLookup[d.id]].include;
gdp.forEach(function(state){
if(state.State == stateIdLookup[d.id]){
state.include = !+state.include}
})
d3.selectAll(".state")
.style("fill", colorSelected);
updatePie(gdp)
})
updatePie(gdp)
});
});
})
</script>
id abb name
1 AL Alabama
2 AK Alaska
4 AZ Arizona
5 AR Arkansas
6 CA California
8 CO Colorado
9 CT Connecticut
10 DE Delaware
12 FL Florida
13 GA Georgia
15 HI Hawaii
16 ID Idaho
17 IL Illinois
18 IN Indiana
19 IA Iowa
20 KS Kansas
21 KY Kentucky
22 LA Louisiana
23 ME Maine
24 MD Maryland
25 MA Massachusetts
26 MI Michigan
27 MN Minnesota
28 MS Mississippi
29 MO Missouri
30 MT Montana
31 NE Nebraska
32 NV Nevada
33 NH New Hampshire
34 NJ New Jersey
35 NM New Mexico
36 NY New York
37 NC North Carolina
38 ND North Dakota
39 OH Ohio
40 OK Oklahoma
41 OR Oregon
42 PA Pennsylvania
44 RI Rhode
45 SC South Carolina
46 SD South Dakota
47 TN Tennessee
48 TX Texas
49 UT Utah
50 VT Vermont
51 VA Virginia
53 WA Washington
54 WV West Virginia
55 WI Wisconsin
56 WY Wyoming
State GDP include
California 2448467 0
Texas 1639375 0
New York 1455568 0
Florida 893189 0
Illinois 771896 0
Pennsylvania 684313 0
Ohio 599093 0
New Jersey 579379 0
North Carolina 509718 0
Georgia 501241 0
Virginia 480876 0
Massachusetts 478941 0
Michigan 468029 0
Washington 449404 0
Maryland 365209 0
Minnesota 334780 0
Indiana 331126 0
Colorado 318600 0
Tennessee 310276 0
Wisconsin 300699 0
Arizona 298204 0
Missouri 290713 0
Connecticut 262212 0
Louisiana 253517 0
Oregon 228120 0
Alabama 209382 0
South Carolina 199256 0
Kentucky 194578 0
Oklahoma 179835 0
Iowa 171532 0
Kansas 149090 0
Utah 148225 0
Nevada 141204 0
Arkansas 123424 0
District of Columbia 122936 0
Nebraska 112208 0
Mississippi 106880 0
New Mexico 90810 0
Hawaii 79595 0
New Hampshire 71632 0
West Virginia 71123 0
Delaware 66150 0
Idaho 65202 0
Rhode Island 56323 0
Maine 55137 0
Alaska 54256 0
North Dakota 53686 0
Montana 45799 0
South Dakota 45415 0
Wyoming 40170 0
Vermont 29750 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment