Skip to content

Instantly share code, notes, and snippets.

@johnburnmurdoch
Last active February 21, 2017 05:58
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 johnburnmurdoch/bcdb4e85c7523a2b0e64961f0d227154 to your computer and use it in GitHub Desktop.
Save johnburnmurdoch/bcdb4e85c7523a2b0e64961f0d227154 to your computer and use it in GitHub Desktop.
// https://github.com/1wheel/d3-jetpack-module Version 0.0.14. Copyright 2016 Adam Pearce.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-transition'), require('d3-axis'), require('d3-scale'), require('d3-collection'), require('d3-queue'), require('d3-request')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-transition', 'd3-axis', 'd3-scale', 'd3-collection', 'd3-queue', 'd3-request'], factory) :
(factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3,global.d3,global.d3));
}(this, function (exports,d3Selection,d3Transition,d3Axis,d3Scale,d3Collection,d3Queue,d3Request) { 'use strict';
function translateSelection(xy) {
return this.attr('transform', function(d,i) {
return 'translate('+[typeof xy == 'function' ? xy.call(this, d,i) : xy]+')';
});
};
function parseAttributes(name) {
if (typeof name === "string") {
var attr = {},
parts = name.split(/([\.#])/g), p;
name = parts.shift();
while ((p = parts.shift())) {
if (p == '.') attr['class'] = attr['class'] ? attr['class'] + ' ' + parts.shift() : parts.shift();
else if (p == '#') attr.id = parts.shift();
}
return {tag: name, attr: attr};
}
return name;
}
function append(name) {
var n = parseAttributes(name), s;
name = d3Selection.creator(n.tag);
s = this.select(function() {
return this.appendChild(name.apply(this, arguments));
});
//attrs not provided by default in v4
for (var key in n.attr) { s.attr(key, n.attr[key]) }
return s;
};
function selectAppend(name) {
var select = d3Selection.selector(name),
n = parseAttributes(name), s;
name = d3Selection.creator(n.tag);
s = this.select(function() {
return select.apply(this, arguments)
|| this.appendChild(name.apply(this, arguments));
});
//attrs not provided by default in v4
for (var key in n.attr) { s.attr(key, n.attr[key]) }
return s;
};
function tspans(lines, lh) {
return this.selectAll('tspan')
.data(lines).enter()
.append('tspan')
.html(function(d) { return d; })
.attr('x', 0)
.attr('dy', function(d, i) { return i ? (lh + 'em') || '1em' : 0; });
};
function appendMany(data, name){
return this.selectAll(null).data(data).enter().append(name);
};
function at(name, value) {
if (typeof(name) == 'object'){
for (var key in name){
this.attr(key.replace(/([a-z\d])([A-Z])/g, '$1-$2').toLowerCase(), name[key])
}
return this
} else{
return arguments.length == 1 ? this.attr(name) : this.attr(name, value)
}
};
function f(){
var functions = arguments
//convert all string arguments into field accessors
var i = 0, l = functions.length
while (i < l) {
if (typeof(functions[i]) === 'string' || typeof(functions[i]) === 'number'){
functions[i] = (function(str){ return function(d){ return d[str] } })(functions[i])
}
i++
}
//return composition of functions
return function(d) {
var i=0, l = functions.length
while (i++ < l) d = functions[i-1].call(this, d)
return d
}
}
f.not = function(d){ return !d }
f.run = function(d){ return d() }
f.objToFn = function(obj, defaultVal){
if (arguments.length == 1) defaultVal = undefined
return function(str){
return typeof(obj[str]) !== undefined ? obj[str] : defaultVal }
}
function st(name, value) {
if (typeof(name) == 'object'){
for (var key in name){
addStyle(this, key, name[key])
}
return this
} else{
return arguments.length == 1 ? this.style(name) : addStyle(this, name, value)
}
function addStyle(sel, style, value){
var style = style.replace(/([a-z\d])([A-Z])/g, '$1-$2').toLowerCase()
var pxStyles = 'top left bottom right padding-top padding-left padding-bottom padding-right border-top b-width border-left-width border-botto-width m border-right-width margin-top margin-left margin-bottom margin-right font-size width height stroke-width line-height margin padding border max-width min-width'
if (~pxStyles.indexOf(style) ){
sel.style(style, typeof value == 'function' ? f(value, addPx) : addPx(value))
} else{
sel.style(style, value)
}
return sel
}
function addPx(d){ return d.match ? d : d + 'px' }
};
function wordwrap(line, maxCharactersPerLine) {
var w = line.split(' '),
lines = [],
words = [],
maxChars = maxCharactersPerLine || 40,
l = 0;
w.forEach(function(d) {
if (l+d.length > maxChars) {
lines.push(words.join(' '));
words.length = 0;
l = 0;
}
l += d.length;
words.push(d);
});
if (words.length) {
lines.push(words.join(' '));
}
return lines.filter(function(d){ return d != '' });
};
function ascendingKey(key) {
return typeof key == 'function' ? function (a, b) {
return key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : key(a) >= key(b) ? 0 : NaN;
} : function (a, b) {
return a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : a[key] >= b[key] ? 0 : NaN;
};
};
function descendingKey(key) {
return typeof key == 'function' ? function (a, b) {
return key(b) < key(a) ? -1 : key(b) > key(a) ? 1 : key(b) >= key(a) ? 0 : NaN;
} : function (a, b) {
return b[key] < a[key] ? -1 : b[key] > a[key] ? 1 : b[key] >= a[key] ? 0 : NaN;
};
};
function conventions(c){
c = c || {}
c.margin = c.margin || {top: 20, right: 20, bottom: 20, left: 20}
;['top', 'right', 'bottom', 'left'].forEach(function(d){
if (!c.margin[d] && c.margin[d] != 0) c.margin[d] = 20
})
c.width = c.width || c.totalWidth - c.margin.left - c.margin.right || 900
c.height = c.height || c.totalHeight - c.margin.top - c.margin.bottom || 460
c.totalWidth = c.width + c.margin.left + c.margin.right
c.totalHeight = c.height + c.margin.top + c.margin.bottom
c.parentSel = c.parentSel || d3Selection.select('body')
c.rootsvg = c.parentSel.append('svg')
c.svg = c.rootsvg
.attr('width', c.totalWidth)
.attr('height', c.totalHeight)
.append('g')
.attr('transform', 'translate(' + c.margin.left + ',' + c.margin.top + ')')
c.x = c.x || d3Scale.scaleLinear().range([0, c.width])
c.y = c.y || d3Scale.scaleLinear().range([c.height, 0])
c.xAxis = c.xAxis || d3Axis.axisBottom().scale(c.x)
c.yAxis = c.yAxis || d3Axis.axisLeft().scale(c.y)
c.drawAxis = function(){
c.svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + c.height + ')')
.call(c.xAxis);
c.svg.append('g')
.attr('class', 'y axis')
.call(c.yAxis);
}
return c
}
function attachTooltip(sel, tooltipSel, fieldFns){
if (!sel.size()) return
tooltipSel = tooltipSel || d3Selection.select('.tooltip')
sel
.on('mouseover.attachTooltip', ttDisplay)
.on('mousemove.attachTooltip', ttMove)
.on('mouseout.attachTooltip', ttHide)
.on('click.attachTooltip', function(d){ console.log(d) })
var d = sel.datum()
fieldFns = fieldFns || d3Collection.keys(d)
.filter(function(str){
return (typeof d[str] != 'object') && (d[str] != 'array')
})
.map(function(str){
return function(d){ return str + ': <b>' + d[str] + '</b>'} })
function ttDisplay(d){
tooltipSel
.classed('tooltip-hidden', false)
.html('')
.appendMany(fieldFns, 'div')
.html(function(fn){ return fn(d) })
d3Selection.select(this).classed('tooltipped', true)
}
function ttMove(d){
var tt = tooltipSel
if (!tt.size()) return
var e = d3Selection.event,
x = e.clientX,
y = e.clientY,
n = tt.node(),
nBB = n.getBoundingClientRect(),
doctop = (window.scrollY)? window.scrollY : (document.documentElement && document.documentElement.scrollTop)? document.documentElement.scrollTop : document.body.scrollTop,
topPos = y+doctop-nBB.height-18;
tt.style('top', (topPos < 0 ? 18 + y : topPos)+'px');
tt.style('left', Math.min(Math.max(20, (x-nBB.width/2)), window.innerWidth - nBB.width - 20)+'px');
}
function ttHide(d){
tooltipSel.classed('tooltip-hidden', true);
d3Selection.selectAll('.tooltipped').classed('tooltipped', false)
}
}
function loadData(files, cb){
var q = d3Queue.queue()
files.forEach(function(d){
var type = d.split('.').reverse()[0]
var loadFn = {csv: d3Request.csv, tsv: d3Request.tsv, json: d3Request.json}[type]
if (!loadFn) return cb(new Error('Invalid type', d))
q.defer(loadFn, d)
})
q.awaitAll(cb)
}
function nestBy(array, key){
return d3Collection.nest().key(key).entries(array).map(function(d){
d.values.key = d.key
return d.values
})
}
function round(n, p) {
return p ? Math.round(n * (p = Math.pow(10, p))) / p : Math.round(n);
};
d3Selection.selection.prototype.translate = translateSelection
d3Transition.transition.prototype.translate = translateSelection
d3Selection.selection.prototype.append = append
d3Selection.selection.prototype.selectAppend = selectAppend
d3Selection.selection.prototype.tspans = tspans
d3Selection.selection.prototype.appendMany = appendMany
d3Selection.selection.prototype.at = at
d3Selection.selection.prototype.st = st
d3Selection.selection.prototype.prop = d3Selection.selection.prototype.property
exports.wordwrap = wordwrap;
exports.parseAttributes = parseAttributes;
exports.f = f;
exports.ascendingKey = ascendingKey;
exports.descendingKey = descendingKey;
exports.conventions = conventions;
exports.attachTooltip = attachTooltip;
exports.loadData = loadData;
exports.nestBy = nestBy;
exports.round = round;
Object.defineProperty(exports, '__esModule', { value: true });
}));
code shortName region lifeEx gdpPerCap10 gdpPerCapPPP11 population
AFG Afghanistan South Asia 60.374 619.751 1808.126 32526562
ALB Albania Europe & Central Asia 77.83 4543.088 11015.164 2889167
DZA Algeria Middle East & North Africa 74.808 4794.049 13822.566 39666519
ASM American Samoa East Asia & Pacific NA NA NA 55538
ADO Andorra Europe & Central Asia NA NA NA 70473
AGO Angola Sub-Saharan Africa 52.267 4153.146 6937.631 25021974
ATG Antigua and Barbuda Latin America & Caribbean 75.938 13708.995 21660.222 91818
ARG Argentina Latin America & Caribbean 76.159 10514.588 19126.342 43416755
ARM Armenia Europe & Central Asia 74.676 3796.517 7906.917 3017712
ABW Aruba Latin America & Caribbean 75.451 NA NA 103889
AUS Australia East Asia & Pacific 82.251 54708.184 43631.236 23781169
AUT Austria Europe & Central Asia 81.337 47754.595 44048.431 8611088
AZE Azerbaijan Europe & Central Asia 70.763 6115.758 16698.864 9651349
BHS The Bahamas Latin America & Caribbean 75.234 20683.869 21602.675 388019
BHR Bahrain Middle East & North Africa 76.683 22347.971 43753.898 1377237
BGD Bangladesh South Asia 71.626 972.881 3136.561 160995642
BRB Barbados Latin America & Caribbean 75.496 15971.015 15408.385 284215
BLR Belarus Europe & Central Asia 72.976 6158.995 16661.99 9513000
BEL Belgium Europe & Central Asia 80.588 45036.128 41825.875 11285721
BLZ Belize Latin America & Caribbean 70.077 4392.547 7967.767 359287
BEN Benin Sub-Saharan Africa 59.511 804.724 1931.665 10879829
BMU Bermuda North America 80.797 NA NA 65235
BTN Bhutan South Asia 69.471 2668.121 7860.987 774830
BOL Bolivia Latin America & Caribbean 68.344 2392.766 6531.074 10724705
BIH Bosnia and Herzegovina Europe & Central Asia 76.433 4801.88 10118.77 3810416
BWA Botswana Sub-Saharan Africa 64.429 7080.119 14876.362 2262485
BRA Brazil Latin America & Caribbean 74.402 11159.254 14454.937 207847528
VGB British Virgin Islands Latin America & Caribbean NA NA NA 30117
BRN Brunei East Asia & Pacific 78.81 32226.096 73604.88 423188
BGR Bulgaria Europe & Central Asia 75.407 7612.025 17000.142 7177991
BFA Burkina Faso Sub-Saharan Africa 58.588 644.609 1592.917 18105570
BDI Burundi Sub-Saharan Africa 56.692 206.711 682.944 11178921
CPV Cabo Verde Sub-Saharan Africa 73.147 3500.205 6157.897 520502
KHM Cambodia East Asia & Pacific 68.212 1020.908 3278.221 15577899
CMR Cameroon Sub-Saharan Africa 55.493 1303.589 2925.887 23344179
CAN Canada North America 81.957 50000.56 42894.667 35851774
CYM Cayman Islands Latin America & Caribbean NA NA NA 59967
CAF Central African Republic Sub-Saharan Africa 50.658 292.165 581.136 4900274
TCD Chad Sub-Saharan Africa 51.556 951.685 2043.544 14037472
CHI Channel Islands Europe & Central Asia 80.606 NA NA 163692
CHL Chile Latin America & Caribbean 81.496 14660.505 22197.043 17948141
CHN China East Asia & Pacific 75.782 6497.482 13571.686 1371220000
COL Colombia Latin America & Caribbean 73.993 7447.877 12988.339 48228704
COM Comoros Sub-Saharan Africa 63.257 758.694 1393.256 788474
ZAR Dem. Rep. Congo Sub-Saharan Africa 58.659 384.507 736.68 77266814
COG Congo Sub-Saharan Africa 62.311 3163.173 5993.153 4620330
CRI Costa Rica Latin America & Caribbean 79.403 9237.952 14646.57 4807850
CIV Côte d'Ivoire Sub-Saharan Africa 51.56 1496.236 3300.072 22701556
HRV Croatia Europe & Central Asia 77.329 13807.347 20663.929 4224404
CUB Cuba Latin America & Caribbean 79.391 NA NA 11389562
CUW Curaçao Latin America & Caribbean 77.824 NA NA 158040
CYP Cyprus Europe & Central Asia 80.132 27787.806 30603.531 1165300
CZE Czech Republic Europe & Central Asia 78.276 21214.196 30380.591 10551219
DNK Denmark Europe & Central Asia 80.549 58098.289 44041.735 5676002
DJI Djibouti Middle East & North Africa 62.016 1650.308 3279.124 887861
DMA Dominica Latin America & Caribbean NA 6916.851 10204.036 72680
DOM Dominican Republic Latin America & Caribbean 73.5 6552.694 13371.529 10528391
ECU Ecuador Latin America & Caribbean 75.872 5366.545 10776.578 16144363
EGY Egypt Middle East & North Africa 71.122 2707.086 10249.958 91508084
SLV El Salvador Latin America & Caribbean 72.755 3853.108 8095.559 6126583
GNQ Equatorial Guinea Sub-Saharan Africa 57.647 19433.267 38243.354 845060
ERI Eritrea Sub-Saharan Africa 63.663 NA NA NA
EST Estonia Europe & Central Asia 77.239 17638.494 27345.247 1311998
ETH Ethiopia Sub-Saharan Africa 64.035 486.269 1529.894 99390750
FRO Faroe Islands Europe & Central Asia 81.693 NA NA 48199
FJI Fiji East Asia & Pacific 70.089 4349.524 8756.4 892145
FIN Finland Europe & Central Asia 81.129 45132.79 38940.93 5482013
FRA France Europe & Central Asia 82.373 41533.867 37774.999 66808385
PYF French Polynesia East Asia & Pacific 76.542 NA NA 282764
GAB Gabon Sub-Saharan Africa 64.383 10751.935 18860.214 1725292
GMB The Gambia Sub-Saharan Africa 60.228 536.278 1577.569 1990924
GEO Georgia Europe & Central Asia 74.669 4010.254 9015.888 3679000
DEU Germany Europe & Central Asia 80.844 45408.306 43787.816 81413145
GHA Ghana Sub-Saharan Africa 61.312 1696.645 3954.524 27409893
GIB Gibraltar Europe & Central Asia NA NA NA 32217
GRC Greece Europe & Central Asia 81.285 22573.416 24094.794 10823732
GRL Greenland Europe & Central Asia NA NA NA 56114
GRD Grenada Latin America & Caribbean 73.366 8391.155 12734.262 106825
GUM Guam East Asia & Pacific 79.126 NA NA 169885
GTM Guatemala Latin America & Caribbean 71.722 3052.295 7252.95 16342897
GIN Guinea Sub-Saharan Africa 58.733 417.097 1135.487 12608590
GNB Guinea-Bissau Sub-Saharan Africa 55.16 533.794 1367.299 1844325
GUY Guyana Latin America & Caribbean 66.406 3663.418 7064.45 767085
HTI Haiti Latin America & Caribbean 62.747 727.783 1650.593 10711067
HND Honduras Latin America & Caribbean 73.136 2313.045 4785.444 8075060
HKG Hong Kong SAR, China East Asia & Pacific 83.98 36173.317 53462.863 7305700
HUN Hungary Europe & Central Asia 75.873 14516.683 24831.346 9844686
ISL Iceland Europe & Central Asia 82.061 45411.045 42324.56 330823
IND India South Asia 68.014 1750.623 5729.777 1311050527
IDN Indonesia East Asia & Pacific 68.888 3834.056 10385.323 257563815
IRN Iran Middle East & North Africa 75.389 NA NA 79109272
IRQ Iraq Middle East & North Africa 69.4 5119.252 14458.854 36423395
IRL Ireland Europe & Central Asia 81.154 65292.383 61378.36 4640703
IMY Isle of Man Europe & Central Asia NA NA NA 87780
ISR Israel Middle East & North Africa 82.154 33116.78 31970.689 8380400
ITA Italy Europe & Central Asia 82.69 33849.392 34219.761 60802085
JAM Jamaica Latin America & Caribbean 75.654 5000.709 8333.485 2725941
JPN Japan East Asia & Pacific 83.588 47150.366 37872.462 126958472
JOR Jordan Middle East & North Africa 74.052 3976.043 10239.664 7594547
KAZ Kazakhstan Europe & Central Asia 71.62 10616.676 23522.291 17544126
KEN Kenya Sub-Saharan Africa 61.576 1133.459 2901.013 46050302
KIR Kiribati East Asia & Pacific 65.952 1615.576 1873.497 112423
PRK Dem. People's Rep. Korea East Asia & Pacific 70.075 NA NA 25155317
KOR Korea East Asia & Pacific 82.156 25022.802 34386.575 50617045
KSV Kosovo Europe & Central Asia 71.098 3796.233 9142.148 1797151
KWT Kuwait Middle East & North Africa 74.585 35888.581 70107.458 3892115
KGZ Kyrgyz Republic Europe & Central Asia 70.402 1017.147 3224.932 5957000
LAO Lao PDR East Asia & Pacific 66.117 1531.221 5345.261 6802023
LVA Latvia Europe & Central Asia 74.188 14321.258 23080.361 1978440
LBN Lebanon Middle East & North Africa 79.373 7045.494 13089.012 5850743
LSO Lesotho Sub-Saharan Africa 49.701 1370.266 2770.2 2135022
LBR Liberia Sub-Saharan Africa 60.834 367.165 784.581 4503438
LBY Libya Middle East & North Africa 71.716 NA NA 6278438
LIE Liechtenstein Europe & Central Asia 82.261 NA NA 37531
LTU Lithuania Europe & Central Asia 73.966 15231.267 26807.182 2910199
LUX Luxembourg Europe & Central Asia 82.207 106408.574 92468.14 569676
MAC Macao SAR, China East Asia & Pacific 80.553 55860.177 104718.262 587606
MKD Macedonia Europe & Central Asia 75.342 5093.836 12732.403 2078453
MDG Madagascar Sub-Saharan Africa 65.086 409.924 1376.26 24235390
MWI Malawi Sub-Saharan Africa 62.722 493.663 1111.649 17215232
MYS Malaysia East Asia & Pacific 74.718 10878.389 25311.907 30331007
MDV Maldives South Asia 76.773 7221.621 11993.911 409163
MLI Mali Sub-Saharan Africa 57.986 720.81 1904.857 17599694
MLT Malta Middle East & North Africa 81.746 24351.432 32719.946 431333
MHL Marshall Islands East Asia & Pacific NA 3344.566 3673.154 52993
MRT Mauritania Sub-Saharan Africa 63.017 NA NA 4067564
MUS Mauritius Sub-Saharan Africa 74.194 9468.941 18864.106 1262605
MEX Mexico Latin America & Caribbean 76.722 9510.596 16490.346 127017224
FSM Micronesia East Asia & Pacific 69.101 2793.358 3284.135 104460
MDA Moldova Europe & Central Asia 71.456 1978.256 4742.019 3554150
MCO Monaco Europe & Central Asia NA NA NA 37731
MNG Mongolia East Asia & Pacific 69.464 3946.281 11477.827 2959134
MNE Montenegro Europe & Central Asia 76.181 7259.986 15254.307 622388
MAR Morocco Middle East & North Africa 74.016 3239.552 7364.766 34377511
MOZ Mozambique Sub-Saharan Africa 55.026 511.467 1119.698 27977863
MMR Myanmar East Asia & Pacific 65.858 1308.747 4930.59 53897154
NAM Namibia Sub-Saharan Africa 64.68 6000.038 9778.405 2458830
NRU Nauru East Asia & Pacific NA 11158.993 14974.753 10222
NPL Nepal South Asia 69.605 689.514 2312.394 28513700
NLD Netherlands Europe & Central Asia 81.305 51268.471 46353.852 16936520
NCL New Caledonia East Asia & Pacific 77.573 NA NA 273000
NZL New Zealand East Asia & Pacific 81.405 36801.396 35158.641 4595700
NIC Nicaragua Latin America & Caribbean 74.81 1849.029 4884.151 6082032
NER Niger Sub-Saharan Africa 61.458 383.831 897.395 19899120
NGA Nigeria Sub-Saharan Africa 52.754 2548.174 5638.887 182201962
MNP Northern Mariana Islands East Asia & Pacific NA NA NA 55070
NOR Norway Europe & Central Asia 81.751 89492.841 63649.505 5195921
OMN Oman Middle East & North Africa 77.085 15965.94 37541.075 4490541
PAK Pakistan South Asia 66.183 1142.752 4706.185 188924874
PLW Palau East Asia & Pacific NA 10410.088 14385.969 21291
PAN Panama Latin America & Caribbean 77.595 10750.937 20885.339 3929141
PNG Papua New Guinea East Asia & Pacific 62.607 NA NA 7619321
PRY PY Latin America & Caribbean 72.922 3822.861 8639.282 6639123
PER Peru Latin America & Caribbean 74.526 5934.548 11767.522 31376670
PHL Philippines East Asia & Pacific 68.266 2639.868 6938.21 100699395
POL Poland Europe & Central Asia 77.254 14650.116 25322.538 37999494
PRT Portugal Europe & Central Asia 80.722 21960.475 26513.983 10348648
PRI Puerto Rico Latin America & Caribbean 79.375 NA NA 3474182
QAT Qatar Middle East & North Africa 78.597 74686.617 132937.666 2235355
ROM Romania Europe & Central Asia 75.063 9530.657 20483.775 19832389
RUS Russia Europe & Central Asia 70.366 11038.811 23895.341 144096812
RWA Rwanda Sub-Saharan Africa 63.966 689.688 1655.175 11609666
WSM Samoa East Asia & Pacific 73.512 3641.009 5574.068 193228
SMR San Marino Europe & Central Asia NA NA NA 31781
STP São Tomé and Principe Sub-Saharan Africa 66.385 1292.872 3022.902 190344
SAU Saudi Arabia Middle East & North Africa 74.337 21312.807 50283.934 31540372
SEN Senegal Sub-Saharan Africa 66.373 1042.495 2273.624 15129273
SRB Serbia Europe & Central Asia 75.534 5661.107 13277.752 7098247
SYC Seychelles Sub-Saharan Africa 73.229 13617.884 25524.955 92900
SLE Sierra Leone Sub-Saharan Africa 50.879 490.564 1473.913 6453184
SGP Singapore East Asia & Pacific 82.646 51855.079 80191.539 5535002
SXM Sint Maarten (Dutch part) Latin America & Caribbean NA NA NA 38817
SVK Slovak Republic Europe & Central Asia 76.715 18643.147 28254.256 5424050
SVN Slovenia Europe & Central Asia 80.52 23778.561 29097.343 2063768
SLB Solomon Islands East Asia & Pacific 67.931 1475.36 2067.13 583591
SOM Somalia Sub-Saharan Africa 55.355 NA NA 10787104
ZAF South Africa Sub-Saharan Africa 57.182 7593.358 12393.255 54956920
SSD South Sudan Sub-Saharan Africa 55.682 717.696 1741.098 12339812
ESP Spain Europe & Central Asia 83.078 30587.551 32329.588 46418269
LKA Sri Lanka South Asia 74.795 3637.539 11047.667 20966000
KNA St. Kitts and Nevis Latin America & Caribbean NA 15080.773 23562.942 55572
LCA St. Lucia Latin America & Caribbean 75.047 6822.606 10278.98 184999
MAF St. Martin (French part) Latin America & Caribbean 79.322 NA NA 31754
VCT St. Vincent and the Grenadines Latin America & Caribbean 72.937 6575.445 10462.41 109462
SDN Sudan Sub-Saharan Africa 63.459 1807.663 4121.137 40234882
SUR Suriname Latin America & Caribbean 71.151 9114.883 15687.232 542975
SWZ Swaziland Sub-Saharan Africa 48.935 4057.284 8122.049 1286970
SWE Sweden Europe & Central Asia 81.956 55186.039 45505.303 9798871
CHE Switzerland Europe & Central Asia 82.849 75531.472 56517.452 8286976
SYR Syrian Arab Republic Middle East & North Africa 70.071 NA NA 18502413
TJK Tajikistan Europe & Central Asia 69.598 932.911 2661.385 8481855
TZA Tanzania Sub-Saharan Africa 64.944 842.374 2510.036 53470420
THA Thailand East Asia & Pacific 74.422 5775.137 15346.647 67959359
TMP Timor-Leste East Asia & Pacific 68.259 983.508 2253.168 1245015
TGO Togo Sub-Saharan Africa 59.656 553.86 1371.564 7304578
TON Tonga East Asia & Pacific 72.792 3700.243 5198.345 106170
TTO Trinidad and Tobago Latin America & Caribbean 70.441 16696.03 31283.55 1360088
TUN Tunisia Middle East & North Africa 74.144 4328.542 10769.933 11107800
TUR Turkey Europe & Central Asia 75.164 11522.705 19460.482 78665830
TKM Turkmenistan Europe & Central Asia 65.599 6932.844 15527.404 5373502
TCA Turks and Caicos Islands Latin America & Caribbean NA NA NA 34339
TUV Tuvalu East Asia & Pacific NA 3706.314 3687.484 9916
UGA Uganda Sub-Saharan Africa 58.466 672.809 1738.462 39032383
UKR Ukraine Europe & Central Asia 71.187 2825.85 7456.93 45198200
ARE United Arab Emirates Middle East & North Africa 77.368 39313.274 65716.984 9156963
GBR United Kingdom Europe & Central Asia 81.056 41187.684 38519.491 65138232
USA United States North America 78.941 51638.065 52704.199 321418820
URY Uruguay Latin America & Caribbean 76.986 13943.904 19952.253 3431555
UZB Uzbekistan Europe & Central Asia 68.339 1856.719 5716.496 31299500
VUT Vanuatu East Asia & Pacific 71.918 2823.185 2806.27 264652
VEN Venezuela Latin America & Caribbean 74.236 NA NA 31108083
VNM Vietnam East Asia & Pacific 75.629 1684.866 5667.411 91703800
VIR Virgin Islands Latin America & Caribbean 79.773 NA NA 103574
WBG West Bank and Gaza Middle East & North Africa 72.904 2648.974 4714.925 4422143
YEM Yemen Middle East & North Africa 63.818 774.45 2649.313 26832215
ZMB Zambia Sub-Saharan Africa 60.047 1607.358 3602.327 16211767
ZWE Zimbabwe Sub-Saharan Africa 57.498 814.56 1677.97 15602751
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,user-scalable=no">
<title>d3</title>
<script src="https://unpkg.com/d3/build/d3.min.js"></script>
<script src="https://unpkg.com/d3-swoopy-drag"></script>
<script src="d3-jetpack-module.js"></script>
<style media="screen">
html, body{
font-family:Arial,sans-serif;
font-size: 18px;
}
text{
fill: #000;
font-size: 18px;
}
.heading{
font-size: 1.15rem;
font-weight: 600;
}
.title{
font-size: 0.8rem;
}
.legend text{
font-size: 0.7rem;
fill: #74736c;
}
path.domain{
fill: none;
stroke: none;
}
.tick line{
shape-rendering: crispEdges;
stroke: lightgrey;
stroke-width: 1;
}
.tick text{
font-size: 0.75rem;
}
.label{
font-size: 0.85rem;
}
.shadow{
text-shadow:2px 2px 2px #fff, -2px -2px 2px #fff, -2px 2px 2px #fff, 2px -2px 2px #fff, -2px 0px 2px #fff, 2px 0px 2px #fff;
}
</style>
</head>
<body>
<svg></svg>
<script type="text/javascript">
var width = 600,
height = 500,
margin = {
left:20,
top:80,
right:0,
bottom:30
};
function calculateDistance(x1,y1,x2,y2){
return Math.sqrt( Math.pow(x1-x2,2) + Math.pow(y1-y2,2) )
}
var svg = d3.select("svg")
.at({
width: width + "px",
height: height + "px"
})
.st({
width: width,
height: height
});
var heading = svg.append("text.heading")
.translate([0, 16])
.tspans(["A snapshot of global socio-economic development in 2016,", "as measured by GDP per capita and life expectancy"],1.1)
function prepare(d){
d.label = d.shortName;
d.region = d.region;
d.lifeEx = +d.lifeEx;
d.gdpPerCap10 = +d.gdpPerCap10;
d.gdpPerCapPPP11 = +d.gdpPerCapPPP11;
d.population = +d.population;
return d;
}
function render(data){
data = data.filter(d => !isNaN(d.gdpPerCap10) && !isNaN(d.lifeEx));
// console.log(data);
// Define and draw x axis
var x = d3.scaleLog()
.base(10)
.range([margin.left, width-margin.right])
.domain(d3.extent(data, d=> d.gdpPerCap10));
var xAxis = d3.axisTop()
.scale(x)
.ticks(5)
.tickFormat(d3.format(","))
.tickSize(-(height-(margin.bottom+margin.top)));
var xDraw = svg.append("g.axis.x")
.translate([0, margin.top])
.call(xAxis);
// Show/hide and style ticks to make the log scale clear
d3.selectAll(".x .tick").filter(d => [100, 300, 1000, 3000, 10000, 30000].indexOf(d) < 0)
.selectAll("text, line")
.st({
"stroke-dasharray": "2 2"
})
.text("");
// Add an x-axis title
var xTitle = svg.append("text.x.title.shadow")
.translate([x(300)-11, margin.top+13])
.html("GDP per capita (constant 2010 US$) &rarr;");
// Define and draw y axis
var y = d3.scaleLinear()
.range([height-margin.bottom, margin.top])
.domain(d3.extent(data, d=> d.lifeEx));
var yAxis = d3.axisLeft()
.scale(y)
.ticks(5)
.tickSize(-(width-(margin.left+margin.right)));
var yDraw = svg.append("g.axis.y")
.translate([margin.left, 0])
.call(yAxis);
// Add a y-axis title
var yTitle = svg.append("text.y.title.shadow")
.translate([margin.left+2, y(79)-6])
.tspans(["Life", "expectancy", "at birth", "(years)","&darr;"],1.1);
// Define a circle area scale
var areaScale = d3.scaleSqrt()
.range([0, 35])
.domain([0, d3.max(data, d => d.population)]);
var pops = data.map(d => d.population).sort((a,b) => a-b);
// Draw an area legend
var areaLegend = svg.append("g.legend").translate([width-85, height-180]);
var areaGroups = areaLegend.selectAll("g")
.data([10000000, 100000000, 500000000])
.enter()
.append("g");
var areaCircles = areaGroups.append("circle")
.at({
cy: d => -areaScale(d),
r: d => areaScale(d),
fill: "none",
stroke: "#74736c"
});
var areaLines = areaGroups.append("line")
.at({
y1: d => -2*areaScale(d),
y2: d => -2*areaScale(d),
x2: 50,
stroke: "#74736c"
});
var areaNames = areaGroups.append("text.shadow")
.at({
y: d => -2*areaScale(d)+5,
x: 50
})
.html(d => (d/1000000) + "m");
// Define a region colour scale
var colours = d3.scaleOrdinal()
.range(['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f'])
.domain(data.map(d => d.region).filter((element, index, array) => array.indexOf(element)===index));
// Draw a colour legend
var colourLegend = svg.append("g.legend").translate([width-155, height-150]);
var colourGroups = colourLegend.selectAll("g")
.data(colours.domain())
.enter()
.append("g")
.translate((d,i) => [0, i*20]);
var colourNames = colourGroups.append("text.shadow")
.html(d => d);
var colourDots = colourGroups.append("circle")
.at({
cx: -8,
cy: -5,
r: 5,
fill: d => colours(d)
})
// Draw and position a group element for each country
var countries = svg.selectAll("g.country")
.data(data)
.enter()
.append("g.country")
.translate(d => [x(d.gdpPerCap10), y(d.lifeEx)]);
// Draw a bubble for each country
var bubbles = countries.append("circle")
.at({
r: d => areaScale(d.population)
})
.st({
fill: d => colours(d.region),
"fill-opacity": 0.6,
stroke: d => colours(d.region)
});
labels.forEach(function(d){
countries.filter(v => v.label == d.label)
.selectAll("text.label")
.data([d])
.enter()
.append("text.label.shadow")
.html(d.label);
countries.selectAll(".label").filter(v => v.label == d.label)
.translate(d.translate);
countries.filter(v => v.label == d.label)
.selectAll("path")
.data([d])
.enter()
.insert("path","text")
.attr("d", d.path)
.style("fill", "none")
.style("stroke", "#74736c");
});
countries.on("dblclick", function(d){
var selection = d3.select(this);
selection.selectAll("*:not(circle)").remove();
labels.splice(labels.map(a => a.label).indexOf(selection.data()[0].label),1);
});
countries.on("click", function(d){
var selection = d3.select(this);
selection
.selectAll("text.label")
.data([d])
.enter()
.append("text.label.shadow")
.html(d.label);
if(labels.map(a => a.label).indexOf(selection.data()[0].label)<0){
labels.push({
label: selection.data()[0].label
});
};
countries.selectAll(".label")
.st({cursor: "pointer"})
.call(
d3.drag()
.on("drag", function(){
var selection = d3.select(this);
var dataPoint = data[data.map(a => a.label).indexOf(selection.data()[0].label)];
selection
.translate([d3.event.x, d3.event.y])
.st({cursor: "crosshair"});
if(calculateDistance(d3.mouse(svg.node())[0], d3.mouse(svg.node())[1], x(dataPoint.gdpPerCap10), y(dataPoint.lifeEx)) > areaScale(dataPoint.population)){
var path = d3.select(selection.node().parentNode)
.selectAll("path")
.data(["M " + (d3.event.x + selection.node().getBoundingClientRect().width/2) + ", " + d3.event.y + " A 30 30 0 0 0 0,0"], p => p);
path
.attr("d", p => p)
.style("fill", "none")
.style("stroke", "#74736c");
path.exit().remove()
path.enter()
.insert("path","text")
.attr("d", p => p)
.style("fill", "none")
.style("stroke", "#74736c");
}else{
var path = d3.select(selection.node().parentNode)
.selectAll("path")
.remove();
}
})
.on("end", function(){
var selection = d3.select(this);
var dataPoint = data[data.map(a => a.label).indexOf(selection.data()[0].label)];
selection
.st({cursor: "pointer"});
if(labels.map(a => a.label).indexOf(selection.data()[0].label)>=0){
labels[labels.map(a => a.label).indexOf(selection.data()[0].label)].translate = [d3.event.x, d3.event.y];
if(calculateDistance(d3.mouse(svg.node())[0], d3.mouse(svg.node())[1], x(dataPoint.gdpPerCap10), y(dataPoint.lifeEx)) > areaScale(dataPoint.population)){
labels[labels.map(a => a.label).indexOf(selection.data()[0].label)].path = d3.select(selection.node().parentNode).select("path").attr("d");
}else{
delete labels[labels.map(a => a.label).indexOf(selection.data()[0].label)].path;
}
}else{
labels.push({
label: selection.data()[0].label,
translate: [d3.event.x, d3.event.y],
path: d3.select(selection.node().parentNode).select("path").attr("d")
});
}
})
);
});
countries.selectAll(".label")
.st({cursor: "pointer"})
.call(
d3.drag()
.on("drag", function(){
var selection = d3.select(this);
var dataPoint = data[data.map(a => a.label).indexOf(selection.data()[0].label)];
selection
.translate([d3.event.x, d3.event.y])
.st({cursor: "crosshair"});
if(calculateDistance(d3.mouse(svg.node())[0], d3.mouse(svg.node())[1], x(dataPoint.gdpPerCap10), y(dataPoint.lifeEx)) > areaScale(dataPoint.population)){
var path = d3.select(selection.node().parentNode)
.selectAll("path")
.data(["M " + (d3.event.x + selection.node().getBoundingClientRect().width/2) + ", " + d3.event.y + " A 30 30 0 0 0 0,0"], p => p)
path
.attr("d", p => p)
.style("fill", "none")
.style("stroke", "#74736c");
path.exit().remove()
path.enter()
.insert("path","text")
.attr("d", p => p)
.style("fill", "none")
.style("stroke", "#74736c");
}else{
var path = d3.select(selection.node().parentNode)
.selectAll("path")
.remove();
}
})
.on("end", function(){
var selection = d3.select(this);
var dataPoint = data[data.map(a => a.label).indexOf(selection.data()[0].label)];
selection
.st({cursor: "pointer"});
if(labels.map(a => a.label).indexOf(selection.data()[0].label)>=0){
labels[labels.map(a => a.label).indexOf(selection.data()[0].label)].translate = [d3.event.x, d3.event.y];
if(calculateDistance(d3.mouse(svg.node())[0], d3.mouse(svg.node())[1], x(dataPoint.gdpPerCap10), y(dataPoint.lifeEx)) > areaScale(dataPoint.population)){
labels[labels.map(a => a.label).indexOf(selection.data()[0].label)].path = d3.select(selection.node().parentNode).select("path").attr("d");
}else{
delete labels[labels.map(a => a.label).indexOf(selection.data()[0].label)].path;
}
}else{
labels.push({
label: selection.data()[0].label,
translate: [d3.event.x, d3.event.y],
path: d3.select(selection.node().parentNode).select("path").attr("d")
});
}
})
);
}
d3.csv("gapMinder2015.csv", prepare, render);
var labels = [];
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment