Make a choropleth map with Mapbox part 2: publish your style with Mapbox GL JS

In part 1, you styled US population density data in the Mapbox Studio style editor and published a new style. In part 2, you will make this style come to life with interactions using Mapbox GL JS.

View finished map.

How Mapbox Studio and Mapbox GL JS work together

In the last guide, you used the Mapbox Studio style editor to design your map and create a style. But what did the software actually produce when you clicked Publish?

What is a style?

The style is the most important part of making a web map: it contains all the rules for what features to draw on the web page and how to draw them. Both Mapbox Studio and Mapbox GL JS interact directly with your style: the Mapbox Studio style editor is a visual interface for creating the style, and Mapbox GL JS is used to add the style to a web page and interact with it directly by adding and changing the layers and sources in response to browser events.

A map style is a JSON object in the Mapbox Style Specification that contains all of the things the browser needs to draw your map correctly. Its main parts are:

  • sources: links to all of the data that will be styled on the map. When creating a style with the Mapbox Studio style editor, sources are raster and vector tilesets in your Mapbox account.
  • sprite: a link to all of the images and icons that are used in the style.
  • glyphs: a link to all of the fonts that are used in the style.
  • layers: a list of rules for how the data in sources should be displayed on the map.

When you added the population density data to your Mapbox Studio style in part 1, a link to it was also added to the list of sources in a style object (we normally just refer to these as “styles”). Similarly, when you added the population density layer and gave it styling rules for the each category of data, that layer was also added to the list of layers in your style.

Get started

Here’s what you need to get started:

  • An access token. You can find your access tokens on your account page.
  • The style URL for your style. This can be found on the share page for your style. (From your Styles page click on your population density style and then click Share & use.)
  • Mapbox GL JS. The Mapbox JavaScript API for building web maps.
  • A text editor. You’ll be writing HTML, CSS, and JavaScript after all.

Create a webpage

Open your text editor and create a file called index.html. Set up the document by adding Mapbox GL JS and its associated CSS file in the header.

<script src='https://api.mapbox.com/mapbox-gl-js/v0.33.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v0.33.1/mapbox-gl.css' rel='stylesheet' />

Next, markup the page to create a map container, an info box, and a legend.

<div id='map'></div>
<div class='map-overlay' id='features'><h2>US population density</h2><div id='pd'><p>Hover over a state!</p></div></div>
<div class='map-overlay' id='legend'></div>

You will also want to apply some CSS to visualize what the layout looks like. This is particularly important for the map div, which requires a height to be visualized on the page.

body {
  margin: 0;
  padding: 0;
}

h2,
h3 {
  margin: 10px;
  font-size: 1.2em;
}

h3 {
  font-size: 1em;
}

p {
  font-size: 0.85em;
  margin: 10px;
  text-align: left;
}

/**
* Create a position for the map
* on the page */
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

/**
* Set rules for how the map overlays
* (info box and legend) will be displayed
* on the page. */
.map-overlay {
  position: absolute;
  bottom: 0;
  right: 0;
  background: rgba(255, 255, 255, 0.8);
  margin-right: 20px;
  font-family: Arial, sans-serif;
  overflow: auto;
  border-radius: 3px;
}

#features {
  top: 0;
  height: 100px;
  margin-top: 20px;
  width: 250px;
}

#legend {
  padding: 10px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  line-height: 18px;
  height: 150px;
  margin-bottom: 40px;
  width: 100px;
}

.legend-key {
  display: inline-block;
  border-radius: 20%;
  width: 10px;
  height: 10px;
  margin-right: 5px;
}

View demo one.

Initialize map

Now that you’ve added structure to the page, you can start writing some JavaScript! First thing you’ll need to do is add your access token. Without this, the rest of the code will not work. Note: all of the following code should be between <script> tags.

mapboxgl.accessToken = '<your access token here>';

Now that you’ve added the structure of the page, you can add a map object into the map div. Be sure to replace your-style-url with the style URL for the style you created in part 1 of this guide – otherwise the code won’t work!

var map = new mapboxgl.Map({
  container: 'map', // container id
  style: 'your-style-url' // replace this with your style URL
});

View demo two.

Add additional information

With some projects, this is where you’d stop: you put a map on a page! But for this map, you will add two pieces of additional information that will make the map even more useful: a legend, and an information window that shows the population density for whatever state the cursor is hovering on.

The ‘load’ event

In order to make sure the rest of the code can execute, it need to live in a callback function that is executed when the map is finished loading.

map.on('load', function() {
  // the rest of the code will go in here
});

Create arrays of intervals and colors

Creating a list of the stops you used when styling your layer that contains state data will allow us to add a legend to our map in a later step.

Remember: this code goes inside of the load callback function!

var layers = ['0-10', '10-20', '20-50', '50-100', '100-200', '200-500', '500-1000', '1000+'];
var colors = ['#FFEDA0', '#FED976', '#FEB24C', '#FD8D3C', '#FC4E2A', '#E31A1C', '#BD0026', '#800026'];

Add a legend

The following code adds a legend to the map. To do so, it iterates through the list of layers you defined above and adds a legend element for each one based on the name of the layer and its color.

for (i = 0; i < layers.length; i++) {
  var layer = layers[i];
  var color = colors[i];
  var item = document.createElement('div');
  var key = document.createElement('span');
  key.className = 'legend-key';
  key.style.backgroundColor = color;

  var value = document.createElement('span');
  value.innerHTML = layer;
  item.appendChild(key);
  item.appendChild(value);
  legend.appendChild(item);
}

View demo three.

Add the info window

When the cursor is hovering over a state, the info window should show the population density information for that state. If the cursor is not hovering over a state, the info window should say, “Hover over a state!”

To do this, add a listener for the mousemove event, identify which state is at the location of the cursor if any, and update the info window.

map.on('mousemove', function(e) {
  var states = map.queryRenderedFeatures(e.point, {
    layers: ['statedata']
  });

  if (states.length > 0) {
    document.getElementById('pd').innerHTML = '<h3><strong>' + states[0].properties.name + '</strong></h3><p><strong><em>' + states[0].properties.density + '</strong> people per square mile</em></p>';
  } else {
    document.getElementById('pd').innerHTML = '<p>Hover over a state!</p>';
  }
});

View demo four.

Final touches

Almost done! A couple last little steps:

Cursor

Add a single line of code to give the map the default pointer cursor.

map.getCanvas().style.cursor = 'default';

Map bounds

Make sure the map shows the continental U.S. when it’s loaded by setting the bounds of the map on load:

map.fitBounds([[-133.2421875, 16.972741], [-47.63671875, 52.696361]]);

Mission complete

Check out your finished interactive choropleth map!

View finished map.

Nice job! For more things you can do with Mapbox Studio, check out the Mapbox Studio Manual. For more information on Mapbox GL JS and how it works, check out the Mapbox GL JS fundamentals guide.

Additional questions? Ask our support team or learn more about How Mapbox Works.