Icon map

Interactive icon map, suitable for small datasets. Use icons, images or emoji for your markers

Updated 5 years ago by Flourish team

How to use this template

Icon map templates

Allows you to quickly map a symbol map featuring icons from FontAwesome. The template creates a key which doubles as a filter so end users can click different categories of icons on or off.

Data requirements

All you need is a spreadsheet with a row for each item that you want to put on the map and columns for lat and long. To specify particular icons, first specify a category column in your main spreadsheet and then you can add styles for each category in the second sheet, as shown with the sample data.

You can optionally also specify additional columns in order to size the icons, show a title, description, image and other any other information in the popup.

Icon codes

When configuring an icon in the Icons data sheet, the easiest option is just to type in an emoji. However, you can also use any icon in FontAwesome 4. For a full list and search, see the FontAwesome site. You can use the full name (e.g. “fa-user”) or miss off the “fa” (e.g. “user”). The template also supports d3 symbols using this format: “d3-star”, “d3-cross”, etc.

Tips

  • The icons are drawn in the order of the spreadsheet, so sort your sheet to control the stacking order
  • When configuring an icon you can change the colour, opacity, outline colour
  • You can choose a different background map by pointing to a different map tile set (e.g. one of these)
  • The “Link” column setting lets you hyperlink from the markers to any webpage, but note that this will only work when published or previewing, not in the editor

Credits

This template uses Leaflet with – by default – basemap tiles created by Stamen Design.

This section documents API usage specific to this template, so for an introduction we suggest you refer to the generic API documentation instead.

template: _700

version: _5

Template data

There are three different formats in which you can supply data to this template. The most convenient for you to use likely depends on the source of your data, as described below.

1. Array of arrays, and a bindings object

You can supply arrays of arrays to opts.data, which might look like:

{
    data: {
        markers: [
            [ "MarkersColumn1Value1", "MarkersColumn2Value1",
            [ "MarkersColumn1Value2", "MarkersColumn2Value2",
            [ "MarkersColumn1Value3", "MarkersColumn2Value3",
            ...
        ],
        icons: [
            [ "IconsColumn1Value1", "IconsColumn2Value1",
            [ "IconsColumn1Value2", "IconsColumn2Value2",
            [ "IconsColumn1Value3", "IconsColumn2Value3",
            ...
        ]
    }
}

where each array of arrays represents the rows in a data sheet.

To tell the API how the values from each column should be associated with the keys that the template is expecting, you must also supply an object attached to opts.bindings. (The meanings of the keys in the bindings object are documented below.) The minimal bindings you can supply for this template are as shown in this example:

{
    template: "_700",
    version: "_5",
    bindings: {
        markers: {
            lat: 0, // index of a column in your data
            long: 1, // index of a column in your data
        },
        icons: {
            category_name: 0, // index of a column in your data
            icon: 1, // index of a column in your data
        }
    },
    data: {
        markers: [
            [ "MarkersColumn1Value1", "MarkersColumn2Value1",
            [ "MarkersColumn1Value2", "MarkersColumn2Value2",
            [ "MarkersColumn1Value3", "MarkersColumn2Value3",
            ...
        ],
        icons: [
            [ "IconsColumn1Value1", "IconsColumn2Value1",
            [ "IconsColumn1Value2", "IconsColumn2Value2",
            [ "IconsColumn1Value3", "IconsColumn2Value3",
            ...
        ]
    }
}

All possible bindings that you can supply are shown in this example:

{
    template: "_700",
    version: "_5",
    bindings: {
        markers: {
            lat: 0, // index of a column in your data
            long: 1, // index of a column in your data
            category: 2, // index of a column in your data
            name: 3, // index of a column in your data
            description: 4, // index of a column in your data
            image: 5, // index of a column in your data
            link: 6, // index of a column in your data
            size: 7, // index of a column in your data
            metadata: [8, 9, ...], // index(es) of column(s) in your data
        },
        icons: {
            category_name: 0, // index of a column in your data
            icon: 1, // index of a column in your data
            background_color: 2, // index of a column in your data
            background_padding: 3, // index of a column in your data
            size: 4, // index of a column in your data
            color: 5, // index of a column in your data
            opacity: 6, // index of a column in your data
            stroke_width: 7, // index of a column in your data
            stroke: 8, // index of a column in your data
        }
    },
    data: {
        markers: [
            [ "MarkersColumn1Value1", "MarkersColumn2Value1",
            [ "MarkersColumn1Value2", "MarkersColumn2Value2",
            [ "MarkersColumn1Value3", "MarkersColumn2Value3",
            ...
        ],
        icons: [
            [ "IconsColumn1Value1", "IconsColumn2Value1",
            [ "IconsColumn1Value2", "IconsColumn2Value2",
            [ "IconsColumn1Value3", "IconsColumn2Value3",
            ...
        ]
    }
}

2. Array of objects with arbitrary keys, and a bindings object

This format is most likely useful when you have data from an external source, such as CSV data loaded from d3-dsv. You should supply this attached to the opts.data, which might look like:

{
        markers: [
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            ...
        ],
        icons: [
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            ...
        ]
    }

... but with the keys being the column headers from your source data instead. You must also supply an object attached to opts.bindings. The minimal bindings you can supply for this template are as shown in this example:

{
    template: "_700",
    version: "_5",
    bindings: {
        markers: {
            lat: "MarkersHeader1",
            long: "MarkersHeader2",
        },
        icons: {
            category_name: "IconsHeader1",
            icon: "IconsHeader2",
        }
    },
    data: {
        markers: [
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            ...
        ],
        icons: [
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            ...
        ]
    }
}

All possible bindings that you can supply are shown in this example:

{
    template: "_700",
    version: "_5",
    bindings: {
        markers: {
            lat: "MarkersHeader1",
            long: "MarkersHeader2",
            category: "MarkersHeader3",
            name: "MarkersHeader4",
            description: "MarkersHeader5",
            image: "MarkersHeader6",
            link: "MarkersHeader7",
            size: "MarkersHeader8",
            metadata: ["MarkersHeader9", "MarkersHeader10", ...],
        },
        icons: {
            category_name: "IconsHeader1",
            icon: "IconsHeader2",
            background_color: "IconsHeader3",
            background_padding: "IconsHeader4",
            size: "IconsHeader5",
            color: "IconsHeader6",
            opacity: "IconsHeader7",
            stroke_width: "IconsHeader8",
            stroke: "IconsHeader9",
        }
    },
    data: {
        markers: [
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            { "MarkersHeader1": ..., "MarkersHeader2": ..., ... },
            ...
        ],
        icons: [
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            { "IconsHeader1": ..., "IconsHeader2": ..., ... },
            ...
        ]
    }
}

(As before, the keys containing "Header" would be replaced by column names from your data source.)

3. Array of objects with template-defined keys

There is an alternative format you can use, which is likely to be easier to use if your data is not from a spreadsheet source. With this alternative format you supply your data to the template as an array of objects, attached to opts.data, where the keys must be those used by the template, as documented below. In this case there is no need to supply a bindings object, since the key names are already those expected by the template. The required properties in the data object are as follows (scroll down for a description of what each property is):

{
    template: "_700",
    version: "_5",
    data: {
    markers: [
        {
            lat: ...,
            long: ...,
            metadata: [...]
        },
        ...
    ],
    icons: [
        {
            category_name: ...,
            icon: ...
        },
        ...
    ]
},
    ...
}

And the full list of all possible properties is as follows:

{
    template: "_700",
    version: "_5",
    data: {
    markers: [
        {
            lat: ...,
            long: ...,
            category: ...,
            name: ...,
            description: ...,
            image: ...,
            link: ...,
            size: ...,
            metadata: [...]
        },
        ...
    ],
    icons: [
        {
            category_name: ...,
            icon: ...,
            background_color: ...,
            background_padding: ...,
            size: ...,
            color: ...,
            opacity: ...,
            stroke_width: ...,
            stroke: ...
        },
        ...
    ]
},
    ...
}

Meanings of the template data keys:

  • markers.lat: lat
  • markers.long: long
  • markers.category: Category of place. Values should match the 'Category' column in the Icon styles sheet.
  • markers.name: Name of place, shown in popup
  • markers.description: Description of place, shown in popup
  • markers.image: Image, shown in popup
  • markers.link: Link to open when marker is clicked; works when published but not in the editor
  • markers.size: size
  • markers.metadata: Extra metadata to show in the popup. Add as many columns as you like
  • icons.category_name: Values should match the 'Category' column in the Places sheet, and should not be repeated.
  • icons.icon: The image for the marker. Can be a Font Awesome icon name, e.g. 'circle' or 'chevron-right'; a D3 SVG icon name, e.g. 'd3-star' or 'd3-cross'; an image URL; or an emoji.
  • icons.background_color: Background colour, e.g. '#fff' or 'red'
  • icons.background_padding: Background padding in pixels, e.g. 2
  • icons.size: Pixel size of the icon
  • icons.color: Colour of the icon - this can be a hex value like '#fff', or a web-safe value like 'red'
  • icons.opacity: Opacity of the icon between 0 and 1, e.g. 0.5
  • icons.stroke_width: Border width in pixels, e.g. 24
  • icons.stroke: Border colour, e.g. '#fff' or 'red'

Template settings

Options for opts.state.

Design

tint_fill color

Map tint.

tint_opacity number

Map tint opacity.

Max: 1

tiles_url string

Styles.

Allowed values:

  • https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png (Black & White)
  • https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png (Watercolour)
  • https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.png (Terrain)
  • other (Other)

tiles_opacity number

Opacity.

Max: 1

custom_tiles_url string

Custom tile url. Specify a url to a custom tileset, with {} as variables, eg. https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.png

custom_tiles_url_retina string

Custom tile url for retina (optional). Specify a url to a custom retina tileset that will be loaded on retina devices, with {} as variables, eg. https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}@2x.png

attribution string

Tiles attribution. Add the appropriate attribution for your map tiles

Map starting point

map_start_center_lat number

Latitude.

Min: -90

Max: 90

map_start_center_long number

Longitude.

Min: -180

Max: 180

map_zoom number

Zoom.

Max: 16

popup.show_popups boolean

Popups.

Allowed values:

  • true (Enabled)
  • false (Disabled)

popup.is_custom boolean

Popup contents.

Allowed values:

  • false (Auto)
  • true (Custom content)

popup.custom_template text

Popup content. The text to appear in the popup. You can use {{column_name}} to add a value from your data. It must be in a selected column, but you can add columns to “Metadata” if you just want to include them for use in the popup. Advanced users can include HTML to apply layouts, formatting, images, etc.

popup.show_pointer boolean

Pointer.

popup.show_shadow boolean

Shadow.

popup.style_popups boolean

Custom styling.

popup.text_color color

Text colour.

popup.align string

Alignment.

Allowed values:

  • left (fa-align-left)
  • center (fa-align-center)
  • right (fa-align-right)

popup.font_size number

Font size.

Min: 1

popup.fill_color color

Fill colour.

popup.opacity number

Fill opacity.

Max: 1

popup.padding number

Padding.

popup.border_radius number

Radius. Corner radius of popup

Legend

show_legend boolean

Show legend.

legend_title string

Title.

legend_background color

Background.

legend_opacity number

Opacity.

Max: 1

legend_textcolor color

Text color.

legend_size number

Icon size.

legend_showborder boolean

Show border.

Default icon styles

default_icon_icon string

Icon content. This will be used when nothing is specified in the data. Can be a letter, emoji or Font Awesome icon name

default_icon_size number

Size.

Max: 100

default_icon_fill color

Colour. Ignored for emoji

default_icon_background color

Background colour.

default_icon_opacity number

Opacity.

Max: 1

default_icon_background_padding number

Padding.

default_icon_stroke_width number

Border width.

default_icon_stroke color

Border colour.

default_icon_pointer_offset boolean

Add pointer to circle.

default_icon_category string

Category label.

enable_icon_random_offset boolean

Spread out icons with same coordinates. Useful, for example, to spread out markers positioned at the center of a postcode or zip code

icon_random_offset number

Offset in pixels.

Map limits

disable_zoom boolean

Disable zoom & panning.

map_min_lat number

Min lat.

map_max_lat number

Max lat.

map_min_long number

Min lng.

map_max_long number

Max lng.

map_min_zoom number

Min zoom level.

map_max_zoom number

Max zoom level.

Max: 20

Animations

pan_duration number

Animation duration. Speed of panning animation in story mode (in seconds)

Custom CSS (advanced)

css text

Custom CSS styles. Any CSS code entered here will be applied to the graphic, overriding the default styles

Number formatting

localization.input_decimal_separator string

Decimal separator in data sheet. Used for interpreting your data. Only change if data is not displaying on the chart as expected.

Allowed values:

  • . (.)
  • , (,)

localization.output_separators string

Number format to display. How the numbers should appear on chart labels

Allowed values:

  • ,. (12,235.67)
  • ., (12.345,67)
  • . (12235.67)
  • , (12345,67)
  • . (12 235.67)
  • , (12 345,67)