The Power BI Ecosystem
Power BI is a suite of tools by Microsoft that lets you connect to data sources, transform raw data, build interactive visualizations, and share insights across your organization. It's the most widely used BI tool in the world.
Power BI Desktop
Free Windows app for building reports & dashboards. This is where you'll spend most of your time.
Power BI Service
Cloud platform (app.powerbi.com) for publishing, sharing, and collaborating on reports.
Power BI Mobile
iOS/Android apps for viewing dashboards on the go.
Power BI Gateway
Bridge between on-premises data and the cloud service for scheduled refreshes.
Why Power BI?
🏆 Key Advantages
Free Desktop app — No license needed to build reports locally.
100+ data connectors — Excel, SQL, web APIs, SharePoint, Salesforce, and more.
DAX formula language — Powerful analytics engine for complex calculations.
Microsoft integration — Works seamlessly with Excel, Teams, SharePoint, Azure.
Natural Language Q&A — Ask questions in plain English and get charts.
Industry leader — Gartner Magic Quadrant leader for 16+ consecutive years.
How Power BI Works
Transform & Clean
Relationships & DAX
Charts & Dashboards
Share & Collaborate
Power BI vs Other BI Tools
| Feature | Power BI | Tableau | Looker |
|---|---|---|---|
| Price | Free desktop / $10-$20/user/mo | $70+/user/mo | Custom pricing |
| Best For | Microsoft ecosystem users | Advanced visualization | SQL-first teams |
| Learning Curve | Low-Medium | Medium | Medium-High |
| Formula Language | DAX + Power Query M | Calculated Fields | LookML |
| Data Limits (Free) | 1GB per dataset | Limited | N/A |
Career value: Power BI skills are among the most in-demand for data analysts, business analysts, and financial analysts. LinkedIn consistently ranks it in the top 10 most sought-after technical skills.
🧠 Quick Check
Which Power BI component is a free Windows application for building reports?
Installing Power BI Desktop
Go to powerbi.microsoft.com/desktop or the Microsoft Store
Run the installer (Windows only). ~500MB download.
Use a Microsoft work/school account (optional for local use).
Mac users: Power BI Desktop is Windows-only. Use a VM (Parallels, VMware), Windows 365 Cloud PC, or access the Power BI Service (web) at app.powerbi.com.
The Interface Layout
Key Interface Areas
Report Canvas
The main area where you drag visuals, design layouts, and build your dashboard pages.
Visualizations Pane
Choose chart types (bar, line, pie, map, etc.) and configure visual formatting.
Fields Pane
Lists all tables and columns from your data model. Drag fields onto visuals.
Filters Pane
Apply filters at visual, page, or report level to narrow down displayed data.
Three Views
👁️ View Modes (Bottom-Left Icons)
📊 Report View — Build and design your visualizations and dashboard pages.
📋 Table View (Data View) — See your data in a spreadsheet-like grid. Good for verifying data.
🔗 Model View — View and manage relationships between your tables. Essential for multi-table models.
Get Data
Click Home → Get Data to see all available connectors. The most common ones:
Excel
.xlsx and .xls files. Select specific sheets or tables.
CSV / Text
Comma-separated or tab-delimited flat files.
SQL Server
Direct query or import from SQL Server databases.
Web
Scrape tables from web pages by URL.
SharePoint
Lists and document libraries from SharePoint Online.
Azure / Cloud
Azure SQL, Synapse, Databricks, Snowflake, etc.
Step-by-Step: Importing Excel Data
Connection Modes
| Mode | How It Works | Best For |
|---|---|---|
| Import | Copies data into Power BI's in-memory engine. Fastest queries. | Most scenarios. Files, small-medium databases. |
| DirectQuery | Queries the source database live. No data stored in PBI. | Very large datasets, real-time needs. |
| Composite | Mix Import and DirectQuery tables in one model. | Hybrid scenarios. |
| Live Connection | Connect to SSAS or Power BI datasets. No local model. | Enterprise shared models. |
Always choose "Transform Data" instead of "Load" when importing for the first time. This opens Power Query where you can clean your data before it enters the model — saving headaches later.
Data Refresh
After initial import, you can refresh data to get latest updates:
🔄 Refresh Options
Manual Refresh — Click the Refresh button in Desktop or Service.
Scheduled Refresh — Set up automatic refreshes (up to 8x/day on Pro, 48x on Premium) in the Power BI Service.
Incremental Refresh — Only refresh new/changed data (for large tables).
Gateway Required — For on-premises data sources, install a data gateway.
What is Power Query?
Power Query is the data transformation engine built into Power BI (and Excel). It lets you clean, reshape, merge, and prepare data before it hits your data model. Every step is recorded and replayable.
Clean & Transform
Common Transformations
Remove Columns
Right-click column header → Remove. Keep only what you need.
Rename Columns
Double-click a column header to rename. Use clear, descriptive names.
Change Data Type
Click the type icon (ABC/123) left of column name. Fix numbers stored as text.
Filter Rows
Click the dropdown arrow on any column header to filter values.
Remove Duplicates
Right-click column → Remove Duplicates.
Split Column
Split "Full Name" into "First" and "Last" by delimiter.
Merge Queries
JOIN two tables together (like SQL JOIN). Home → Merge Queries.
Append Queries
Stack tables vertically (like SQL UNION). Home → Append Queries.
Unpivot Columns
Turn wide data (months as columns) into tall data (month as a row field).
Applied Steps
📝 Step-by-Step Recording
Every action you take in Power Query is recorded as an Applied Step in the right panel. Steps are executed in order, top to bottom. You can go back to any step, edit it, delete it, or reorder steps. This makes your transformations reproducible — when data refreshes, all steps are re-applied automatically.
The M Language
Behind every Power Query step is code written in M (Power Query Formula Language). You can view and edit it in the Advanced Editor.
let
Source = Excel.Workbook(File.Contents("C:\Sales.xlsx")),
SalesTable = Source{[Name="Sheet1"]}[Data],
// Promote first row as headers
PromotedHeaders = Table.PromoteHeaders(SalesTable),
// Change types
ChangedTypes = Table.TransformColumnTypes(PromotedHeaders, {
{"Sales", type number},
{"Date", type date}
}),
// Filter out nulls
FilteredRows = Table.SelectRows(ChangedTypes, each [Sales] <> null)
in
FilteredRows
You don't need to learn M! The GUI generates M code automatically. But understanding it helps when you need custom logic or want to debug complex transforms.
Best Practices
1. Remove unused columns early (saves memory). 2. Set correct data types for every column. 3. Rename columns to business-friendly names. 4. Filter out junk/test data. 5. Always use "Close & Apply" when done.
Transformation Sequence
You import a messy Excel file. Put these Power Query steps in the correct order:
A) Change data types B) Remove unneeded columns C) Promote headers D) Filter out blank rows E) Rename columns
Star Schema
The star schema is the gold standard for Power BI data models. It has a central Fact Table (transactions/events) surrounded by Dimension Tables (descriptive attributes).
Month
Quarter
Year
DateKey ⟶
ProductKey ⟶
CustomerKey ⟶
Amount
Quantity
Name
Category
Price
Name
City
Segment
Relationships
In Model View, you connect tables by dragging a column from one table to another. Power BI often auto-detects relationships.
| Relationship Type | Meaning | Example |
|---|---|---|
| One-to-Many (1:*) | One row in dim matches many rows in fact | 1 Product → Many Sales rows |
| One-to-One (1:1) | Each row matches exactly one row | Employee → Employee Details |
| Many-to-Many (*:*) | Many rows on both sides (use with caution) | Students ↔ Courses |
Cross-Filter Direction
🔀 Single vs Both
Single (default, recommended) — Filters flow from Dimension → Fact table only. Clean, predictable behavior.
Both (bi-directional) — Filters flow in both directions. Can cause ambiguity. Use sparingly, only when needed.
Avoid circular dependencies! If Table A filters Table B and Table B filters Table A through different paths, you'll get errors. Keep your model as a clean star schema to prevent this.
Modeling Best Practices
1. Use star schema — one fact table, multiple dimension tables.
2. Always use one-to-many relationships with single-direction filtering.
3. Create a dedicated Date table (essential for time intelligence).
4. Hide foreign key columns from Report View (users don't need to see IDs).
5. Avoid calculated columns when a measure will do (saves memory).
Choosing the Right Visual
| Visual | Best For | Example Use Case |
|---|---|---|
| 📊 Bar/Column Chart | Comparing categories | Sales by Product Category |
| 📈 Line Chart | Trends over time | Monthly Revenue over 3 years |
| 🥧 Pie / Donut | Part-of-whole (≤6 categories) | Market share by region |
| 📋 Table / Matrix | Detailed data, drill-down | Invoice details, pivot-style summaries |
| 🃏 Card / Multi-row Card | Single KPI number | Total Revenue: $2.4M |
| ⏲️ KPI Visual | KPI vs Target | Actual vs Budget with trend |
| 🗺️ Map | Geographic data | Sales by State/Country |
| 🌊 Waterfall | Incremental changes | How profit builds from revenue to costs |
| 🔥 Treemap | Hierarchical proportions | Category → Sub-category breakdown |
| 📏 Gauge | Value against a target range | Customer satisfaction score |
| 🔀 Scatter Plot | Correlation between 2 variables | Price vs. Quantity sold |
| 🎯 Funnel | Sequential stages | Sales pipeline: Leads → Won |
| 📊 Combo Chart | Two different measures | Revenue (bars) + Margin % (line) |
| 🧩 Slicer | Interactive filter control | Date range, category selector |
Building Your First Visual
Slicers — The Most Important Interactive Element
Slicers are visual filters that let users interactively control what data is displayed on the page.
🧩 Slicer Types
List slicer — Dropdown or checkbox list of values.
Date Range slicer — Between dates, Before, After, or Relative date.
Numeric range slicer — Slider for number ranges.
Relative date slicer — "Last 30 days", "This quarter", etc.
Pro tip: Use "Sync slicers" (View → Sync Slicers) to make a slicer control multiple pages at once.
🧠 Quick Check
Which visual is best for showing a trend over time?
Dashboard Design Principles
Purpose First
Every visual should answer a specific question. If it doesn't, remove it.
Visual Hierarchy
Most important KPIs at top-left. Eyes scan in a Z or F pattern.
Consistent Colors
Use a consistent color palette. 3-5 colors max. Use your brand colors.
Alignment & Spacing
Align visuals to a grid. Equal spacing. Use View → Snap to Grid.
Clear Labels
Descriptive titles, proper axis labels, data labels where helpful.
Mobile Layout
Use View → Mobile Layout to design phone-optimized versions.
Format Pane Deep Dive
Select any visual and click the Format (paint roller) icon in the Visualizations pane:
🖌️ Key Formatting Options
General — Size, position, alt text, padding
Title — Show/hide, text, font, color, alignment, background
Data labels — Show values on bars/points, format, position
Legend — Position (top, bottom, left, right), font size
X/Y Axis — Labels, range, gridlines, title
Data colors — Customize individual bar/segment colors
Background — Visual background color, transparency
Border — Outline around the visual
Shadow — Drop shadow effect
Themes
Apply a consistent look across all visuals with themes:
{
"name": "Corporate Dark",
"dataColors": ["#3498db", "#2ecc71", "#e74c3c", "#f39c12", "#9b59b6"],
"background": { "color": "#1a1a2e" },
"foreground": { "color": "#e0e0e0" },
"textClasses": {
"label": { "fontFace": "Segoe UI", "color": "#cccccc" }
}
}
Conditional Formatting
Dynamically color cells, bars, or icons based on values. Right-click a field in the Values well → Conditional formatting:
🌈 Options
Background color — Color scale (green to red for performance)
Font color — Red for negative, green for positive
Data bars — Mini bar charts inside table cells
Icons — ✅❌⚠️ indicators based on rules
Web URL — Make values clickable links
Cross-Filtering & Cross-Highlighting
By default, clicking a bar/segment in one visual filters all other visuals on the page. This is the core interactive behavior.
🔀 Interaction Types
Select a visual → Format → Edit Interactions to control how other visuals respond:
🔍 Filter — Other visuals show only the selected subset.
✨ Highlight — Other visuals dim unrelated data (default for bars).
⛔ None — Other visual ignores the selection entirely.
Drill Down & Drill Through
Drill Down (within a visual)
When a visual has a hierarchy (e.g., Year → Quarter → Month → Day), users can drill into deeper levels:
Drill Through (to another page)
Navigate from a summary to a detail page for a specific item:
Bookmarks & Buttons
Bookmarks save a snapshot of the page state (filters, visibility, scroll position). Combine with buttons for powerful navigation.
📑 Use Cases
Toggle views — Switch between chart and table view of the same data.
Reset filters — "Clear All Filters" button.
Storytelling — Walk through a presentation with bookmark navigation.
Show/hide panels — Toggle a filter panel or info panel visibility.
How: View → Bookmarks pane → Add Bookmark. Then Insert → Button → set Action to Bookmark.
Custom Tooltips
Create a dedicated page and use it as a rich tooltip that appears on hover:
Pro Tip: Custom tooltips are one of the most impressive features for stakeholders. A bar chart showing revenue by product can show a rich tooltip with product image, margin %, and trend mini-chart on hover.
Q&A Visual (Natural Language)
Insert → Q&A lets users type questions in plain English like "What was total sales last quarter by region?" and Power BI auto-generates a visual. Great for self-service exploration.
What is DAX?
DAX (Data Analysis Expressions) is the formula language used in Power BI, Power Pivot, and Analysis Services. It's similar to Excel formulas but designed for relational data models and aggregations.
📐 DAX vs Excel
Excel: Formulas operate on cells → =SUM(A1:A100)
DAX: Formulas operate on columns/tables → SUM(Sales[Amount])
DAX references columns with the syntax: TableName[ColumnName]
Core Aggregation Functions
// Basic Aggregations
Total Sales = SUM(Sales[Amount])
Order Count = COUNT(Sales[OrderID])
Unique Custs = DISTINCTCOUNT(Sales[CustomerID])
Avg Price = AVERAGE(Products[Price])
Max Sale = MAX(Sales[Amount])
Row Count = COUNTROWS(Sales)
CALCULATE — The Most Important Function
CALCULATE modifies the filter context. It evaluates an expression with modified filters — it's the key to almost every advanced DAX pattern.
// Total Sales for Electronics category ONLY
Electronics Sales =
CALCULATE(
SUM(Sales[Amount]),
Products[Category] = "Electronics"
)
// Total Sales ignoring any region filter
Total Sales All Regions =
CALCULATE(
SUM(Sales[Amount]),
ALL(Region)
)
Understanding Filter Context
🔍 Filter Context = The Environment
Every DAX expression evaluates within a filter context — the set of active filters from slicers, visuals, rows, and columns.
When you put [Total Sales] in a bar chart by Category, DAX automatically evaluates SUM(Sales[Amount]) separately for each category. The visual provides the filter context.
CALCULATE lets you override or modify this context.
Key Filter Functions
| Function | Purpose |
|---|---|
ALL(Table) | Remove all filters from a table |
ALLEXCEPT(Table, Col) | Remove all filters except specified columns |
FILTER(Table, Condition) | Return a filtered table (row-by-row evaluation) |
SELECTEDVALUE(Col) | Return the value if exactly one is selected |
HASONEVALUE(Col) | Check if exactly one value is in context |
VALUES(Col) | Return distinct values in current context |
Common mistake: Using FILTER when a simple column condition in CALCULATE would work. CALCULATE(SUM(...), Table[Col] = "X") is more efficient than using FILTER(ALL(Table), ...) for simple conditions.
Write a DAX Measure
Write a measure called Online Sales that calculates total sales amount only where the Sales[Channel] column equals "Online".
Calculated Columns
A new column added to an existing table. Calculated row by row during data refresh. Stored in memory.
// Add a Profit column to the Sales table
Profit = Sales[Revenue] - Sales[Cost]
// Categorize customers by spend tier
Customer Tier =
IF(
Customers[TotalSpend] > 10000, "Gold",
IF(Customers[TotalSpend] > 5000, "Silver", "Bronze")
)
Measures
A formula that calculates at query time based on the current filter context. Not stored row-by-row — computed dynamically.
// Profit Margin %
Profit Margin % =
DIVIDE(
SUM(Sales[Profit]),
SUM(Sales[Revenue]),
0
)
// % of Grand Total
% of Total =
DIVIDE(
SUM(Sales[Amount]),
CALCULATE(SUM(Sales[Amount]), ALL(Sales))
)
// Year-over-Year Growth
YoY Growth % =
VAR CurrentYear = SUM(Sales[Amount])
VAR PriorYear = CALCULATE(
SUM(Sales[Amount]),
SAMEPERIODLASTYEAR(DateTable[Date])
)
RETURN
DIVIDE(CurrentYear - PriorYear, PriorYear, 0)
When to Use Which?
| Calculated Column | Measure | |
|---|---|---|
| Evaluated | Row by row at refresh | Dynamically at query time |
| Stored | Yes — takes memory | No — computed on the fly |
| Filter Context | Has Row Context only | Responds to filter context |
| Use For | Categorization, row-level calc, slicing/filtering | Aggregations, KPIs, ratios, % |
| Can be used in slicer? | ✅ Yes | ❌ No |
Rule of thumb: If the result changes when the user clicks a slicer or filters the visual, it should be a measure. If it's a fixed per-row classification, use a calculated column. When in doubt, use a measure — they're more memory efficient.
DIVIDE — Safe Division
// Always use DIVIDE instead of / for safe division
// DIVIDE returns the 3rd argument (default 0) instead of error
Margin = DIVIDE([Profit], [Revenue], 0)
// Instead of this (will ERROR on divide by zero):
// Margin = [Profit] / [Revenue]
Date Table Requirement
Time Intelligence functions require a proper Date table — a dedicated table with one row per day, no gaps, marked as a Date Table.
DateTable =
ADDCOLUMNS(
CALENDAR(DATE(2020,1,1), DATE(2026,12,31)),
"Year", YEAR([Date]),
"Month", FORMAT([Date], "MMMM"),
"MonthNum", MONTH([Date]),
"Quarter", "Q" & FORMAT([Date], "Q"),
"DayOfWeek", FORMAT([Date], "dddd"),
"YearMonth", FORMAT([Date], "YYYY-MM")
)
Critical: After creating the Date table, right-click it in Model view → "Mark as Date Table" and select the Date column. Without this, Time Intelligence functions won't work correctly.
Essential Time Intelligence Functions
// Year-to-Date Total
Sales YTD =
TOTALYTD(SUM(Sales[Amount]), DateTable[Date])
// Month-to-Date Total
Sales MTD =
TOTALMTD(SUM(Sales[Amount]), DateTable[Date])
// Previous Year (Same Period)
Sales Last Year =
CALCULATE(
SUM(Sales[Amount]),
SAMEPERIODLASTYEAR(DateTable[Date])
)
// Previous Month
Sales Last Month =
CALCULATE(
SUM(Sales[Amount]),
PREVIOUSMONTH(DateTable[Date])
)
// Running Total (Cumulative)
Running Total =
CALCULATE(
SUM(Sales[Amount]),
FILTER(
ALL(DateTable),
DateTable[Date] <= MAX(DateTable[Date])
)
)
// YoY Growth Percentage
YoY Growth % =
VAR CY = SUM(Sales[Amount])
VAR PY = CALCULATE(
SUM(Sales[Amount]),
SAMEPERIODLASTYEAR(DateTable[Date])
)
RETURN
DIVIDE(CY - PY, PY, 0)
Time Intelligence Function Reference
| Function | Returns |
|---|---|
TOTALYTD() | Year-to-date running total |
TOTALMTD() | Month-to-date running total |
TOTALQTD() | Quarter-to-date running total |
SAMEPERIODLASTYEAR() | Shifts dates back by one year |
PREVIOUSMONTH() | Dates from the previous month |
PREVIOUSQUARTER() | Dates from the previous quarter |
DATEADD(dates, -1, YEAR) | Shift dates by any interval |
DATESYTD() | Set of dates from start of year to current |
PARALLELPERIOD() | Shift entire period by intervals |
What is RLS?
Row-Level Security (RLS) restricts data access at the row level. A sales manager in the East region only sees East data, even though the report contains all regions.
Setting Up RLS
// Static RLS: East Region role
[Region] = "East"
// Dynamic RLS: Filter by logged-in user's email
[ManagerEmail] = USERPRINCIPALNAME()
Dynamic RLS using USERPRINCIPALNAME() is far more scalable than creating static roles for every user. Maintain a mapping table (UserEmail → Region/Department) and filter against it.
Testing RLS
In Desktop: Modeling → View as Roles to test each role before publishing. Verify that users only see their allowed data.
Publishing to Power BI Service
Workspaces
📁 Workspace Types
My Workspace — Personal sandbox. Only you can see it.
Shared Workspaces — Collaborative spaces where teams work together. Assign Admin, Member, Contributor, or Viewer roles.
App Workspaces — Staging area for publishing polished "Apps" to the organization.
Sharing Options
| Method | Best For | License Needed |
|---|---|---|
| Share Report | Quick sharing with specific people | Pro or Premium Per User |
| Publish App | Polished, read-only experience for many users | Pro / PPU |
| Embed in Teams | View reports inside Microsoft Teams tabs | Pro / PPU |
| Publish to Web | Public, no-login access (⚠️ no security) | Free |
| Embed in Website | Integrate into internal portals/apps | Embed license |
Scheduled Refresh
🔄 Keep Data Fresh
In the Power BI Service, go to Dataset Settings → Scheduled Refresh:
Pro: Up to 8 refreshes per day
Premium: Up to 48 refreshes per day
On-premises data? Install a Data Gateway to bridge your local network to the cloud service.
Data Model Optimization
Remove Unused Columns
Every column costs memory. If it's not in a visual or DAX, remove it in Power Query.
Reduce Cardinality
Fewer unique values = smaller model. Round timestamps to dates.
Use Integer Keys
Integer joins are much faster than text joins.
Avoid Bi-Directional
Single-direction relationships are faster and more predictable.
DAX Performance Tips
// ✅ GOOD: Use variables (calculated once)
Profit % =
VAR TotalRevenue = SUM(Sales[Revenue])
VAR TotalCost = SUM(Sales[Cost])
RETURN
DIVIDE(TotalRevenue - TotalCost, TotalRevenue, 0)
// ❌ BAD: Repeating the same calculation
// Profit % = DIVIDE(SUM(Sales[Revenue]) - SUM(Sales[Cost]), SUM(Sales[Revenue]))
// ✅ GOOD: Use DIVIDE for safe division
// ❌ BAD: Using / which errors on zero
// ✅ GOOD: Use DISTINCTCOUNT instead of COUNTROWS(VALUES(...))
// ✅ GOOD: Use ISBLANK instead of checking = BLANK()
Performance Analyzer
Use View → Performance Analyzer in Desktop to measure how long each visual takes to render. Click "Start recording", interact with the report, then review results.
📊 What to Look For
DAX query time — If a visual takes >1 second, optimize the measure or reduce data.
Visual display time — Too many data points? Use Top N filters or aggregation.
Other — Network/rendering overhead. Usually not actionable.
Report Best Practices Checklist
1. Use star schema with proper relationships.
2. Create a Date table and mark it as Date Table.
3. Use measures for all aggregations (not implicit).
4. Use VAR in complex measures for readability and performance.
5. Use DIVIDE() instead of / operator.
6. Limit visuals to 8-10 per page (too many = slow).
7. Use bookmarks for toggling, not cramming everything on one page.
8. Apply consistent formatting and naming conventions.
9. Add alt text to every visual for accessibility.
10. Test with Performance Analyzer before publishing.
🎯 Project: Sales Performance Dashboard
📋 Requirements
Build a multi-page Power BI report for the fictional "Contoso Electronics" company. Your dashboard should enable the VP of Sales to monitor performance, identify trends, and drill into details.
Page 1: Executive Summary
KPI Overview Page
Create the following elements:
KPI Cards (top row): Total Revenue, Total Profit, Profit Margin %, Total Orders, Unique Customers
Charts:
— Revenue trend by Month (Line Chart)
— Revenue by Product Category (Horizontal Bar Chart)
— Revenue by Region (Donut Chart)
— Top 10 Products by Revenue (Table with conditional formatting)
Slicers: Date Range, Region, Product Category
Page 2: Product Deep Dive
Product Analysis Page
Visuals to include:
— Revenue by Category and Sub-Category (Decomposition Tree or Matrix with drill-down)
— Product scatter plot: Quantity Sold (X) vs Profit Margin % (Y), sized by Revenue
— Top/Bottom 5 products toggle (using bookmarks + buttons)
— Product detail table with conditional formatting (data bars on Revenue, icons on Margin %)
Interactions: Set up Drill Through from Page 1 — right-click any product to see details.
Page 3: Time Analysis
Time Intelligence Page
Visuals to include:
— YTD vs Prior Year YTD (combo chart: bars + line)
— MoM Growth % (column chart with conditional colors: green positive, red negative)
— Cumulative Revenue Running Total (area chart)
— Seasonal patterns: Revenue by Day of Week (bar chart)
Final Checklist
✅ Before Publishing
☐ All measures are explicitly defined (no implicit aggregations)
☐ Date table created and marked as Date Table
☐ Star schema model with proper relationships
☐ Foreign key columns hidden from Report View
☐ Consistent theme and color palette applied
☐ Slicers synced across pages where appropriate
☐ Drill-through navigation works correctly
☐ Alt text added to all visuals
☐ Performance Analyzer checked (no visual > 2s)
☐ Mobile layout created (View → Mobile Layout)
☐ RLS roles configured and tested (if needed)
🎉 Congratulations!
You've completed the Power BI Mastery course! You've learned the entire stack: connecting to data, Power Query transformations, data modeling, DAX formulas, visualizations, interactivity, security, publishing, and performance optimization.
Keep learning: Explore Microsoft Learn, SQLBI.com (best DAX resource), and practice with the Power BI Sample Datasets. Consider the PL-300 certification to validate your skills!