An Internet Expedition (or what I learned navigating a New York Times graphic's source code) / by Becca Barton

The best way to learn how to do something is to study the work of the greats. Today, we're going on an expedition through the New York Times' source code. Grab your tools, and let's get started.


Our map.

Our map.

Part I: A Quick Survey of the DOM

A quick scan of our map shows a typical breakdown: meta tags at the top, some CSS thrown in, followed by some HTML. For the purposes of making this journey concise and expedient, we're going to be mainly venturing through the script in the document. This means we'll be treating the meta tags and social media and Google Analytics like the far-out corners of the map: you're probably not going to need to know the exact terrain, but it's nice to know that they're there.

Moving on, we hit our basic setup in the DOM. Open up the link of our map, and inspect element. Hovering over each element will give us a good idea of what all these pieces are doing. We can see that the header is one element, the graphic is another, and the footer is, fittingly, the end element. Keep exploring the layout of the land, and when you're ready, we'll move on to the meat of the expedition.

Part II: Exploring All Our Routes

Starting out in the source code, let's start with the fun part: clicking on any link that looks like it might have a trailmarker. How will you know what's down a trail if you don't explore it? Starting in the footer, clicking on the first link leads us to the source for the base of the whole graphic: the data. We can see that this graphic's data is coming from the U.S. Census Bureau— pretty trustworthy, and it's worth knowing where all the data's coming from. 

Skipping down to the script source links, the first link shows they're using Google Maps API, which is, mercifully, pretty well-documented. Note the specification in the API url here: libraries is set to geometry. According to the Google Maps documentation, using a setting of geometry adds built-in functions to calculate geometric values, including geographic area. This gives us a clue that they may be adding shapes on top of the map Google's API returns, and a quick check back at our map confirms this, with the area lines for the 'Percentage below poverty' graph, and the circles for the 'Number living below poverty' map. 

Next, we see two script sources linking to different parts of the poverty map, one to the map.js, and one to a lib.js. Looking at lib.js first, we can tell at first glance that it is very, very long, and we are not going to be able to make it to the end of the trail and back before sundown. But the first word gives us a hint: d3 is set up as a constructor, with many functions inside. This tells us that the graphic is using D3, the data-visualization javascript library. Also, this file is not wrapped in a document ready function, meaning that, as its name would suggest, this is a supplemental library file that the other javascript files in the graphic are pulling from.

Switching gears to maps.js, we can see this whole document is wrapped in a (function(){});, meaning it's ready to start firing as soon as the document is ready and loaded. As a quick sidetrack, note on line 7 the (RegExp.$1). According to Mozilla's JavaScript documentation, this nifty method will accept any number 1-9, preceded by a $, and in return will give back one of the nine most recently memorized items from RegExp pattern matching. Not really pertinent to what we're looking at, but much like taking time to identify the name of a tree, it's fun information to tuck into your back pocket.

Part III: Heading Deeper Into the Forest

We're really in the thick of it now. Still on map.js, this is another case of a long trail we're not going to make it back from in time. But a quick scan shows some interesting helper methods being setup here: a constructor called Waiter is setup with some prototype methods to help it wait around on objects in the program until they're ready. A few take an argument of ctx, which according to the experts over at Stack Overflow means 'context', and is usually used to pass around in a program to help maintain state, as opposed to global variables.

A quick overview of some other things happening: This document is setting up a lot of JavaScript objects that are adding some important basic functionality to the program. There are objects changing the CSS based on the state, one to load scripts, a data table object aptly named DataTable, and constructors setting up different document reactions to mouse events. 

This has been fun, but we need to head back to the main trail. Back in the source code underneath the footer, there's more JavaScript to explore. Starting from the beginning, they're setting the variable selected up to the previously defined constant CITY_DATA, which will help swap out the location data depending on which city's map the user clicks on to view. 

Next, a variable slug is set up to normalize text that's being passed in as an argument to a function. From the regex used here, it looks as though it's trying to eliminate any characters that aren't letter characters and then lowercase the result.

The next variable, cities, is calling on the d3 library and selecting elements in the DOM with an id of 'g-cities', and a class of 'g-city'. From here, the following few lines are appending HTML to the cities variable. What this all really appears to be doing is setting up a way to swap out all of the data depending on which city map is currently selected. We can also see that they're using slug to set up a unique link to an image depending on which city's map has been selected. So RESTful!

Now that the city url has been appended, an event is set up to listen for any clicks on cities in the DOM. Once clicked, a function that zooms into the currently set latitude and longitude fires, based on where the user's mouse is. This is a part of D3's library, and it's pretty neat. If you're interested in learning more, checkout this visual.

A variable called selection is pointed toward this (in this case, buttons, which is what's calling this function). 'id' is set to point toward anything in this that has the attribute 'data-id'.  Next a function toggle is called, and if we take a quick peek ahead on the map, we can see that that function is being defined just a few lines below. 

Normally when we encounter toggle in the wild, it behaves by, well, toggling between hiding and showing the selected element. The one we see here in the New York Times' code is a slightly different beast. This one works by taking the buttons and keys and returning a boolean value depending on whether the value of their attribute 'data-id' matches id or not. Then, depending on the size of the window, a certain image is returned for the map.

Looking ahead, we see a try/catch statement, which is a classic JavaScript way to try out some code and catch certain data if an exception is thrown during the execution of the try block. Here, the try block is checking to see if location data is available, and if not, catching the error event. If it is, the map zooms to the location given the latitude and longitude found during the execution of the try block. Also interesting to note is it's using decodeURIComponent, a JS method that takes a piece of previously encoded information and outputs the decoded (read: pretty) translation. For example, you know when you see a %20 in a url to indicate there's a space there?  That's the encoded version. The decoded version would read with the spaces, as in "personal space".

Part IV: The End of Our Journey

At long last, we've come to the sweet, sweet end of the trail. We saw a whole lot of code here today, some setting up mouse event functions, some setting up conditions to swap out images, and some setting variables for D3. And while we didn't go to the end of every trail and back, much like a typical hike, simply exploring the main trail and taking a quick peek down the side trails gave us more than enough to explore. We saw some interesting sites and learned some useful things today, so go ahead and head home with the pride that you now know a little bit more about the wilderness that is someone else's source code today.