Docs / Build Workflow

Visualization Types

One type for one purpose

Each visualization type answers a specific kind of question. Picking the right type is not about aesthetics — it is about making the answer legible at a glance. Every type has its own deep reference page below; each page enumerates exactly which mapping.* and chart.* fields the renderer reads, the cross-filter behavior, worked examples, and design notes.

All visualizations share the same top-level fields (id, title, query, type, filters, format, published). Per-type configuration lives in mapping plus exactly one of: a chart block (for ECharts-based types), a type-specific block (kpi, grid, matrix) for the DOM-based types, or a Markdown body for the text note. The text note is also the one type where query is optional — a note with no query is pure prose.

Supported types

Eleven types are accepted in the type: field — exactly these tokens, nothing else. Note report_matrix is spelled with an underscore, and there is no table or number type (a data table is grid; a single figure is kpi).

typeConfig blockRequired mappingCross-filter clicks
kpikpi, comparisonvalueConsumer only — never emits
barchartx, series[]Emits the clicked category
linechartx, yEmits the clicked x value
piechartx, yEmits the slice category
scatterchartx, yEmits — requires chart.cross_filter_emit (label/x/series)
heatmapchartx, y, valueEmits — requires chart.cross_filter_emit (x/y)
funnelchartstage, valueEmits the clicked stage
sankeychartsource, target, valueEmits — requires chart.cross_filter_emit (source/target)
gridgrid, paginationnone (columns optional)Cell clicks — opt out with grid.cross_filter: false
report_matrixmatrix, paginationnone (must be empty)Cell clicks — opt out with matrix.cross_filter: false
textbodytoken map (optional)Consumer only — never emits
  • kpi — single metric with optional delta and comparison.
  • bar — categorical comparison; supports stacking, dual-axis, horizontal orientation.
  • line — time series; supports dual axis and multi-series.
  • pie — part-of-whole composition; supports donut and rose variants.
  • scatter — two-measure correlation; one point per row.
  • heatmap — two-dimensional intensity grid with explicit color scale.
  • funnel — conversion or pipeline stages with drop-off.
  • sankey — flow / attribution diagram; one row = one link (source → target).
  • grid — row-level data table; supports pagination, frozen columns, composite cells.
  • report_matrix — hierarchical report with grouped rows, totals, and PDF export.
  • text — a Markdown note: headings, prose, and instructions placed between charts. Optionally weaves a live value from a single-row query into a sentence.

Anything else passed as type: is unsupported and rejected at validation time.

The chart block is typed and closed

For ECharts-based types (bar, line, pie, scatter, heatmap, funnel, sankey) the chart block is a small, typed surface. Three categories of properties live in it:

  • Looky shortcuts — single keys that collapse multiple coordinated decisions into one decision (e.g. chart.stack: percent, chart.variant: donut, chart.show_value_labels).
  • Pass-through fields — scalars or arrays mirrored to a specific underlying option (e.g. chart.center, chart.symbol_size, chart.gap).
  • Pass-through blocks — nested objects with a curated, snake_case set of properties (e.g. chart.legend, chart.tooltip, chart.x_axis, chart.y_axis, chart.value_label, chart.label, chart.visual_map).

Any property not listed in the per-type reference page is rejected at validation time. There is no escape hatch for raw chart-library options.

The DOM-based types use their own block

kpi, grid, report_matrix, and text are not built on a chart library, so they do not have a chart block at all. kpi, grid, and report_matrix use a top-level type-specific block instead — kpi, grid, matrix — plus auxiliary blocks (pagination for grid and report_matrix, comparison for kpi).

The text note carries a Markdown body instead. A static note is pure prose and needs no query. To weave a live value into a sentence, add a single-row query and a mapping of token names to result fields, then reference them in the body as {{ token }} or {{ token | "$#,##0" }} — each value is escaped and optionally number-formatted. Links in the body accept only http, https, and relative URLs.

Where to look for each topic

Format string reference (shared by every type)

Number formatting is field-keyed across all viz types. Per-field patterns win over slot patterns; slot patterns win over the root pattern.

A pattern is read left to right as: optional + (always show the sign) → optional currency ($ or a 3-letter code like EUR) → the digit core → optional % → optional a (compact) or b (bytes).

The digit core uses 0 for a mandatory digit and # for an optional one. Separators are literal — the pattern's own punctuation decides the output's punctuation: the last . or , followed by one or two digit placeholders is the decimal separator; any other separator in the integer part becomes the thousands separator. That means both conventions work, and they mean different things:

Pattern1234567.891 renders asReading
#,##01,234,568US grouping, no decimals
#,##0.001,234,567.89US grouping, two decimals
#.##0,001.234.567,89European grouping, two decimals
#0,001234567,89No grouping, comma decimal — not "US with grouping"
$#,##0a$1MCompact currency, whole units
$#,##0.0a$1.2MCompact currency, one decimal
#,##0.00%for 0.1234: 12.34%Percent multiplies by 100
+#,##0.0%for 0.1234: +12.3%Signed percent (deltas)
EUR#,##0EUR 1,234,568Currency-code prefix
#0b1.2GBBytes with unit scaling

Every example in these docs uses the US-style convention (#,##0.00); pick one convention per workspace and stay consistent — mixing #0,00 (comma decimal) into a workspace of #,##0 patterns produces numbers that read wrong to half your audience.

If no format pattern is set for a field, the platform falls back to a default decimal format with two fraction digits.