Skip to content

Variables (Filters & Inputs)

Variables describe the filters and inputs that live inside the dashboard shell. Each definition renders a labeled control, and the runtime keeps queries and charts in sync when values change. Variables must be explicitly referenced in query filters so behavior stays predictable.

Variable names must be unique within a file and across all imported files.


How Variables are Defined

Every entry under variables needs a name, a source (column, query, MetricFlow, or dbt), and an input widget. The compiler:

  • derives a title (label) and placeholder from the slugified name unless you override them,
  • validates that the chosen input matches the source type,
  • keeps default undefined unless you explicitly set it.

Variables do not auto-apply themselves. Wire them in your query filters (plain names, Jinja expressions, helper functions) so you stay in control.

variables:
  region:
    column: orders.region
    input: select

  product_family:
    query: queries.product_family_list
    input: multiselect

  location:
    dimension: geography.region
    input: select

  profit_metric:
    measure: financial.profit
    input: select

  territory:
    model: analytics.orders
    column: territory
    input: select

Inputs and Type Mapping

Each variable declares an input. Pick a widget that matches the data type you expect—the runtime enforces this constraint and renders the appropriate UI. The table below captures the recommended defaults; daterange is the default for date or timestamp sources so you can work with start/end values in expressions.

For a complete reference of all input types and their options, see UI Elements.

Input Description Default Type
select Single-choice dropdown string
multiselect Dropdown with multiple choices array / string[]
input / text Free-form text string
textarea Multi-line text string
slider Numeric slider (min, max, step required) number
datepicker Single date picker date (for rare single-date filters)
daterange Date range picker date / timestamp (preferred default)
checkbox Boolean toggle boolean
radio Small set of explicit options string

Column Binding (most common)

column binds a variable to a table column (<tablename>.<columnname>). The compiler reads the column’s metadata (type, enums, nullability) to populate options, determine operators, and suggest placeholder text. Column bindings still require explicit wiring inside query filters.

variables:
  region:
    column: orders.region
    input: select

Add operator, default, or allow_null only if you need to override the default behavior.

Query-Powered Variables

query draws variable options from custom SQL. Pass either an existing query name (query: queries.regions) or inline SQL. The result must include at least one column for the value; additional label or description columns improve the UI.

variables:
  brand:
    query: |
      SELECT brand_id AS value, brand_name AS label
      FROM brands
      ORDER BY brand_name
    input: select

MetricFlow Integration

Use dimension or measure to reference MetricFlow entities. Dataface fetches type, values, descriptions, and roll-ups from the semantic layer so you rarely duplicate metadata.

variables:
  geography:
    dimension: geography.region
    input: select

  revenue_metric:
    measure: revenue.total
    input: select

dbt Integration

model + column refers to a dbt model column. The manifest resolves the model and metadata, giving you the same experience as a regular column.

variables:
  territory:
    model: analytics.orders
    column: territory
    input: select

Additional Options

  • default: initial value before user interaction
  • placeholder: override the auto-generated hint
  • allow_null: let the variable be empty
  • options: static list or dynamic_query reference for select/multiselect
  • min/max/step: required for sliders
  • operator: controls how the value becomes a filter expression

Wiring Variables to Queries

Variables must be referenced explicitly in query filters (plain name, Jinja expression, or helper function). The compiler turns those references into SQL filters, and the runtime refetches whenever a referenced variable changes.

When a variable is unset or null, filters should gracefully handle this by returning 1=1 (always true) so no filtering is applied. This is the default behavior when using the filter() helper macro.

queries:
  sales:
    sql: |
      SELECT * FROM orders
      WHERE {{ filter('region', '=', region) }}
        AND {{ filter_date_range('order_date', date_range) }}
    profile: my_postgres

For simple filter references (non-SQL queries), you can use direct variable references:

queries:
  sales:
    filters:
      region: region
      date: "{{ date_range.start }} to {{ date_range.end }}"

For formatting, conditional logic, and helper macros, see Expressions.

Reactive Behavior

  • Queries refresh when their referenced variables change.
  • Charts redraw either when their queries finish or when chart-level filters reference variables.
  • Debouncing, optimistic loading, and errors are handled automatically.

Example: Column-bound Filter

By default, variables are unset (null) until a user selects a value. Use the filter() macro in SQL queries to handle this gracefully—when the variable is null, it returns 1=1 (no filter applied).

variables:
  region:
    column: orders.region
    input: select
    # No default - variable starts as null/unset

queries:
  sales:
    sql: |
      SELECT
        region,
        SUM(revenue) as total_revenue
      FROM orders
      WHERE {{ filter('region', '=', region) }}
      GROUP BY region
    profile: my_postgres

When region is null/unset, the filter returns 1=1 and all regions are shown. When a user selects a region, the filter becomes region = 'North' (or whatever was selected).

For more examples and details on the filter() macro, see Expressions.

Interactive Variables (HTML Mode)

When rendering dashboards in HTML format, variables become interactive controls that users can manipulate directly in the browser. Changes trigger a re-render with updated values.

How It Works

  1. Each variable with an input type renders as an HTML form control
  2. When the user changes a value, the dashboard re-renders with the new variable value
  3. Variable values can be used in chart titles, queries, and conditional logic via Jinja templates

Supported Interactive Input Types

Input HTML Control Description
select <select> dropdown Single-choice selection
text / input <input type="text"> Free-form text entry
number <input type="number"> Numeric input with min/max/step
slider / range <input type="range"> Slider with value display
checkbox <input type="checkbox"> Boolean toggle
date / datepicker <input type="date"> Date selection

Example: Interactive Dashboard

title: Sales Dashboard

variables:
  region:
    label: Region
    input: select
    options:
      static: [North, South, East, West]
    # No default - starts unset, shows all regions

  min_revenue:
    label: Min Revenue
    input: number
    min: 0
    max: 10000
    step: 100
    # No default - starts unset, no minimum filter

queries:
  sales:
    sql: |
      SELECT product, SUM(revenue) as revenue
      FROM orders
      WHERE {{ filter('region', '=', region) }}
        AND {{ filter('revenue', '>=', min_revenue) }}
      GROUP BY product
    profile: my_postgres

charts:
  sales_chart:
    title: "Sales{% if region %} for {{ region }} Region{% endif %}"
    type: bar
    query: sales
    x: product
    y: revenue

rows:
  - sales_chart

Static Options

For interactive-only variables (not bound to a data source), use options.static. Note: variables don't need an "All" option—when unset, they simply don't apply any filter.

variables:
  category:
    input: select
    options:
      static: [Electronics, Accessories, Tools]
    # No default - starts unset, shows all categories

queries:
  products:
    sql: |
      SELECT * FROM products
      WHERE {{ filter('category', '=', category) }}
    profile: my_postgres

These variables don't need a column, query, or other source—the options are defined statically in the YAML. When the variable is unset (no selection), the filter() macro returns 1=1 and all categories are shown.

Using Variables in Templates

Variables can be used anywhere Jinja templates are supported:

  • Chart titles: title: "Sales for {{ region }}"
  • Query SQL: WHERE region = '{{ region }}'
  • Conditional rendering: include: "{{ show_details }}"

Advanced Topics

For nested dependencies, conditional filters, and layout orchestration driven by variables, see Advanced Variables.

  • UI Elements – Complete reference for all input types and options
  • Expressions – Formatting, conditional logic, and the filter() macro
  • Advanced Variables – Dependent variables and conditional layouts
  • Queries – How variables plug into query filters
  • Charts – Interactions that set variables or add filters