by jsoma

jsoma / mapsheet

Easily create interactive maps from data in Google Spreadsheets. Supports Google Maps, Leaflet, Mapb...

208 Stars 49 Forks Last release: Not found 34 Commits 0 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:


Mapsheet.js makes an interactive map out of a Google Spreadsheet. It depends on Tabletop.js and whatever map provider you're using (supports Leaflet, Google Maps, Mapbox (which is basically Leaflet!), and MapQuest).

It is also dead simple.

Optional but fun: Mapsheet supports Handlebars for info window templates.

So how do I do this?

First, you make a published Google Spreadsheet. You can find out how to do this in the Tabletop docs. The only columns you actually need are latitude and longitude. We're also friendly enough to allow lat, lng, long, any probably anything else you can think of.

A pretty full-fledged example might be: let's say you have some restaurants you'd like to map, and you want some info to show up in a popup when you click on the marker. Here goes nothing:

<!-- We'll need to include Google Maps, Handlebars for templating, and jQuery for general futzing about -->
<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>

<!-- Tabletop.js for accessing Google Spreadsheets and Mapsheet.js for mapping, of course -->
<script type="text/javascript" src="tabletop.js"></script>
<script type="text/javascript" src="mapsheet.js"></script>

<!-- This is where the map will go -->
<div id="map"></div>

<!-- Let's make the map not too big -->
  #map {
    width: 600px;
    height: 500px;

<!-- This is the popup you'll get when you click a marker. 
     {{these}} are columns in your spreadsheet -->
<script id="popup-template" type="text/x-handlebars-template">
  <img src="{{image}}">
  <p>{{location}} in {{neighborhood}}</p>

<!-- Okay, time to do this! -->
<script type="text/javascript">
  $(document).ready( function() {       
    // Make sure the spreadsheet is published!
    var published_spreadsheet_url = ''; 

    // Let's get the popup template and compile it using Handlebars
    var source   = $("#popup-template").html();
    var template = Handlebars.compile(source);

    // OK, now let's make the map
    var map = Mapsheet({
      key: published_spreadsheet_url,
      element: "map",
      popupTemplate: template

Most of the code is just including libraries! And if you'd like to map pet stores or murder scenes instead? Just make a different spreadsheet, change the URL, and edit the popup template. Voila: a brand new map.


The Moving Parts

Mapsheet itself

Initialization options

When you initialize Mapsheet you have plenty of options to pick through.

are the only two required parameters, though! I've tried to note the ones that are provider-specific.

is the URL to the published Google Spreadsheet you're dealing with

is the id of the element that's going to become the map. You can also pass in an element.

is a callback for when a marker is clicked. this is the default this, the first parameter is the event and the second is the Mapsheet.Point (check the examples!)

is an array of columns to display in the info window if you don't feel like using a template. Check the examples!

is the map, if you feel like rendering it without using a Mapsheet provider.

is a function that returns content for the info window popup. It's passed the Tabletop model for the given row. It overrides both

is the id of a Handlebars template that will be used for the info window that pops up when you click the marker on the map. You can also provider the compiled template instead.

is the provider of the map service. I detail the providers a bit more below, but your options are

are passed through to the marker, and are used for things like specifying marker shadows and other very-specific-to-the-provider details.

is the column that you'd like to use as the title of the point (e.g., the name of the place). This is only important if using
, or if you want hover effects for MapQuest or Google.

is the callback for when the map has been successfully drawn. It will be passed two objects: the mapsheet object and the tabletop object. See the Tabletop.js docs if you'd like more info on that part.

provides the context of the callback, if necessary.

passes right through to Tabletop.

is the layer that you'd like to render your markers on (not supported by Google)

are options passed passed to the marker layer if you want a custom backing map, or specify attribution, etc (Leaflet only)


is the rendered map

is an array of Mapsheet.Point objects



is the Tabletop model of the row the marker is associated with

is the longitude, pulled from a column named

is the latitude, pulled from a column named

gets the title of the marker - this column is set through

gives you the marker's
[ lat, lng ]

returns the value of the given column. Not that it matters to you, but: Multi-word and capitalized things, like 'Web URL' are fixed up in an attempt to successfully read from tabletop, i.e. converted into lowercase with spaces removed (
turns into

, or
to create content for the info window popup

returns true if latitude() and longitude() both return valid floats

returns the raw marker (from Google or MapQuest etc)


Must respond to


Their constructor sets up the options,

draws the map, and
puts the points on it and auto-fits the zoom and bounds.


Google Maps as


Leaflet (using MapQuest tiles by default, but supports CloudMade, etc) as

(be sure to include the CSS)

MapBox as


MapQuest as


Customizing Your Map

Styling info windows

All of the info boxes live inside of a

, so feel free to apply styles to
.mapsheet-popup h3
, etc

Customizing the map itself (roads, water, etc)

You'll need to pick a provider that allows map customization

CloudMade has a billion styles over at their map style editor, you'll just have to check out the

example. You need an API key, but it ain't tough beyond that.

MapBox could also work for you, especially if you have a lot of stuff going on.

Custom Markers

I think it's really stupid that, generally speaking, providers make it so tough to have custom-colored markers. So I tried to make it easy!

Custom markers are supported for Google Maps, Leaflet, and MapBox (to varying degrees).


Custom color: Add a

hex color
column in your spreadsheet to customize the color of each marker.

Custom icon: If you want to an specify icon for each point, add an

icon url
column in your spreadsheet. You'll probably want to make it the full path, i.e.

Custom default icon: If want every point to have the same marker, just not the default, you can pass a default icon URL through

, typically as

Custom icon + shadows: Check the

example, it's complicated.

Provider support

Google Maps: custom colors, custom icons, custom default icon

MapBox: custom icons

Leaflet: custom icons, custom icons + shadows, custom default icon

General notes on using colored/custom icons

If you're unsure of what hex colors are, pop on over to or Wikipedia - they're just strings of numbers/letters like FF36A2 that end up as colors.*

When you customize your icons using Leaflet, you'll probably want to pass some

as well to make sure everything lines up nicely.
markerOptions: { iconSize: [32, 37], iconAnchor: [16, 37] }
works for the icons from the Map Icons Collection. Read more on the Leaflet site.

Using other Leaflet tile providers

Leaflet defaults to serving tiles from MapQuest, because it's free, and doesn't require an API key. If you'd like to use CloudMade or something instead, you'll need to make some changes. You'll need to pass in a mapOptions along the lines of the following

    mapOptions: {
        subdomains: 'abc',
        tilePath: 'http://{s}{apikey}/{styleId}/256/{z}/{x}/{y}.png',
        styleId: 1930,
        apikey: 'Your CloudMade API Key',
        attribution: 'An appropriate credit line without MapQuest'

And then you should be all set!


There are a lot of examples in

, check them out!

If you're looking for the least complicated one, check out

. It isn't too customizable but it gets the job done.
is the zaniest of the bunch.



Hi, I'm Jonathan Soma. I run the Brooklyn Brainery, and make all sorts of nonsense.


Fix up the docs to actually be nice and pleasant

Don't show popups if there's no content in the popup

Replace the sample map with some quality, dedicated sample maps

Callbacks callbacks everywhere

Notes about styling your infoboxes

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.