-
Notifications
You must be signed in to change notification settings - Fork 2
D3 step 2
Wouldn't it be cool to add some animation to your map? Make it react to our mouse actions?
Let's see, when the mouse moves over the world map, we can create a function for it. This is a function for the things that have to happen when the mouse moves over a country:
// Create Event Handlers for mouse
function handleMouseOver(d, i) { // Add interactivity
// Use D3 to select element, change color
d3.select(this)
.style("fill", "orange");
};
A JavaScript function is a block of code designed to perform a particular task. A JavaScript function is executed when "something" invokes it (calls it).
A JavaScript function is defined with the function
keyword, followed by a name
, followed by parentheses ()
. The parentheses may include parameter names separated by commas (parameter1, parameter2, ...)
. The code to be executed, by the function, is placed inside curly brackets: {}
The code inside the function will execute when "something" invokes (calls) the function:
- When an event occurs (when a user clicks a button)
- When it is invoked (called) from JavaScript code
- Automatically (self invoked)
Let's explain our function
ℹ️ Our function is called handleMouseOver
and takes has no arguments.
ℹ️ The code to be executed is a d3 function. With d3 we select the object the mouse is on and give it a new style property. "fill" , "orange"
So this is only the function. You can add it to your code, but nothing will happen until you ivoke the function somewhere else.
We want to evoke this function when the mouse is on a path. With D3 we can add a action to the objects.
layerWorld.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", "#313030")
.style("stroke", "#5a5959")
.on("mouseover", handleMouseOver);
Now see what happens on your map when you move your mouse around!
Of course we also want the color to disappear again. For this we need a new function for the mouse-out action.
We call this function handleMouseOut
.
function handleMouseOut(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this)
.style("fill", "#313030")
};
.on("mouseout", handleMouseOut);
.on("mousedown", ..)
Tip: any DOM event type supported by your browser may be used.
The world data actually has a lot of attributes. We can use these attributes for styling the data! To see what attributes are available in the data set we can do 3 things.
- Open the GeoJSON file with your text editor to see the raw data.
- Let the browser print your data set in the console.
- Open the GeoJSON file in Qgis for example.
Let's try the first 2!
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"scalerank":1,"featurecla":"Admin-0 country","labelrank":3,"sovereignt":"Afghanistan","sov_a3":"AFG","adm0_dif":0,"level":2,"type":"Sovereign country","admin":"Afghanistan","adm0_a3":"AFG","geou_dif":0,"geounit":"Afghanistan","gu_a3":"AFG","su_dif":0,"subunit":"Afghanistan","su_a3":"AFG","brk_diff":0,"name":"Afghanistan","name_long":"Afghanistan","brk_a3":"AFG","brk_name":"Afghanistan","brk_group":"","abbrev":"Afg.","postal":"AF","formal_en":"Islamic State of Afghanistan","formal_fr":"","note_adm0":"","note_brk":"","name_sort":"Afghanistan","name_alt":"","mapcolor7":5,"mapcolor8":6,"mapcolor9":8,"mapcolor13":7,"pop_est":28400000,"gdp_md_est":22270,"pop_year":-99,"lastcensus":1979,"gdp_year":-99,"economy":"7. Least developed region","income_grp":"5. Low income","wikipedia":-99,"fips_10":"","iso_a2":"AF","iso_a3":"AFG","iso_n3":"004","un_a3":"004","wb_a2":"AF","wb_a3":"AFG","woe_id":-99,"adm0_a3_is":"AFG","adm0_a3_us":"AFG","adm0_a3_un":-99,"adm0_a3_wb":-99,"continent":"Asia","region_un":"Asia","subregion":"Southern Asia","region_wb":"South Asia","name_len":11,"long_len":11,"abbrev_len":4,"tiny":-99,"homepart":1},"geometry":{"type":"Polygon","coordinates":[[[61.210817091725744,35.650072333309225],[62.230651483005886,35.270663967422294],[62.98466230657661,35.40404083916762],[63.19353844590035,35.857165635718914],[63.98289594915871,36.0079574651466],[64.5464791197339,36.31207326918427],[64.7461051776774,37.111817735333304],[65.58894778835784,37.30521678318564],[65.74563073106683,37.66116404881207],[66.21738488145934,37.39379018813392],[66.51860680528867,37.36278432875879],[67.07578209825962,37.35614390720929],[67.82999962755952,37.144994004864685],[68.13556237170138,37.02311513930431],[68.85944583524594,37.344335842430596],[69.19627282092438,37.15114350030743],[69.51878543485796,37.60899669041342],[70.11657840361033,37.58822276463209],[70.27057417184014,37.735164699854025],[70.3763041523093,38.13839590102752],[70.80682050973289,38.486281643216415],[71.34813113799026,38.25890534113216],[71.23940392444817,37.953265082341886],[71.54191775908478,37.905774441065645],[71.44869347523024,37.06564484308052],[71.8446382994506,36.73817129164692],[72.1930408059624,36.948287665345674],[72.63688968291729,37.047558091778356],[73.26005577992501,37.495256862939],[73.9486959166465,37.4215662704908],[74.98000247589542,37.419990139305895],[75.15802778514092,37.13303091078912],[74.57589277537298,37.02084137628346],[74.06755171091783,36.83617564548845],[72.92002485544447,36.72000702569632],[71.84629194528392,36.50994232842986],[71.26234826038575,36.074387518857804],[71.49876793812109,35.650563259416],[71.61307620635071,35.153203436822864],[71.11501875192164,34.733125718722235],[71.15677330921346,34.34891144463215],[70.8818030129884,33.98885590263852],[69.9305432473596,34.02012014417511],[70.3235941913716,33.35853261975839],[69.68714725126486,33.105498969041236],[69.26252200712256,32.5019440780883],[69.31776411324256,31.901412258424443],[68.92667687365767,31.620189113892067],[68.55693200060932,31.713310044882018],[67.79268924344478,31.58293040620963],[67.68339358914747,31.30315420178142],[66.93889122911847,31.304911200479353],[66.38145755398602,30.738899237586452],[66.34647260932442,29.887943427036177],[65.0468620136161,29.472180691031905],[64.35041873561852,29.560030625928093],[64.14800215033125,29.340819200145972],[63.55026085801117,29.468330796826166],[62.54985680527278,29.31857249604431],[60.87424848820879,29.829238999952608],[61.781221551363444,30.735850328081238],[61.69931440618083,31.379506130492672],[60.94194461451113,31.548074652628753],[60.863654819588966,32.18291962333443],[60.536077915290775,32.98126882581157],[60.963700392506006,33.52883230237626],[60.52842980331158,33.676446031218006],[60.80319339380745,34.40410187431986],[61.210817091725744,35.650072333309225]]]}},
....
]
}
console.log(data);
line in your code after the call for the data to view your dataset in the browser. So you get:
//Call the geojson data
d3.json("world.geojson", function(json) {
//view the data
console.log(json);
//Bind data and create one path per GeoJSON feature
layerWorld.selectAll("path")
.data(json.features)
.enter()
...
Web console
tab. Here you will see your Object printed.
- Click with your right mouse button, choose :
Inspect Element
- Or Press F12
The GeoJSON FeatureCollection contains Features which each exist out of properties and a geometry.
We can use these attributes to style the map. Let's try to make a Choropleth out of our world map.
To make a color scheme we need an extra d3 package. The scale-chromatic library. This contains several color scales. Have a look at https://github.com/d3/d3-scale-chromatic for all the possibilities!
<head>
of your index.html
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
var color = d3.scaleThreshold()
.domain(d3.range(0, 8))
.range(d3.schemeBlues[8]);
ℹ️ the .domain
is the data range, the attribute we use only has values from 0 to 8. Note! If you take another attribute you should also adjust the domain accordingly!
ℹ️ the .range
is the color range. We use the Blue schema with 8 steps.
ℹ️ The d3.scaleTreshold()
function converts our domain to our range. Here it is exactly the same, but your domain can be much bigger or smaller. The threshold scale allows you to specify arbitrary breaks in continuous data.
Have a look at https://github.com/d3/d3-scale for all the D3 scales available!
.style("fill", "#313030")
to:
.style("fill", function(d){
return color(d.properties.mapcolor7)
})
Do you notice that our mouse-out action resets the color of the countries to grey again?
➡️ Continue to D3 step 3 if you feel really confident! If you are almost running out of time it might be nice to spend the last bit of the workshop on putting your map on-line! Go to the Hosting on Github to learn how!