Skip to content
Development
Skill

/visualization-settings

Choosing a card's `display` and authoring `visualization_settings` for question_write and patch_dashcard — which chart fits which data shape, the output-column-name rule, minimum keys per chart family, map regions, the column_settings JSON-string-key footgun. Triggers — "make

From plugin
metabase
50k30 skills11 agents23 commands

Claude Code

$ npx -y skills add metabase/metabase --skill visualization-settings --agent claude-code

SKILL.md

visualization-settings.SKILL.md
name: visualization-settings
description: Choosing a card's `display` and authoring `visualization_settings` for question_write and patch_dashcard — which chart fits which data shape, the output-column-name rule, minimum keys per chart family, map regions, the column_settings JSON-string-key footgun. Triggers — "make this a bar/line/pie chart", "what chart should I use", "format as currency", "the card renders as a table instead of a chart", "conditional formatting", "region map".

Visualization: pick the chart, then set it

Two fields, set through `question_write` and mergeable per dashcard via `dashboard_write`'s `patch_dashcard`:

  • **`display`** — `table`, `bar`, `line`, `area`, `row`, `pie`, `scalar`, `smartscalar`, `combo`, `pivot`, `funnel`, `map`, `scatter`, `waterfall`, `progress`, `gauge`, `sankey`. Nothing else: an unknown value (`bargraph`, `histogram`, `number`) is accepted and renders nothing; `scalar` **is** the Number viz.
  • **`visualization_settings`** — a map keyed per display (`graph.*`, `pie.*`, `table.*`, …). **Nothing validates it**: unknown or wrong-display keys are stored and ignored; a wrong binding renders blank or falls back to a table. Feedback is read-back, not errors.

Step 1 — display by data shape

  • **Single number** → `scalar`; `smartscalar` for change vs previous period (needs a time breakout); `gauge`/`progress` for value vs target.
  • **Measure across categories** → `bar`; `row` (horizontal) for long or many labels.
  • **Trend** → `line`; `area` for stacked composition over time; `combo` for two related measures on unlike scales (never unrelated ones). Never `scalar`/`pie` for a trend.
  • **Part-to-whole** → `pie`, ≤5 slices only; beyond that a sorted `bar`/`row`.
  • **Distribution** → `bar` histogram (bin the field — `learn("query-dialect")`, binning).
  • **Correlation** → `scatter` (third measure → bubble size).
  • **Contributions to a total** → `waterfall`; **stage drop-off** → `funnel`; **flow between nodes** → `sankey`.
  • **Geographic** → `map` (region/choropleth, or pin/grid from lat+long).
  • **Precise values, many columns, nothing fits** → `table`; `pivot` for a two-dimension cross-tab.

Step 2 — bind output columns

**Every binding key takes output column-name strings, never field ids** — the names the query produces: a `count` aggregation is `count`, a breakout its field's name, a named aggregation its `name` option, a second `sum` in a stage `sum_2`. Empty `{}` is valid for a simple aggregate (auto-bound); set keys to pin or override:

{"display": "bar",
 "visualization_settings": {"graph.dimensions": ["CATEGORY"], "graph.metrics": ["count"]}}
  • `bar`/`line`/`area`/`combo`/`row`/`scatter`: `graph.dimensions` (x; a 2nd entry = series breakout), `graph.metrics` (y). Stacked: `"stackable.stack_type": "stacked"` (`"normalized"` = 100%).
  • `pie`: `{"pie.dimension": "CATEGORY", "pie.metric": "count"}`
  • `scalar`: `{"scalar.field": "count"}` (only with >1 column)
  • `funnel`: `{"funnel.dimension": "STAGE", "funnel.metric": "count"}`
  • `map` region: `{"map.type": "region", "map.region": "us_states", "map.dimension": "STATE", "map.metric": "count"}`. `map.region`: `"us_states"` (dimension values = 2-letter state codes or state names, `"CA"`/`"California"`), `"world_countries"` (2-letter ISO codes or country names, `"US"`/`"United States"`), or an admin-added custom-GeoJSON key. Pin/grid: `"map.type": "pin"` + `map.latitude_column` + `map.longitude_column`.
  • `sankey`: `{"sankey.source": "FROM", "sankey.target": "TO", "sankey.value": "count"}`
  • `waterfall`: exactly one dimension + one metric.
  • `table`: always renders; `table.columns` (`[{"name": …, "enabled": …}]`) orders and hides columns.

`column_settings`: JSON-string keys

Per-column formatting keys are **JSON-encoded arrays passed as strings**, inner quotes escaped — never an object key:

"visualization_settings": {
  "column_settings": {
    "[\"name\",\"TOTAL\"]": {"number_style": "currency", "currency": "USD", "decimals": 2},
    "[\"name\",\"CREATED_AT\"]": {"date_style": "MMMM D, YYYY"}}}

Always author `["name", "<output column>"]`. A `["ref", ["field", id, opts]]` key appears in read-back — don't author it; when editing such a card keep those keys verbatim.

Escape hatch and catalog

For anything intricate — combo charts, conditional formatting, pivot splits, click behavior — read a UI-built card with the look you want (`get_content {"items": [{"type": "question", "id": <id>}], "include": ["visualization_settings"]}`) and reuse its `visualization_settings` verbatim; the server produced it, so it's valid for that display. Every key with values and defaults, `series_settings`, conditional formatting, pivot splits, dashcard click behavior: `learn("visualization-settings", "settings")`.

Don't

  • Don't invent display values — accepted, renders nothing.
  • Don't put field ids in `graph.dimensions` / `pie.metric` / `scalar.field` — output column names only, or the chart renders blank.
  • Don't write a `column_settings` key as an object, or author the `["ref", …]` form — ignored.
  • Don't pick `pie` for >5 slices, `combo` for unrelated metrics, or `scalar`/`pie` for a trend — renders, misleads.
  • Don't report a chart as rendering from the write response — its `visualization_settings` echo is what got stored, not proof anything draws.

To confirm

`get_content {"items": [{"type": "question", "id": <id>}], "include": ["visualization_settings"]}` returns `visualization_settings` as stored (alongside `display`, which every question read carries) — proof the settings saved, not that the chart renders. `question_write` also echoes `visualization_settings` in its response, so a write you just made needs no second call. `fields: ["visualization_settings"]` reads the blob alone; a card with nothing stored returns `{}`. Rendering (a region whose values don't match, a binding to a missing column) has no API check: call it unverified unless the user has viewed th

Read more
@metabase
Ships withmetabase

Metabase is the easy, open-source way for everyone in your company to ask questions and learn from data.

50k30 skills11 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
50.3k
Star history of metabase/metabase on GitHub, a chart by star-history.com

Other skills on metabase.

add-malli-schemas

add-malli-schemas

Efficiently add Malli schemas to API endpoints in the Metabase codebase with proper patterns, validation timing, and error…

@metabase@metabaseInstall Skill
add-tracing

add-tracing

Add OpenTelemetry tracing spans to Clojure code following Metabase tracing conventions. Use when instrumenting backend code with…

@metabase@metabaseInstall Skill
api-changelog

api-changelog

Draft or audit the REST API changelog (docs/developers-guide/api-changelog.md) by semantically diffing the checked-in OpenAPI…

@metabase@metabaseInstall Skill
app-db-migrations

app-db-migrations

Add, test, run and roll back application-database (Liquibase) migrations. Use when adding a changeset, changing a table or column…

@metabase@metabaseInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about visualization-settings.

Which coding agents can use visualization-settings?
visualization-settings installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.