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).
type | Config block | Required mapping | Cross-filter clicks |
|---|---|---|---|
kpi | kpi, comparison | value | Consumer only — never emits |
bar | chart | x, series[] | Emits the clicked category |
line | chart | x, y | Emits the clicked x value |
pie | chart | x, y | Emits the slice category |
scatter | chart | x, y | Emits — requires chart.cross_filter_emit (label/x/series) |
heatmap | chart | x, y, value | Emits — requires chart.cross_filter_emit (x/y) |
funnel | chart | stage, value | Emits the clicked stage |
sankey | chart | source, target, value | Emits — requires chart.cross_filter_emit (source/target) |
grid | grid, pagination | none (columns optional) | Cell clicks — opt out with grid.cross_filter: false |
report_matrix | matrix, pagination | none (must be empty) | Cell clicks — opt out with matrix.cross_filter: false |
text | body | token 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
- What fields each viz type accepts — the per-type reference page above.
- How filters wire in — Filters.
- Cross-filter behavior — Cross-filtering.
- What Malloy syntax the engine understands — Malloy support.
- How dashboards compose visualizations — Dashboards.
- Adapter divergences — Source adapter differences.
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:
| Pattern | 1234567.891 renders as | Reading |
|---|---|---|
#,##0 | 1,234,568 | US grouping, no decimals |
#,##0.00 | 1,234,567.89 | US grouping, two decimals |
#.##0,00 | 1.234.567,89 | European grouping, two decimals |
#0,00 | 1234567,89 | No grouping, comma decimal — not "US with grouping" |
$#,##0a | $1M | Compact currency, whole units |
$#,##0.0a | $1.2M | Compact 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#,##0 | EUR 1,234,568 | Currency-code prefix |
#0b | 1.2GB | Bytes 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.