Skip to content

Interactive Board Example

A board with variables and filters that update charts dynamically, built on the Dundersign demo dataset; paste it into the playground and it renders as-is.


Complete Board

title: "Document Activity with Filters"

source: db

variables:
  status:
    input: select
    options:
      static: ["sent", "completed"]
    # No default: starts on All statuses

  date_range:
    input: daterange
    # No default: starts on the full history

  min_pages:
    input: slider
    min: 1
    max: 20
    step: 1
    default: 1

queries:
  filtered_documents:
    sql: |
      SELECT
        status,
        COUNT(*) AS documents,
        ROUND(AVG(page_count), 1) AS avg_pages,
        ROUND(AVG(days_to_complete), 1) AS avg_days_to_complete
      FROM dundersign.documents
      WHERE {{ filter('status', status) }}
        AND {{ filter_date_range('created_at', date_range) }}
        AND {{ filter('page_count', min_pages, '>=') }}
      GROUP BY status
      ORDER BY documents DESC

  monthly:
    sql: |
      SELECT month, revenue, active_users
      FROM dundersign_serving.monthly_metrics
      WHERE {{ filter_date_range('month', date_range) }}
        AND month > (SELECT MIN(month) FROM dundersign_serving.monthly_metrics)
        AND month < (SELECT MAX(month) FROM dundersign_serving.monthly_metrics)
      ORDER BY month

rows:
  - title: "Filtered Document View"
    grid:
      columns: 24
      items:
        - item: documents_chart
          width: 12
        - item: revenue_chart
          width: 12
        - item: documents_table
          width: 24

    charts:
      documents_chart:
        title: "Documents by Status"
        query: queries.filtered_documents
        type: bar
        x: status
        y: documents

      revenue_chart:
        title: "Revenue by Month"
        query: queries.monthly
        type: line
        x: month
        y: revenue

      documents_table:
        title: "Status Details"
        query: queries.filtered_documents
        type: table
Document Activity with Filters Status:AllDate Range:All datesMin Pages:1 Filtered Document View 01,0002,000sentcompletedDocuments by StatusOct2025NovDecJan2026FebMarAprMayJunJul01,0002,0003,000Revenue by Month Status DetailsStatusDocumentsAvg PagesAvg Days to Completesent2.55K3.4—completed2.45K3.65 Data as of 14:25 UTC on 6 Oct 2026 made withdbt Charts
▶

Note how date_range is wired into both queries: one variable can drive any number of charts.


How Variables Work

Variable Definition

Variables are defined at the board level:

variables:
  status:
    input: select
    options:
      static: ["sent", "completed"]
    # No default: starts on All statuses
  • input: The UI component (select, slider, daterange, etc.)
  • options: Available options (static list or dynamic query)
  • default: Initial value; omit it to start unfiltered

Wiring Variables to Queries

Variables are referenced in the query SQL: the filter() helper skips the condition entirely when its variable is unset:

queries:
  filtered_documents:
    sql: |
      SELECT status, COUNT(*) AS documents
      FROM dundersign.documents
      WHERE {{ filter('status', status) }}
        AND {{ filter_date_range('created_at', date_range) }}
        AND {{ filter('page_count', min_pages, '>=') }}
      GROUP BY status

When a variable changes, the query automatically re-executes with the new values.


User Interaction Flow

  1. User selects status from dropdown → status variable updates
  2. User adjusts date range → date_range variable updates
  3. User moves slider → min_pages variable updates
  4. Query re-executes with new filter values
  5. Charts update automatically with new data

Key Concepts

Handling "All" Values

When a variable can be "All", filter() already does the right thing for an unset value, and a non-required select or multiselect already offers a clear-selection row back to that unset state, so most boards need nothing further. If you want "All" to instead appear as one of the visible, selectable options in the list, use a Jinja conditional in the SQL:

WHERE {{ filter('status', status if status != 'All' else None) }}

This shows all statuses when "All" is selected, otherwise filters to the selected status.

Multiple Variable Types

This example shows three common variable types: - Select: Single choice dropdown - Date range: Date range picker - Slider: Numeric range input

Grid Layout with Multiple Charts

Using grid layout to show multiple charts:

grid:
  columns: 24
  items:
    - item: documents_chart
      width: 12
    - item: revenue_chart
      width: 12
    - item: documents_table
      width: 24

Extensions

Add More Variables

Add additional filters:

variables:
  priority:
    input: multiselect
    options:
      static: ["low", "normal", "high", "urgent"]
    default: ["high", "urgent"]

Dynamic Options

Load options from a query:

variables:
  template:
    input: select
    options:
      query: queries.template_list