Extract Power BI PBIR visuals into reusable templates. Use when users want to save an existing visual configuration as a template, standardize visual formats across projects, or add new visual types to the template library.
Extracts Power BI PBIR visuals into reusable templates by replacing hardcoded values with placeholders. Use when users want to save existing visual configurations, standardize formats across projects, or add new visual types to the template library.
/plugin marketplace add cn-dataworks/pbir-visuals/plugin install cn-dataworks-pbir-visuals@cn-dataworks/pbir-visualsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Extract existing PBIR visuals and convert them to reusable templates with placeholders.
Use when the user wants to:
Find the visual.json file to extract:
# List pages in the report
Glob: .Report/definition/pages/*/page.json
# List visuals on a page
Glob: .Report/definition/pages/[PageGUID]/visuals/*/visual.json
# Read specific visual
Read: .Report/definition/pages/[PageGUID]/visuals/[VisualGUID]/visual.json
Identify:
visualType property (card, barChart, lineChart, etc.)visualContainerObjects and visual.objectsReplace specific values with {{PLACEHOLDER}} syntax:
Always Replace:
| Value | Placeholder |
|---|---|
| Visual GUID (name) | {{VISUAL_NAME}} |
| Position x | {{X}} |
| Position y | {{Y}} |
| Position z | {{Z}} |
| Width | {{WIDTH}} |
| Height | {{HEIGHT}} |
| Tab order | {{TAB_ORDER}} |
| Title text | {{TITLE}} |
| Filter names (GUIDs) | {{FILTER_GUID}} |
Data Binding Replacements:
| Binding | Placeholders |
|---|---|
| Primary measure | {{TABLE_NAME}}, {{MEASURE_NAME}} |
| Multiple measures | {{MEASURE_1_TABLE}}, {{MEASURE_1_NAME}}, etc. |
| Category axis | {{CATEGORY_TABLE}}, {{CATEGORY_COLUMN}} |
| Series/Legend | {{SERIES_TABLE}}, {{SERIES_COLUMN}} |
| Matrix rows | {{ROW_TABLE}}, {{ROW_COLUMN}} |
| Matrix columns | {{COLUMN_TABLE}}, {{COLUMN_COLUMN}} |
| Map location | {{LOCATION_TABLE}}, {{LOCATION_COLUMN}} |
| Scatter X/Y | {{X_MEASURE_TABLE}}, {{Y_MEASURE_TABLE}}, etc. |
Formatting Replacements (Optional):
| Property | Placeholder |
|---|---|
| Font size | {{FONT_SIZE}} |
| Display units | {{DISPLAY_UNITS}} |
| Colors | {{MEASURE_1_COLOR}}, etc. |
| Legend position | {{LEGEND_POSITION}} |
Before saving, verify:
$schema)Naming Convention:
[visual-type]-[variant].json
Examples:
- card-single-measure.json
- line-chart-with-series.json
- slicer-dropdown.json
- azure-map-bubble.json
Save Location:
visual-templates/[template-name].json
Add entry to visual-templates/README.md:
| `[template-name].json` | [Visual Type] | [Description] |
Document any unique placeholders for this template.
Source visual.json:
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/2.4.0/schema.json",
"name": "SalesByRegionBar",
"position": {
"x": "100",
"y": "200",
"z": "2000",
"height": "300",
"width": "400",
"tabOrder": "1"
},
"visual": {
"visualType": "barChart",
"query": {
"queryState": {
"Category": {
"projections": [
{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "dim_region" } },
"Property": "region_name"
}
},
"queryRef": "dim_region.region_name",
"nativeQueryRef": "region_name",
"active": true
}
]
},
"Y": {
"projections": [
{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "Fact_Sales" } },
"Property": "Total Sales"
}
},
"queryRef": "Fact_Sales.Total Sales",
"nativeQueryRef": "Total Sales"
}
]
}
}
}
}
}
Extracted template:
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/2.4.0/schema.json",
"name": "{{VISUAL_NAME}}",
"position": {
"x": "{{X}}",
"y": "{{Y}}",
"z": "{{Z}}",
"height": "{{HEIGHT}}",
"width": "{{WIDTH}}",
"tabOrder": "{{TAB_ORDER}}"
},
"visual": {
"visualType": "barChart",
"query": {
"queryState": {
"Category": {
"projections": [
{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "{{CATEGORY_TABLE}}" } },
"Property": "{{CATEGORY_COLUMN}}"
}
},
"queryRef": "{{CATEGORY_TABLE}}.{{CATEGORY_COLUMN}}",
"nativeQueryRef": "{{CATEGORY_COLUMN}}",
"active": true
}
]
},
"Y": {
"projections": [
{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "{{TABLE_NAME}}" } },
"Property": "{{MEASURE_NAME}}"
}
},
"queryRef": "{{TABLE_NAME}}.{{MEASURE_NAME}}",
"nativeQueryRef": "{{MEASURE_NAME}}"
}
]
}
}
}
}
}
For visuals with multiple Y values, use numbered placeholders:
{{MEASURE_1_TABLE}}, {{MEASURE_1_NAME}}
{{MEASURE_2_TABLE}}, {{MEASURE_2_NAME}}
{{MEASURE_3_TABLE}}, {{MEASURE_3_NAME}}
Keep conditional formatting rules but placeholder the references:
"rules": [
{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "{{TABLE_NAME}}" } },
"Property": "{{MEASURE_NAME}}"
}
}
}
]
Some formatting values should remain hardcoded (good defaults):
Before finalizing template:
$schema property preserved at topname → {{VISUAL_NAME}}{{FILTER_GUID}}{{TITLE}}When adding new templates:
visual-templates/README.md