Skip to content

Dashboard YAML Management

Depictio supports managing dashboards as human-readable YAML files using the depictio-cli command-line tool. This enables Infrastructure-as-Code (IaC) workflows, version control integration, and reproducible dashboard deployments.

Implementation Reference

The DashboardDataLite model and CLI dashboard commands were introduced in PR #663. Domain validation (enum constraints, cross-field rules, server schema checks) was added in PR #684.

Overview

┌─────────────────┐                        ┌─────────────────┐
│   YAML Files    │  depictio-cli import   │    MongoDB      │
│   (version      │ ─────────────────────▶ │   Dashboard     │
│    controlled)  │                        │                 │
│                 │  depictio-cli export   │                 │
│                 │ ◀───────────────────── │                 │
└─────────────────┘                        └─────────────────┘

Key Benefits:

  • Version Control: Track dashboard changes in Git with meaningful diffs
  • Infrastructure-as-Code: Manage dashboards alongside your project configuration
  • Human-Readable Format: Edit dashboards directly in YAML (60-80 lines vs 500+ in MongoDB)
  • Reproducible Deployments: Import dashboards to any Depictio instance
  • Early Validation: Catch invalid field values and incompatible combinations before importing

CLI Commands

The depictio-cli dashboard command group provides three commands for YAML management:

Command Description Server Required
validate Validate YAML (schema + server schema) Optional (for Pass 2)
import Import YAML to server Yes (unless --dry-run)
export Export dashboard to YAML Yes

Validate

Validate a dashboard YAML file. Runs in two passes:

  • Pass 1 — schema + domain (always, no server required): checks required fields, enum values (visu_type, column_type), and cross-field rules (aggregation × column_type, interactive_type × column_type, mode/code_content).
  • Pass 2 — server schema (default when --config is provided): resolves each component's workflow_tag + data_collection_tag against the live delta table schema, checks that column_name exists, and validates aggregation/interactive type against the inferred column type. Skip with --offline.
depictio-cli dashboard validate <yaml_file> [OPTIONS]
Option Description
--config, -c Path to CLI config file (enables server schema validation — Pass 2)
--offline Skip server schema check (Pass 1 only — useful without server access)
--verbose, -v Show detailed validation output
--api API base URL (default: from config)

Examples:

# Schema + domain only (no server needed)
depictio-cli dashboard validate my_dashboard.yaml

# Full validation including server column check
depictio-cli dashboard validate my_dashboard.yaml --config ~/.depictio/admin_config.yaml

# Force offline even when config is provided
depictio-cli dashboard validate my_dashboard.yaml --config ~/.depictio/admin_config.yaml --offline

Example Output (all passes OK):

Validating: my_dashboard.yaml
  Pass 1: schema + domain constraints
  ✓ Schema + domain OK
  Pass 2: server schema validation
  ✓ Server schema OK

✓ Validation passed

Example Output (domain error — invalid visu_type):

Validating: my_dashboard.yaml
  Pass 1: schema + domain constraints
✗ Schema/domain validation failed
                         Validation Errors
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Component     ┃ Field     ┃ Message                                            ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ pie-chart     │ -         │ Invalid visu_type 'pie' for mode='ui'.             │
│               │           │ Valid values: scatter, line, bar, box, histogram   │
│ treemap-chart │ -         │ Invalid visu_type 'treemap' for mode='ui'.         │
│               │           │ Valid values: scatter, line, bar, box, histogram   │
└───────────────┴───────────┴────────────────────────────────────────────────────┘

Import

Import a dashboard YAML file to the server. Always runs schema + domain validation first (Pass 1). Also runs server schema validation by default (Pass 2) — skip with --offline.

depictio-cli dashboard import <yaml_file> [OPTIONS]
Option Description
--config, -c Path to CLI config file (required unless --dry-run)
--project, -p Project ID (overrides project_tag in YAML)
--overwrite Update existing dashboard with same title
--dry-run Validate schema + domain only, don't import (no server needed)
--offline Skip server schema check (column names not verified)
--api API base URL (default: from config)

Validation before import

dashboard import always validates your YAML before sending it to the server. A failed validation aborts the import — you never import a dashboard that fails schema or domain checks.

Examples:

# Schema + domain validation only (no config, no import)
depictio-cli dashboard import dashboard.yaml --dry-run

# Full validation + import (server schema check runs by default)
depictio-cli dashboard import dashboard.yaml --config ~/.depictio/admin_config.yaml

# Import without server schema check
depictio-cli dashboard import dashboard.yaml --config ~/.depictio/admin_config.yaml --offline

# Update existing dashboard with same title
depictio-cli dashboard import dashboard.yaml --config ~/.depictio/admin_config.yaml --overwrite

# Override project from YAML
depictio-cli dashboard import dashboard.yaml --config ~/.depictio/admin_config.yaml --project 646b0f3c1e4a2d7f8e5b8c9a

Example Output:

Validating: dashboard.yaml
✓ Validation passed
  Title: Iris Dashboard Demo
  Components: 7
  Project: Iris_Dataset_Project (from YAML project_tag)

Loading CLI configuration...
✓ Configuration loaded
  API URL: localhost:8058

Importing dashboard (project: Iris_Dataset_Project)...
✓ Dashboard imported successfully!
  Dashboard ID: 6824cb3b89d2b72169309737
  Title: Iris Dashboard Demo
  Project ID: 650a1b2c3d4e5f6a7b8c9d0e

View at: localhost:8058/dashboard/6824cb3b89d2b72169309737

Export

Export a dashboard from the server to a YAML file.

depictio-cli dashboard export <dashboard_id> [OPTIONS]
Option Description
--config, -c Path to CLI config file (required)
--output, -o Output file path (default: dashboard.yaml)
--api API base URL (default: from config)

Examples:

# Export to default file
depictio-cli dashboard export 6824cb3b89d2b72169309737 --config ~/.depictio/admin_config.yaml

# Export to specific file
depictio-cli dashboard export 6824cb3b89d2b72169309737 --config ~/.depictio/admin_config.yaml -o iris_dashboard.yaml

YAML Format

DashboardDataLite Structure

The lite format is designed for human readability:

title: Dashboard Title
subtitle: Optional subtitle
project_tag: Project_Name

grid_sections: []      # optional — see Dashboard Sections below
filter_sections: []    # optional

components:
  - tag: component-identifier
    component_type: figure|card|text|interactive|table|image|multiqc|map|advanced_viz
    workflow_tag: engine/workflow_name
    data_collection_tag: dc_tag
    section: Section Name   # optional — the section this component belongs to
    # Component-specific fields...

Dashboard Sections (v1.4.0+)

Two independent lists group a dashboard into named, foldable sections: grid_sections organises the main canvas, filter_sections organises the left filter panel. A component joins one by naming it in its own section field.

grid_sections:
  - name: Cohort
    icon: mdi:counter
    color: teal
    description: How many samples, and of what
    collapsed: false
  - name: Quality control
    icon: mdi:check-decagram
    color: orange
    collapsed: true

filter_sections:
  - name: Sample
    icon: mdi:test-tube
    color: blue

components:
  - tag: sample-count
    component_type: card
    section: Cohort
    # ...
  - tag: habitat-filter
    component_type: interactive
    section: Sample
    # ...
Field Type Default Description
name str required Matched against each component's section
icon str null Iconify id, drawn in the section header
color str null Mantine palette name (teal, orange, …). An unknown name falls back to the theme default rather than failing the import
description str null Hint line under the header
collapsed bool false Start folded
persistent bool false Render on every tab of the dashboard (v1.6.0+)
pin str top top or bottom: which edge a persistent section sits at. Ignored unless persistent (v1.6.0+)

Both lists default to empty, so a dashboard that declares no sections renders exactly the flat grid it did before.

What section accepts

  • section is valid on every component type, not just interactive ones.
  • A component with no section renders above the first section.
  • Section specs reject unknown keys outright, so a typo fails the import rather than being silently ignored.
  • An interactive group may not span two sections — grouped controls must sit together, or the import fails with "Interactive component groups must sit in a single section".
  • Folding is not just visual: a folded section fetches nothing until you open it.

Sections on every tab (v1.6.0+)

persistent: true hands a section to the whole dashboard instead of the tab that declares it. The flag is valid in both lists, and means something slightly different in each:

  • a grid section renders on every other tab too, read-only, above or below that tab's own content;
  • a filter section's controls join every tab's filter panel, and the values picked in them survive a tab switch.

pin chooses which edge it sits at, on every tab including the one that declares it: top (the default) before that tab's own sections, bottom after them. bottom is what a reference block usually wants: a raw-data table present everywhere without pushing aside each tab's own introduction.

filter_sections:
  - name: Variety
    icon: mdi:filter-variant
    color: blue
    description: Which flowers to look at, on every tab
    persistent: true          # pin defaults to top

grid_sections:
  - name: Raw Data
    icon: mdi:table
    color: gray
    description: Per-flower records behind every figure
    collapsed: true
    persistent: true
    pin: bottom

Only the declaring tab lists the section and its components; the other tabs say nothing about it and receive it automatically. This is the bundled Iris demo, whose Overview tab declares both of the above while Iris Petal Analysis declares neither and shows both.

How a persistent section behaves

  • Sections are still matched by name, so two tabs may each declare a persistent section called Filters without colliding: identity is the declaring tab plus the list plus the name.
  • A tab cannot edit a section it does not declare. In the editor the section's menu offers a jump to the tab that owns it instead.
  • Folding is shared: folding a persistent section on one tab folds it on all of them.
  • pin accepts only top or bottom; anything else fails the import.
  • Both keys round-trip through dashboard export unchanged.
  • Neither key does anything on a dashboard with a single tab.

Funnel filtering (v1.7.0+)

funnel_filtering is a dashboard-level boolean deciding whether the filter panel marks which values still lead to a non-empty result. It defaults to true, so it only needs writing when opting a dashboard out:

title: Palmer Penguins
funnel_filtering: false   # omit, or set true, to keep the funnel on

The key round-trips through dashboard export / import like any other dashboard field.

What the flag does and does not control

  • It is the author's default, not a lock. The button in the filter panel flips funnelling for a single page view without writing anything, so a viewer with no edit rights can still turn it off, and a viewer turning it on cannot change what the next person sees.
  • A dashboard saved before v1.7.0 has no such key. Readers test !== false rather than truthiness, so an absent value inherits the funnel rather than falling through undefined to off; only an explicit false opts out.
  • It gates both affordances at once: the per-value highlighting and the funnel overview button.

See Funnel filtering for what it looks like in the panel.

Complete Example

title: Iris Dashboard Demo
subtitle: Sample analysis dashboard
project_tag: Iris_Dataset_Project

grid_sections:              # optional — foldable groups in the main canvas
  - name: Overview
    icon: mdi:counter
    color: teal
  - name: Distributions
    icon: mdi:chart-box
    color: violet

filter_sections:            # optional — foldable groups in the left filter panel
  - name: Sample
    icon: mdi:test-tube
    color: blue

components:
  # Figure: Box plot
  - tag: box-variety-sepal-length
    component_type: figure
    workflow_tag: python/iris_workflow
    data_collection_tag: iris_table
    section: Distributions
    visu_type: box
    dict_kwargs:
      x: variety
      y: sepal.length
      color: variety
      title: Sepal Length by Variety

  # Figure: Scatter plot
  - tag: scatter-sepal-petal
    component_type: figure
    workflow_tag: python/iris_workflow
    data_collection_tag: iris_table
    section: Distributions
    visu_type: scatter
    dict_kwargs:
      x: sepal.length
      y: petal.length
      color: variety

  # Card: Metric with aggregation
  - tag: sepal-length-average
    component_type: card
    workflow_tag: python/iris_workflow
    data_collection_tag: iris_table
    section: Overview
    aggregation: average
    column_name: sepal.length
    icon_name: mdi:leaf
    icon_color: "#8BC34A"

  # Interactive: MultiSelect filter
  - tag: variety-filter
    component_type: interactive
    workflow_tag: python/iris_workflow
    data_collection_tag: iris_table
    section: Sample
    interactive_component_type: MultiSelect
    column_name: variety
    custom_color: "#858585"

  # Interactive: RangeSlider filter
  - tag: sepal-length-filter
    component_type: interactive
    workflow_tag: python/iris_workflow
    data_collection_tag: iris_table
    section: Sample
    interactive_component_type: RangeSlider
    column_name: sepal.length

  # Table: Data display
  - tag: data-table
    component_type: table
    workflow_tag: python/iris_workflow
    data_collection_tag: iris_table

  # Image: Gallery component
  - tag: sample-gallery
    component_type: image
    workflow_tag: python/image_workflow
    data_collection_tag: sample_images
    image_column: image_path
    thumbnail_size: 150
    columns: 3
    max_images: 9

  # MultiQC: Quality control report
  - tag: fastqc-quality
    component_type: multiqc
    workflow_tag: python/nf_workflow
    data_collection_tag: multiqc_report
    selected_module: fastqc
    selected_plot: per_base_sequence_quality

  # Figure: Clustered heatmap
  - tag: gene-expression-heatmap
    component_type: figure
    workflow_tag: python/bio_workflow
    data_collection_tag: expression_matrix
    visu_type: heatmap
    dict_kwargs:
      index_column: gene_name
      row_annotations: [gene_type]
      cluster_rows: true
      normalize: zscore

  # Map: Scatter map with selection
  - tag: sampling-map
    component_type: map
    workflow_tag: python/my_workflow
    data_collection_tag: sample_metadata
    lat_column: latitude
    lon_column: longitude
    color_column: biome
    hover_columns: [sample_id, site_name]
    map_style: carto-positron
    selection_enabled: true
    selection_column: sample_id

Component Types Reference

Type Description Required Fields
figure Plotly charts (scatter, box, heatmap, etc.) visu_type (ui mode) or code_content (code mode)
card Metric cards with aggregations aggregation, column_name
interactive Filters (RangeSlider, MultiSelect, etc.) interactive_component_type, column_name
table Data tables (none required — title auto-generated from DC tag)
text Headings and prose tiles (none required — title is the heading, body the prose)
image Image galleries from S3/MinIO image_column
multiqc MultiQC quality control report viewer selected_module, selected_plot
map Geospatial maps (scatter, density, choropleth) lat_column, lon_column (scatter/density) or locations_column, GeoJSON source (choropleth)

Figure Component

Two rendering modes are supported:

UI Mode (default) — select a chart type and pass Plotly Express parameters:

- tag: scatter-plot
  component_type: figure
  workflow_tag: python/workflow_name
  data_collection_tag: table_dc
  visu_type: scatter       # see valid values below
  dict_kwargs:
    x: column_x
    y: column_y
    color: category_column
    title: Chart Title

Valid visu_type values (UI mode): scatter, line, bar, box, histogram, heatmap

Code Mode — write arbitrary Python/Plotly code for full flexibility:

- tag: custom-plot
  component_type: figure
  workflow_tag: python/workflow_name
  data_collection_tag: table_dc
  mode: code
  code_content: |
    import plotly.express as px
    fig = px.scatter_matrix(df, dimensions=["sepal.length", "sepal.width", "petal.length"])

ComplexHeatmap — clustered heatmap with annotations (via plotly-complexheatmap):

- tag: gene-expression-heatmap
  component_type: figure
  workflow_tag: python/workflow_name
  data_collection_tag: expression_dc
  visu_type: heatmap
  dict_kwargs:
    index_column: gene_name
    value_columns: [sample_A, sample_B, sample_C]
    row_annotations: [gene_type, pathway]
    cluster_rows: true
    cluster_cols: true
    normalize: zscore
    colorscale: RdBu_r
    split_rows_by: gene_type
    cluster_method: ward
    cluster_metric: euclidean

Heatmap dict_kwargs parameters:

Parameter Type Description
index_column string Column for row labels
value_columns list Numeric columns for the matrix (omit for all numeric)
row_annotations list Columns shown as colored side bars
cluster_rows / cluster_cols bool Enable hierarchical clustering
normalize string zscore, minmax, or none
colorscale string Plotly colorscale (e.g. RdBu_r, Viridis)
split_rows_by string Split heatmap rows by annotation column
cluster_method string ward, average, complete, single
cluster_metric string euclidean, correlation, cosine

Code mode and visu_type

visu_type is not validated when mode: code. Any Plotly chart can be built in code mode. code_content must be non-empty when mode: code.

Selection filtering — enable lasso/box selection to filter linked components:

- tag: scatter-with-selection
  component_type: figure
  visu_type: scatter
  selection_enabled: true
  selection_column: sample_id   # required when selection_enabled=true
  # ...

Card Component

Single-metric card:

- tag: metric-card
  component_type: card
  workflow_tag: python/workflow_name
  data_collection_tag: table_dc
  aggregation: average
  column_name: numeric_column
  column_type: float64     # optional — enables offline aggregation validation
  icon_name: mdi:chart-line
  icon_color: "#2196F3"

Multi-metric summary card — secondary aggregations displayed below the hero value:

- tag: petal-length-summary
  component_type: card
  workflow_tag: python/iris_workflow
  data_collection_tag: iris_table
  aggregation: average           # hero metric (large display)
  aggregations:                  # secondary metrics (compact rows)
    - median
    - std_dev
    - min
    - max
  secondary_layout: grid         # optional — how the block below the hero is drawn
  column_name: petal.length
  column_type: float64
  icon_name: mdi:leaf
  icon_color: "#43A047"
  title: "Petal Length"

aggregations is read by the four list-driven layouts (vertical, the default; compact; grid; box_plot). The other twelve secondary_layout values compute their own block and ignore it — see the field table below.

Conditional aggregation — pre-filter data before computing metrics:

- tag: high-coverage-count
  component_type: card
  workflow_tag: python/samples_workflow
  data_collection_tag: samples
  aggregation: count
  column_name: sample_id
  column_type: object
  filter_expr: "(col('coverage') >= 30) & (col('quality_score') > 80)"
  icon_name: mdi:filter-check-outline
  icon_color: "#F4511E"
  title: "High-Quality Samples"

filter_expr accepts a Polars expression string. See Filter Expressions for the full reference.

Aggregation × column_type compatibility:

column_type Valid aggregations
int64 count, nunique, sum, average, median, min, max, range, variance, std_dev, percentile, q1, q3, box_plot_stats, skewness, kurtosis
float64 count, nunique, sum, average, median, min, max, range, variance, std_dev, percentile, q1, q3, box_plot_stats, skewness, kurtosis
bool count, sum, min, max
datetime count, min, max
timedelta count, sum, min, max
category count, mode
object count, mode, nunique

column_type is optional

If you omit column_type, validation against the compatibility table is skipped offline. When --config is provided, the column type is inferred from the server schema and used for validation automatically.

Secondary layout fieldssecondary_layout picks how the block under the hero value is drawn, and each layout reads one companion field. The full list of layouts and what they render is in Components.

Field Type Default Read by
secondary_layout str vertical (picks the layout) — one of the 16 modes
aggregations list[str] null vertical, compact, grid, box_plot
breakdown_col str null top_n, concentration, composition, donut
top_n_count int (1–5) 3 top_n, concentration, composition, donut
coverage_max float null coverage, gauge
threshold_value (v1.4.0+) float null threshold — the QC cut-off; without it the strip is not drawn
threshold_direction (v1.4.0+) min | max min thresholdmin is at-least (coverage, %Q30), max is at-most (duplication, contamination)
threshold_warn (v1.4.0+) float null threshold — ignored unless on the failing side of threshold_value
attrition_cols (v1.4.0+) list[str] [] attrition — ordered stage columns after the card's own, never re-sorted by value
trend_col (v1.4.0+) str null trend — the ordered column the sparkline buckets along
# Pass/warn/fail against a QC cut-off
- tag: mean-coverage
  component_type: card
  workflow_tag: python/samples_workflow
  data_collection_tag: samples
  aggregation: average
  column_name: coverage
  column_type: float64
  secondary_layout: threshold
  threshold_value: 30
  threshold_warn: 20
  threshold_direction: min
  title: "Mean Coverage"

Interactive Component

# MultiSelect — for categorical/text columns
- tag: category-filter
  component_type: interactive
  workflow_tag: python/workflow_name
  data_collection_tag: table_dc
  interactive_component_type: MultiSelect
  column_name: category

# RangeSlider — for numeric columns
- tag: numeric-filter
  component_type: interactive
  workflow_tag: python/workflow_name
  data_collection_tag: table_dc
  interactive_component_type: RangeSlider
  column_name: value
  column_type: float64     # optional — enables offline type compatibility check

# DateRangePicker — for datetime columns
- tag: date-filter
  component_type: interactive
  workflow_tag: python/workflow_name
  data_collection_tag: table_dc
  interactive_component_type: DateRangePicker
  column_name: sample_date

Scoped interactive component — pre-filter data to restrict available options:

# Only show varieties present in rows where petal.length > 4
- tag: long-petal-variety-filter
  component_type: interactive
  workflow_tag: python/iris_workflow
  data_collection_tag: iris_table
  interactive_component_type: MultiSelect
  column_name: variety
  column_type: object
  filter_expr: "col('petal.length') > 4"
  title: "Varieties (petal > 4 cm)"

filter_expr scopes the component's options/range to the filtered subset. See Filter Expressions.

Interactive type × column_type compatibility:

column_type Valid interactive_component_type
int64 Slider, RangeSlider
float64 Slider, RangeSlider
datetime DateRangePicker
category Select, MultiSelect, SegmentedControl
object Select, MultiSelect, SegmentedControl
bool (not yet supported)
timedelta (not supported)

Table Component

- tag: data-table
  component_type: table
  workflow_tag: python/workflow_name
  data_collection_tag: table_dc
  page_size: 25            # rows per page (default: 100)
  columns: [col1, col2]   # optional: allowlist of visible columns (omit to show all)
  compact: false          # optional: tighter row and header heights (default: false)
  title: "Sample Data"    # optional: auto-generated from DC tag if omitted
  description: "Complete measurements across all samples"  # optional subtitle
  title_size: h3          # h1, h2, h3, or sm (default: sm)
  title_align: left       # left (default), center, or right

Title / description fields are rendered as a header above the AG Grid table. When title is omitted, it is auto-generated from data_collection_tag.

Text Component

Headings and prose used to document and organise a dashboard. Text tiles bind to no data source, so workflow_tag and data_collection_tag are unused.

- tag: section-overview
  component_type: text
  title: Within-Sample Diversity
  order: 2                    # heading level H1–H6 (default: 1)
  alignment: left             # horizontal: left (default), center, right
  vertical_alignment: center  # vertical: top, center (default), bottom
  body: |
    Shannon, observed features and Faith's PD measure within-sample
    richness and evenness.
Field Type Default Description
order int (1–6) 1 Heading level, H1 through H6
alignment left | center | right left Horizontal alignment of the title and body
vertical_alignment top | center | bottom center Where the text block sits vertically in its tile
body str "" Optional paragraph below the heading

vertical_alignment defaults to center (v1.4.0+)

Set vertical_alignment: top for the pre-v1.4.0 rendering. See Components for why the default changed.

Image Component

- tag: image-gallery
  component_type: image
  workflow_tag: python/workflow_name
  data_collection_tag: images_dc
  image_column: image_path   # required: column with image paths
  thumbnail_size: 150        # pixels (default: 150)
  columns: 4                 # grid columns (default: 4)
  max_images: 20             # max images shown (default: 20)

s3_base_folder is optional

If omitted, the image base folder is resolved automatically from the data collection's S3 configuration at runtime.

MultiQC Component

Embeds a specific plot from a MultiQC quality control report. Both selected_module and selected_plot are required — they uniquely identify which plot to render.

- tag: fastqc-quality
  component_type: multiqc
  workflow_tag: python/nf_workflow
  data_collection_tag: multiqc_report
  selected_module: fastqc
  selected_plot: per_base_sequence_quality

Both fields are required

Omitting either selected_module or selected_plot will fail validation. YAML-defined components must be explicit about which plot to display.

Map Component

Supports three map types: scatter_map (default), density_map, and choropleth_map.

Scatter map — point markers at lat/lon coordinates:

- tag: sampling-map
  component_type: map
  workflow_tag: python/my_workflow
  data_collection_tag: sample_metadata
  lat_column: latitude
  lon_column: longitude
  color_column: biome
  size_column: read_count
  hover_columns: [sample_id, site_name]
  map_style: carto-positron
  selection_enabled: true
  selection_column: sample_id

Choropleth map — colored regions from GeoJSON:

- tag: country-choropleth
  component_type: map
  workflow_tag: python/my_workflow
  data_collection_tag: sample_metadata
  map_type: choropleth_map
  locations_column: country_name
  featureidkey: properties.NAME
  color_column: sample_id
  choropleth_aggregation: count
  color_continuous_scale: Viridis
  opacity: 0.6
  # GeoJSON source — pick one:
  geojson_url: "https://example.com/countries.geojson"   # URL
  # geojson_dc_tag: europe_geojson                        # DC tag

Valid map_type values: scatter_map, density_map, choropleth_map

Valid map_style values: open-street-map, carto-positron, carto-darkmatter

Choropleth requirements

Choropleth maps require locations_column, color_column, and a GeoJSON source (geojson_url, geojson_dc_tag, or geojson_data). Selection filtering is not supported on choropleth maps.

Placement (v1.4.0+) — a map can stay in the grid or be lifted into a dashboard-wide panel that follows the viewer across every tab. See Components for what each state looks like.

# two extra keys on any map component
placement: floating            # grid (default) or floating
floating_initial_state: docked # compact (default), expanded, docked, hidden
Field Values Default Description
placement grid, floating grid floating claims no grid cell; the map belongs to the whole tab family
floating_initial_state compact, expanded, docked, hidden compact The state the panel opens in. Ignored when placement: grid

State is remembered per viewer

floating_initial_state only sets where the panel starts. Once a viewer moves, resizes or folds it, their own choice is remembered for that dashboard family.

Validation

The CLI validates YAML files in two passes:

┌──────────────────────────────────────────────────────────────┐
│  Pass 1 — Schema + Domain  (always, no server needed)        │
│                                                              │
│  ✓ YAML syntax parsing                                       │
│  ✓ Required fields (title, component required fields)        │
│  ✓ visu_type enum (scatter, line, bar, box, histogram, ...)  │
│  ✓ mode/code_content cross-field rule                        │
│  ✓ selection_enabled/selection_column cross-field rule       │
│  ✓ aggregation × column_type compatibility (if provided)     │
│  ✓ interactive_type × column_type compatibility (if provided)│
│  ✓ MultiQC: selected_module + selected_plot both required    │
│  ✓ Image: image_column required                              │
├──────────────────────────────────────────────────────────────┤
│  Pass 2 — Server Schema  (with --config, skip: --offline)    │
│                                                              │
│  ✓ Resolves workflow_tag + data_collection_tag → DC schema   │
│  ✓ Checks column_name exists in delta table schema           │
│  ✓ Infers column_type from schema → validates aggregation    │
│    and interactive_component_type against inferred type      │
└──────────────────────────────────────────────────────────────┘

Error output is a clean per-component table — each invalid field gets its own row:

                     Validation Errors
┏━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ Component              ┃ Field           ┃ Message        ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ image-missing-column   │ image_column    │ Field required │
│ multiqc-missing-module │ selected_module │ Field required │
│ multiqc-missing-plot   │ selected_plot   │ Field required │
└────────────────────────┴─────────────────┴────────────────┘

Best Practices

File Organization

project/
├── project.yaml              # Project configuration
├── dashboards/
│   ├── overview.yaml         # Main overview dashboard
│   ├── qc_metrics.yaml       # QC-specific dashboard
│   └── samples.yaml          # Sample analysis dashboard
└── README.md

Component Naming

Use descriptive tags that indicate purpose:

# Good: Descriptive tags
- tag: box-variety-sepal-length   # Chart type + data
- tag: sepal-length-average       # Metric + aggregation
- tag: variety-filter             # Column + purpose

# Avoid: Generic tags
- tag: figure-1
- tag: card-2

Incremental Validation Workflow

# Step 1 — check schema and domain constraints (no server needed)
depictio-cli dashboard validate my.yaml

# Step 2 — full validation including column names
depictio-cli dashboard validate my.yaml --config ~/.depictio/admin_config.yaml

# Step 3 — dry import (schema check only, no write)
depictio-cli dashboard import my.yaml --dry-run

# Step 4 — actual import
depictio-cli dashboard import my.yaml --config ~/.depictio/admin_config.yaml

# Step 5 — roundtrip check (export back and diff)
depictio-cli dashboard export <id> -o out.yaml
diff my.yaml out.yaml

Version Control

  • Do version control dashboard YAML files
  • Use meaningful commit messages describing dashboard changes
  • Review diffs before merging dashboard changes
  • Tag releases when deploying to production

See Also