Report Visuals Skill
This skill helps create Power BI reports and visuals in PBIR (Power BI Report) format.
When to Use This Skill
- •Creating report pages with dimensions and layout
- •Adding visuals (charts, tables, cards, slicers)
- •Configuring visual queries (binding data to visuals)
- •Setting up filters, bookmarks, drill-through
- •Creating mobile layouts
PBIR Structure Overview
code
<ProjectName>.Report/
├── definition.pbir # Report pointer file
├── report.json # Report configuration
├── StaticResources/ # Images and resources
│ └── RegisteredResources/
└── definition/
├── pages/
│ ├── ReportSection1/
│ │ └── page.json
│ └── ReportSection2/
│ └── page.json
├── bookmarks/
└── ...
Report Configuration
report.json
json
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/report/1.0.0/schema.json",
"themeCollection": {
"baseTheme": {
"name": "CY24SU06",
"reportVersionAtImport": "5.55",
"type": "SharedResources"
}
},
"config": {
"version": 5,
"defaultDrillFilterOtherVisuals": true
},
"objects": {}
}
Page Structure
Basic Page
json
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/page/1.0.0/schema.json",
"name": "ReportSection1a2b3c4d",
"displayName": "Sales Overview",
"displayOption": "FitToPage",
"height": 720,
"width": 1280,
"visuals": [],
"filters": [],
"ordinal": 0
}
Page Properties
| Property | Description | Values |
|---|---|---|
name | Unique identifier | ReportSection + GUID |
displayName | User-visible name | Any string |
displayOption | Sizing mode | FitToPage, FitToWidth, ActualSize |
height | Page height in pixels | 720 (standard), 1080 (tall) |
width | Page width in pixels | 1280 (standard), 1920 (wide) |
ordinal | Page order | 0, 1, 2, ... |
Page Sizes
| Size | Width | Height | Use Case |
|---|---|---|---|
| 16:9 | 1280 | 720 | Standard dashboard |
| 4:3 | 1280 | 960 | Traditional reports |
| Letter | 816 | 1056 | Print reports |
| Custom | Any | Any | Special layouts |
Visual Structure
Common Visual Properties
Every visual has this structure:
json
{
"name": "visual_unique_id",
"position": {
"x": 0,
"y": 0,
"width": 400,
"height": 300,
"z": 0,
"tabOrder": 0
},
"visual": {
"visualType": "columnChart",
"query": { ... },
"objects": { ... },
"visualContainerObjects": { ... }
}
}
Position Object
| Property | Description |
|---|---|
x | Left position in pixels |
y | Top position in pixels |
width | Visual width in pixels |
height | Visual height in pixels |
z | Layer order (higher = on top) |
tabOrder | Keyboard navigation order |
Visual Types
Column Chart
json
{
"name": "columnChart1",
"position": {
"x": 20,
"y": 20,
"width": 600,
"height": 400,
"z": 0,
"tabOrder": 0
},
"visual": {
"visualType": "columnChart",
"query": {
"queryState": {
"Category": {
"projections": [
{
"field": {
"Column": {
"Expression": {
"SourceRef": { "Entity": "Products" }
},
"Property": "Category"
}
},
"queryRef": "Products.Category",
"active": true
}
]
},
"Y": {
"projections": [
{
"field": {
"Measure": {
"Expression": {
"SourceRef": { "Entity": "Sales" }
},
"Property": "Total Sales"
}
},
"queryRef": "Sales.Total Sales",
"active": true
}
]
}
}
},
"objects": {
"categoryAxis": [{
"properties": {
"show": { "expr": { "Literal": { "Value": "true" } } }
}
}],
"valueAxis": [{
"properties": {
"show": { "expr": { "Literal": { "Value": "true" } } }
}
}]
}
}
}
Bar Chart
json
{
"name": "barChart1",
"position": { "x": 20, "y": 20, "width": 500, "height": 350, "z": 0, "tabOrder": 0 },
"visual": {
"visualType": "barChart",
"query": {
"queryState": {
"Category": {
"projections": [{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "Products" } },
"Property": "Product Name"
}
},
"queryRef": "Products.Product Name",
"active": true
}]
},
"Y": {
"projections": [{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "Sales" } },
"Property": "Total Sales"
}
},
"queryRef": "Sales.Total Sales",
"active": true
}]
}
}
}
}
}
Line Chart
json
{
"name": "lineChart1",
"position": { "x": 20, "y": 20, "width": 600, "height": 400, "z": 0, "tabOrder": 0 },
"visual": {
"visualType": "lineChart",
"query": {
"queryState": {
"Category": {
"projections": [{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "Date" } },
"Property": "Month"
}
},
"queryRef": "Date.Month",
"active": true
}]
},
"Y": {
"projections": [{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "Sales" } },
"Property": "Total Sales"
}
},
"queryRef": "Sales.Total Sales",
"active": true
}]
}
}
}
}
}
Card (Single Value)
json
{
"name": "card1",
"position": { "x": 20, "y": 20, "width": 200, "height": 100, "z": 0, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": {
"queryState": {
"Values": {
"projections": [{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "Sales" } },
"Property": "Total Sales"
}
},
"queryRef": "Sales.Total Sales",
"active": true
}]
}
}
},
"objects": {
"labels": [{
"properties": {
"fontSize": { "expr": { "Literal": { "Value": "28D" } } }
}
}]
}
}
}
Table
json
{
"name": "table1",
"position": { "x": 20, "y": 20, "width": 500, "height": 400, "z": 0, "tabOrder": 0 },
"visual": {
"visualType": "tableEx",
"query": {
"queryState": {
"Values": {
"projections": [
{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "Products" } },
"Property": "Product Name"
}
},
"queryRef": "Products.Product Name",
"active": true
},
{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "Sales" } },
"Property": "Total Sales"
}
},
"queryRef": "Sales.Total Sales",
"active": true
},
{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "Sales" } },
"Property": "Total Quantity"
}
},
"queryRef": "Sales.Total Quantity",
"active": true
}
]
}
}
}
}
}
Matrix
json
{
"name": "matrix1",
"position": { "x": 20, "y": 20, "width": 600, "height": 400, "z": 0, "tabOrder": 0 },
"visual": {
"visualType": "pivotTable",
"query": {
"queryState": {
"Rows": {
"projections": [{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "Products" } },
"Property": "Category"
}
},
"queryRef": "Products.Category",
"active": true
}]
},
"Columns": {
"projections": [{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "Date" } },
"Property": "Year"
}
},
"queryRef": "Date.Year",
"active": true
}]
},
"Values": {
"projections": [{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "Sales" } },
"Property": "Total Sales"
}
},
"queryRef": "Sales.Total Sales",
"active": true
}]
}
}
}
}
}
Slicer
json
{
"name": "slicer1",
"position": { "x": 20, "y": 20, "width": 200, "height": 300, "z": 0, "tabOrder": 0 },
"visual": {
"visualType": "slicer",
"query": {
"queryState": {
"Values": {
"projections": [{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "Products" } },
"Property": "Category"
}
},
"queryRef": "Products.Category",
"active": true
}]
}
}
},
"objects": {
"general": [{
"properties": {
"orientation": { "expr": { "Literal": { "Value": "'Vertical'" } } }
}
}],
"selection": [{
"properties": {
"selectAllCheckboxEnabled": { "expr": { "Literal": { "Value": "true" } } },
"singleSelect": { "expr": { "Literal": { "Value": "false" } } }
}
}]
}
}
}
Date Slicer
json
{
"name": "dateSlicer1",
"position": { "x": 20, "y": 20, "width": 300, "height": 80, "z": 0, "tabOrder": 0 },
"visual": {
"visualType": "slicer",
"query": {
"queryState": {
"Values": {
"projections": [{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "Date" } },
"Property": "Date"
}
},
"queryRef": "Date.Date",
"active": true
}]
}
}
},
"objects": {
"general": [{
"properties": {
"orientation": { "expr": { "Literal": { "Value": "'Horizontal'" } } }
}
}],
"data": [{
"properties": {
"mode": { "expr": { "Literal": { "Value": "'Between'" } } }
}
}]
}
}
}
Semantic Query Format
The query object binds visuals to data. Key concepts:
Field Reference
json
{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "TableName" } },
"Property": "ColumnName"
}
}
}
Measure Reference
json
{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "TableName" } },
"Property": "MeasureName"
}
}
}
Query Buckets
| Bucket | Used By | Purpose |
|---|---|---|
Category | Charts | X-axis grouping |
Y | Charts | Y-axis values |
Series | Charts | Legend grouping |
Values | Cards, Tables | Data fields |
Rows | Matrix | Row headers |
Columns | Matrix | Column headers |
Tooltips | All | Hover information |
Filters
Visual-Level Filter
json
{
"name": "Filter123",
"expression": {
"Column": {
"Expression": { "SourceRef": { "Entity": "Products" } },
"Property": "Category"
}
},
"type": "Categorical",
"filter": {
"Version": 2,
"From": [{"Name": "p", "Entity": "Products", "Type": 0}],
"Where": [{
"Condition": {
"In": {
"Expressions": [{"Column": {"Expression": {"SourceRef": {"Source": "p"}}, "Property": "Category"}}],
"Values": [[{"Literal": {"Value": "'Electronics'"}}]]
}
}
}]
}
}
Page-Level Filter
Add to the page's filters array using the same structure.
Conditional Formatting
Data Bars
json
{
"objects": {
"values": [{
"properties": {
"backColor": {
"solid": { "color": { "expr": { "Literal": { "Value": "'#E8E8E8'" } } } }
}
}
}]
}
}
Color by Rules
json
{
"properties": {
"fontColor": {
"expr": {
"Conditional": {
"Cases": [
{
"Condition": { "Comparison": { "Left": { "Measure": "..." }, "Right": { "Literal": { "Value": "0" } } } },
"Value": { "Literal": { "Value": "'#FF0000'" } }
}
],
"Else": { "Literal": { "Value": "'#00FF00'" } }
}
}
}
}
}
Boundaries and Constraints
DO
- •Always validate JSON syntax before saving
- •Use unique
namevalues for all visuals - •Reference only existing tables and measures
- •Test visuals after creating page files
- •Keep visual positions within page bounds
- •Use
zordering for overlapping visuals
DO NOT
- •Never hardcode data values in visuals
- •Never reference non-existent measures
- •Never use duplicate visual names
- •Never exceed page width/height bounds
- •Never modify auto-generated IDs without testing
Workflow Integration
After creating visuals:
- •Open in Power BI Desktop - Validate the report loads
- •Check data binding - Verify visuals show correct data
- •Test interactions - Confirm cross-filtering works
- •Validate - Use the
best-practicesskill for quality checks
Common Issues
"Visual won't render"
- •Check JSON syntax (use JSON validator)
- •Verify all table/measure references exist
- •Ensure position is within page bounds
"No data displayed"
- •Verify
queryRefmatches the field path - •Check that measures are defined in semantic model
- •Confirm table relationships exist
"Page won't load"
- •Validate page.json has required properties
- •Check
$schemareference is correct - •Ensure
namefollows expected format