======================= Bubble ======================= .. include:: ../../complete.rst .. contents:: A Bubble slice includes a group of categorized circles. Click on or hover over a circle to reveal other circles nested in it, representing a level of hierarchy. Bubble config ============= Bubble slices support the :doc:`common_configuration`. Additional options are: descriptionTemplateName ----------------------- CSS selector of the template that is supposed to render selected node's details/description in the breadcrumb, :Optional: Yes, there is a default template that renders the label :Values: CSS selector :Example: .. code-block:: python config: descriptionTemplateName: "#bubble-description-template" tooltipTemplateName ------------------- CSS selector of the template that is supposed to display the tooltip for the hovered bubble :Optional: Yes, there is a default template that renders the label :Values: CSS selector :Example: .. code-block:: python config: descriptionTemplateName: "#bubble-tooltip-template" colorFieldRange -------------------------- Min/max values of a color field. This range defines the bubble's circle fill color. The text label color (on top of that circle) is determined by the front-end dynamically. The app tries to use complimentary/inverse color for text for easier readability (eg. dark text on light circle). :Optional: yes, by default the app will dynamically calculate the range of the colorField values in the data :Values: array of two numeric values :Example: .. code-block:: python config: colorFieldRange: "[0, 100]" colorField -------------------------- Name of the field in the data item that will be used to map to the color of a bubble. This field defines the bubble's circle fill color. The text label color (on top of that circle) is determined by the front-end dynamically. The app tries to use complimentary/inverse color for text for easier readability (eg. dark text on light circle). :Optional: yes, default is ``value`` :Values: string :Example: .. code-block:: python config: colorField: "myColorField" sizeField -------------------------- Name of the field in the data item that will be used to map to the size of a bubble :Optional: yes, default is ``value`` :Values: string :Example: .. code-block:: python config: sizeField: "mySizeField" popSound -------------------------- A URL to the sound that should play when a bubble is "popped" :Optional: yes, by default there is no sound :Values: URL string :Example: .. code-block:: python config: popSound: "http://soundbible.com/mp3/Punch_HD-Mark_DiAngelo-1718986183.mp3" height (bubble) -------------------------- The height (in px) of the chart :Optional: yes, default is 400 :Values: number :Example: .. code-block:: python config: popSound: 500 Flavors of Bubble ================= There is a default renderer that can be used. This renderer works for fixed hierarchies only (like country/region/city). Dynamic trees (like a company's reporting structure aren't supported). This renderer works by gathering data from a recipe at each level of the hierarchy. The data is then structured into a tree. .. _bubble_flavor_sizeField: sizeField (bubble) --------------------- :Optional: yes, (uses config.sizeField if not provided). This metric must be used in the recipe(s) :Values: string .. _bubble_flavor_colorField: colorField (bubble) ---------------------- :Optional: yes, (uses config.colorField if not provided). This metric must be used in the recipe(s) :Values: string .. _bubble_flavor_group_by_type: group_by_type ------------- All selections in a slice must have the same group_by_type. If the bubble has more than one level, set a group_by_type. :Optional: yes, uses the first level if not provided. :Values: string .. note:: group_by_type and slice item ids Slices must have a single group by type but hierarchical slices support selection at multiple levels of the hierarchy. For instance if the hierarchy were country/region/city, a user can perform selections at multiple levels, like: Canada, United States/Tennessee and Germany/Bavaria/Munich. The render_config should include a group_by_type and the ids of the levels will be concatenated using a '~' .. code-block:: python render_config={'group_by_type': 'country_hierarchy', 'levels': ['country', 'region', 'city']} The selection that lower slices receive would look like .. code-block:: python country_hierarchy: ['Canada', 'United States~Tennessee', 'Germany~Bavaria~Munich'] Slices receiving this filtering need to use custom filters to decide what to do with these selections. .. _bubble_flavor_levels: levels ------ A list of levels to use in the bubble. Generally the same as the dimensions used in the recipe. These have to be specified explicitly because dimension order is not maintained in recipes. :Optional: no, A list of levels to use in the bubble. Generally the same as the dimensions used in the recipe. These have to be specified explicitly because dimension order is not maintained in recipes. :Values: list of strings .. _bubble_flavor_levelsData: levelsData ---------- An optional list of data at each level starting from the root. Must be have length one greater than levels because it includes the root data. :Optional: yes :Values: list of recipe.all() .. note:: When to use levelsData If levelsData isn't supplied, the renderer will generate recipes for all levels above the rendered recipe. These recipes will be generic, they won't include any extra filtering that the rendered recipe used. So if the rendered recipe just uses dimensions and metrics you can use this automatic behavior. If the rendered recipe uses filtering, you need to construct a recipe for each level. Here's an example of levelsData in action. It's needed because the recipes use the filter Census.age>60 .. code-block:: python def build_response(self): metrics = ('avgage', 'pop2000') dims = ('first_letter_state', 'state') recipe = self.recipe().dimensions(*dims).metrics(*metrics) levelsData = [ self.recipe().dimensions().metrics(*metrics).filters(Census.age>60).all(), self.recipe().dimensions('first_letter_state').metrics(*metrics).filters(Census.age>60).all(), self.recipe().dimensions('first_letter_state', 'state').metrics(*metrics).filters(Census.age>60).all(), ] self.response['responses'].append(recipe.render( render_config={ 'levels': dims, 'colorField': metrics[0], 'sizeField': metrics[1], 'levelsData': levelsData })) Examples of Bubble Renderer --------------------------- Here are some examples of the bubble slice renderer. One level (group_by_type will be state) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python def build_response(self): metrics = ('avgage', 'pop2000') dims = ('state',) recipe = self.recipe().dimensions(*dims).metrics(*metrics) self.response['responses'].append(recipe.render( render_config={ 'levels': dims, })) .. image:: ./images/bubble-renderer-onelevel.png :width: 640 Three level with custom group_by_type ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When using multiple levels it's recommended to use a custom group_by_type .. code-block:: python def build_response(self): metrics = ('avgage', 'pop2000') dims = ('first_letter_state', 'state', 'sex') recipe = self.recipe().dimensions(*dims).metrics(*metrics) self.response['responses'].append(recipe.render( render_config={ 'levels': dims, 'colorField': metrics[0], 'sizeField': metrics[1], 'group_by_type': 'bubble', })) .. image:: ./images/bubble-renderer-threelevel.png :width: 640 Two level with custom filtering ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Custom filtering means you need to supply levelData. This filtering is limiting data to people with age over 60. .. code-block:: python def build_response(self): metrics = ('avgage', 'pop2000') dims = ('first_letter_state', 'state') recipe = self.recipe().dimensions(*dims).metrics(*metrics) levelsData = [ self.recipe().dimensions().metrics(*metrics).filters(Census.age>60).all(), self.recipe().dimensions('first_letter_state').metrics(*metrics).filters(Census.age>60).all(), self.recipe().dimensions('first_letter_state', 'state').metrics(*metrics).filters(Census.age>60).all(), ] self.response['responses'].append(recipe.render( render_config={ 'levels': dims, 'colorField': metrics[0], 'sizeField': metrics[1], 'group_by_type': 'bubble', 'levelsData': levelsData })) .. image:: ./images/bubble-renderer-customfiltering.png :width: 640