Advanced Map Exploration


Maps are great on a dashboard. Why? Well, the brain can easily decode a map as all the data is visual, no text is needed to understand the data story. This is why I think maps should be used in Einstein Analytics. You probably already know that Einstein Analytics comes with some out of the box maps you can use, which is of countries and US states. These maps work very well in most cases, but some times you may want to switch the map depending on what area of the world you want to look at, a use case I looked at previously. But what if you want to be able to drill down into a certain state or country and look at a more detailed view? Well, this use case demands a little more development, but it is possible (just see below).

Overview of the solution

What we will end up with, as you can see from the image, is a state map where we can select a state and the map to the left changes based on the selection. In order to do this, we obviously need two steps; one that groups by state and another that groups by city. As you probably guessed we need to bind the selection from the state map to the map parameter of the second widget. As we cannot control the API name of the custom map, we will need to have this detail available somewhere. Therefore, we first need to add this information to the dataset where after we can use this as a grouping in a hidden step. If it sounds complicated, don’t worry I will go through it step by step.

Custom Maps

In order to have this advanced state (or country) exploration, we need to introduce some custom maps. As you may know, we do not have individual state maps, so we do need to create and import these maps, which can be a larger exercise. Personally I always check out this page to see if there are any GeoJSON files that works for what I am trying to do. Most times there is a little work to be done before you can import the file, but in this use case, I have made the files I am using available for you to try out.

California Map

Illinois Map

Texas Map

Once you have downloaded these maps it’s time for you to import the maps into Einstein Analytics. Choose to open any dataset you have in Analytics Studio and group by any dimension.

Next, you need to choose map as the chart to use for your lens, which is done by clicking the chart symbol on the right side of the explorer and clicking the map chart.

By default, you will see the world map, but we want to use a custom map. To do this choose the paint roller on the right-hand-side to show the formatting options. In the ‘Map’ section next to ‘Map Type’ you will see a little + sign, which is where we can import our custom maps. If you do not see this + sign make sure you have the permission in the permission set that is assigned to your user.

So click the + to open the dialog box for creating custom maps. We now need to import the first file by clicking the ‘Upload GeoJSON’ button – you can pick any of the GeoJSON files that you have downloaded, I’ll import Illinois, give it a name and save it.

This action has only imported the GeoJSON file it has not made it available for end users to select it as a map type, so on the left-hand-side make sure to give your new Illinois map a name like “IL’, select the projection type ‘Equirectangular’ and click ‘Done’.

Your new custom map should now be used in the lens you created. Now unless your dataset contains a column with the same values as in the map, your map will not show any data. However, for what we need to do now it does not matter. So switch to the JSON by typing cmd+E (Mac) or ctrl+E (PC). If you enter cmd+F (Mac) or ctrl+F (PC) you will be able to search for the ‘map’ parameter. Make sure to copy the id and save the custom map id somewhere where you can find it again; in my case, the id for Illinois is ‘Custom: map_1554240882300’.

You will need to do repeat this exercise for all the custom maps you need.

Get the data right

In order to automatically drill down into the map, we need to have a dataset that contains a measure, the state, the city, the custom map id, and the projection type. Now most likely you will get the first three fields from Salesforce, but the latter two you need to create manually and add to your dataset based on the state. Hence if I have a row that is a city in California then the custom map should be that of California – see example below.

As you can see in my very simple dataset I have the fields I need to create my two steps used for my maps, but I also have the matching custom map. Hence, where the state is Illinois I have a column ‘Map’ that gives the value of the custom map name and there is also a column that contains the projection type of the map or the ‘MapType’ which in my case is ‘Equirectangular’ for all custom maps.

Now in my example, I have just created a sample csv file containing a few rows and imported the file as a dataset in Analytics Studio. In reality, you don’t want to have to do this. The best way to tackle this would be to create a csv file containing ‘State’, ‘Map’ and ‘MapType’, which you import into Analytics Studio. Once you have this new dataset you can add this information in a dataflow or recipe. This particular exercise I will not cover in this blog, but if you are doing this in the dataflow this csv file would be the right side of an augment using ‘State’ as the key. If you are using a recipe it’s a simple ‘Add Data’ function and again use ‘State’ as the key.

If you just want to try this in your developer org here is my csv file. Just remember to rename ‘aaa’ with your California map id, ‘bbb’ with your Illinois map id and ‘ccc’ with your Texas id.

Build your steps

First thing to do is to create the dashboard and add the two map steps. The “State Map” step is a simple step that has sum of ‘Measure’ and grouped by ‘State’.

The next step is what I call the 1State map, which has sum of ‘Measure’ and is grouped by ‘City’. This map is utilizing the Illinois custom map we imported.

Finally, we need our hidden step that includes our ‘State’, ‘Map’ and ‘MapType’. So create another step that is grouped by these three dimensions. The measure can be kept as count of rows, as we don’t really need that value.

As mentioned this is a hidden step, so you do not need to add this step to the canvas, however, if you find it useful to see it works, then you can show it temporarily.

Adding bindings

Now we have come to the dynamic part; creating the binding on the widget that uses the custom map. So we need to jump into the Dashboard JSON. The easiest way to find the widget we need is by searching for the step name (in my case ‘1State_1’) and when you find “step”: “1State_1” that’s the widget you need to modify. My widget is shown below and what we care to find is the ‘Map’ and the ‘projectionType’ parameters, which I have highlighted.

"chart_2": {
"type": "chart",
"parameters": {
"visualizationType": "choropleth",
"autoFitMode": "keepLabels",
"theme": "wave",
"title": {
"label": "",
"fontSize": 14,
"subtitleLabel": "",
"subtitleFontSize": 11,
"align": "center"
"binValues": false,
"bins": {
"breakpoints": {
"low": 0,
"high": 100
"bands": {
"low": {
"label": "",
"color": "#B22222"
"medium": {
"label": "",
"color": "#ffa500"
"high": {
"label": "",
"color": "#008000"
"legend": {
"show": true,
"showHeader": true,
"inside": false,
"descOrder": false,
"position": "right-top",
"customSize": "auto"
"tooltip": {
"customizeTooltip": false,
"showDimensions": true,
"dimensions": "",
"showMeasures": true,
"measures": "",
"showPercentage": true,
"showNullValues": true,
"showBinLabel": true
"trellis": {
"enable": false,
"showGridLines": true,
"flipLabels": false,
"type": "x",
"chartsPerLine": 4,
"size": [
"applyConditionalFormatting": true,
"showActionMenu": true,
"map": "Custom: map_1554240882300",
"autoZoom": false,
"projectionType": "Equirectangular",
"lowColor": "#C5DBF7",
"highColor": "#1674D9",
"step": "1State_1",
"exploreLink": true

Once you have found the ‘map’ parameter you can add your binding in looking at the Hidden step and the value of the ‘Map’ column. The binding is a result binding and it will look something like this:

"map": "{{cell(Hidden_1.result, 0, "Map").asString()}}",

Next, we need to add the binding to the ‘projectionType’ parameter. Just as with the binding above we need to look at the hidden step but the column will be the ‘MapType. In the end, your binding should look like this:

"projectionType": "{{cell(Hidden_1.result, 0, "MapType").asString()}}",

And that’s it, you have now applied advanced drill down for your map. Make sure to test it works for you and then you can remove the hidden step from the canvas, but of course still keep it hidden in the background.

To be honest, if you are using Equirectangular as your projection type everywhere you do not need to bind this value or to add it to your dataset, but I like to keep the option of mixing the projection type.

Finishing up

This solution can also be applied to country, however, you need to group by country instead of state, which shouldn’t be a surprise. But as you can see in my example we are only allowing to drill down into three states, in real use cases you probably want to drill down into any of the US states. This is possible, but you would, of course, need to get a hold of a GeoJSON for all the states and then upload each one of them as a custom map and grab their id. It will be a little time consuming, but once it’s done it will look really cool.

How useful was this post?

Click on a star to rate useful the post is!

Written by

11 thoughts on “Advanced Map Exploration”

  • 1
    Feby on May 28, 2019 Reply

    Hi Rikke, I’m trying to make a country map exploration. Everything was created as you have explained above, but the 1StateMap it is showing only one custom map type and it is not changing as per my selection on StateMap. The hidden step is moving fine. What went wrong for my widget.

    • 2
      Alex on August 6, 2019 Reply

      Try to do the same on Chart JSON properties, not Step one’s.
      Faced the same. But then applied bindings to the same parameters on Widget, not Step.

      • 3
        Robert W Greaves on September 22, 2020 Reply

        Binding only the widget fails as well since both the step and the widget have the custom map property. And if you bind both then “Invalid Map” error appears where the map should be.

        I’m thinking this solution worked in a previous Einstein release, but it does not seem to work anymore.

        Any ideas?

  • 4
    Sreeram on July 25, 2019 Reply

    I am trying to build a dashboard to show the spread of Properties across the globe, identified by the Latitude-Longitude coordinates of the Property.
    Can I get the geoJSON of a World Map having Latitude-Longitude coordinates?

    Similarly, I would like a geoJSON for the Map of USA by Zipcode.

  • 5
    Sougata Paul on November 29, 2019 Reply

    Hi Rikki.
    Thanks for sharing such a good tutorial.
    I have a requirement where we have to show the state wise / City wise data for every state of USA. Can you please share me the link where can I get the GeoJson for all USA states ?

  • 6
    UKB on March 15, 2020 Reply

    HI Rikke,

    As you mentioned that we need to some changes to GeoJson file after downloading from this website:

    Question is what kind of changes that we need to do before uploading it to Einstein Analytics.

  • 7
    Mithilesh Dubey on March 31, 2020 Reply

    Hi Rikke,

    I’m trying to learn from you tutorial but not getting ‘+’ icon when trying to create custom map. is there any additional permission required to create custom map.

    Thanks for such a great blog. Awaiting your response.

    • 8
      Rikke on March 31, 2020 Reply

      Yes, it’s a permission for your permission set. I think is called something with create custom map.

      • 9
        Mithilesh Dubey on March 31, 2020 Reply

        Thanks for such a quick turn around Rikke. I got it sorted.

  • 10
    Shefali on September 2, 2021 Reply

    Hey Rikke! Thank You so much for this amazing blog!
    Also I am unable to delete some custom maps. It gives the error that it is used but they are not used any where.

    • 11
      Rikke on September 2, 2021 Reply

      Hi Shefali. Have a look at this blog.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.