Journocode: Marker Map mit leaflet.js

Showing locations on a map can be pretty cool to provide some context for your story or to give your reader an overview of where the story takes place. A good way to build a simple, yet responsive and professional looking map is to use the JavaScript library Leaflet.

In an earlier post, „Your first choropleth map„, we used Leaflet as well, but coded the map using the Leaflet R package, which works like a wrapper to translate the more common Leaflet functions into R syntax. It’s very useful if you’re more used to R syntax and don’t want to learn JavaScript anytime soon. But using the original JS library and coding the map with JavaScript will give us way more freedom when customizing the map, which is why we’ll try it that way today.

As an example, let’s start with a map of the locations of data journalism newsrooms in the German speaking area. This is what the finished map will look like:

Before we start, we need to pick a code editor. As we’ve discussed in our Intro to HTML, CSS and JavaScript, we could write our code in any text editor if we wanted. But its way nicer to work with an editor that helps us organize our code, that highlights the Syntax and helps with indentation and code completion. Most data journalists I know use Sublime or Atom. Atom is a project by the great guys from GitHub and it’s open source. I prefer using it, while Kira, for example, prefers Sublime because it’s better with larger datasets. Once you’ve set up your editor of choice, you can start right away.

Create a new folder named my_map. This is where we’re going to put all the files and code we need to build our first leaflet marker map. Now, go to your code editor and open a new file. Let’s save it as index.html. This file is where all the code we’ll write in JavaScript and CSS later will be put in it’s right place so it can work together to create our map. If you’re confused about any of this, take a quick look at part two of our intro post, where we discuss JavaScript libraries and file management.

When we’re all done, a simple double click on index.html will open a browser window showing us our map. Now, let’s build our map, file by file.

index.html

This file will provide a structure that our map can bind to so it has somewhere to display. We’re going to go over its content a little quicker in this post, since we’ve discussed the structure of HTML documents in our previous post.

We’ll start with a <html> tag that contains the entire content of our document. Between <head> tags we can include scripts, styles and meta information. In the meta tag we set the charset to utf-8 to include German umlauts (ä,ö,ü and ß) for our map like in Düsseldorf or Tröger.

With <link> we can source Leaflets CSS stylesheets from an URL. With <script> we include the JavaScript code of the library. If you copy and paste the URLs to your browser, you can have a look at all the code that’s in the library! Instead of including them via an URL, we could also save the entire content to a file and keep it locally in our my_map folder.

leaflet.css and leaflet.js are the default scripts and styles of a leaflet map. We can use the functions provided by those files to write our personal maps. We’ll save our code in additional files and source them between the <head> tags of the index.html file. When opening the index file in a browser, the default libraries and the files with our changes are loaded. This is why we’ll add a style.css and an app.js to the html document. We’ll create those in a minute.

Last but not least, we’ll add a div containing the map between the <body> tags. We’ll give it the ID map, which is the variable name we will pass to the JavaScript code in app.js so it knows where on the webpage to put the map. We add an onLoad event to the body, so the JavaScript is executed as soon as the page is loaded.

When you build more complex webpages, your index.html will probably contain a lot more elements. But for now, we want to create a page containing only the map, so our html file is ready. Save it in your my_map folder. If you doubleclick it, an empty browser window should open. There’s nothing there yet, of course, because we haven’t coded the actual map.

Custom marker icons

Before we get into starting the map, let’s create a folder named icons in our main folder. Because we’ll start with two location markers, we’ll add two custom markers I made with the design program sketch as png-files:

Everything we’ll code here has to be within the function myFunction() that we added as an onLoad event in the index.html. If you named it differently, use the name you chose here as well.

function myFunction() {
}

Next, we add the variable map. Here we set the default viewpoint and the background tiles. You can choose background tiles and get the code to change the settings here. The function setView() sets the default viewpoint and zoom level when the page is loaded. We’ve set it to 52.201675, 10.507759. If you look for that location in Google Maps, you’ll find yourself in Braunschweig, Germany.

Now save the changes and doubleclick index.html! Here you have your first customized marker map with leaflet.js. Congratulations! If that’s enough for you right now, that’s fine. In the last section, we’re going to take a look at how to automatically add multiple markers at once to your map.

Adding information to app.js with a loop

If you want to add more locations with custom markers and popup texts to a map, you might not want to code every icon and marker individually. There is a faster way to get this, even if it looks more complicated at first glance. But let’s give it a try!

We will now add some more of the data journalism newsrooms in Germany and Switzerland. First of all, add these additional custom markers to your icons folder:

Writing a loop isn’t that time saving when you only have seven locations to mark, like in this example. But imagine if you had a lot more points to add to the map: The manual way I showed above would be pretty exhausting.

Now for the data. Let’s say you have a .csv file with all the information on the different newsrooms we want to add to the map like this:

We have the longitude and latitude, the newsrooms name, the media company, the city, the newsroom’s head/leader and the path to the customized icon.

Now, JavaScript really likes its data saved as a JSON (JavaScript Object Notation) file. You can convert .csv files into .json files quite easily with free online tools, for example here. For now, simply download the data directly as a JSON file here and add it to the my_map folder. Open it and take a look around to get to know this data format if it’s new to you.

Next, we need to add the library jquery to our index.html to deal with the JSON data:

Save the file and open app.js. Delete everything from // create custom marker to var popup = L.popup();. Instead, we are going to load the JSON file and loop through it. Journocoder Sakander Zirai showed me this trick to load the JSON data as soon as the rest of the page is loaded:

When the data from the JSON file is loaded, we want a function called processData() to be executed, like we specified in the success attribute above. It doesn’t exist yet, so let’s write it!

We can loop through the information in the JSON file with a for loop. You may remember for loops from our tutorials on R. They may look a little different in JavaScript, but they’re quite similar to the R for loops in how they work. So let’s start our loop:

var customicon = L.icon({
// the iconUrl is now the ith element in data.icon
iconUrl: data.icon,
iconSize: [52, 60], // size of the icon
iconAnchor: [26, 60], // point of the icon which will correspond to marker's location
popupAnchor: [0, -60] // point of the icon where the popup window will open
});

Now, because we have two icons with different orientations (SRF.png and Zeit.png) in our data, we add an if-statement to the loop to customize the icon settings if the company names match these two:

Now doubleclick on your index.html again and you’ll see your map! You can now add as many markers as you like to your data!

Feel free to change the settings or scroll through the default leaflet css and js to see what functions you can customize. In order to show off your map, just upload my_map to your server and set the url path to the index.html.

Both maps are hosted on our GitHub page. If you have any problems, questions or feedback send us a message or leave a comment! It’s also useful to have a look at Leaflets documentation or to look for help on StackOverflow.