
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.

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.

