Code the World Part 3
At this point, we’ve used D3 to great a world map that looks like this:

It can even be rotated with the cursor. But wouldn’t it be nice if data could be plotted and visualized on the globe? That’s what we’re going to do. I’m going to assign a variable to a link that contains the data for the cities around the world that have Free Code Camp participants.
var fccCities ='https://raw.githubusercontent.com/samosale/fccCities/master/d3.geojson';Now we need to add that variable to our queue, place a second argument in our ready function, and create another variable inside the ready function to access the correct array in the json:
d3.queue()
.defer(d3.json, worldCoords)
.defer(d3.json, fccCities)
.await(ready)//add a second argument to the ready functionfunction ready (error, data, fccCities){ var countries = topojson.feature(data, data.objects.countries).features;var cities = fccCities.features; // right here!!
Next is to append a new path representing the data to the svg.
var points = svg.append('g');// create the variablepoints.selectAll('path.gt').data(cities)
.enter().append('path')
.attr('class', 'gt')
.attr("d", path)
.attr("fill", "#d8a61c")
.attr("fill-opacity",.9)
The globe is now populated with little, yellow dots. It should look like this:

Looks kind of cool…but wouldn’t it be nice if the size of the dot varied depending on the population of the city?
For that, we’ll need to take advantage of D3’s builit in pointRadius() function which returns a number and determines the size of the dot.
In order to make the dot return a size based on population size, we’ll need to write our own function to define the sizes and we’ll need to write a function to access the population key in the cities array.
Here’s our function defining the possible sizes. Notice that I divide the population by 100000 so that the dot size will be in proportion with the globe. I just picked this number based on preference.
function getRadius(pop) {
pop = pop / 100000;
if(pop === 0) return 1;
else if(pop < 5) return 2;
else if(pop < 10) return 5;
else if(pop < 50) return 8;
else if(pop < 100) return 10;
else if(pop < 200) return 20;
else return 30;}
Here’s adding that function to the points path:
points.selectAll('path.gt').data(cities)
.enter().append('path')
.attr('class', 'gt')
.attr("d", path.pointRadius(function(d){ return getRadius(+d.properties.population)})) // right here! the + is indicates that the return value is an int
.attr("fill", "#d8a61c")
.attr("fill-opacity",.9)So that whole section will look like this:
var points = svg.append('g');
function getRadius(pop) {
pop = pop / 100000;
if(pop === 0) return 1;
else if(pop < 5) return 2;
else if(pop < 10) return 5;
else if(pop < 50) return 8;
else if(pop < 100) return 10;
else if(pop < 200) return 20;
else return 30;}
points.selectAll('path.gt').data(cities)
.enter().append('path')
.attr('class', 'gt')
.attr("d", path.pointRadius(function(d){ return getRadius(+d.properties.population)}))
.attr("fill", "#d8a61c")
.attr("fill-opacity",.9)
That’s better:

One thing to note is to make sure that the I needed to add
svg.selectAll("path.gt").attr("d", path);to the “world” path. Without it, when the globe is dragged using the “world” path, the city dots will not drag with it.
One last thing for this part is to change up the css so that everything is a little more visible.
body {
background: #333333;
}
.water {
fill: #020021;;
cursor: pointer;
}.land {
fill: #666666;
stroke: #FFF;
stroke-width: 0.7px;
cursor: pointer;
}
And now the city dots are easier to view.

Here’s the codepen:
That’s it for part 3. In the part 4 — the final part — I’ll add a tool tip to each data point and zoom functionality.
