Rolling Choropleth Globe in D3
Programmable rolling chloropeth globe in D3 with modifiable country colors, tool-tips and rotations. Pre-compiled to be dropped into your webpage.
Demo: https://boscoh.github.io/rolling-globe
Installation
Download the package.
Open the file example/index.html
in the browser.
How-to
Quick-start. To create a globe, you need require.js
and rolling-globe.min.js
from the dist
directory in the package. Then in your HTML file:
<div
id="globe"
style="
width: calc(100vw - 60px);
height: calc(100vh - 160px);">
</div>
<script src="./require.js"></script>
<script>
require(['./rolling-globe.min.js'], function (rollingGlobe) {
var g = new rollingGlobe.Globe('#globe')
})
</script>
Matching country indices. To access the the countries in the globe, you need to obtain the index of the country. This can be obtained using the getICountry
method, with a query based on the built-in country properties (described in the section Looking up Countries below). To find Australia:
var i = g.getICountry({'iso_a3': 'AUS'})
Rotation to a selected country.
g.rotateTransitionToICountry(i)
Handle clicks and double-clicks.
g.clickCountry = function (i) {
console.log('clicked: ' + g.features[i].properties.name)
g.setHighlight(i)
g.rotateTransitionToICountry(i, function () {
g.draw()
})
}
Setting country colors.
g.colors[i] = 'green'
g.borderColors[i] = 'blue'
Setting color palette based on country values.
// let's say populations is a list of country
// populations sorted by the country index
for (var i = 0; i < g.values.length; i += 1) {
g.values[i] = populations[i]
}
g.resetCountryColorsFromValues('red')
g.draw()
// optional legend
g.drawLegend()
Highlight specific countries with outline.
g.highlightColor = 'green'
g.iHighlightCountry = i
g.draw()
Replace tool-tip.
g.getCountryPopupHtml = function (i) {
return g.features[i].properties.name + ': ' + g.values[i]
}
Resize: The resize method will resize the globe to fit the parent <div>
. Attach the function the window resize function:
window.onresize = function() { g.resize() }
Development
Download package and load the module using require.js
The module has been written in ES6, a very nice dialect, and transpiled into a single file for easy deployment, which includes all the necessary data files to get up and running. To compile dist/globe.min.js
use:
> npm intall
> webpack
During development, it is suggested to run with the file watcher, and re-load example/index.html
which uses the compiled version in the dist
directory:
> webpack --watch
Looking up Countries
Each country is internally represented by an index iCountry, which refers to SVG vector data stored in this.world
. This index is used to access the this.values
, this.colors
, this.borderColors
and this.features
.
Each country comes with a default set properties, which is stored in a list this.features
. Each element in this list feature
has a sub-field dictionary feature.properties
, such as this one for Australia:
{
"scalerank": 1,
"featurecla": "Admin-0 country",
"labelrank": 2,
"sovereignt": "Australia",
"sov_a3": "AU1",
"adm0_dif": 1,
"level": 2,
"type": "Country",
"admin": "Australia",
"adm0_a3": "AUS",
"geou_dif": 0,
"geounit": "Australia",
"gu_a3": "AUS",
"su_dif": 0,
"subunit": "Australia",
"su_a3": "AUS",
"brk_diff": 0,
"name": "Australia",
"name_long": "Australia",
"brk_a3": "AUS",
"brk_name": "Australia",
"brk_group": "",
"abbrev": "Auz.",
"postal": "AU",
"formal_en": "Commonwealth of Australia",
"formal_fr": "",
"note_adm0": "",
"note_brk": "",
"name_sort": "Australia",
"name_alt": "",
"mapcolor7": 1,
"mapcolor8": 2,
"mapcolor9": 2,
"mapcolor13": 7,
"pop_est": 21262641,
"gdp_md_est": 800200,
"pop_year":` -99,
"lastcensus": 2006,
"gdp_year":` -99,
"economy": "2. Developed region: nonG7",
"income_grp": "1. High income: OECD",
"wikipedia":` -99,
"fips_10": "",
"iso_a2": "AU",
"iso_a3": "AUS",
"iso_n3": "036",
"un_a3": 36,
"wb_a2": "AU",
"wb_a3": "AUS",
"woe_id":` -99,
"adm0_a3_is": "AUS",
"adm0_a3_us": "AUS",
"adm0_a3_un":` -99,
"adm0_a3_wb":` -99,
"continent": "Oceania",
"region_un": "Oceania",
"subregion": "Australia and New Zealand",
"region_wb": "East Asia & Pacific",
"name_len": 9,
"long_len": 9,
"abbrev_len": 4,
"tiny":` -99,
"homepart": 1
}
To lookup the iCountry index:
- you can iterate through the country features
this.features
and match the properties of each country to your country identifier. - or use a default dictionary
this.iCountryFromId
that maps the iCountry index toiso_n3
field of a country feature. - use the lookup method
this.getICountry({key: value})
, which will match the key, value pair to the values infeature.properties
of each country, and return the iCountry index if successful
References
The SVG vector data is stored in this.world
, and this is taken from Mike Bostocks's world-atlas, which was generated from the data at Natural Earth at the resolution of 1:110.
The Globe object has the following properties:
this.world
- topoJson data used to generate the SVGthis.features
- list of features for each countrythis.values
- list of numerical values for each countrythis.colors
- list of colors for countriesthis.borderColors
- list of colors for borders of countriesthis.iCountryFromId
- dictionary to mapiso_n3
to iCountry indicethis.nullColor
- color of country with values set to nullthis.borderColor
- color of country bordersthis.outerBorderColor
- color of globe borderthis.fillColor
- color of waterthis.highlightColor
- color of border outline for highlighted countrythis.scaleFactor
- zoom factor for globethis.iHighlightCountry
- iCountry to be highlighted with this.highlightColor; none if null
Methods:
this.getICountry(query)
- query comes in the form of{key: value}
that is used to searchthis.features
for a matching property, function will return matchin iCountry index, or nullthis.dblclickCountry(iCountry)
- overridable callback for double-clickthis.clickCountry(iCountry)
- overridable callback fro clickthis.getCountryPopupHtml(iCountry)
- overridable callback to generate the HTML for the tool-tip pop-up for a country mouse-over.this.resize()
- resizes the globe to the size of the parent div. Useful for web-responsive divs.this.rotateTo(r)
- direct rotation to the rotational coordinater=[-Longitude, -Latitude]
, this is the internal D3 rotational coordinate system.this.rotateTransition(targetR, callback)
- animated transition analogue tothis.rotateTo
with callback upon end of animationthis.rotateTransitionToICountry(iCountry, callback)
- animated rotation to countrythis.resetCountryColorsFromValues(maxColor, maxValue = null, minColor = '#DDD')
- recolors the countries usingthis.values
frommaxColor
tominColor
using a linear color palettethis.draw()
- force redraw