Skip to content

Instantly share code, notes, and snippets.

@zzhang115
Last active May 9, 2018 07:51
Show Gist options
  • Save zzhang115/e4f4ca607e4972c699e8711f70977766 to your computer and use it in GitHub Desktop.
Save zzhang115/e4f4ca607e4972c699e8711f70977766 to your computer and use it in GitHub Desktop.
Geomap
/**
* d3.tip
* Copyright (c) 2013 Justin Palmer
*
* Tooltips for d3.js SVG visualizations
*/
// eslint-disable-next-line no-extra-semi
;(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module with d3 as a dependency.
define([
'd3-collection',
'd3-selection'
], factory)
} else if (typeof module === 'object' && module.exports) {
/* eslint-disable global-require */
// CommonJS
var d3Collection = require('d3-collection'),
d3Selection = require('d3-selection')
module.exports = factory(d3Collection, d3Selection)
/* eslint-enable global-require */
} else {
// Browser global.
var d3 = root.d3
// eslint-disable-next-line no-param-reassign
root.d3.tip = factory(d3, d3)
}
}(this, function(d3Collection, d3Selection) {
// Public - contructs a new tooltip
//
// Returns a tip
return function() {
var direction = d3TipDirection,
offset = d3TipOffset,
html = d3TipHTML,
node = initNode(),
svg = null,
point = null,
target = null
function tip(vis) {
svg = getSVGNode(vis)
if (!svg) return
point = svg.createSVGPoint()
document.body.appendChild(node)
}
// Public - show the tooltip on the screen
//
// Returns a tip
tip.show = function() {
var args = Array.prototype.slice.call(arguments)
if (args[args.length - 1] instanceof SVGElement) target = args.pop()
var content = html.apply(this, args),
poffset = offset.apply(this, args),
dir = direction.apply(this, args),
nodel = getNodeEl(),
i = directions.length,
coords,
scrollTop = document.documentElement.scrollTop ||
document.body.scrollTop,
scrollLeft = document.documentElement.scrollLeft ||
document.body.scrollLeft
nodel.html(content)
.style('opacity', 1).style('pointer-events', 'all')
while (i--) nodel.classed(directions[i], false)
coords = directionCallbacks.get(dir).apply(this)
nodel.classed(dir, true)
.style('top', (coords.top + poffset[0]) + scrollTop + 'px')
.style('left', (coords.left + poffset[1]) + scrollLeft + 'px')
return tip
}
// Public - hide the tooltip
//
// Returns a tip
tip.hide = function() {
var nodel = getNodeEl()
nodel.style('opacity', 0).style('pointer-events', 'none')
return tip
}
// Public: Proxy attr calls to the d3 tip container.
// Sets or gets attribute value.
//
// n - name of the attribute
// v - value of the attribute
//
// Returns tip or attribute value
// eslint-disable-next-line no-unused-vars
tip.attr = function(n, v) {
if (arguments.length < 2 && typeof n === 'string') {
return getNodeEl().attr(n)
}
var args = Array.prototype.slice.call(arguments)
d3Selection.selection.prototype.attr.apply(getNodeEl(), args)
return tip
}
// Public: Proxy style calls to the d3 tip container.
// Sets or gets a style value.
//
// n - name of the property
// v - value of the property
//
// Returns tip or style property value
// eslint-disable-next-line no-unused-vars
tip.style = function(n, v) {
if (arguments.length < 2 && typeof n === 'string') {
return getNodeEl().style(n)
}
var args = Array.prototype.slice.call(arguments)
d3Selection.selection.prototype.style.apply(getNodeEl(), args)
return tip
}
// Public: Set or get the direction of the tooltip
//
// v - One of n(north), s(south), e(east), or w(west), nw(northwest),
// sw(southwest), ne(northeast) or se(southeast)
//
// Returns tip or direction
tip.direction = function(v) {
if (!arguments.length) return direction
direction = v == null ? v : functor(v)
return tip
}
// Public: Sets or gets the offset of the tip
//
// v - Array of [x, y] offset
//
// Returns offset or
tip.offset = function(v) {
if (!arguments.length) return offset
offset = v == null ? v : functor(v)
return tip
}
// Public: sets or gets the html value of the tooltip
//
// v - String value of the tip
//
// Returns html value or tip
tip.html = function(v) {
if (!arguments.length) return html
html = v == null ? v : functor(v)
return tip
}
// Public: destroys the tooltip and removes it from the DOM
//
// Returns a tip
tip.destroy = function() {
if (node) {
getNodeEl().remove()
node = null
}
return tip
}
function d3TipDirection() { return 'n' }
function d3TipOffset() { return [0, 0] }
function d3TipHTML() { return ' ' }
var directionCallbacks = d3Collection.map({
n: directionNorth,
s: directionSouth,
e: directionEast,
w: directionWest,
nw: directionNorthWest,
ne: directionNorthEast,
sw: directionSouthWest,
se: directionSouthEast
}),
directions = directionCallbacks.keys()
function directionNorth() {
var bbox = getScreenBBox()
return {
top: bbox.n.y - node.offsetHeight,
left: bbox.n.x - node.offsetWidth / 2
}
}
function directionSouth() {
var bbox = getScreenBBox()
return {
top: bbox.s.y,
left: bbox.s.x - node.offsetWidth / 2
}
}
function directionEast() {
var bbox = getScreenBBox()
return {
top: bbox.e.y - node.offsetHeight / 2,
left: bbox.e.x
}
}
function directionWest() {
var bbox = getScreenBBox()
return {
top: bbox.w.y - node.offsetHeight / 2,
left: bbox.w.x - node.offsetWidth
}
}
function directionNorthWest() {
var bbox = getScreenBBox()
return {
top: bbox.nw.y - node.offsetHeight,
left: bbox.nw.x - node.offsetWidth
}
}
function directionNorthEast() {
var bbox = getScreenBBox()
return {
top: bbox.ne.y - node.offsetHeight,
left: bbox.ne.x
}
}
function directionSouthWest() {
var bbox = getScreenBBox()
return {
top: bbox.sw.y,
left: bbox.sw.x - node.offsetWidth
}
}
function directionSouthEast() {
var bbox = getScreenBBox()
return {
top: bbox.se.y,
left: bbox.se.x
}
}
function initNode() {
var div = d3Selection.select(document.createElement('div'))
div
.style('position', 'absolute')
.style('top', 0)
.style('opacity', 0)
.style('pointer-events', 'none')
.style('box-sizing', 'border-box')
return div.node()
}
function getSVGNode(element) {
var svgNode = element.node()
if (!svgNode) return null
if (svgNode.tagName.toLowerCase() === 'svg') return svgNode
return svgNode.ownerSVGElement
}
function getNodeEl() {
if (node == null) {
node = initNode()
// re-add node to DOM
document.body.appendChild(node)
}
return d3Selection.select(node)
}
// Private - gets the screen coordinates of a shape
//
// Given a shape on the screen, will return an SVGPoint for the directions
// n(north), s(south), e(east), w(west), ne(northeast), se(southeast),
// nw(northwest), sw(southwest).
//
// +-+-+
// | |
// + +
// | |
// +-+-+
//
// Returns an Object {n, s, e, w, nw, sw, ne, se}
function getScreenBBox() {
var targetel = target || d3Selection.event.target
while (targetel.getScreenCTM == null && targetel.parentNode == null) {
targetel = targetel.parentNode
}
var bbox = {},
matrix = targetel.getScreenCTM(),
tbbox = targetel.getBBox(),
width = tbbox.width,
height = tbbox.height,
x = tbbox.x,
y = tbbox.y
point.x = x
point.y = y
bbox.nw = point.matrixTransform(matrix)
point.x += width
bbox.ne = point.matrixTransform(matrix)
point.y += height
bbox.se = point.matrixTransform(matrix)
point.x -= width
bbox.sw = point.matrixTransform(matrix)
point.y -= height / 2
bbox.w = point.matrixTransform(matrix)
point.x += width
bbox.e = point.matrixTransform(matrix)
point.x -= width / 2
point.y -= height / 2
bbox.n = point.matrixTransform(matrix)
point.y += height
bbox.s = point.matrixTransform(matrix)
return bbox
}
// Private - replace D3JS 3.X d3.functor() function
function functor(v) {
return typeof v === 'function' ? v : function() {
return v
}
}
return tip
}
// eslint-disable-next-line semi
}));
id name Feed_2013 Food_2013 population
AFG Afghanistan 1536 21471 7.153835406
ALB Albania 1319 6952 18.97295742
DZA Algeria 8706 63455 13.71995903
AGO Angola 18518 30121 61.47870257
ATG Antigua and Barbuda 0 119 0
ARG Argentina 15780 65063 24.25341592
ARM Armenia 1313 5862 22.39849881
AUS Australia 18471 43975 42.00341103
AUT Austria 6823 18167 37.55710904
AZE Azerbaijan 4234 15928 26.58211954
AZE Bahamas 2 627 0.318979266
BGD Bangladesh 6670 114184 5.84144889
BRB Barbados 62 407 15.23341523
BLR Belarus 20407 17445 116.9790771
BEL Belgium 11068 22268 49.70361056
BLZ Belize 128 424 30.18867925
BEN Benin 4008 12473 32.13340816
BMU Bermuda 3 103 2.912621359
BOL Bolivia (Plurinational State of) 2488 11027 22.5628004
BIH Bosnia and Herzegovina 1462 6994 20.90363168
BWA Botswana 48 2224 2.158273381
BRA Brazil 127479 312488 40.79484652
BRN Brunei Darussalam 17 530 3.20754717
BGR Bulgaria 2111 10224 20.64749609
BFA Burkina Faso 90 18890 0.476442562
CIV C?te d'Ivoire 1106 27057 4.087666778
CPV Cabo Verde 70 651 10.75268817
KHM Cambodia 1214 12421 9.773770228
CMR Cameroon 4332 30520 14.19397117
CAN Canada 52274 67893 76.99468281
CAF Central African Republic 2 4185 0.047789725
TCD Chad 207 8194 2.526238711
CHL Chile 8258 24642 33.51189027
CHN China 199 11557 1.721900147
CHN China 0 739 0
CHN China 691903 2499252 27.68440317
CHN China 10505 30220 34.76174719
COL Colombia 12223 64621 18.91490382
COD Congo 32 5168 0.619195046
CRI Costa Rica 1625 6642 24.46552243
HRV Croatia 4063 7404 54.87574284
CUB Cuba 8151 18823 43.30340541
CYP Cyprus 789 1454 54.26409904
CZE Czechia 5454 18524 29.44288491
KOR Democratic People's Republic of Korea 1632 22848 7.142857143
DNK Denmark 15671 11589 135.2230563
DJI Djibouti 0 791 0
DMA Dominica 41 138 29.71014493
DOM Dominican Republic 2480 14399 17.22341829
ECU Ecuador 2401 17149 14.00081637
EGY Egypt 30168 131916 22.86909852
SLV El Salvador 1429 6926 20.63239965
EST Estonia 1251 2613 47.87600459
ETH Ethiopia 1370 66726 2.053172676
FJI Fiji 138 1108 12.45487365
FIN Finland 4309 11874 36.28937174
FRA France 45537 120542 37.77687445
PYF French Polynesia 8 404 1.98019802
GAB Gabon 502 2535 19.80276134
GMB Gambia 30 1408 2.130681818
GEO Georgia 903 5635 16.02484472
DEU Germany 60418 158473 38.12510649
GHA Ghana 9756 44967 21.69591033
GRC Greece 8906 23836 37.36365162
GRD Grenada 28 122 22.95081967
GTM Guatemala 1624 13791 11.77579581
GIN Guinea 1295 11423 11.33677668
GNB Guinea-Bissau 10 1220 0.819672131
GUY Guyana 621 1062 58.47457627
HTI Haiti 962 8204 11.72598732
HND Honduras 830 8263 10.04477793
HUN Hungary 9287 14348 64.72679119
ISL Iceland 214 604 35.43046358
IND India 98258 1238335 7.934686494
IDN Indonesia 19062 237826 8.015103479
IRN Iran (Islamic Republic of) 23362 122793 19.02551448
IRQ Iraq 6316 30961 20.39985789
IRL Ireland 7517 10643 70.62858217
ISR Israel 5050 14263 35.40629601
ITA Italy 32287 121163 26.64757393
JAM Jamaica 338 3878 8.715832904
JPN Japan 34952 153161 22.82043079
JOR Jordan 2503 8477 29.52695529
KAZ Kazakhstan 14404 32695 44.055666
KEN Kenya 1196 47401 2.52315352
KIR Kiribati 0 135 0
KWT Kuwait 1044 6123 17.05046546
KGZ Kyrgyzstan 4085 8442 48.38900734
LAO Lao People's Democratic Republic 2035 8561 23.77058755
LVA Latvia 1222 3542 34.50028233
LBN Lebanon 1274 7408 17.19762419
LSO Lesotho 2 1801 0.111049417
LBR Liberia 70 3310 2.114803625
LTU Lithuania 3866 6340 60.97791798
LUX Luxembourg 293 1218 24.05582923
MDG Madagascar 1686 19488 8.651477833
MWI Malawi 8018 17215 46.57566076
MYS Malaysia 7412 31580 23.47055098
MDV Maldives 0 559 0
MLI Mali 1309 15737 8.317976743
MLT Malta 177 826 21.42857143
MRT Mauritania 177 3894 4.545454545
MUS Mauritius 205 1589 12.90119572
MEX Mexico 43530 166591 26.12986296
MNG Mongolia 422 3280 12.86585366
MNE Montenegro 346 1502 23.03595206
MAR Morocco 8468 47208 17.93763769
MOZ Mozambique 3440 25077 13.71774933
MMR Myanmar 23326 51583 45.22032453
NAM Namibia 107 2693 3.973264018
NPL Nepal 3135 33509 9.355695485
NLD Netherlands 17983 35849 50.16318447
NCL New Caledonia 51 367 13.89645777
NZL New Zealand 3468 7603 45.61357359
NIC Nicaragua 655 5358 12.22471071
NER Niger 1573 16267 9.669883814
NGA Nigeria 72046 228877 31.47804279
NOR Norway 5521 9707 56.87648089
OMN Oman 331 5966 5.548105934
PAK Pakistan 9511 180994 5.254870327
PAN Panama 1036 4524 22.90008842
PRY Paraguay 7314 8316 87.95093795
PER Peru 7284 40447 18.00875219
PHL Philippines 12757 100429 12.70250625
POL Poland 39451 70616 55.86694234
PRT Portugal 6445 21604 29.83243844
QAT Republic of Korea 20049 77125 25.99546191
MDA Republic of Moldova 3303 4643 71.13934956
ROU Romania 17199 43598 39.4490573
RUS Russian Federation 117021 253892 46.09085753
RWA Rwanda 0 18547 0
KNA Saint Kitts and Nevis 0 56 0
LCA Saint Lucia 13 216 6.018518519
VCT Saint Vincent and the Grenadines 63 158 39.87341772
WSM Samoa 8 329 2.431610942
STP Sao Tome and Principe 0 251 0
SAU Saudi Arabia 23682 35912 65.94453108
SEN Senegal 76 10653 0.713414062
SRB Serbia 11163 14236 78.4138803
SLE Sierra Leone 1802 6144 29.32942708
SVK Slovakia 2413 7709 31.30107666
SVN Slovenia 795 3700 21.48648649
SLB Solomon Islands 0 727 0
ZAF South Africa 10619 59621 17.81083846
ESP Spain 56543 81051 69.76224846
LKA Sri Lanka 530 20550 2.579075426
SDN Sudan 664 42997 1.544293788
SUR Suriname 120 632 18.98734177
SWZ Swaziland 114 1269 8.983451537
SWE Sweden 6937 19719 35.17926873
CHE Switzerland 3567 15983 22.3174623
TJK Tajikistan 5549 8543 64.95376331
THA Thailand 19122 78567 24.33846271
THA The former Yugoslav Republic of Macedonia 886 3482 25.44514647
TLS Timor-Leste 18 837 2.150537634
TGO Togo 302 6379 4.734284371
TTO Trinidad and Tobago 176 1773 9.926677947
TUN Tunisia 4344 18479 23.50776557
TUR Turkey 35502 145101 24.46709533
TKM Turkmenistan 4972 7082 70.20615645
UGA Uganda 697 40247 1.731806097
UKR Ukraine 74170 79580 93.2018095
ARE United Arab Emirates 2349 13095 17.93814433
GBR United Kingdom 27033 122946 21.98770192
TZA United Republic of Tanzania 4168 54968 7.582593509
USA United States of America 296863 641776 46.25648201
URY Uruguay 2476 5316 46.57637321
UZB Uzbekistan 19934 47311 42.13396462
VUT Vanuatu 12 370 3.243243243
VEN Venezuela (Bolivarian Republic of) 5756 39706 14.49654964
VNM Viet Nam 22712 105399 21.54859154
YEM Yemen 420 18325 2.291950887
ZMB Zambia 816 10180 8.015717092
ZWE Zimbabwe 262 9524 2.750944981
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.names {
fill: none;
stroke: #fff;
stroke-linejoin: round;
}
/* Tooltip CSS */
.d3-tip {
line-height: 1.5;
font-weight: 400;
font-family:"avenir next", Arial, sans-serif;
padding: 6px;
background: rgba(0, 0, 0, 0.6);
color: #66ccff;
border-radius: 1px;
pointer-events: none;
}
/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 8px;
width: 100%;
line-height: 1.5;
color: rgba(0, 0, 0, 0.6);
position: absolute;
pointer-events: none;
}
/* Northward tooltips */
.d3-tip.n:after {
content: "\25BC";
margin: -1px 0 0 0;
top: 100%;
left: 0;
text-align: center;
}
/* Eastward tooltips */
.d3-tip.e:after {
content: "\25C0";
margin: -4px 0 0 0;
top: 50%;
left: -8px;
}
/* Southward tooltips */
.d3-tip.s:after {
content: "\25B2";
margin: 0 0 1px 0;
top: -80px;
left: 0;
text-align: center;
}
/* Westward tooltips */
.d3-tip.w:after {
content: "\25B6";
margin: -4px 0 0 -1px;
top: 50%;
left: 100%;
}
/* text{
pointer-events:none;
}*/
.details{
color:white;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/queue.v1.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="d3-tip.js"></script>
<script>
var format = d3.format(",");
// Set tooltips
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Country: </strong><span class='details'>" + d.properties.name + "<br></span>" + "<strong>Population: </strong><span class='details'>" + format(d.population) +"</span>";
})
var margin = {top: 50, right: 0, bottom: 0, left: 900},
width = 1330,
height = 600;
// width = 1330 - margin.left - margin.right,
// height = 650 - margin.top - margin.bottom;
var scale = [10,20,30,40,50,60,70,80,90,100];
var legend_labels = ["10", "20+", "30+", "40+", "50+", "60+", "70+", "80+", "90+", "100"];
var color = d3.scale.threshold()
.domain(scale)
.range(["rgb(0, 102, 204)",
"rgb(0, 153, 255)",
"rgb(51, 153, 255)",
"rgb(153, 204, 255)",
"rgb(204, 153, 255)",
"rgb(255, 153, 255)",
"rgb(255, 102, 204)",
"rgb(255, 51, 153)",
"rgb(204, 102, 153)",
"rgb(102, 0, 51)"]);
var path = d3.geo.path();
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append('g')
.attr('class', 'map');
var projection = d3.geo.mercator()
.scale(130)
.translate( [width / 2, height / 1.5]);
var path = d3.geo.path().projection(projection);
svg.call(tip);
queue()
.defer(d3.json, "world_countries.json")
.defer(d3.tsv, "final_country_feed_food_comparison.tsv")
.await(ready);
// var color_domain = [50, 150, 350, 750, 1500]
// var ext_color_domain = [0, 50, 150, 350, 750, 1500]
// var color_legend = d3.scale.threshold()
// .domain(color_domain)
// .range(["#adfcad", "#ffcb40", "#ffba00", "#ff7d73", "#ff4e40", "#ff1300"]);
function ready(error, data, population) {
var populationById = {};
population.forEach(function(d) { populationById[d.id] = +d.population; });
data.features.forEach(function(d) { d.population = populationById[d.id] });
svg.append("g")
.attr("class", "countries")
.selectAll("path")
.data(data.features)
.enter().append("path")
.attr("d", path)
.style("fill", function(d) { return color(populationById[d.id]); })
.style('stroke', 'white')
.style('stroke-width', 1.5)
.style("opacity",0.8)
// tooltips
.style("stroke","white")
.style('stroke-width', 0.3)
.on('mouseover',function(d){
tip.show(d);
d3.select(this)
.style("opacity", 1)
.style("stroke","white")
.style("stroke-width",3);
})
.on('mouseout', function(d){
tip.hide(d);
d3.select(this)
.style("opacity", 0.8)
.style("stroke","white")
.style("stroke-width",0.3);
});
svg.append("path")
.datum(topojson.mesh(data.features, function(a, b) { return a.id !== b.id; }))
// .datum(topojson.mesh(data.features, function(a, b) { return a !== b; }))
.attr("class", "names")
.attr("d", path);
//Adding legend for our Choropleth
var legend = svg.selectAll("g.legend")
.data(scale)
.enter().append("g")
.attr("class", "legend");
var ls_w = 20, ls_h = 20;
legend.append("rect")
.attr("x", 50)
.attr("y", function(d, i){ return height - (i*ls_h) - 2*ls_h;})
.attr("width", ls_w)
.attr("height", ls_h)
.style("fill", function(d, i) { return color(d); })
.style("opacity", 0.8);
legend.append("text")
.attr("x", 80)
.attr("y", function(d, i){ return height - (i*ls_h) - ls_h - 4;})
.text(function(d, i){ return legend_labels[i]; });
}
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
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