Author Image

CEO & Co-founder of Visivo

Customizable Analytics with Visivo's Code-First Approach

Learn how Visivo's BI-as-code philosophy enables teams to build highly customizable analytics dashboards that adapt to any use case through YAML configuration.

Customizable analytics dashboard configuration

Modern analytics demands flexibility. Every team has unique data sources, specific visualization needs, and particular workflows. Forrester research found that between 60% and 73% of enterprise data goes unused for analytics, often because generic BI tools force teams into rigid templates that don't match their specific requirements.

Visivo's code-first approach enables complete customization through YAML configuration and version-controlled development, addressing this critical gap. As Gartner notes, "Only 20% of analytics insights will deliver business outcomes through 2022," highlighting the importance of flexible, customizable analytics that actually fit organizational needs.

Here's how teams achieve fully customizable analytics using Visivo's BI-as-code platform.

The Power of Configuration-Driven Analytics

Traditional BI tools hide configuration behind GUI interfaces, making customization difficult and version control impossible. Visivo flips this model by exposing every aspect of your analytics through readable, maintainable YAML files. This approach transforms analytics from black-box dashboards to transparent, customizable systems that evolve with your needs.

This transparency is crucial for modern analytics workflows. Learn more about the benefits of configuration-driven approaches in our guide on YAML vs GUI BI Configuration and discover how this approach enables Developer-First BI Workflows.

When you define analytics as code, customization becomes natural. Need a specific chart type? Configure it. Want custom color schemes? Define them. Require complex data transformations? Write them directly in SQL. Every aspect of your analytics pipeline becomes programmable, testable, and reproducible.

Building Custom Dashboards with Visivo

Visivo provides over 40 chart types through Plotly.js integration, each fully customizable through YAML configuration. This extensive library of visualization options ensures you're never limited by predefined chart templates. Let's explore how to build a custom sales analytics dashboard that matches your organization's specific requirements.

Starting with Project Configuration

Every Visivo project begins with clear, customizable configuration:

# project.visivo.yml
name: Custom Sales Analytics
cli_version: "1.0.74"

defaults:
  source_name: primary_warehouse
  trace_props:
    # Global customization for all charts
    hovermode: x unified
    hoverlabel:
      bgcolor: "#1a1a1a"
      font:
        family: "Inter, system-ui, sans-serif"
        size: 14
        color: "#ffffff"

This configuration establishes project-wide defaults while allowing individual components to override settings as needed.

Connecting to Your Data Sources

Visivo supports multiple data sources simultaneously, enabling complex analytics across systems. This multi-source capability is essential for modern data architectures, as detailed in our Modern Data Stack Alignment guide:

name: source_example

sources:
  - name: primary_warehouse
    type: snowflake
    account: "{{ env_var('SNOWFLAKE_ACCOUNT') }}"
    database: ANALYTICS
    warehouse: COMPUTE_WH
    schema: SALES
    username: "{{ env_var('SNOWFLAKE_USER') }}"
    password: "{{ env_var('SNOWFLAKE_PASSWORD') }}"

  - name: postgres_operational
    type: postgresql
    host: "{{ env_var('PG_HOST') }}"
    database: operations
    port: 5432
    username: "{{ env_var('PG_USER') }}"
    password: "{{ env_var('PG_PASSWORD') }}"

  - name: local_sqlite
    type: sqlite
    database: ./data/reference_data.db

Notice how environment variables keep sensitive data secure while configuration remains in version control. This approach aligns with modern DevOps best practices and enables secure CI/CD Analytics Implementation.

Creating Custom Data Models

Define exactly how data should be transformed and aggregated:

name: model_example

models:
  - name: sales_performance
    sql: |
      WITH monthly_metrics AS (
        SELECT
          DATE_TRUNC('month', order_date) as month,
          product_category,
          sales_region,
          SUM(order_value) as revenue,
          COUNT(DISTINCT customer_id) as unique_customers,
          COUNT(*) as order_count,
          AVG(order_value) as avg_order_value,
          PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY order_value) as median_order_value
        FROM orders
        WHERE order_status = 'completed'
        GROUP BY 1, 2, 3
      )
      SELECT
        month,
        product_category,
        sales_region,
        revenue,
        unique_customers,
        order_count,
        avg_order_value,
        median_order_value,
        LAG(revenue, 1) OVER (PARTITION BY product_category, sales_region ORDER BY month) as prev_month_revenue,
        revenue - LAG(revenue, 1) OVER (PARTITION BY product_category, sales_region ORDER BY month) as month_over_month_change
      FROM monthly_metrics
      ORDER BY month DESC, revenue DESC

This model demonstrates complex SQL transformations that would be difficult or impossible to achieve through GUI-based tools. For more advanced data transformation patterns, see our guide on Python Data Pipelines and learn about dbt™ Integration for even more sophisticated data modeling.

Designing Custom Visualizations

Create traces with precise control over appearance and behavior:

traces:
  - name: revenue-trend-by-category
    model: ${ref(sales_performance)}
    cohort_on: ?{product_category}
    columns:
      x: month
      y: revenue
      category: product_category
      customers: unique_customers
      change: month_over_month_change
    props:
      type: scatter
      mode: lines+markers
      x: column(x)
      y: column(y)
      name: column(category)
      line:
        shape: spline
        width: 3
      marker:
        size: 8
        line:
          width: 2
          color: '#ffffff'
      hovertemplate: |
        <b>%{fullData.name}</b><br>
        Month: %{x|%B %Y}<br>
        Revenue: $%{y:,.0f}<br>
        Customers: %{customdata[0]:,.0f}<br>
        MoM Change: $%{customdata[1]:+,.0f}<br>
        <extra></extra>
      customdata:
        - column(customers)
        - column(change)

  - name: category-distribution
    model: ${ref(sales_performance)}
    columns:
      labels: product_category
      values: revenue
    filters:
      - ?{month = (SELECT MAX(month) FROM sales_performance)}
    props:
      type: pie
      labels: column(labels)
      values: column(values)
      hole: 0.4
      marker:
        colors:
          - '#3498db'
          - '#e74c3c'
          - '#f39c12'
          - '#2ecc71'
          - '#9b59b6'
      textposition: outside
      textinfo: label+percent
      textfont:
        size: 14

Composing Custom Chart Layouts

Combine traces into charts with specific layouts:

charts:
  - name: revenue-analysis
    traces:
      - ${ref(revenue-trend-by-category)}
    layout:
      title:
        text: "Revenue Trends by Product Category"
        font:
          size: 24
          family: "Inter, sans-serif"
      xaxis:
        title:
          text: "Month"
        tickformat: "%b %Y"
        showgrid: true
        gridcolor: '#e0e0e0'
      yaxis:
        title:
          text: "Revenue ($)"
        tickformat: "$,.0f"
        showgrid: true
        gridcolor: '#e0e0e0'
      height: 450
      margin:
        l: 80
        r: 40
        t: 80
        b: 60
      paper_bgcolor: '#ffffff'
      plot_bgcolor: '#fafafa'
      colorway:
        - '#3498db'
        - '#e74c3c'
        - '#f39c12'
        - '#2ecc71'
        - '#9b59b6'
      legend:
        orientation: h
        yanchor: bottom
        y: 1.02
        xanchor: right
        x: 1

Building Interactive Dashboards

Assemble charts, tables, and controls into cohesive dashboards:

name: example_project

dashboards:
  - name: Sales Performance Dashboard
    rows:
      # Header with branding
      - height: compact
        items:
          - markdown: |
              # Sales Performance Analytics
              **Last Updated**: {{ current_date }}

              This dashboard provides real-time insights into sales performance across product categories and regions.

      # KPI indicators
      - height: small
        items:
          - width: 1
            chart: ${ref(total_revenue_kpi)}}
          - width: 1
            chart: ${ref(customer_count_kpi)}}
          - width: 1
            chart: ${ref(average_order_kpi)}}

      # Main visualizations
      - height: large
        items:
          - width: 2
            chart: ${ref(revenue_analysis)}}
          - width: 1
            chart: ${ref(category_distribution)}}

      # Detailed table
      - height: medium
        items:
          - width: 3
            table: ${ref(detailed_metrics_table)}}

      # Interactive controls
      - height: small
        items:
          - selector:
              name: date-range-selector
              type: single
              options:
                - label: "Last 30 Days"
                  value: "last_30"
                - label: "Last Quarter"
                  value: "last_quarter"
                - label: "Year to Date"
                  value: "ytd"
                - label: "All Time"
                  value: "all"
              default: "last_quarter"

Advanced Customization Techniques

Using Templates for Dynamic Configuration

Visivo supports Jinja2 templating for dynamic dashboard generation:

name: example_project

models:
  - name: example_model
    sql: SELECT * FROM example_table

traces:
  - name: example_trace
    sql: SELECT * FROM table
    model: ${ref(example_model)}
    columns:
      x: date_column
      y: value_column
    props:
      type: scatter


Creating Reusable Components

Build modular configurations that can be shared across projects:

name: trace_example

# components/kpi-indicators.visivo.yml
traces:
  - name: generic_kpi_indicator
    model: ${ref(kpi_metrics)}}
    props:
      type: indicator
      mode: number+delta
      value: column(current_value)[0]
      delta:
        reference: column(previous_value)[0]
        relative: true
        increasing:
          color: '#2ecc71'
        decreasing:
          color: '#e74c3c'
      number:
        font:
          size: 48
          family: "Inter, sans-serif"
      domain:
        x: [0, 1]
        y: [0, 1]

Then include and customize in your main project:

name: visivo_project

includes:
  - path: components/kpi-indicators.visivo.yml

Implementing Custom Color Schemes

Define organization-specific color palettes:

name: trace_example

defaults:
  trace_props:
    marker:
      colorscale:
        - [0, '#1a237e']     # Deep blue
        - [0.25, '#3949ab']  # Medium blue
        - [0.5, '#5e35b1']   # Purple
        - [0.75, '#e91e63']  # Pink
        - [1, '#ff6f00']     # Orange

Testing Your Custom Analytics

Ensure data quality and accuracy with Visivo's testing framework:

# tests/test_sales_metrics.py
from assertpy import assert_that
from visivo.testing import get_trace_data, get_model_data

def test_revenue_calculations():
    """Verify revenue calculations are accurate"""
    data = get_model_data("sales_performance")

    # Check that revenue is always positive
    assert_that(all(r >= 0 for r in data['revenue'])).is_true()

    # Verify month-over-month calculations
    for i in range(1, len(data)):
        if data['product_category'][i] == data['product_category'][i-1]:
            expected_change = data['revenue'][i] - data['revenue'][i-1]
            actual_change = data['month_over_month_change'][i]
            assert_that(actual_change).is_close_to(expected_change, 0.01)

def test_data_completeness():
    """Ensure no critical data is missing"""
    trace_data = get_trace_data("revenue-trend-by-category")

    # Check for data gaps
    months = trace_data['x']
    assert_that(months).is_not_empty()

    # Verify no null values in critical fields
    assert_that(None not in trace_data['y']).is_true()

Run tests before deployment:

visivo test

This testing approach is part of a broader quality assurance strategy. Learn more about comprehensive testing in our Test Before Dashboard Deployment guide.

Deployment and Version Control

Track all customizations in Git for full auditability. This version control approach enables collaborative development and change tracking, as discussed in our Dashboard Version Control Collaboration guide:

# Initialize version control
git init
git add project.visivo.yml
git add models/*.yml
git add dashboards/*.yml
git commit -m "Initial custom sales analytics configuration"

# Deploy to staging for review
visivo deploy -s staging

# After approval, deploy to production
visivo deploy -s production

Real-World Customization Examples

Organizations using Visivo achieve remarkable customization:

E-commerce Platform: Built product performance dashboards with custom conversion funnels, cohort analyses, and real-time inventory tracking—all defined in 500 lines of YAML.

Financial Services: Created risk analytics dashboards with custom Monte Carlo simulations, value-at-risk calculations, and regulatory compliance reports using Visivo's SQL models.

Healthcare Provider: Developed patient outcome dashboards with HIPAA-compliant data filtering, custom medical chart types, and automated quality metric calculations.

Getting Started with Customization

Ready to build your own custom analytics? Start with Visivo today:

# Install Visivo CLI
pip install visivo

# Initialize a new project
visivo init my-custom-analytics

# Start local development
visivo serve

Visit docs.visivo.io for comprehensive documentation on all customization options, or sign up at app.visivo.io to deploy your custom analytics to the cloud.

For related topics, explore our guides on Visualizations as Code, BI as Code Scalable Systems, and Lightning-Fast Embedded Dashboards.

Custom analytics shouldn't mean starting from scratch or fighting with inflexible tools. With Visivo's code-first approach, every aspect of your analytics becomes customizable, versionable, and reproducible. Transform your data into insights that perfectly match your organization's unique needs.

undefined
Jared Jesionek (co-founder)
Jared Jesionek (co-founder)
Jared Jesionek (co-founder)
agent avatar
How can I help? This connects to our slack so I'll respond real quickly 😄
Powered by Chatlio