> ## Documentation Index
> Fetch the complete documentation index at: https://cubed3-claude-gallant-ramanujan-0b34qw.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Controls

> Filter, time granularity switcher, and parent widgets that let dashboard viewers change what's shown on the dashboard.

Controls are widgets that let dashboard viewers change what's shown without leaving the dashboard. The dashboard builder offers three control types:

* [Filter](#filter) — Narrow the data shown on the dashboard
* [Time granularity switcher](#time-granularity-switcher) — Change the granularity of time-based dimensions
* [Parent](#parent) — Re-point several other controls at once from a single dropdown

Filters and time granularity switchers each target a dimension from your semantic model, and apply the selected value to every [chart][ref-charts] on the dashboard whose query references that dimension. A parent control works one level up: it targets no dimension of its own and drives *other controls* instead.

## Filter

Filter widgets let viewers narrow down the data shown on the dashboard. In the [dashboard builder][ref-workbooks], open the **Add Controls** menu in the toolbar and choose **Filter**. The new filter is added in an unconfigured state — click **Configure Filter** (or open the widget's settings menu) to pick a semantic view and a dimension.

### Operators by dimension type

The available operators depend on the type of the underlying dimension:

| Dimension type | Operators                                                                                                                                  |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| **String**     | `is`, `is not`, `contains`, `not contains`, `starts with`, `not starts with`, `ends with`, `not ends with`, `is null`, `is not null`       |
| **Number**     | `is`, `is not`, `greater than`, `greater than or equal`, `less than`, `less than or equal`, `is null`, `is not null`                       |
| **Time**       | `is`, `is not`, `before date`, `before or on date`, `after date`, `after or on date`, `between`, `relative date`, `is null`, `is not null` |

### Single vs. multiple selection

Filters can allow either a single value or multiple values. Configure this when adding or editing the filter — multi-select is the default for string dimensions, while time and number dimensions default to a single value.

### Default values

You can set a default value that's applied when the dashboard loads. Defaults are useful for scoping the dashboard to "this quarter" or "the user's region" without requiring viewers to interact with the filter first.

There are two ways to set a default:

* **Static default** — pick a value (or values) directly in the filter. Every viewer sees the same default.
* **User attribute default** — resolve the default from the viewer's [user attribute][ref-user-attributes] at load time, so each viewer sees their own personalized default. [Parent controls](#parent-user-attribute-default) support this too.

Static defaults are configured by interacting with the filter in the dashboard builder — the value you select is saved on the widget and applied to every viewer when the dashboard loads.

#### User attribute default

Use the **User attribute default** toggle in the filter's edit sidebar to pre-fill a filter from the viewer's [user attribute][ref-user-attributes]. When the dashboard loads, Cube looks up the attribute value for the current viewer and applies it as the filter's default.

This is useful for scoping a dashboard to the viewer's own slice of the data — for example, defaulting a **Region** filter to the viewer's `region` attribute, or a **Sales rep** filter to their `email`.

To configure it:

<Steps>
  <Step title="Open the filter's settings">
    In the dashboard builder, click the filter widget's settings menu and choose **Edit Filter**.
  </Step>

  <Step title="Enable User attribute default">
    Scroll to the **User attribute default** switch and turn it on.
  </Step>

  <Step title="Pick the attribute">
    Select the [user attribute][ref-user-attributes] whose value should be used as the default. Only attributes defined in your account appear in the picker.
  </Step>
</Steps>

How the attribute value is matched to the filter:

| Attribute type                     | How it's applied                                                                                                                                      |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **String**, **Number**             | Used as a single value. Works with single-value operators like `is` / `is not`, and is also accepted by multi-select filters as a one-item selection. |
| **String array**, **Number array** | Used as a list of values, one per array entry. Empty values are dropped.                                                                              |

Empty, `null`, or unresolvable attribute values are skipped — the filter falls back to whatever static default it has, or no default if none is set.

The user attribute default only seeds the filter's *initial* value. Viewers can still change the filter unless its [visibility](#visibility) is set to **Disabled**, in which case the resolved attribute value is locked in for that viewer. Values passed via URL parameters also take precedence over user attribute defaults, so deep links continue to work.

### Faceted filters

When multiple filters target dimensions from the same semantic view, you can mark them as **faceted**. Faceted filters scope each other's value lists — selecting a value in one filter narrows the options shown in the others, so viewers only see combinations that exist in the data.

For example, on a sales dashboard with a **Country** filter and a **City** filter, marking both as faceted means selecting `United States` in the Country filter limits the City filter to U.S. cities only.

## Time granularity switcher

Time granularity switchers let viewers change the granularity of time-based dimensions on the dashboard — for example, switching a revenue chart from daily to weekly or monthly. The widget targets a single time dimension and applies the chosen [granularity][ref-granularities] to every chart that groups by that dimension.

In the [dashboard builder][ref-workbooks], open the **Add Controls** menu in the toolbar and choose **Time Granularity**. The new switcher is added in an unconfigured state — open its settings to pick a semantic view and a time dimension.

### Allowed granularities

By default, viewers can choose between **day**, **week**, **month**, **quarter**, and **year**. You can narrow this list in the widget's settings to only expose the granularities that make sense for the dashboard.

For time dimensions backed by a `TIMESTAMP` or `DATETIME` column, sub-day granularities (**second**, **minute**, **hour**) are also available. `DATE`-typed columns don't expose sub-day granularities, since they would bucket the entire day into a single point.

Custom granularities defined in the [data model][ref-granularities] aren't offered in this list yet — the switcher exposes the built-in granularities only.

### Default granularity

You can configure a default granularity that's applied when the dashboard loads. If no default is set, charts use the granularity that was saved on the underlying report — viewers can still switch granularities, but the dashboard opens with each chart at its original granularity.

## Parent

A parent control is a dropdown of options you define. Picking one re-points a whole row of other controls at once — so a viewer makes a single choice instead of adjusting three or four filters by hand.

Unlike the other two control types, a parent control targets no dimension and never touches a chart query directly. It applies values to the controls it *drives* — its **children** — and those children then apply themselves to charts exactly as if the viewer had operated each one. Filters and time granularity switchers can both be children; a parent control cannot be a child of another parent control.

For example, an **Analysis** parent with the options `Retail`, `Wholesale` and `Promo` can set a **Channel** filter, a **Minimum order value** filter, and a **Date range** filter to a different combination for each option. Viewers see one dropdown; you can [hide](#visibility) the children if the individual values aren't worth showing.

In the [dashboard builder][ref-workbooks], open the **Add Controls** menu in the toolbar and choose **Parent**, then click **Configure Parent** to set it up. The editor has two tabs — **Options** and **Children**.

<Info>
  Add the child controls to the dashboard *before* the parent control. The **Children** tab can only map controls that already exist, so a parent added to an empty dashboard has nothing to drive yet.
</Info>

### Options

On the **Options** tab, type a label and click **Add** for each entry you want in the dropdown. Options appear as chips — remove one with its close button. A parent control can hold up to 50 options.

Renaming an option later doesn't disturb the values you've mapped to it, so you can reword a label without redoing the mapping — but if the control has a [user attribute default](#parent-user-attribute-default), that match is by label, so rename the attribute's values with it.

### Children

On the **Children** tab, pick a control from **Child control**, then give each of the parent's options a value for it. Each row renders *that child's own control* — a time granularity switcher's row shows its granularity picker, limited to the granularities that switcher allows; a filter's row shows that filter's operator and value inputs. So the values you can offer are exactly the ones a viewer could pick in the child itself.

Repeat for each control you want the parent to drive. Every option/child pair can be in one of three states:

| State                | What happens when the viewer picks that option                                                                                                                     |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **A value**          | The child is set to that value.                                                                                                                                    |
| **Reset to default** | The child is cleared back to its own default. For a filter that means no filtering on that dimension. Turn on the row's **Reset to default** switch.               |
| **Left empty**       | The child is left alone — it keeps whatever value the viewer already had. Use this deliberately when an option shouldn't have an opinion about a particular child. |

While the parent's settings are open, the children it drives are highlighted on the canvas, so you can see the scope of the mapping at a glance.

### One parent per child

A control can be driven by only one parent control at a time. Mapping a child that another parent already drives **moves** it rather than sharing it — the editor warns you before you save, naming the parent that currently owns it.

### Mapping status on child controls

Once a dashboard has at least one parent control, every filter and time granularity switcher on it shows a small indicator reporting how it's driven:

| Status            | Meaning                                                                             |
| ----------------- | ----------------------------------------------------------------------------------- |
| **Fully driven**  | Every option of the owning parent sets this control.                                |
| **Partly driven** | Only some of the owning parent's options set this control; the rest leave it alone. |
| **Not driven**    | No parent control maps this one.                                                    |

Click the indicator to jump straight to the **Children** tab of the parent that owns that control, with it already selected. For a control nothing drives yet, the click opens the first parent control on the dashboard — topmost, then leftmost — so you can map it.

### Default option

A parent control's default is set the same way a filter's static default is — by interacting with the control in the dashboard builder. The option you select is saved on the widget and applied to every viewer when the dashboard loads; there's no static default field in the parent's settings.

Picking in the builder also applies that option's values to the children, so their saved defaults line up with the parent's and a published dashboard opens in a consistent state.

If you never pick an option, the parent opens with nothing selected and the children use their own defaults. Deleting the option that was serving as the default clears it, and the parent goes back to opening on nothing.

<h4 id="parent-user-attribute-default">
  User attribute default
</h4>

The default above is one arrangement for everyone. To give each viewer their own, turn on **User attribute default** in the parent control's settings and pick a [user attribute][ref-user-attributes]. When the dashboard loads, Cube reads that attribute for the current viewer and opens the control on the option it names — and drives the children with it, exactly as if the viewer had picked that option themselves.

This is how you ship one dashboard that opens differently per audience: a **Reporting period** parent whose options are `Month` and `Quarter`, opening on whichever one the viewer's `reporting_period` attribute says, with every filter and time granularity switcher behind it already set to match.

To configure it:

<Steps>
  <Step title="Open the parent control's settings">
    In the dashboard builder, click **Configure Parent** on the control.
  </Step>

  <Step title="Enable User attribute default">
    Below the **Options** and **Children** tabs — next to **Visibility** — turn on the **User attribute default** switch.
  </Step>

  <Step title="Pick the attribute">
    Select the [user attribute][ref-user-attributes] to resolve. Only attributes defined in your account appear in the picker.
  </Step>
</Steps>

The attribute value is matched against the **option labels**, ignoring case and surrounding spaces — an attribute reading `quarter` selects the option labelled `Quarter`. Give the options the labels your attribute already uses, or adjust the attribute values to match.

<Warning>
  Renaming an option leaves its child mappings intact, but the attribute match is by label — so a rename that moves a label away from the values your attribute holds silently stops it resolving, with no error. The control falls back to the option you picked as the default. Rename labels and attribute values together.
</Warning>

| Attribute type                     | How it's applied                                                                                       |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **String**, **Number**             | Matched against the option labels as a single value.                                                   |
| **String array**, **Number array** | The first entry that names an option wins. A parent control is single-select, so the rest are ignored. |

If the value matches no option — or is empty, `null`, or unresolvable — the control falls back to the [default option](#default-option) you picked, and the children keep the arrangement that goes with it.

<Note>
  The attribute is resolved for the viewer, not baked into the dashboard. Editing the attribute's value changes what that viewer opens on the next time the dashboard loads; it never rewrites the published dashboard, so the default you picked in the builder stays intact for everyone else.
</Note>

Viewers can still switch to another option unless the control's [visibility](#visibility) is set to **Disabled**, and their own pick outranks the attribute for the rest of the session. Values passed [in the URL](#sharing-the-current-selection) outrank both — but only what the sharer actually picked travels: a parent control has no parameter of its own, and an untouched, attribute-resolved one puts nothing in the link, so the recipient still opens on their own attribute. When the sharer did pick an option, the link carries that option's *children's* values and the recipient opens on those.

## Sharing the current selection

On a published dashboard, the values a viewer picks in the controls are reflected in the URL, so the view they are looking at is bookmarkable and shareable. Copy the address bar, send it on, and the recipient opens the dashboard with the same filters and granularities applied.

Each control type has its own parameter:

| Control                                                 | Parameter                                      | Example                               |
| ------------------------------------------------------- | ---------------------------------------------- | ------------------------------------- |
| [Filter](#filter)                                       | `f_<semantic_view>.<dimension>=<JSON>`         | `f_orders.status={"value":"shipped"}` |
| [Time granularity switcher](#time-granularity-switcher) | `tg_<semantic_view>.<dimension>=<granularity>` | `tg_orders.created_at=week`           |

The semantic view and dimension are the **internal names** configured on the control — not the display titles you see in the picker. A view shown as `Orders` is usually `orders` in the parameter. Granularities are lowercase and must be one of the switcher's [allowed granularities](#allowed-granularities) — `day`, `week`, `month`, `quarter`, `year`, plus `second`, `minute`, and `hour` for time dimensions that expose them.

You can also write these parameters by hand to open a dashboard in a particular state — see [Pre-set dashboard filters and granularities via URL][ref-embed-url-filters] for the embedded case, which uses the same format.

What does and doesn't travel in the link:

* **Only what the viewer chose.** Values that came from the control's own configuration — a static default, a [default granularity](#default-granularity) — are not written into the URL. Every viewer already gets those from the dashboard itself, and leaving them out means a link stays correct after the dashboard's defaults change.
* **Never a personalized default.** A value resolved from a [user attribute](#user-attribute-default) stays out of the link — whether it seeded a filter directly or reached one through a [parent control](#parent) opening on the viewer's own option. Sharing a dashboard never pins your attribute value onto the recipient; they see it through their own attributes.
* **Filters and granularities together.** Picking both puts both in the link, including when a [parent control](#parent) sets several children at once. A parent control isn't serialized itself — the link carries the values its children ended up with, so the recipient sees the same data while the parent dropdown opens on whatever default it resolves for them, which may not be the option the sharer picked.
* **Written out on published dashboards only.** Reading these parameters works anywhere, including [embedded][ref-embed-url-filters] dashboards; it's the writing that is published-only. In the dashboard builder the URL is left to the editing session, so changing a control there doesn't rewrite it.

When a dashboard opens with these parameters, they are applied on top of whatever defaults the controls carry. A parameter is ignored when nothing on the dashboard can honor it — there is no matching control for that dimension, or the requested granularity isn't in the switcher's [allowed granularities](#allowed-granularities).

## Visibility

Each control has a **Visibility** setting that determines how it appears on the published dashboard. The setting applies to all three control types.

| Visibility            | Behavior on the published dashboard                                                                                                                                                                                                                                                                                                                            |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Visible** (default) | Shown on the dashboard and viewers can change its value.                                                                                                                                                                                                                                                                                                       |
| **Hidden**            | Not shown to viewers, but the control's value is still applied to the charts it targets. Use this to scope a dashboard with a fixed value — e.g., always filter to the current quarter — without exposing the control. Hiding the *children* of a [parent control](#parent) is the usual way to present one dropdown instead of the row of controls behind it. |
| **Disabled**          | Shown on the dashboard so viewers can see the active value, but they cannot change it.                                                                                                                                                                                                                                                                         |

Set the visibility from the **Visibility** dropdown when editing the control. **Hidden** controls remain visible in the dashboard builder so editors can reconfigure them, but disappear from the published view.

## Interaction with charts

This section applies to filters and time granularity switchers. A [parent control](#parent) has no dimension and never applies to a chart itself, so it doesn't appear in any chart's [Controls mapping](#controls-mapping) — it acts only through the children it drives, and it's those children that show up here.

When a control is added to a dashboard, it's automatically wired up to every [chart][ref-charts] whose query already uses the same dimension. Charts that don't reference that dimension are left alone, so a dashboard can mix scoped and unscoped views by default. You can override this default per chart from its [Controls mapping](#controls-mapping) — disable the control for that chart, or remap it onto a different dimension.

### Incompatible controls

If controls of a certain type are incompatible with a particular chart's query, the chart skips all controls of that type and renders the data without them. Filters and time granularity switchers are skipped independently — if filters fail but a time granularity switcher works, the chart shows the granularity-adjusted data without filtering, and vice versa.

The chart displays a warning icon to indicate the problem:

| Icon               | Meaning                                              |
| ------------------ | ---------------------------------------------------- |
| Crossed-out filter | Filters were skipped for this chart                  |
| Crossed-out clock  | Time granularity override was skipped for this chart |

Hover over the icon for details. Click it to open the chart's [Controls mapping](#controls-mapping) and fix the issue — remap the control to a compatible dimension or disable it for this chart.

### Controls mapping

Each chart decides which controls apply to it through its **Controls mapping**. The mapping is resolved automatically in most cases and only needs manual attention when a control targets a dimension the chart doesn't have.

Open **Controls mapping** from a chart's settings menu to inspect or override the mapping for that chart. For each control on the dashboard you can:

* **Toggle the control on or off** for the chart, even when a mapping exists
* **Pick a different dimension** from the chart's semantic view to remap the control to

Three states show up in the mapping sidebar:

| Status                      | What it means                                                                                                                                      |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Mapped automatically**    | The control's dimension exists on the chart's semantic view, so it's wired up without configuration.                                               |
| **Manually mapped**         | You (or an AI agent) picked a specific dimension for this chart. **Reset** restores the automatic mapping.                                         |
| **Can't map automatically** | The control targets a dimension that doesn't exist on the chart's semantic view. The chart is unaffected by the control until you map it manually. |

For [time granularity switchers][ref-time-grain], the dimension picker is restricted to time-typed dimensions on the chart's semantic view, since other dimension types can't be resolved by the time granularity pipeline.

Mappings are also configurable by AI agents when they build or edit a dashboard, so an agent can wire controls across charts that use different semantic views without you needing to revisit each chart manually.

[ref-time-grain]: #time-granularity-switcher

[ref-embed-url-filters]: /embedding/iframe/dashboards#pre-set-dashboard-filters-via-url

[ref-workbooks]: /docs/explore-analyze/workbooks

[ref-charts]: /docs/explore-analyze/dashboards/widgets/charts

[ref-granularities]: /docs/data-modeling/dimensions

[ref-user-attributes]: /admin/users-and-permissions/user-attributes
