Skip to Content
Author's profile photo Michael Howles

Design Studio SDK (1.3/1.4) – Open Source Maps (Part 2) Choropleth Maps

For those who just want to know if they can download, yes!  This is open source free stuff available today by downloading the SCN Design Studio SDK Development Community package (preview build at this time.)


UPDATE – Part 3 blog is now up: SAP Design Studio SDK – Choropleth Maps Refined, Part 3

Details, Documentation, Thoughts follow:

I did a Part 1 on maps, which means I was obligated to at least do a Part 2, right?

To summarize, in Part 1, I talked about a Leaflet Maps approach with tile-based maps.  The (still quite buggy) SDK source I gave out took a marker-overlay approach to visualize data.  This came with its own Geocoding challenges that I tried to approach in a few different ways there.  I plan on revisiting this one day but there’s a lot of baggage with this component so I wanted to start over from scratch with the mapping attempt.

I continue to be a bigger and bigger fan of Mike Bostock and his D3 and Topojson examples.  Topojson works with DS to project map data onto an SVG or Canvas component (English: It draws vector maps.)  The format of this data is a latitude-longitude JSON format that is an extension of an already popular GeoJSON format.  The advantage of Topojson format is that it can reuse shared feature boundaries (United State’s northern border sharing the same as Canada’s, as an example) so the data size can be dramatically less than GeoJSON.  And fortunately, his Topojson code supports either format!

So what are vector maps good for?  They could probably serve as a pretty good foundation for a map for things like administrative boundaries, rivers, etc.  The map tiles I built in Part 1, were actually built from mostly these JSON vectors.  There’s a balance of how many vector layers you’d want to render in an SVG on the fly, so sometimes pre-rastering as tiles to make nice tile sets makes sense.  But I wanted to settle on just a feature layer that represents either countries or their state/region/provinces and then allow for a datasource’s view map to those features.  For example, if my dataset were this:

/wp-content/uploads/2015/02/c1_645113.png

I would want to take whatever dimension(s) is in the rows (State in this 2D depiction) and designate that as the geographic feature “key”.  The measures that follow obviously will be the data to visualize.

If you take a look at some of the Topojson examples you can see that Mike Bostock has some great (and many times mindblowingly exotic) visualizations.

Two ones I thought hard on were an Area Choropleth Map and a Bubble Map.  I decided to pick the first one as the second one probably could be borderline chartjunk but maybe I’ll go back and make this another option one day (or the Open Source Community can!)

So time for another picture:

/wp-content/uploads/2015/02/c2_645114.png

What we have here is a Choropleth map that is showing Sales 2010 Measure, with many properties on the right for reference.

First, some simple properties available in either the Default Properties panel or in Additional Properties Panel (illustrated above):

  • Measure to Color – Which Measure member you will be visualizing.  You can specify it by name or leave blank.  If you leave blank, the map will pick the first member in columns.
  • Legend Title – Title of Legend, if you leave blank, it will be the title of the Measure you are visualizing.
  • On Select – Fires a BIAL event for use in scripting
  • Animation Duration – Length of animated transitions
  • Display Globe/Display Graticule – Turns off the ocean/world sphere and the lat/lng gridlines.
  • Display Legend – Hides/Shows Legend
  • Display Tooltips – Hides/Shows Tooltips
  • Map Top/Left/Right/Bottom – Control the ‘plot area’ of the map.
  • Legend X/Y/Width/Scale – Controls size/positioning of vertical legend
  • Map Avoids Legend – Toggles whether Map automatically avoids overlap with legend
  • Horizontal Scale Left/Right/Bottom/Height – Control the size/positioning of the horizontal color scale
  • Land/Background/Hover Color – Self explanatory, (also you can control appearance using CSS as with other components.)

Now, some of the more interesting properties:

  • Colors and Color Scale – The amount of colors you chose dictate your Choropleth Scale.  (Shown in the legend on the left and the reference scale on the bottom) – The scale can either be quantile or quantize.  Non-statisticians can read a good summary of the difference of D3 scales here. An easy way to think of the difference of each scale is that quantize is an equal distribution of color, and as a result how colors are distributed on the map features.

    /wp-content/uploads/2015/02/c3_645115.png
    I also render a reference scale on the bottom so that you can quickly visualize proportionately how big each bucket is.  It also serves a purpose at runtime (more on this in a minute)

  • Projection method – The nice thing about vectors is they can be projected/transformed based in many ways whereas rastered map tiles are typically only available in Mercator form.  What are some examples of other projections?  Check here.  Illustrated below is how you can even transition this on the fly (click image if not animated)

    /wp-content/uploads/2015/02/c4a_645116.gif

  • Maps – GeoJSON/TopoJSON maps can be found in various places freely online, however many times it’s hard to know where to start.  Since this is a topic of its own, I’ve written a separate post (Design Studio SDK: How to create home-made map files for Choropleth Maps) with details on how you can create your OWN maps if you cannot find one in the right format, or if you want to maintain the map attributes that are stored in it, too.  A note about size, though… Design Studio will choke if you try to store properties that are too large.  I’ve found that TopoJSON/GeoJSON files can be easily simplified (see my other post above) down to 20-40k per map.  Design Studio handles this just fine.  I once tried to use a highly detailed 600k file and it choked, so be careful.

    However, I’ve done some example canned maps for you and included them in the component:

    /wp-content/uploads/2015/02/c5_645117.png
    In the ‘Mapping’ tab, we see under ‘Settings’ we have the ability to download a map to your component.  I emphasize the word download as the approach I’ve taken is to store the map as a property in the Design Studio application rather than linking to an online source that may be susceptible to networking or firewall issues outside of your control.

    If you note in the picture, there are two main categories – ‘Canned Maps’ and ‘SCN Community Maps’.  The canned maps are all contained as files local to the Additional Properties panel so while they are technically ‘downloaded’ from local resources, they are offline files.  The ‘SCN Community Maps’ is a work-in-progress approach that actually currently link to a GitHub Pages repository I’ve placed here (org-scn-design-studio-community/sdkcommunitymaps · GitHub) – You can even just visually browse this GitHub repository on your own and see how GitHub even shows you a mapping preview.

    /wp-content/uploads/2015/02/c6_645118.png
    A quick note – I am looking for better hosting solutions for these files than GitHub – Since these files are downloaded using AJAX/JSONP, there are bandwidth limits on how many requests per hour that it will serve up.  If anyone has a better free and reliable host to serve static content, please let me know and I’ll modify the entry to point to that location.  I’ve left it to Github-Pages repository for this initial release.

    And as for your own custom maps I mentioned, you can find the JSON tab to paste it here.

    /wp-content/uploads/2015/02/c7_645131.png

  • Map Attributes – Map attributes (shown in the GitHub screenshot above and in the JSON example above) are attributes (NAME_1, VARNAME_1, etc) specific to each feature.  This is where you can map this component property’s label attribute and also specify which attribute should be the matching “key” for your Dimension values.  The source I used for the provided maps almost always has a ‘NAME_1’ attribute which indicates the name of the country/region/etc.  Note, you will inevitably run into a situation where your data’s key or text does not match an existing attribute in the map.  Perhaps your data only give you ‘AL’ instead of ‘Alabama’.  This is where you have control of your downloaded copy of the map, simply change the JSON to match your keys!  There are even online free applications to make the job easier for you!

    There are several but one that I played with was http://geojson.io.  Example:

    /wp-content/uploads/2015/02/c8_645133.png
    As you can see, you get a table editor and visual map to work with.  You can also delete worthless columns such as ‘ID_0’, ‘ISO’, etc to cut down on file size.

    I’ve given a very primitive read-only table also that if you just need to ‘see’ what are in these attributes, you can do so for a quick check:

    /wp-content/uploads/2015/02/c9_645137.png
    So back to the point of the usage of these attributes we turn back to the ‘Settings’ tab:

    /wp-content/uploads/2015/02/c10_645138.png

I’ve just kind of been working on this in the past week in the evening so that’s all for now!


Again, this is open source free stuff available today by downloading the SCN Design Studio SDK Development Community package (preview build at this time.)

If you are interested in this specific source code, it can be found here: https://github.com/org-scn-design-studio-community/sdkpackage/tree/master/src/org.scn.community.geovis/res/Choropleth

And finally a parting YouTube movie showing the above example at runtime using many of the properties and BIAL scripting:

As always, feedback/questions/comments/bug reports are welcomed!

Assigned Tags

      21 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Vincent Dechandon
      Vincent Dechandon

      Really nice. I had no time to check the source but it looks like you used HighMaps ( + Highcharts looking at your video), nice choice. Fresh but promising.

      The concept of directly type the geoJSON inside the properties is also a good idea because I find it's kinda hard to create a catalog a designer can custom with its own file.

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      This was not done with Highmaps. This was done from scratch with D3 and Topojson.

      Author's profile photo Vincent Dechandon
      Vincent Dechandon

      Oh okay 🙂 . Nice anyway 😛 .

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      Thanks 😀

      Author's profile photo Mustafa Bensan
      Mustafa Bensan

      Another high quality contribution as usual, Mike.  In the YouTube video is the line chart a built-in feature of the map or are you toggling the visibility of a standard chart? 🙂

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      It is a regular DS chart just put there to illustrate use of On Select and illustrate how the component handles resize transitions.

      Author's profile photo Cesar Buendia Rios
      Cesar Buendia Rios

      Hello Michael, I'm using your work and need load a custom map file but don't know how do it, only can select a integrated map but I cant load my own map. Please can you tell me how ?

      Thanks

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      Hey Cesar,

      Under the JSON tab, just paste in the GeoJSON.  That's it!

      Author's profile photo Jeroen van der A
      Jeroen van der A

      nice work Mike. I will have a go with this

      Author's profile photo James Rapp
      James Rapp

      This is great Mike ... I didn't see any way to leverage lat/log coordinates if we're maintaining them. Did I miss anything or is this based on the geocoding headaches you explained in the previous post?

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author
      Author's profile photo James Rapp
      James Rapp

      You sure did ... man, who can keep up with a 4 part series? Thanks for the quick response!

      Author's profile photo Former Member
      Former Member

      Hello,

      great blog!! The link to the source code does not work, however:

      https://github.com/org-scn-design-studio-community/sdkpackage/tree/master/src/org.scn.community.geovis/res/Choropleth

      Can you please update it?

      Thanks

      Author's profile photo Karol Kalisz
      Karol Kalisz

      the correct link is

      sdkpackage/src/org.scn.community.databound/res/Choropleth…

      ("geovis" is wrong, should be "databound")

      Author's profile photo Former Member
      Former Member

      Hello Michael,


      I can use the google maps api?


      Thanks

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      Nope.  This doesn't use Map Tiles at all.

      This one uses most other Map Tile providers, though:

      Design Studio 1.6 SDK - Leaflet Maps for more mapping goodness

      There's a Leaflet plugin that's supposed to translate Google Map tiles over to this tile pattern but I've not implemented it because of Google license.

      Author's profile photo Former Member
      Former Member

      Hi Mike,

      I also want to transition the projection method on the fly, as illustrated here:

      /wp-content/uploads/2016/03/c4a_912626.gif

      How can I do that? Because regarding the projection method,  I just find this:

      /wp-content/uploads/2016/03/projectionmethod_912628.png

      Thx for your help,

      Greetz

      /edit: Solved it myself, via setProjection (JavaScript) 😉

      Author's profile photo Colin Terry
      Colin Terry

      Hi Mike,

      I'm having trouble trying to dynamically switch the component to use another measure. I have a Datasource based off a universe, which has two measures - "Amount Sold" and "Quantity Sold". However when i try and execute the command 'CHOROPLETH1.setMeasure("Quantity Sold");' I'm getting an error!

      Any suggestions?

      Colin

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      Can you give the error message?

      Author's profile photo Colin Terry
      Colin Terry

      Hi Mike.

      I have now managed to achieve what I was after by setting a measure filter on the data-source instead, however the error listed when I use the setmeasure function is:

      'A JavaScript error occurred. Unexpected token A in JSON at position 0 SyntaxError: Unexpected token A in JSON at position 0 at Object.parse (native) at Function.jQuery.parseJSON (http://localhost:61158/aad/zen/mimes/combined_static_includes_1.js?version=20160314171511:8486:22) at Choropleth.updateColorRange (http://localhost:61158/aad/zen/mimes/sdk_include/org.scn.community.databound/res/Choropleth/Choropleth.js?version=20160314171511&hash=1464959118830:417:23) at Choropleth.updateLegend (http://localhost:61158/aad/zen/mimes/sdk_include/org.scn.community.databound/res/Choropleth/Choropleth.js?version=20160314171511&hash=1464959118830:578:9) at VizBase.afterUpdate (http://localhost:61158/aad/zen/mimes/sdk_include/org.scn.community.shared/os/viz-modules/VizBase.js?version=20160314171511&hash=undefined:481:7) at Choropleth.afterUpdate (http://localhost:61158/aad/zen/mimes/sdk_include/org.scn.community.databound/res/Choropleth/Choropleth.js?version=20160314171511&hash=1464959118830:371:22) at dispatchProperties (http://localhost:61158/aad/zen/mimes/combined_static_includes_1.js?version=20160314171511:10313:264729) at sap.ui.core.Control.extend.dispatchProperties (http://localhost:61158/aad/zen/mimes/combined_static_includes_1.js?version=20160314171511:10313:277878) at update (http://localhost:61158/aad/zen/mimes/combined_static_includes_1.js?version=20160314171511:10313:259583) at updateComponent (http://localhost:61158/aad/zen/mimes/combined_static_includes_1.js?version=20160314171511:10313:140285)Please contact yourapplication designer'



      On a similar note, what is the syntax for setting a pallete dynamically? Where can I find the required pallete name to include in the setColorPalette("") function?


      Thanks,


      Colin


      Author's profile photo Former Member
      Former Member

      Hi Colin,

       

      What is the syntax you used for setMeasure() and setColorPallete(). thanks in advance