Skip to content

Best Practices

Dashboard design and development best practices for Dataface.


Naming Conventions

Dashboard Names

  • Use lowercase with underscores: sales_overview, not Sales Overview
  • Be descriptive: monthly_sales_dashboard is better than dashboard1
  • Avoid spaces and special characters

Query Names

  • Use descriptive names that indicate what data the query fetches: sales, products, customers
  • Keep names concise but clear
  • Use explicit namespacing (queries.sales) when needed to avoid collisions

Chart IDs

  • Use descriptive names: revenue_by_month, not chart1
  • Indicate chart purpose: sales_trend, kpi_revenue
  • Be consistent with naming patterns

Variable Names

  • Use clear, descriptive names: region, date_range, min_revenue
  • Avoid abbreviations unless widely understood
  • Use snake_case consistently

Organization Strategies

Keep queries for the same domain together:

queries:
  # Sales queries
  sales: ...
  sales_by_region: ...

  # Product queries
  products: ...
  product_categories: ...

Use Tabs for Logical Grouping

Break dashboards into logical groups with tabs (or details for collapsible groups):

tabs:
  items:
    - title: "Overview"
      rows: [kpi_row]        # High-level KPIs
    - title: "Trends"
      rows: [trend_chart]    # Time series charts
    - title: "Details"
      rows: [detail_table]   # Detailed tables

Add Descriptions

Help others understand your dashboard:

title: "Sales Dashboard"
description: "Monthly sales metrics and trends by region"

Performance Optimization

Limit Query Results

Use limit when you don't need all rows:

queries:
  sales:
    metrics: [total_revenue]
    dimensions: [month]
    limit: 100  # Only fetch 100 rows

Reuse Queries

Multiple charts can reference the same query (more efficient):

queries:
  sales:
    metrics: [total_revenue]
    dimensions: [month, region]

charts:
  chart1:
    query: sales  # Same query
  chart2:
    query: sales  # Same query

rows: [chart1, chart2]

Use Time Grain

Let the system handle time grouping when possible:

queries:
  monthly:
    metrics: [total_revenue]
    dimensions: [order_date]
    time_grain: month  # Automatic grouping

Filter Early

Filter in the query, not the chart:

queries:
  filtered:
    sql: |
      SELECT month, SUM(revenue) AS total_revenue FROM orders
      WHERE {{ filter('region', region) }}
        AND {{ filter_date_range('order_date', date_range) }}
      GROUP BY month
    source: warehouse

User Experience

Provide Defaults

Set sensible default values for variables:

variables:
  region:
    default: "North"  # Show useful data by default

  date_range:
    input: daterange
    default: ["2024-01-01", "2024-01-31"]  # a daterange default is a [start, end] list

Use Appropriate Input Types

Match input types to use cases:

  • Select: Single choice from predefined list
  • Slider: Numeric ranges
  • Date range: Time period selection
  • Checkbox: Simple on/off flags

Add Descriptions

Help text makes dashboards more usable:

charts:
  revenue_chart:
    title: "Revenue by Month"
    description: "Monthly revenue trends over the past 12 months"
    query: sales
    type: bar

Test Interactions

Verify click actions and filters work as expected:

  • Test all variable combinations
  • Verify chart interactions
  • Check filter behavior
  • Test on different screen sizes

Common Patterns

Summary + Detail

Show high-level summary with drill-down detail using tabs:

tabs:
  items:
    - title: "Summary"
      rows: [summary_kpi]
    - title: "Details"
      rows: [detail_table]

For click-through drill-down instead of tabs, use chart-level link: — see Interactions.

Time Series with Filters

Combine time series with filters:

variables:
  region: ...

queries:
  trends:
    sql: |
      SELECT month, SUM(revenue) AS total_revenue FROM orders
      WHERE {{ filter('region', region) }}
      GROUP BY month
    source: warehouse

charts:
  trend_chart:
    query: trends
    type: line
    x: month
    y: total_revenue

Comparison Views

Compare metrics side by side:

charts:
  comparison:
    query: sales
    type: bar
    x: month
    y: total_revenue
    color: region  # Compare regions

Anti-Patterns to Avoid

❌ Missing Query References

charts:
  chart1:
    query: nonexistent  # Error: query doesn't exist

❌ Invalid Metric Names

queries:
  sales:
    metrics: [invalid_metric]  # Error: metric doesn't exist in Semantic Layer

❌ Circular Dependencies

variables:
  var1:
    default: "{{ var2 }}"  # var2 depends on var1 - circular!
  var2:
    default: "{{ var1 }}"

❌ Missing Required Fields

charts:
  chart1:
    # Missing: query, type
    x: month

❌ YAML Syntax Errors

Common mistakes: - Wrong indentation (use spaces, not tabs) - Missing colons - Unquoted special characters


Version Control Best Practices

Commit Dashboard Files

Dashboard YAML files are version-controlled: - Commit dashboard changes with model changes - Use descriptive commit messages - Review dashboard changes in PRs

Organize by Feature

Group related dashboards:

faces/
  sales/
    overview.yml
    trends.yml
  marketing/
    campaigns.yml
    leads.yml

Document Changes

Add comments for complex logic:

queries:
  complex:
    sql: |
      SELECT SUM(revenue) AS total_revenue FROM orders
      WHERE status = 'active'   -- active customers only
        AND NOT is_test         -- exclude test data
    source: warehouse

Development Workflow

Validate Before Committing

Always validate your dashboards before committing:

dft validate faces/

See the CLI Reference for validation options.

Inspect Resolved Output for Debugging

When troubleshooting, render the dashboard to JSON to see the resolved layout, charts, and executed query data:

dft render faces/sales.yml --format json

See the CLI Reference for rendering options.

Preview While Developing

Use the serve command for fast iteration:

dft serve

dft serve auto-discovers the project and prints the URL on startup. See the CLI Reference for server options.