Skip to main content

visualization

Choose a card's `display` (chart type) and author its `visualization_settings` for the `mb` CLI — which chart fits which data shape, the required keys per chart, the rule that settings name OUTPUT columns, and the `column_settings` JSON-string-key footgun; the full per-chart key catalog is in references. Use when deciding or fixing how a card renders — "what chart should I use", "make this a bar/line/pie chart", "map this by state", "format this column as currency", "add conditional formatting", "the card renders as a table instead of a chart", or any `display` / `visualization_settings` work.

Quellinformationen

Repository
metabase/metabase-cli
Letzte Quellaktivität
28. September 2026 um 15:40
Erkannte Sprache von SKILL.md
Englisch
Sterne
16
Forks
6

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
2 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
visualization
description
Choose a card's `display` (chart type) and author its `visualization_settings` for the `mb` CLI — which chart fits which data shape, the required keys per chart, the rule that settings name OUTPUT columns, and the `column_settings` JSON-string-key footgun; the full per-chart key catalog is in references. Use when deciding or fixing how a card renders — "what chart should I use", "make this a bar/line/pie chart", "map this by state", "format this column as currency", "add conditional formatting", "the card renders as a table instead of a chart", or any `display` / `visualization_settings` work.
allowed-tools
Read, Write, Edit, Bash, AskUserQuestion
# Visualization: pick the chart, then set it > **Building charts as part of a guided data project?** Follow the `data-workflow` **Shared Contract** — answer-first with detail on demand, ask before showing PII, honor the autonomy mode, name what the CLI can't do instead of erroring into raw SQL: `mb skills get data-workflow`. A card has two presentation fields alongside its `dataset_query`: - **`display`** — the chart type (`bar`, `line`, `pie`, `scalar`, `map`, `table`, …); pick from the valid values below. - **`visualization_settings`** — a map whose keys are **namespaced by `display`** (`graph.*` for bar/line/area/combo, `pie.*` for pie, `table.*` for table, …). The server stores almost anything and **silently ignores keys that don't apply** to the chosen `display`. Nothing validates `visualization_settings` — there is no pre-flight to fail past. A `display` typo or a misnamed key is accepted by the API; the card just renders as a default table or drops the setting. So **the feedback loop is read-back, not pre-flight**: after `card create`/`update`, confirm with `mb card get <id> --full --json` (or open the card) that it rendered as intended. Flag conventions and body-input precedence live in `core` (`mb skills get core`); the `dataset_query` itself is the `mbql` skill's job (`mb skills get mbql`). This skill is only about how the result is displayed. Two steps: **(1) pick the `display` that fits the data**, then **(2) bind the data columns and set options**. ## Step 1 — pick the `display` for your data Decide which relationship in the data matters most, then pick the chart. The shape each one needs is in the per-display table further down. - **Single headline number** → `scalar` (one KPI). `smartscalar` when the story is the change vs the previous period. `gauge`/`progress` for one value against a target/goal. - **Compare a measure across categories** → `bar` (vertical). Use `row` (horizontal bar) when labels are long or there are many categories. Sort by value unless the dimension has a natural order. - **Change over time / trend** → `line` for a continuous series; `bar`/`area` for a few discrete periods. Two measures on unlike scales → `combo` (line + bar, dual-axis) — only when the metrics are genuinely related. - **Part-to-whole, one snapshot** → `pie`, but only for a meaningful whole with **≤5 slices**; beyond that use a sorted `bar`/`row`. Composition over time → stacked `area`/`bar`. - **Distribution / spread / outliers** → a `bar` histogram (bin the measure — see `mbql` binning). <!-- requires: boxplotDisplay --> - **Spread across several groups** → `boxplot` compares the groups' distributions directly. <!-- /requires --> - **Correlation between two measures** → `scatter` (a third measure → bubble size). - **Sequential additive contributions** (start → +/− steps → total) → `waterfall`. - **Stage drop-off in an ordered, cumulative funnel** → `funnel`. - **Flow volume between nodes** (source → target + weight) → `sankey`. - **Geographic** → `map`: region/choropleth (a region dimension + a measure), pin (lat + long), or grid/heat (coordinates + measure). - **Precise values, many columns, mixed types, or no chart fits** → `table`; `pivot` for a cross-tab of two dimensions; `object` for a single record's detail. Valid `display` values — the registered visualizations: `table`, `bar`, `line`, `area`, `row`, `pie`, `scalar`, `smartscalar`, `combo`, `pivot`, `funnel`, `map`, `scatter`, `waterfall`, `progress`, `gauge`, `object`, `sankey`. The API types `display` as a plain string and accepts any value — it renders an unknown one as nothing. (`scalar` **is** the "Number" viz — `display: number` is a legacy serialization alias, not a registered visualization; use `scalar`. `list` exists but is hidden — don't pick it. `heading`/`text`/`link`/`iframe`/`action` are dashcard virtuals, not standalone cards — see references.) A typo like `bargraph`/`linechart` is accepted and renders blank — the most common "why is my chart blank" cause. ## Step 2 — bind data columns and set options ### Which chart for which data, and what to set **Use for** is the data shape each chart suits. **Required** is the minimum to set for it to render as a chart — omit it and the card falls back to a "which columns?" prompt. Everything else is optional (full keys in references). **Empty `"visualization_settings": {}` is valid**: for a simple aggregate the binding is auto-picked, so set keys only to pin or override. | `display` | Use for | Required | | --------------------------- | --------------------------------------------------------- | ---------------------------------------------------------- | | `scalar` | 1 row, 1 column | — (`scalar.field` only if >1 column) | | `smartscalar` | one value grouped by a single **time** field | — (needs a time breakout; `scalar.field` auto) | | `gauge` | 1 row, 1 numeric column | — (`gauge.segments` auto) | | `progress` | 1 row, ≥1 numeric column | — (`progress.goal` defaults to 0) | | `bar` `line` `area` `combo` | >1 row, ≥2 cols, ≥1 dimension + ≥1 measure | `graph.dimensions`, `graph.metrics` | | `row` | as bar; prefer for long/many category labels | `graph.dimensions`, `graph.metrics` | | `scatter` | two numeric measures (correlation) | `graph.dimensions`, `graph.metrics` (`scatter.bubble` opt) | | `waterfall` | exactly 1 dimension + ≥1 measure; sequential | `graph.dimensions` (1), `graph.metrics` (1) | | `pie` | ≥2 rows, ≥2 cols, ≥1 dimension + ≥1 measure; ≤~5 slices | `pie.dimension`, `pie.metric` | | `funnel` | 2 columns (stage + value); ordered stages | `funnel.dimension`, `funnel.metric` | | `map` (region) | a string/region dimension + a measure | `map.region`, `map.dimension`, `map.metric` | | `map` (pin/grid) | latitude + longitude columns | `map.latitude_column`, `map.longitude_column` | | `sankey` | ≥3 cols, ≥2 non-date dimensions, ≥1 measure; acyclic flow | `sankey.source`, `sankey.target`, `sankey.value` | | `pivot` | ≥2 cols, all aggregated/breakout | — (`pivot_table.column_split` auto) | | `table` `object` | anything (table is the universal fallback) | — (always renders) | <!-- requires: boxplotDisplay --> `boxplot` is registered too: ≥3 cols, ≥2 dimensions, ≥1 measure, on **unaggregated** rows; required keys `graph.dimensions`, `graph.metrics`. <!-- /requires --> ### The rule that trips everyone: settings name **output columns**, by name `graph.dimensions`, `graph.metrics`, `pie.dimension`, `pie.metric`, `scalar.field`, `funnel.metric`, `map.latitude_column`, `sankey.source`, … all take **output column-name strings** — the names the query _produces_, not field ids. A `count` aggregation outputs the column `count`; a breakout on a field outputs that field's name; a named aggregation outputs its `name`. These strings are **identical in the API form and the portable (git-sync) form** — no numeric-vs-name footgun here. The names come from the query's output, not from `mb field`/`mb table`. If you set `name` on an aggregation (see the `mbql` skill), use that same string here. ## Minimum-viable settings per chart family (API form) Each block is the `visualization_settings` to pair with the given `display`. The `dataset_query` is elided — build it per the `mbql` skill. Output columns (`CATEGORY`, `count`, …) are whatever the query's breakout/aggregation produce. **Bar / line / area / combo** — one dimension on the x-axis, one or more metrics (the four share an identical key set; switch `display` freely): ```json "display": "bar", "visualization_settings": { "graph.dimensions": ["CATEGORY"], "graph.metrics": ["count"] } ``` (Multiple metrics: `"graph.metrics": ["count","sum"]`. Stacked: add `"stackable.stack_type": "stacked"` — or `"normalized"` for 100%. A second dimension in `graph.dimensions` becomes a series breakout.) **Row** — same keys; axes are visually swapped (horizontal bars). **Pie** — one dimension, one metric: ```json "display": "pie", "visualization_settings": { "pie.dimension": "CATEGORY", "pie.metric": "count" } ``` **Scalar** (single big number) — the field to surface (only needed if >1 column): ```json "display": "scalar", "visualization_settings": { "scalar.field": "count" } ``` **Map (region/choropleth)** — region map + dimension + metric: ```json "display": "map", "visualization_settings": { "map.type": "region", "map.region": "us_states", "map.dimension": "STATE", "map.metric": "count" } ``` **Table** — column order/visibility plus per-column formatting: ```json "display": "table", "visualization_settings": { "table.columns": [ { "name": "CATEGORY", "enabled": true }, { "name": "count", "enabled": true } ], "column_settings": { "[\"name\",\"count\"]": { "column_title": "Orders" } } } ``` ## `column_settings`: the JSON-string-key footgun `column_settings` is a map **whose keys are themselves JSON-encoded arrays** — so inside a JSON body the inner quotes must be escaped. The key is a _string_, never an object. - **Key by column name:** `["name", "<output column name>"]` → in a JSON body, `"[\"name\",\"count\"]"`. It is the key Metabase writes, the same in API and portable form. - A card read back may key a column `["ref", ["field", <id>, …]]` instead. Metabase reads that key before the name key, so edit a column's settings under the key it already has. ```json "column_settings": { "[\"name\",\"TOTAL\"]": { "number_style": "currency", "currency": "USD", "decimals": 2 }, "[\"name\",\"CREATED_AT\"]": { "date_style": "MMMM D, YYYY" } } ``` The exhaustive per-column key list (number/date formatting, `view_as`, alignment, mini bars, click behavior) is in the references file. ## Escape hatch: pull a real card instead of authoring from scratch For anything beyond a single dimension + metric — combo charts, conditional formatting, pivot splits, click behavior, series colors — the cheapest **correct** path is to build it once in the Metabase UI and copy the result: ```bash mb card get <id> --full --json | jq '.visualization_settings' ``` Paste that block into your `card create`/`update` body. The server produced it, so it's valid for that `display`. ## Full per-visualization key catalog The body above covers the high-frequency 90%. The complete per-chart key tables — every key with its values and defaults, the data shape each chart suits, the full `column_settings` and `series_settings` vocabularies, conditional formatting, pivot splits, virtual cards (heading/text/link/iframe), and click behavior — live in the references file. Load on demand, not by default: ```bash mb skills get visualization --full # appends references/settings.md to this body mb skills path visualization # → the skill dir; then Read references/settings.md ``` ## Don't - Don't invent `display` values (`bargraph`, `linechart`, `histogram`) or use `number`/`list` — use a registered value; the API accepts a typo and renders nothing. - Don't put numeric field ids in `graph.dimensions`/`pie.metric`/`scalar.field`/`map.latitude_column` etc. — they take **output column-name strings**. - Don't reach for a `pie` with >5 slices, a `combo` of unrelated metrics, or a `pie`/`scalar` to show a trend — see Step 1. - Don't write a `column_settings` key as an object — it's a JSON **string** (`"[\"name\",\"COL\"]"`), inner quotes escaped. - Don't expect a pre-flight to catch viz mistakes — there is none. Verify by reading the card back. - Don't hand-author complex charts when you can pull a working `visualization_settings` from a UI-built card. - Don't look for an event/annotation key in `visualization_settings` — vertical event markers on time-series charts come from timelines (`mb timeline` / `mb timeline-event`) living in the question's own collection (same collection only, no sub-collection inheritance; question view only, never dashboard cards).
Auf GitHub ansehen