Skip to content

Instantly share code, notes, and snippets.

@seemantk
Created November 16, 2015 04:42
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 seemantk/7ede42303b973902e202 to your computer and use it in GitHub Desktop.
Save seemantk/7ede42303b973902e202 to your computer and use it in GitHub Desktop.
Global Bilateral Migration

This interactive graph, using data from the World Bank's Global Migration Database shows links between migrants' locations and their countries of birth. The slider bar allows for different cut-off levels for the graph, and the year is selected by scrolling over it.

{"DZA": "Algeria",
"AGO": "Angola",
"EGY": "Egypt, Arab Rep.",
"BGD": "Bangladesh",
"NER": "Niger",
"LIE": "Liechtenstein",
"NAM": "Namibia",
"VEN": "Venezuela, RB",
"BGR": "Bulgaria",
"BOL": "Bolivia",
"GHA": "Ghana",
"PAK": "Pakistan",
"CPV": "Cape Verde",
"JOR": "Jordan",
"LBR": "Liberia",
"LBY": "Libya",
"MYS": "Malaysia",
"PRI": "Puerto Rico",
"MYT": "Mayotte",
"PRK": "Korea, Dem. Rep.",
"PSE": "West Bank and Gaza",
"TZA": "Tanzania",
"BWA": "Botswana",
"KHM": "Cambodia",
"TTO": "Trinidad and Tobago",
"PRY": "Paraguay",
"HKG": "Hong Kong SAR, China",
"SAU": "Saudi Arabia",
"LBN": "Lebanon",
"SVN": "Slovenia",
"BFA": "Burkina Faso",
"SVK": "Slovak Republic",
"MRT": "Mauritania",
"CHI": "Channel Islands",
"HRV": "Croatia",
"CHL": "Chile",
"CHN": "China",
"SMR": "San Marino",
"JAM": "Jamaica",
"GIB": "Gibraltar",
"DJI": "Djibouti",
"GIN": "Guinea",
"FIN": "Finland",
"URY": "Uruguay",
"THA": "Thailand",
"SYC": "Seychelles",
"NPL": "Nepal",
"LAO": "Lao PDR",
"YEM": "Yemen, Rep.",
"PHL": "Philippines",
"ZAF": "South Africa",
"KIR": "Kiribati",
"TGO": "Togo",
"VIR": "Virgin Islands (U.S.)",
"SYR": "Syrian Arab Republic",
"MAC": "Macao SAR, China",
"NIC": "Nicaragua",
"MLT": "Malta",
"KAZ": "Kazakhstan",
"TCA": "Turks and Caicos Islands",
"PYF": "French Polynesia",
"NIU": "Niue",
"DMA": "Dominica",
"KSV": "Kosovo",
"BEN": "Benin",
"GUF": "French Guiana",
"BEL": "Belgium",
"DEU": "Germany",
"GUM": "Guam",
"LKA": "Sri Lanka",
"FLK": "Falkland Islands (Malvinas)",
"GBR": "United Kingdom",
"GUY": "Guyana",
"CRI": "Costa Rica",
"COK": "Cook Islands",
"MAR": "Morocco",
"ROM": "Romania",
"MNP": "Northern Mariana Islands",
"LSO": "Lesotho",
"HUN": "Hungary",
"TKM": "Turkmenistan",
"SUR": "Suriname",
"NLD": "Netherlands",
"BMU": "Bermuda",
"TCD": "Chad",
"GEO": "Georgia",
"MNE": "Montenegro",
"MNG": "Mongolia",
"SDN": "Sudan",
"MHL": "Marshall Islands",
"MTQ": "Martinique",
"zzz": "Refugees",
"BLZ": "Belize",
"NFK": "Norfolk Island",
"MMR": "Myanmar",
"AFG": "Afghanistan",
"BDI": "Burundi",
"VGB": "Virgin Islands, British",
"BLR": "Belarus",
"GRD": "Grenada",
"TKL": "Tokelau",
"GRC": "Greece",
"GRL": "Greenland",
"SHN": "Saint Helena",
"AND": "Andorra",
"MOZ": "Mozambique",
"TJK": "Tajikistan",
"HTI": "Haiti",
"MEX": "Mexico",
"ANT": "Netherlands Antilles",
"ZWE": "Zimbabwe",
"LCA": "St. Lucia",
"IND": "India",
"LVA": "Latvia",
"BTN": "Bhutan",
"VCT": "St. Vincent and the Grenadines",
"VNM": "Vietnam",
"NOR": "Norway",
"CZE": "Czech Republic",
"ATG": "Antigua and Barbuda",
"FJI": "Fiji",
"HND": "Honduras",
"MUS": "Mauritius",
"DOM": "Dominican Republic",
"LUX": "Luxembourg",
"ISR": "Israel",
"FSM": "Micronesia, Fed. Sts.",
"PER": "Peru",
"REU": "Reunion",
"IDN": "Indonesia",
"VUT": "Vanuatu",
"MKD": "Macedonia, FYR",
"COD": "Congo, Dem. Rep.",
"COG": "Congo, Rep.",
"ISL": "Iceland",
"GLP": "Guadeloupe",
"ETH": "Ethiopia",
"COM": "Comoros",
"COL": "Colombia",
"NGA": "Nigeria",
"PRT": "Portugal",
"MDA": "Moldova",
"STP": "Sao Tome and Principe",
"MDG": "Madagascar",
"ECU": "Ecuador",
"SEN": "Senegal",
"MDV": "Maldives",
"ASM": "American Samoa",
"SPM": "Saint Pierre and Miquelon",
"SRB": "Serbia",
"FRA": "France",
"LTU": "Lithuania",
"RWA": "Rwanda",
"ZMB": "Zambia",
"GMB": "Gambia, The",
"WLF": "Wallis and Futuna",
"FRO": "Faeroe Islands",
"GTM": "Guatemala",
"DNK": "Denmark",
"MSR": "Montserrat",
"AUS": "Australia",
"AUT": "Austria",
"IMY": "Isle of Man",
"PLW": "Palau",
"KEN": "Kenya",
"TUR": "Turkey",
"ALB": "Albania",
"OMN": "Oman",
"TUV": "Tuvalu",
"ITA": "Italy",
"BRN": "Brunei Darussalam",
"TUN": "Tunisia",
"RUS": "Russian Federation",
"BRB": "Barbados",
"BRA": "Brazil",
"CIV": "Cote d'Ivoire",
"TLS": "Timor-Leste",
"GNQ": "Equatorial Guinea",
"USA": "United States",
"QAT": "Qatar",
"WSM": "Samoa",
"AZE": "Azerbaijan",
"GNB": "Guinea-Bissau",
"SWZ": "Swaziland",
"TON": "Tonga",
"CAN": "Canada",
"UKR": "Ukraine",
"KOR": "Korea, Rep.",
"AIA": "Anguilla",
"CAF": "Central African Republic",
"CHE": "Switzerland",
"CYP": "Cyprus",
"BIH": "Bosnia and Herzegovina",
"SGP": "Singapore",
"TWN": "Taiwan, China",
"SOM": "Somalia",
"UZB": "Uzbekistan",
"CMR": "Cameroon",
"POL": "Poland",
"KWT": "Kuwait",
"ERI": "Eritrea",
"GAB": "Gabon",
"CYM": "Cayman Islands",
"ARE": "United Arab Emirates",
"EST": "Estonia",
"MWI": "Malawi",
"ESP": "Spain",
"IRQ": "Iraq",
"SLV": "El Salvador",
"MLI": "Mali",
"IRL": "Ireland",
"IRN": "Iran, Islamic Rep.",
"ABW": "Aruba",
"SLE": "Sierra Leone",
"KNA": "St. Kitts and Nevis",
"PAN": "Panama",
"SCG": "Serbia and Montenegro",
"SLB": "Solomon Islands",
"NZL": "New Zealand",
"MCO": "Monaco",
"JPN": "Japan",
"KGZ": "Kyrgyz Republic",
"UGA": "Uganda",
"NCL": "New Caledonia",
"PNG": "Papua New Guinea",
"ARG": "Argentina",
"SWE": "Sweden",
"BHS": "Bahamas, The",
"BHR": "Bahrain",
"ARM": "Armenia",
"NRU": "Naura",
"CUB": "Cuba"}
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.link {
stroke: #ccc;
stroke-width: 1.5px;
stroke-opacity: 0.5;
}
.node ellipse {
fill: #fff;
stroke: #000;
stroke-width: 0.5px;
}
.node text {
pointer-events: none;
font: 10px sans-serif;
}
.axis {
opacity: 0.5;
font: 10px sans-serif;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.axis .domain {
fill: none;
stroke: #000;
stroke-opacity: .3;
stroke-width: 4px;
stroke-linecap: round;
}
.axis .halo {
fill: none;
stroke: #ddd;
stroke-width: 3px;
stroke-linecap: round;
}
.slider .handle {
fill: #fff;
stroke: #000;
stroke-opacity: .5;
stroke-width: 1.25px;
cursor: grab;
}
</style>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 750;
var height = 350;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("g").attr("class","linkg");
svg.append("g").attr("class","nodeg");
var force = d3.layout.force()
.size([width - 100, height])
.nodes([{}])
.gravity(0.2)
.charge(-200);
var x = d3.scale.linear()
.domain([500000, 5000000])
.range([250, 80])
.clamp(true);
var brush = d3.svg.brush()
.y(x)
.extent([0, 0]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + (width - 20) + ",0)")
.call(d3.svg.axis()
.scale(x)
.orient("left")
.tickFormat(function(d) { return d / 1000000.0 ; })
.tickSize(0)
.tickPadding(12))
.select(".domain")
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "halo");
var slider = svg.append("g")
.attr("class", "slider")
.call(brush);
slider.selectAll(".extent,.resize")
.remove();
var handle = slider.append("circle")
.attr("class", "handle")
.attr("transform", "translate(" + (width - 20) + ",0)")
.attr("r", 5);
svg.append("text")
.attr("x", width - 15)
.attr("y", height - 75)
.attr("text-anchor", "end")
.attr("font-size", "10px")
.style("opacity", 0.5)
.text("> x million")
svg.append("text")
.attr("x", width - 15)
.attr("y", height - 60)
.attr("text-anchor", "end")
.attr("font-size", "10px")
.style("opacity", 0.5)
.text("bilateral migration")
var bigGraph = {"nodes":[], "links":[]};
function compare(a,b) {
if (a.i < b.i)
return -1;
if (a.i > b.i)
return 1;
return 0;
}
var selectyeartext = ["2000","1990","1980","1970","1960"];
var selectyearids = [2000,1990,1980,1970,1960];
var selectyear = 2000;
d3.csv("migration.csv", function(error, migrationTable) {
d3.json("countrynames.json", function(error, countrynames) {
// construct graph object from table
var nodes = {};
var nCount = 0;
var lCount = 0;
migrationTable.forEach(function(m){
if (!(m.cCode1 in nodes)) { nodes[m.cCode1] = nCount; nCount += 1; };
if (!(m.cCode2 in nodes)) { nodes[m.cCode2] = nCount; nCount += 1; };
bigGraph.links.push({"source": nodes[m.cCode1] ,
"target": nodes[m.cCode2] ,
"1960": m.totalMigration1960 ,
"1970": m.totalMigration1970 ,
"1980": m.totalMigration1980 ,
"1990": m.totalMigration1990 ,
"2000": m.totalMigration2000 ,
"linkname" : lCount
});
lCount += 1;
});
bigGraph.nodes = $.map(nodes, function(v, k) {
return {"x": width * Math.random(), "y": height * Math.random(), "i": v, "name": k, "countryname": countrynames[k]};
});
bigGraph.nodes.sort(compare);
// text fields used as selectors
for (var i=0; i<selectyearids.length; i++) {
svg.append("text").attr("x", width - 215 + (selectyearids.length - i - 1) * 50).attr("y", height - 10)
.attr("class", "text-button1")
.attr("id", selectyearids[i]).style("opacity", i == 0 ? 1 : 0.5 )
.attr("iv", i)
.attr("text-anchor", "end")
.attr("font-size", "10px")
.text(selectyeartext[i])
.on('mouseover', function(e){
// determine which text-'button' is selected
var selectedNum = parseInt(d3.select(this)[0][0].attributes.iv.value);
// change opacities of text-'buttons'
d3.selectAll(".text-button1").style("opacity",0.5);
d3.select(this).style("opacity",1);
selectyear = selectyearids[selectedNum];
redraw(bigGraph, selectcutoff, selectyear);
});
}
brush.on("brush", brushed);
slider
.call(brush.extent([2000000, 2000000]))
.call(brush.event);
redraw(bigGraph,selectcutoff,selectyear);
});
});
function brushed() {
var value = brush.extent()[0];
if (d3.event.sourceEvent) { // not a programmatic event
value = x.invert(d3.mouse(this)[1]);
brush.extent([value, value]);
}
handle.attr("cy", x(value));
selectcutoff = value;
redraw(bigGraph,selectcutoff,selectyear);
}
function redraw(bigGraph, cutoff, year) {
var currentNodes = force.nodes();
var graph = {"nodes":[], "links":[]};
var nodeList = {};
var nlCount = 0;
graph.links = $.map(bigGraph.links, function(v) {
if (v[''+year] > cutoff) {
if (!(v.source in nodeList)) { nodeList[v.source] = nlCount; nlCount += 1; };
if (!(v.target in nodeList)) { nodeList[v.target] = nlCount; nlCount += 1; };
return {"source": nodeList[v.source], "target": nodeList[v.target], "distance": v[''+year], "linkname": v.linkname};
}
});
graph.nodes = $.map(bigGraph.nodes, function(v) {
if (v.i in nodeList) {
var current = -1;
currentNodes.forEach(function(n,i){
if (n.name == v.name) { current = i; }
});
if (current > -1) {
return {"x": currentNodes[current].x, "y": currentNodes[current].y, "i": nodeList[v.i], "name": v.name, "countryname": v.countryname};
} else {
return {"x": v.x, "y": v.y, "i": nodeList[v.i], "name": v.name, "countryname": v.countryname};
}
}
});
graph.nodes.sort(compare);
force
.nodes(graph.nodes)
.links(graph.links);
var link = svg.selectAll(".linkg").selectAll(".link").data(graph.links,function(v){ return v.linkname; });
link.enter()
.append("line")
.attr("class", "link")
.style("opacity",1e-6)
.transition()
.duration(1500)
.style("opacity",1);
link.exit()
.transition()
.duration(500)
.style("opacity",1e-6)
.remove();
var node = svg.selectAll(".nodeg").selectAll(".node").data(graph.nodes,function(v){ return v.name; });
node.exit()
.transition()
.duration(500)
.style("opacity",1e-6)
.remove();
var node2 = node.enter()
.append("g")
.attr("class", "node");
node2.append("ellipse")
.attr("cx", 0)
.attr("cy", 0)
.attr("rx", 16)
.attr("ry", 8)
.attr("title", function(d) { return d.countryname })
.style("opacity",1e-6)
.transition()
.duration(1500)
.style("opacity",1);
node2.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.text(function(d) { return d.name })
.style("opacity",1e-6)
.transition()
.duration(1500)
.style("opacity",1);
force
.linkDistance(function(l) { return 20 + 5 * Math.log(1.0 + 1000000000 / l.distance); })
.start();
force.on("tick", function() {
link
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
}
</script>
</body>
</html>
cCode1 cCode2 totalMigration1960 totalMigration1970 totalMigration1980 totalMigration1990 totalMigration2000
DZA MAR 312124 115660 84287 67438 55003
DZA FRA 776450 1552713 1471001 1412267 1085907
EGY LBY 5988 74590 187381 272108 321516
EGY SAU 15307 74021 356513 914523 984948
BGD SAU 4545 25484 129880 338354 366031
BGD IND 650355 780412 5432785 5104651 4725528
VEN COL 110204 197126 487513 596201 654913
BGR TUR 283073 314044 294041 457910 483239
BOL ARG 94279 112068 134318 166902 264825
PAK SAU 7894 44842 226907 590583 638818
PAK GBR 36977 144748 193538 244074 351425
PAK IND 14956454 12999330 6963235 4996876 3844565
PAK ARE 555 17035 179190 331924 569902
JOR PSE 94080 118909 159903 238107 374706
JOR KWT 14844 175551 317981 460517 435467
MYS CHN 33623 412539 286846 147772 82736
MYS IDN 9862 59245 128586 410625 888429
MYS SGP 132426 240115 265712 393552 791051
PRI USA 712686 1104403 1340763 1670668 1698723
PRK KOR 106400 155619 506226 556317 435814
PSE SYR 121646 14014 259100 365261 484109
PSE ISR 167085 199209 235854 310413 479870
PRY ARG 184542 230028 302801 308341 395972
HKG CHN 1562528 16823 1898814 1995283 2165981
HKG MAC 21831 1629287 20857 156365 83441
SAU YEM 6873 27403 127436 326625 353768
SAU PHL 4594 25751 131327 342153 370735
SAU IND 12466 70210 363360 937342 1012999
SAU IDN 3598 19977 101723 264973 287220
BFA CIV 431683 663687 877015 1049470 1670136
SVK CZE 21857 24157 26698 188217 362784
HRV BIH 613 623 1116 317986 459342
CHL ARG 131471 176682 236230 258875 264817
CHN THA 423375 287223 176055 137833 238982
CHN IDN 1723312 1084717 678577 419701 89909
CHN USA 114191 223335 321193 577518 1024160
CHN CAN 36715 62303 90531 137801 337524
CHN SGP 278847 244565 219420 261693 354562
CHN JPN 53480 53800 52863 135434 337707
JAM USA 28628 87509 224362 367722 582014
FIN SWE 104789 251858 265640 247806 222345
NPL IND 840455 846144 789646 910545 1212737
PHL USA 113011 266440 602777 1079848 1541977
ZAF GBR 173864 219880 268639 232078 269641
ZAF LSO 200245 192126 181245 288742 117235
ZAF MOZ 162330 120046 76099 165325 423685
KAZ RUS 2623319 3515024 3816015 4275248 4516864
KAZ UKR 419850 720018 742668 854432 647743
KAZ UZB 138390 210614 308403 341702 274788
BEN NGA 11803 34962 260488 109599 184395
BEL COD 740039 155907 69542 53722 46132
BEL ITA 205082 270994 326182 255606 212302
DEU GBR 159809 197521 277578 300502 455234
DEU ROM 48513 50459 77169 1146928 326553
DEU GRC 46443 308581 309893 279170 378903
DEU CZE 736952 777179 749670 379009 412098
DEU FRA 178090 261177 275976 280815 372213
DEU AUT 495121 314068 279672 239911 290979
DEU TUR 31402 498642 1740647 1635222 2281974
DEU ITA 274540 640385 690887 599983 685112
DEU RUS 286209 297315 299809 936128 979006
DEU USA 1052384 1037226 1295086 1304223 1365747
DEU POL 2231997 2330478 2373261 1855534 2108150
DEU ESP 76420 284936 246723 220981 243089
DEU SCG 85851 320934 469656 404237 812520
LKA IND 1029985 1121003 881081 720762 570361
GBR IND 205753 344883 409059 434804 532504
GBR AUS 769543 1101357 1155589 1150456 1140253
GBR USA 989863 952725 918708 954572 998944
GBR CAN 1006919 972829 946578 978931 682829
GBR IRL 55585 822468 801410 780759 864191
GBR NZL 234341 270443 294525 313706 282259
MAR FRA 334107 352382 573051 681526 287435
MAR ITA 22852 18556 11237 162871 288412
MAR ESP 118217 72129 89056 120127 266213
HUN USA 258300 222062 161139 121965 97365
TKM RUS 337218 235911 261294 316339 304110
GEO RUS 225876 442939 497854 614314 748950
AFG IRN 42241 75077 284056 680296 762152
BLR RUS 1371929 1677897 1893166 2195291 1485520
BLR UKR 399547 543182 599440 687046 458044
BLR POL 954564 740538 659813 594816 405113
GRC TUR 270478 206985 148896 128311 67352
GRC ALB 50885 53068 58875 110570 488346
GRC USA 181054 229976 263101 229537 197382
TJK RUS 156970 207267 309442 387836 559086
HTI USA 5844 36289 106525 242287 438305
MEX USA 709908 1035188 2569392 4863664 9718536
IND OMN 21845 31510 73080 212145 312053
IND USA 18829 74103 233011 506733 1054369
IND CAN 9565 46551 86218 157619 320158
IND ARE 749 21749 238905 446835 765458
LVA RUS 236232 426515 492286 484355 341039
VNM USA 14427 11275 262269 583982 1029164
HND USA 8708 23374 43814 121533 293725
DOM USA 16082 80065 195161 384903 718008
ISR RUS 60594 72000 117851 233339 420074
PER USA 13201 35701 74502 168096 290754
MKD AUT 3503 12964 317912 15703 22424
COD RWA 16 71132 48568 38546 311472
GLP FRA 37780 14181 101823 31029 255809
ETH ERI 230782 219522 230761 242699 255178
COL USA 19889 91475 178497 337497 548081
PRT FRA 87028 315799 657258 670183 234581
PRT BRA 488805 434238 401916 296299 261438
MDA RUS 209127 295108 354132 477469 481436
MDA UKR 325325 377213 417091 453568 383722
ECU USA 10960 51554 106492 161291 313529
FRA ITA 179848 923738 717206 585877 283572
FRA TUN 273196 300841 360632 369091 314597
FRA USA 165527 129831 194599 208670 280242
FRA POL 540790 337261 210311 178531 837324
FRA ESP 133807 810907 616364 561246 278001
LTU RUS 116059 261736 263332 290053 181936
LTU POL 534669 502456 435834 389288 89494
GTM USA 9709 24331 76015 248063 494651
AUS ITA 218939 323985 266130 253941 221919
AUS NZL 80787 104344 219801 307935 406873
AUT USA 339345 271402 166132 106869 80769
KEN UGA 185655 190161 130163 77790 394269
ALB ITA 12646 11418 12145 42875 275361
ITA USA 1315293 1327740 1039627 727773 574670
ITA CAN 251400 323222 405077 432746 316514
ITA CHE 499117 670454 577930 457318 358928
ITA ARG 927761 704763 503984 398265 244466
RUS AZE 286386 325849 392854 640593 952385
RUS UKR 6734154 7668831 8614586 9807733 7173215
RUS UZB 540184 1012267 1156950 1445792 1664572
RUS POL 412368 360196 276504 210464 506425
RUS EST 151993 300620 337036 365915 258001
RUS KGZ 231051 320559 437202 609385 631313
RUS ARM 130690 153883 176944 205250 510405
BRA JPN 166907 154737 150250 138367 313083
CIV MLI 241229 340530 419739 448217 518618
USA CAN 1271786 1256006 1315287 1240208 1221257
USA UKR 381955 293268 190645 146724 444112
USA KOR 19106 61375 317115 697828 909124
USA TWN 4914 3743 87355 279250 346577
USA POL 780704 649078 457154 427070 500203
USA SLV 9556 20571 108812 506882 831652
USA IRL 360175 308228 232409 201745 187240
USA IRN 7300 5772 134487 229205 294436
USA JPN 127472 181396 357939 489749 550729
USA CUB 87600 525082 683783 800593 895137
AZE ARM 311373 386546 402253 262150 205587
UKR UZB 0 200509 219618 336191 404656
UKR POL 1540991 1309201 988580 727197 546040
KOR JPN 624791 624652 671552 702898 699460
ESP ARG 766041 568547 408700 305181 220887
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment