From custom-visuals
Deneb visual creation, Vega/Vega-Lite spec authoring, and Deneb best practices for PBIR reports. Automatically invoke whenever the user mentions "Deneb" in any context, or asks about Vega/Vega-Lite specs in Power BI, Deneb cross-filtering, Deneb interactivity, pbiColor theme integration, Deneb field name escaping, or Deneb rendering issues.
How this skill is triggered — by the user, by Claude, or both
Slash command
/custom-visuals:deneb-visualsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Use `pbir` for every report mutation.** Read PBIR metadata only for diagnosis. If `pbir` is
examples/spec/vega-lite/bullet-chart.jsonexamples/spec/vega-lite/kpi-card.jsonexamples/spec/vega/bar-chart.jsonexamples/spec/vega/line-chart.jsonexamples/standard-config.jsonexamples/visual/bullet-chart.jsonexamples/visual/kpi-card.jsonexamples/visual/trend-line.jsonexamples/visual/ytd-comparison.jsonexamples/visual/ytd-line-chart.jsonreferences/advanced-patterns.mdreferences/capabilities.mdreferences/community-examples.mdreferences/pbir-structure.mdreferences/vega-lite-patterns.mdreferences/vega-patterns.mdUse
pbirfor every report mutation. Read PBIR metadata only for diagnosis. Ifpbiris unavailable or lacks an operation, stop and report the gap; never edit report JSON directly.
Deneb is a certified custom visual for Power BI that enables Vega and Vega-Lite declarative visualization specs directly inside reports. Author specs using this skill.
Prefer Vega-Lite for new Deneb visuals unless specific Vega-only features are required (signals, event streams, custom projections, force/voronoi layouts). Vega-Lite is more concise, easier to maintain, and covers most chart types. For advanced Vega features, see references/vega-patterns.md and the Vega documentation.
deneb7E15AEF80B9E4D4F8E12924291ECE89Av6.json schema URLs)dataset role (all fields go into one "Values" well)dataLimit.override)vegaLite (default) or vega (when Vega-specific features needed)svg (default, sharp text) or canvas (better for large datasets)Copying a working Deneb visual with pbir cp carries its registration. For a new visual, inspect
publicCustomVisuals with pbir get and update the complete list through pbir set --json,
preserving any existing ids. Never edit report.json directly.
Create the visual and bindings through pbir:
pbir add visual deneb7E15AEF80B9E4D4F8E12924291ECE89A \
"Report.Report/Page.Page" --name RevenueByCategoryDeneb
pbir visuals bind "Report.Report/Page.Page/RevenueByCategoryDeneb.Visual" \
--add "dataset:Sales.Category" --type Column
pbir visuals bind "Report.Report/Page.Page/RevenueByCategoryDeneb.Visual" \
--add "dataset:Sales.Revenue" --type Measure
All fields bind to the single dataset role. Use Table.Column for columns and Table.Measure for measures. Field names in bindings must match those used in the Vega/Vega-Lite spec.
Create a Vega-Lite (or Vega) JSON spec file. Key difference:
"data": {"name": "dataset"} (object)"data": [{"name": "dataset"}] (array){
"$schema": "https://vega.github.io/schema/vega-lite/v6.json",
"data": {"name": "dataset"},
"mark": {"type": "bar", "tooltip": true},
"encoding": {
"y": {"field": "Category", "type": "nominal"},
"x": {"field": "Value", "type": "quantitative"}
}
}
See examples/spec/ for complete spec files (Vega and Vega-Lite) and examples/visual/ for full PBIR visual.json files. Field names in the spec must match the nativeQueryRef (display name) from the field bindings.
pbir visuals deneb "Report.Report/Page.Page/RevenueByCategoryDeneb.Visual" \
--spec-file chart.vl.json --provider vegaLite
The CLI handles PBIR encoding. Keep ordinary Vega or Vega-Lite JSON in the spec file.
Before presenting the spec to the user, dispatch the deneb-reviewer agent to validate syntax and provide design feedback.
pbir visuals bind "Report.Report/Page.Page/RevenueByCategoryDeneb.Visual" --show
pbir validate "Report.Report" --all
"data": [{"name": "dataset"}] (array form)"data": {"name": "dataset"} (object form)., [, ], \, ") become _"Order Lines")Escaping depends on whether the spec is standalone or injected into a PBIR visual.json:
Standalone spec files (in examples/spec/): use double quotes with JSON escaping:
{"calculate": "datum[\"Order Lines\"] - datum[\"Order Lines (PY)\"]", "as": "diff"}
Inside PBIR visual.json (in examples/visual/): the entire spec is a single-quoted DAX literal string. Field names with spaces use doubled single quotes (''):
datum[''Order Lines''] - datum[''Order Lines (PY)'']
Single quotes that are NOT part of field name escaping (e.g., string literals in filter expressions like datum.Series == 'Actuals') work as-is because they don't conflict with the outer single-quote wrapper.
Use Deneb's built-in signals for responsive container sizing:
"width": {"signal": "pbiContainerWidth - 25"},
"height": {"signal": "pbiContainerHeight - 27"}
The offsets account for padding. For absolute positioning of text marks, use {"signal": "width"} instead of hardcoded pixel values.
Always provide a config file for consistent styling. See the Standard Config section in references/vega-patterns.md. Key settings: autosize: fit, view.stroke: transparent, font: Segoe UI.
Use Power BI theme colors instead of hardcoded hex values:
| Function/Scheme | Purpose | Usage in Vega |
|---|---|---|
pbiColor(index) | Theme color by index (0-based) | {"signal": "pbiColor(0)"} |
pbiColor(0, -0.3) | Darken theme color by 30% | Shade: -1 (dark) to 1 (light) |
pbiColor("negative") | Sentiment colors | "min", "middle", "max", "negative", "positive" |
pbiColor("bad") | Aliases for sentiment | "bad" = "negative", "good" = "positive", "neutral" = "middle" |
pbiColorNominal | Categorical palette (distinct) | "range": {"scheme": "pbiColorNominal"} |
pbiColorOrdinal | Ordinal palette (ordered categories) | "range": {"scheme": "pbiColorOrdinal"} |
pbiColorLinear | Continuous gradient | "range": {"scheme": "pbiColorLinear"} |
pbiColorDivergent | Divergent gradient | "range": {"scheme": "pbiColorDivergent"} |
Enable interactivity via the vega objects in visual.json:
| Feature | Property | Default | Notes |
|---|---|---|---|
| Tooltips | enableTooltips | true | Use "tooltip": {"signal": "datum"} in encode |
| Context menu | enableContextMenu | true | Right-click drill-through |
| Cross-filtering | enableSelection | false | Requires __selected__ handling |
| Cross-highlighting | enableHighlight | false | Creates <field>__highlight fields |
When enableSelection is true, handle __selected__ ("on", "off", "neutral") in encode blocks. Selection modes: simple (auto-resolves, up to 250 data points) or advanced (Vega only; required for brush/lasso/region selection, supports up to 2500 via options.limit, exposes pbiCrossFilterApply and pbiCrossFilterClear signals). See references/vega-patterns.md for the simple pattern and references/advanced-patterns.md for the advanced signal API.
Use layered marks -- background at reduced opacity, foreground shows <field>__highlight values. See references/vega-patterns.md for details.
Deneb injects runtime fields into each dataset row. See references/capabilities.md for the full table.
Key fields: __row__ (zero-based row index, replaces removed __identity__), __selected__ (selection state), <field>__highlight + <field>__highlightStatus + <field>__highlightComparator (cross-highlighting), <field>__formatted (pre-formatted value string), <field>__format (Power BI format string).
Breaking change in 1.9:
__identity__and__key__were removed. Replace anydatum.__identity__withdatum.__row__.
autosize: fit in config for responsive Power BI sizingpbiContainerWidth/pbiContainerHeight signals for responsive Vega specspbiColor, pbiColorNominal) instead of hex valuesenter/update/hover encode blocks for clean state management (Vega only)"tooltip": {"signal": "datum"} on marksrenderMode: canvas for many marks, and only then raise dataLimit.override. See references/advanced-patterns.md for the full lever ordernativeQueryRef matches spec field referencesDeneb is the preferred choice for advanced custom visuals that need interactivity (cross-filtering, tooltips, hover effects) and go beyond what native Power BI visuals offer. Use Deneb when you need:
Use SVG measures instead for simple inline graphics in tables/cards (sparklines, data bars, progress bars) where interactivity is not needed. Use Python/R instead for statistical visualizations (distribution analysis, regression, correlation) where the focus is analytical rigor over interactivity.
references/community-examples.md -- 170+ community templates organized by chart type, with author citations and direct linksreferences/vega-patterns.md -- Vega chart patterns (bar, line, scatter, donut, stacked, heatmap, area, lollipop, bullet, KPI card), standard config, transforms and scales referencereferences/vega-lite-patterns.md -- Vega-Lite chart patterns (for editing existing Vega-Lite visuals only)references/pbir-structure.md -- PBIR JSON structure (literal encoding, query state, interactivity example)references/capabilities.md -- Full Deneb object properties reference and template format (usermeta schema)references/advanced-patterns.md -- Advanced cross-filtering signals (Vega pbiCrossFilterApply/pbiCrossFilterClear), performance engineering lever order, and community template round-trip from the terminalexamples/visual/bullet-chart.json -- PBIR visual.json: faceted bullet chart with conditional indicators and cross-filtering (Vega-Lite)examples/visual/kpi-card.json -- PBIR visual.json: KPI card with layered text and conditional % change coloring (Vega-Lite)examples/visual/trend-line.json -- PBIR visual.json: dual-series line chart with fold transform and color/legend mapping (Vega-Lite)examples/visual/ytd-comparison.json -- PBIR visual.json: YTD vs target with dashed lines, endpoint labels, number formatting, and rank-based filtering (Vega-Lite)examples/spec/vega/ -- Standalone Vega spec files (bar-chart, line-chart) -- ready to inject into visual.json after escapingexamples/spec/vega-lite/ -- Standalone Vega-Lite spec files (bullet-chart, kpi-card) -- ready to inject after escapingexamples/standard-config.json -- Standard config for all Deneb specsTo retrieve current Power BI custom visual docs, use microsoft_docs_search + microsoft_docs_fetch (MCP) if available, otherwise mslearn search + mslearn fetch (CLI). Search based on the user's request and run multiple searches as needed to ensure sufficient context before proceeding. Note: Vega/Vega-Lite docs live at vega.github.io (not MS Learn) -- use WebFetch for those.
pbir-format (pbip plugin) -- PBIR JSON format referencepbi-report-design -- Layout and design best practicesr-visuals -- R Script visuals (ggplot2)python-visuals -- Python Script visuals (matplotlib)svg-visuals -- SVG via DAX measures (lightweight inline graphics)npx claudepluginhub data-goblin/power-bi-agentic-development --plugin custom-visualsGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Synthesizes the current conversation into a structured spec (PRD) and publishes it to the project issue tracker with a ready-for-agent label, without interviewing the user.