Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does it mean to scale a projection in d3?

I know that in D3, scales are mathematical maps from input data values (domain) to output data values (range). I know that I can set up a scale that will map input from the domain onto a range, like this:

var scale = d3.scale.linear().domain([100, 500])
.range([10, 350]);
scale(100); //Returns 10

I know that once you setup a scale, you can use it to scale attributes, like this:

.attr("cx", function(d) {
return scale(d[0]); //Returns scaled value
})

However, on Bostock's mapping tutorial scale is used a little differently. Bostock calls scale on whatever is returned by the mercator projection:

var projection = d3.geo.mercator()
    .scale(500)
    .translate([width / 2, height / 2]);

I am trying to understand that line of code and having a little trouble. mercator() returns something -- which is not so clear from the API -- and then the scale method is called on that object with an input value of 500.

What does it mean to call "scale" on a projection like this? How does this relate to scale() as a way to transform 100 in 10 -- as in the example above.

More immediately, if I add this to my code, my geojson map disappears! How do I make it scale properly?

var projection = d3.geo.mercator()
    .scale(500)
    .translate([width / 2, height / 2]);

var path = d3.geo.path()
    .projection(projection); //if I add this little bit to the path, my map disappears!

Here is the GeoJSON I am using: http://geojson.io/#id=gist:AbeHandler/9d28239c592c6b552212&map=10/29.9912/-89.9320

like image 959
bernie2436 Avatar asked Feb 04 '14 23:02

bernie2436


1 Answers

In this case, scale is used in the general sense of the size of something. It's not directly related to the d3 scale functions, but is related to the scale transforms you can apply to an SVG element to make it bigger or smaller. However, instead of scaling a flat drawing, it scales the complex projection.

The projection returned by d3.geo.mercator() is a function. Specifically, it's a function that converts from a longitude/latitude point to an x/y point.

Similarly, the function returned by d3.geo.path() converts GeoJSON data into SVG path definitions. When you assign a modify this function by assigning it a specific projection function, it will use that projection to figure out the position of each point on the path it creates.

Now, why are you not seeing anything at all when you assign a scaled-up projection to your path? It is probably simply that you are so zoomed-in that there is nothing to see: you're lost in empty ocean. The default scale factor on a projection is 150, so a scale of 500 is more than three times zoomed in. Try different scale factors, some bigger and some smaller than 150, to zoom in and out of the map.

Of course, the translation could also be throwing off your map. The translation parameter sets the x/y value for the center (latitude/longitude) point of your map. If you don't specify what you want to use as a center point, the projection uses 0 degrees latitude and 0 degrees longitude. If the geography you're trying to draw is nowhere near that point (which is in the Gulf of Guinea, off the coast of Ghana), then once again nothing is going to show up unless you zoom out considerably (i.e., use a very small scale number).

like image 97
AmeliaBR Avatar answered Oct 07 '22 07:10

AmeliaBR