============= Map ============= .. include:: ../../incomplete.rst .. contents:: A Map slice displays bubbles on a map. With the recent addition of a heatmap layer, a map can display the big picture of what data looks like using a translucent color gradient to indicate data item density. The marker layer can be enabled to display specific data items on the map, and easily compare heatmap data with marker data. Map config ================================ Map slices support the :doc:`common_configuration`. Additional options are: colors (map) ------------ Defines the color (domain/range) of the bubbles on the map. It is an array of ```{`name, domain[min,max], range[min,max]}`` objects, where ``name`` is a data object field used to color the bubble; min/max in domain can be ``null``, which makes it dynamic and derive those values from data :Optional: Yes :Values: an array of ``{name, domain[min,max], range[min,max]}`` objects :Example: .. code-block:: python config: colors: [{"range":["#FFF","#1a8cdb"],"domain":[null,90],"name":"score"}] maxZoom --------- Maximum zoom level in map. Should be a number between 1 and 21 (from Google Maps API) :Optional: Yes, default is 8 :Values: number between 1 and 10 :Example: .. code-block:: python config: maxZoom: 8 minZoom --------- Minimum zoom level in map. Should be a number between 1 and 21 (from Google Maps API). Recommended max of 15 to 17. :Optional: Yes, default is 4 :Values: number between 1 and 21 :Example: .. code-block:: python config: minZoom: 6 sizes (map) ----------- Defines the sizes (domain/range) of the bubbles on the map. It is an array of ``{name, domain[min,max], range[min,max]}`` objects, where ``name`` is a data object field used to size the bubble; min/max in domain can be ``null``, which makes it dynamic and derive those values from data :Optional: Yes :Values: an array of ``{name, domain[min,max], range[min,max]}`` objects :Example: .. code-block:: python config: sizes: [{"range":[20, 50],"domain":[null,90],"name":"score"}] styles ------ Google map styles object, see https://github.com/googlemaps/js-samples for examples https://developers.google.com/maps/documentation/javascript/styling https://developers.google.com/maps/documentation/javascript/style-reference :Optional: Yes :Values: an array of style objects :Example: .. code-block:: python config: styles: [{...}] tooltipTemplateName (map) ------------------------- The CSS selector of a tooltip template (the one displayed when mouse is over the bubble) :Optional: yes, no tooltip will be shown if not defined :Values: CSS selector :Example: .. code-block:: python config: tooltipTemplateName: [#map-slice-tooltip-compliance-template heatmap ------- If the heatmap is configured, map coloring will show the density of data items in various areas of the map. Heatmaps cannot be filtered. Options are found here: https://developers.google.com/maps/documentation/javascript/reference/visualization#HeatmapLayerOptions :Optional: yes :Values: All options found above in the Google Maps Api linked above can be specified to configure the heatmap, such as ``radius``, which can be set to the number of pixels that should be filled in around a data item, shown below. :Example: .. code-block:: python config: layers: heatmap: radius: 20 markers ------- Markers will appear on the map with the provided options. Markers cannot be filtered. Available options specified in the Google Maps API https://developers.google.com/maps/documentation/javascript/reference/marker#MarkerOptions :Optional: yes :Values: All options enumerated in the Google Maps API MarkerOptions are available. A common option is ``selectable``, displayed below. It defaults to true, but can be set to false to display markers that cannot be interacted with by the user. :Example: .. code-block:: python config: layers: markers: selectable: false Flavors of Map ============== Default ------- The map slice requires three fields to render: a **label**, a **longitude** and a **latitude**. You can fulfill these requirements by adding them individually as separate dimensions: :Dimension1: The group_by_type and name of the map bubbles. :Dimension2: The latitude of map bubbles. :Dimension3: The longitude of map bubbles. Alternatively, you may add a single **Place** dimension: .. code-block:: yaml city: kind: Dimension field: city latitude_field: latitude longitude_field: longitude singular: City plural: Cities Metric ingredients are not required but can be helpful for mapping numeric values to size and color properties. Depending on your use-case, some extra configuration may be necessary in order for things to render correctly. In general: :Metric1: The ``count`` property, typically used to size map bubbles. :Metric2: The ``score`` property, typically used to color map bubbles. Two measures: size and color ------------------------------ In your slice's data service: .. code-block:: python {...metrics: ['metric1', 'metric2']} One measure: size or color ---------------------------- In your slice's data service: .. code-block:: python {metrics: ['color_metric']} In your slice's `config`: .. code-block:: python {colors: [{...measure: 'color_metric'}]} One measure: size and color ----------------------------- In your slice's data service: .. code-block:: python {...metrics: ['metric3']} In your slice's `config`: .. code-block:: python config: sizes: [{...measure: 'metric3'}], colors: [{...measure: 'metric3'}] No measures ----------- In your slice's data service: .. code-block:: python {...metrics: []} Any additional metrics provided (> 2) will appear in each response row. Heatmap ------- The heatmap flavor returns data that is then configured in the stack to display as a colored gradient on the map. It can be configured similarly to default, but cannot include filters. Marker ------ The marker flavor returns data that is configured in the stack to display a series of markers on each specific pinpoint returned. It can be configured similarly to default, but cannot include filters. Advanced Map Examples ===================== Sometimes, a dataset will be best represented with a map that contains a combination of the default, heatmap, and marker flavors. For instance, the heatmap can be used to represent club members, and the markers to represent club meeting locations, making it easy to visually identify an under-served section of the membership. .. image:: ./images/map-heatmap-marker-merge-flavor.png :width: 640 This can be accomplished using a series of renders in the data service. Since this complex map is built out of multiple flavors, the responses are merged using ``append_response_item_collections`` before return, like so: .. code-block:: python def build_response(self): recipe = self.recipe().metrics(*metrics)\ .dimensions(*dimensions)\ .filters(*filters) club_region = self.automatic_filters['club_region'] heatmap = self.recipe().metrics(*club_metrics)\ .dimensions(*club_dimensions)\ .include_automatic_filter_keys('club_region') heatmap_rendered = heatmap.render(flavor='heatmap') marker = self.recipe().metrics(*member_metrics)\ .dimensions(*member_dimensions)\ .include_automatic_filter_keys('member_region') marker_rendered = marker.render(flavor='marker') joined = append_response_item_collections(recipe.render(), heatmap_rendered, 'heatmap', marker_rendered, 'marker') self.response['responses'].append(joined)