Skip to content
Data
Skill

/wiring-vizro-actions

Use this skill when adding cross-filter, cross-highlight, drill-through, or data export interactions to a Vizro dashboard — both for choosing the right interaction pattern during design and for implementing actions in code. Activate when the user wants clicks on a chart or table

From plugin
vizro
3.8k6 skills1 MCP
Install
$ npx -y skills add mckinsey/vizro --skill wiring-vizro-actions --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/wiring-vizro-actions

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use this skill when adding cross-filter, cross-highlight, drill-through, or data export interactions to a Vizro dashboard — both for choosing the right interaction pattern during design and for implementing actions in code. Activate when the user wants clicks on a chart or table

SKILL.md

wiring-vizro-actions.SKILL.md
name: wiring-vizro-actions
description: Use this skill when adding cross-filter, cross-highlight, drill-through, or data export interactions to a Vizro dashboard — both for choosing the right interaction pattern during design and for implementing actions in code. Activate when the user wants clicks on a chart or table to filter or highlight other charts, tables, or figures, needs cross-page navigation with pre-set filters, or wants users to download data.

Wiring Vizro Actions

Core concept: Source → Control → Target

All advanced interactions follow the same shape:

1. A **source** component triggers `va.set_control` when the user clicks it. Practical sources are `vm.Graph` and `vm.AgGrid` — they carry click-data (column values from the clicked point/cell) that can drive a dynamic filter. (`vm.Figure`/`vm.Button`/`vm.Card` technically support `set_control` too, but only with a hardcoded literal `value`, so they are not useful for cross-filtering.) 2. `set_control` writes a value into an intermediate **control** (`vm.Filter` or `vm.Parameter`) with an explicit `id`. 3. The control updates **target** components. Filter/Parameter targets are data-bearing components: `vm.Graph`, `vm.AgGrid`, `vm.Figure`, `vm.Table`.

The control is always explicit — you do not connect components directly. This makes interactions composable (you can wire multiple sources to the same control, or one source to multiple controls).

Built-in actions

| Action | Purpose | Trigger | | --- | --- | --- | | `va.export_data()` | Download all on-page data as CSV (respects filters) | `vm.Button` | | `va.set_control(control=..., value=...)` | Set the value of a Filter or Parameter | `vm.Graph` or `vm.AgGrid` |

`import vizro.actions as va`. Built-in actions are passed directly into `actions=` — wrapping them in `vm.Action` raises an error (deliberate: built-ins have their own predefined `inputs`/`outputs` and would conflict with `vm.Action`'s).

# Correct
vm.Button(text="Export data", actions=va.export_data())
vm.Graph(actions=va.set_control(control="region_filter", value="y"))

# Wrong — raises an exception
vm.Graph(actions=[vm.Action(function=va.set_control(...))])

Named interaction patterns

Match data shape + user need to a pattern. Full details (when-to-use, wireframes, spec entries, code) in [actions-reference.md](references/actions-reference.md).

| # | Pattern | When to use | Key mechanic | | --- | --- | --- | --- | | 1 | **Hierarchical Drill-Down** (cross-page) | 2–3 level hierarchy where detail needs a dedicated page | cross-filter + `show_in_url=True` + back button + export | | 2 | **Single-Page Drill-Down** (container) | 2-level hierarchy where detail fits in a container | cross-filter into a container | | 3 | **Comparison Spotlight** (cross-highlight) | Compare one entity against many without removing context | custom chart with `highlight_X` + invisible Parameter | | 4 | **Multi-Dimensional Slice** | 2+ categorical dimensions (e.g. day × time heatmap) | actions chain → multiple Filters | | 5 | **Data Export** | Analyst persona needs the filtered data downloaded | `vm.Button` + `va.export_data()` |

**Decision flow** (pick at most one of Patterns 1–4 as the primary interaction, then independently add Pattern 5 if export is needed):

Does the data have a natural hierarchy (group → individual → detail)?
├─ YES, detail needs its own page → Pattern 1
├─ YES, detail fits in a container → Pattern 2
└─ NO → continue

Compare one entity against many without removing context?
├─ YES → Pattern 3
└─ NO → continue

2+ categorical dimensions, click to drill into one cell?
├─ YES → Pattern 4
└─ NO → A standard sidebar vm.Filter is sufficient — no advanced pattern needed.

Then independently: does the user need to download data?
├─ YES → add Pattern 5 (Data Export button) on top of whichever pattern you chose above (or on its own)
└─ NO → done

When NOT to use advanced interactions

Use a chart or table as a Filter/Parameter source only when the user explicitly asks for it, or when a pattern's "When to use" clause clearly matches. The bullets below are common cases where the sidebar wins.

  • View-only dashboards (executive summary — users glance, not explore)
  • Simple filtering needs (a sidebar dropdown covers it)
  • Small datasets (< ~5 groups — a filter is simpler and clearer)
  • More than 2 interaction patterns per page (becomes confusing)

Key gotchas

  • **`custom_data` for non-positional values**: When cross-filtering from a graph using a column that is not on a positional axis (`x`/`y`/`z`/`lat`/`lon`), add `custom_data="column"` to the figure and use `value="column"` in `set_control`. Otherwise the click does nothing.
  • **`visible=False` for cross-highlight**: When a Parameter is the highlight control, hide its selector — the highlight effect itself is the feedback. Also set `visible=False` on a cross-filter when the user explicitly requests it.
  • **`"NONE"` in highlight Parameter selector options**: Include `"NONE"` as the first option so the chart starts unhighlighted.
  • **`show_in_url=True` for cross-page**: Required on the target Filter. Without it, Vizro raises `ValueError` at build time and the app won't start.
  • **Back button + Flex layout for drill-through targets**: Pages that receive a drill-through must use `layout=vm.Flex(direction="column")` so the back button takes natural height (Grid would waste a full 140px+ row). Put remaining content in a `vm.Container` with its own `vm.Grid`.
  • **Header hint on interactive source**: Always add a short, action-oriented `header` (e.g. `header="Click a bar to filter by region"`) so users know the component is clickable.
  • **Don't use `filter_interaction`**: It is deprecated. Use `va.set_control` instead.

Quick code recipes

Export data (Pattern 5)

vm.Button(text="Export data", actions=va.export_data())

Cross-filter from chart (Pattern 1 or 2)

vm.Graph(
    header="Click a bar to fil
Read more
Ships withvizro

Vizro is a low-code toolkit for building high-quality data visualization apps.

Get the whole plugin

Other skills on vizro.