JRN-418

Data Journalism at CCSU, Fall 2015

Making a Leaflet.JS map from scratch

We've made maps using Google Fusion Table and CartoDB but now we're going to learn how to make one from scratch.

It's good to understand the mechanics of what programs like CartoDB or Silk is using to make their maps to see what's flexible and customizable in the future.

This tutorial will show you how to take a dataset with latitude and longitude columns, map it and style it using Leaflet.js, an open source Javascript library. It's extremely versatile for building many types of interactive maps.

Get the data

We'll be mapping out Dunkin' Donuts locations in Connecticut.

Download the dataset here.

Setting up the environment

Set up the HTML by creating a new file on your computer called leaflet.html and paste the code below in it.

The code above sets up the <html> and links to the leaflet.css and leaflet.js CDN files.

Next, we need to set up the div for where the map will appear and also the javascript to build the map.

Replace the code in leaflet.html with the code below.

Here's what the code above is doing:

var map = L.map('map').setView([41.651426, -72.690940], 8);

The line above sets the variable map and L.map('map') directs the function building the map to render in the div id map (Remember <div id="map"></div>?). The latitude and longitude within setView([]) is where the map should be centered and that's followed by 8 which is the level of zoom it should start at.

Beneath that is

    L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
    }).addTo(map);

So L.tileLayer sets the base layer tiles.

At the end, .addTo(map) pipes latitude, longitude, and zoom information in the variable map above it.

Save the file and open it in a browser.

Congratulations, you've coded a mapa> from scratch.

But we're just getting started. Let's add data to the map.

Adding a popup marker

Insert these lines of code between var map and L.tileLayer

    var marker = L.marker([41.763919, -72.681897]).addTo(map);
        marker.bindPopup("<b>Hello</b><br><a href='http://www.trendct.org'>-TrendCT.org</a>");

L.marker() is function for an icon on the map with the latitude and longitude.

And bindPopup is the HTML you want to appear in the pop up window when people click on it.

Here's what the code looks like

Here's how the marker looks

Adding many dots on a map

Let's get the data. Visit this link.

This is what the data looked like after I scraped it from the Dunkin' Donuts website.

But Leaflet needs these addresses to be translated to latitude and longitude.

To do that, you'll need to 1) concatenate the address, city, state, and zipcode columns into one new column and then 2) geocode the new column.

Here are some good services to geocode batches of addresses:

Batch Geocoding options

However, we can skip all that for now. Just click on the Formatted tab at the bottom.

I've already done the hard work for you.

OK, copy the data in the Formatted tab of the spreadsheet and paste it into the top window of Mr. Data Converter

Select JSON - Row Arrays in the Output as pulldown menu.

Copy the data output in the bottom window and paste it into your code above L.tilelayer.

Add var dlist = before it and add ; to the end.

This turns it into a Javascript array.

Next, delete the marker code we added before:

    var marker = L.marker([41.763919, -72.681897]).addTo(map);
        marker.bindPopup("<b>Hello</b><br><a href='http://www.trendct.org'>-TrendCT.org</a>");

And replace it with

for (var i = 0; i < dlist.length; i++) {
    circle = new L.circle([dlist[i][1],dlist[i][2]], 500, {
    fillOpacity: .8,
    color: '#ffa500',
    fillColor: '#ffa500',
    weight:3,
    radius:40,
    stroke: true
    })
    .bindPopup(dlist[i][0])
    .addTo(map);
    }

This is a loop function that will go through an array of data we just added var dlist and add a circle to the map after it finds the latitude and longitude in each row.

The options below circle are various styles like color and opacity and how big the circles will be.

Here are more options for styling circles.

Also, let's make the height of the map larger. Change #map to 400px.

        #map { height: 400px; }

This what your code should look like.

And here's the map!

Pretty cool, right?

I swapped out the tile link so it would make the orange pop out more.

Adding a legend

We're adding some additional CSS to the <style> section of the HTML.

This sets the dimensions of the box and the font size, as well as other things like padding and color.

Also in the <body> part of the HTML, we're adding a div for the legend to be rendered in.

This is that part of the code.

Adding all those lines of CSS and HTML looks like this.

The legend is in the bottom right corner.

And here's the complete code.