HR Analytics Dashboard in Power BI: Workforce Insights
People analytics is the fastest-growing application of business intelligence in the enterprise — and for good reason. Organizations with mature HR analytics programs have 82% higher three-year average profit than companies with minimal people data capabilities (Deloitte Human Capital Trends). Yet most HR teams still track headcount in Excel spreadsheets and calculate turnover manually in Google Sheets.
Power BI gives HR leaders the same analytical depth that finance and sales teams have had for years — real-time headcount visibility, automated turnover calculations, diversity analytics, and employee lifecycle tracking across the full employee journey from hiring to offboarding.
This guide builds a complete HR analytics platform in Power BI, covering the data model, every critical HR KPI with its DAX formula, and the dashboard pages that drive real workforce decisions.
Key Takeaways
- HR analytics requires a slowly changing dimension (SCD) approach for historical headcount
- Turnover rate calculation must distinguish voluntary vs involuntary separations
- Diversity dashboards require careful privacy design — aggregate, never individual-level where inappropriate
- Employee lifecycle analysis tracks time-to-hire, time-to-productivity, and retention curves
- Absence analytics (Bradford Factor, absence frequency) integrate with payroll data
- DAX measures for headcount are point-in-time (not summed) — requires special calculation patterns
- HRIS systems (Workday, SAP SuccessFactors, BambooHR) all have Power BI connectors
- Row-level security must limit HR data to authorized HR business partners and managers
Data Model for HR Analytics
Core HR Tables
Employee_Snapshot (slowly changing, one row per employee per month):
| Column | Description |
|---|---|
EmployeeID | Employee identifier |
SnapshotDate | Month-end date of snapshot |
Status | Active, On Leave, Terminated |
DepartmentID | FK to Department |
JobLevel | Grade/Band (L1-L8) |
JobTitle | Current job title |
ManagerID | FK to Employee (manager) |
LocationID | FK to Location |
HireDate | Original hire date |
TerminationDate | Termination date (null if active) |
TerminationReason | Voluntary, Involuntary, Retirement, etc. |
BaseSalary | Monthly base salary |
FullTimeEquivalent | 1.0 for FT, 0.5 for PT |
Gender | M/F/Non-binary (anonymized for small groups) |
AgeGroup | Aggregated age band (not raw age) |
Ethnicity | Self-reported ethnic group |
TenureMonths | Months employed at snapshot date |
Hiring_Events (one row per hire):
HireID,EmployeeID,ApplicationDate,OfferDate,AcceptDate,StartDate,DepartmentID,SourceChannel,HiringManagerID,JobRequisitionID
Absence_Records (one row per absence event):
AbsenceID,EmployeeID,StartDate,EndDate,DaysAbsent,AbsenceType,Reason,ApprovalStatus
Performance_Reviews (one row per review):
ReviewID,EmployeeID,ReviewDate,PerformanceRating,ManagerID
Training_Completions (one row per training):
TrainingID,EmployeeID,CompletionDate,ProgramName,HoursCompleted
Headcount Analytics
Headcount Point-in-Time Calculation
Headcount is a snapshot measure (how many employees exist at a point in time), not a sum. This requires special DAX handling:
// Headcount at any selected date
Headcount =
CALCULATE(
COUNTROWS(Employee_Snapshot),
Employee_Snapshot[Status] = "Active",
// Use the latest available snapshot for the selected period
Employee_Snapshot[SnapshotDate] = MAX(Employee_Snapshot[SnapshotDate])
)
// FTE-adjusted Headcount
FTE Headcount =
CALCULATE(
SUMX(
FILTER(Employee_Snapshot, Employee_Snapshot[Status] = "Active"),
Employee_Snapshot[FullTimeEquivalent]
),
Employee_Snapshot[SnapshotDate] = MAX(Employee_Snapshot[SnapshotDate])
)
// Headcount by Department (for matrix/bar chart)
Dept Headcount =
CALCULATE(
[Headcount],
ALLEXCEPT(Employee_Snapshot, Employee_Snapshot[DepartmentID])
)
// Headcount growth (vs prior month)
Headcount MoM Change =
[Headcount] -
CALCULATE(
[Headcount],
DATEADD(Date[Date], -1, MONTH)
)
// Headcount trend (for sparkline or line chart)
Headcount Trend =
CALCULATE(
[Headcount],
REMOVEFILTERS(Date[Month])
)
Turnover Rate Analytics
Turnover is the most-tracked HR metric and the most commonly miscalculated. The correct formula uses the average headcount as the denominator (not beginning or ending headcount).
Turnover KPIs
// Total Terminations in Period
Terminations =
CALCULATE(
COUNTROWS(Employee_Snapshot),
Employee_Snapshot[Status] = "Terminated",
Employee_Snapshot[TerminationDate] >= MIN(Date[Date]),
Employee_Snapshot[TerminationDate] <= MAX(Date[Date])
)
// Voluntary Terminations (resigned)
Voluntary Terminations =
CALCULATE(
[Terminations],
Employee_Snapshot[TerminationReason] = "Voluntary"
)
// Involuntary Terminations (laid off, fired)
Involuntary Terminations =
CALCULATE(
[Terminations],
Employee_Snapshot[TerminationReason] = "Involuntary"
)
// Average Headcount (for turnover denominator)
Avg Headcount =
AVERAGEX(
VALUES(Date[Month]),
[Headcount]
)
// Annualized Turnover Rate
Turnover Rate =
DIVIDE(
[Terminations],
[Avg Headcount],
0
) * 12 -- Annualize if showing monthly data
// Voluntary Turnover Rate
Voluntary Turnover Rate =
DIVIDE([Voluntary Terminations], [Avg Headcount], 0) * 12
// Regrettable Turnover (voluntary + high performers)
Regrettable Turnover =
CALCULATE(
[Voluntary Terminations],
RELATED(Performance_Reviews[PerformanceRating]) >= 4 -- High performers
)
// Retention Rate
Retention Rate = 1 - [Turnover Rate]
// New Hire Survival Rate (% of new hires still employed after 90 days)
90 Day Survival Rate =
DIVIDE(
CALCULATE(
COUNTROWS(Hiring_Events),
DATEDIFF(Hiring_Events[StartDate], TODAY(), DAY) >= 90,
RELATED(Employee_Snapshot[Status]) = "Active"
),
CALCULATE(
COUNTROWS(Hiring_Events),
DATEDIFF(Hiring_Events[StartDate], TODAY(), DAY) >= 90
),
0
)
Diversity, Equity, and Inclusion Metrics
Privacy-Aware DEI Analytics
DEI analytics must be implemented with privacy guardrails — never display individual-level data by sensitive attributes, and suppress data for groups smaller than a configurable minimum (typically 5-10 employees).
// Gender ratio (with suppression for small groups)
Gender Ratio Female =
VAR FemaleCount = CALCULATE([Headcount], Employee_Snapshot[Gender] = "Female")
VAR TotalCount = [Headcount]
RETURN
IF(TotalCount >= 10, DIVIDE(FemaleCount, TotalCount, 0), BLANK())
// Pay equity ratio (female to male)
Gender Pay Ratio =
VAR FemalePay = CALCULATE(
AVERAGE(Employee_Snapshot[BaseSalary]),
Employee_Snapshot[Gender] = "Female"
)
VAR MalePay = CALCULATE(
AVERAGE(Employee_Snapshot[BaseSalary]),
Employee_Snapshot[Gender] = "Male"
)
RETURN DIVIDE(FemalePay, MalePay, 0)
// Leadership diversity (% of senior roles filled by underrepresented groups)
Leadership Diversity % =
DIVIDE(
CALCULATE(
[Headcount],
Employee_Snapshot[JobLevel] IN {"L6","L7","L8"},
Employee_Snapshot[Gender] = "Female"
),
CALCULATE(
[Headcount],
Employee_Snapshot[JobLevel] IN {"L6","L7","L8"}
),
0
)
DEI Dashboard KPIs
| KPI | Formula | Target |
|---|---|---|
| Gender Balance | Female % of total headcount | 50% ± 5% |
| Gender Pay Gap | Female avg salary / Male avg salary | > 97% |
| Leadership Diversity | Underrepresented groups in senior roles | > 30% |
| Diverse Hiring Rate | Diverse hires / total hires | > 40% |
| Promotion Equity | Promotion rate by gender/ethnicity | ± 2% between groups |
Employee Lifecycle Analysis
Time-to-Hire
// Average days from job posting to offer acceptance
Avg Time to Hire =
AVERAGEX(
Hiring_Events,
DATEDIFF(
Hiring_Events[ApplicationDate],
Hiring_Events[AcceptDate],
DAY
)
)
// Offer Acceptance Rate
Offer Acceptance Rate =
DIVIDE(
CALCULATE(COUNTROWS(Hiring_Events), Hiring_Events[AcceptDate] <> BLANK()),
CALCULATE(COUNTROWS(Hiring_Events), Hiring_Events[OfferDate] <> BLANK()),
0
)
// Source Channel Effectiveness (hired employees by source)
Source Hire Rate =
DIVIDE(
COUNTROWS(Hiring_Events),
CALCULATE(
COUNTROWS(Hiring_Events),
REMOVEFILTERS(Hiring_Events[SourceChannel])
),
0
)
Tenure Distribution
// Tenure bucket (for histogram)
Tenure Bucket =
SWITCH(TRUE(),
Employee_Snapshot[TenureMonths] < 3, "0-3 months",
Employee_Snapshot[TenureMonths] < 12, "3-12 months",
Employee_Snapshot[TenureMonths] < 24, "1-2 years",
Employee_Snapshot[TenureMonths] < 60, "2-5 years",
Employee_Snapshot[TenureMonths] < 120, "5-10 years",
"10+ years"
)
// Average Tenure at Separation
Avg Tenure at Separation =
AVERAGEX(
FILTER(Employee_Snapshot, Employee_Snapshot[Status] = "Terminated"),
Employee_Snapshot[TenureMonths]
)
Absence Analytics
Absence KPIs
// Absence Rate (% of working days lost)
Absence Rate =
DIVIDE(
SUM(Absence_Records[DaysAbsent]),
[Headcount] * NETWORKDAYS(MIN(Date[Date]), MAX(Date[Date])),
0
)
// Bradford Factor (frequency-weighted absence score)
// B = S² × D (S = absence episodes, D = total days)
Bradford Factor =
VAR Spells = COUNTROWS(Absence_Records)
VAR Days = SUM(Absence_Records[DaysAbsent])
RETURN Spells * Spells * Days
// Average Absence Days per Employee
Avg Absence Days =
DIVIDE(SUM(Absence_Records[DaysAbsent]), [Headcount], 0)
// Absence by Type (breakdown)
Medical Absence Days =
CALCULATE(
SUM(Absence_Records[DaysAbsent]),
Absence_Records[AbsenceType] = "Medical"
)
5-Page HR Dashboard Architecture
Page 1: Workforce Overview
- Headcount KPI card (current vs prior year)
- FTE Headcount (actual vs target)
- Headcount by Department (bar chart)
- Headcount trend 12 months (line chart)
- New Hires vs Terminations (butterfly/comparison bar chart)
- Geographic headcount map
Page 2: Turnover Analysis
- Annualized Turnover Rate (gauge vs industry benchmark)
- Voluntary vs Involuntary (donut chart)
- Turnover by Department (sorted bar chart, highest first)
- Turnover by Tenure Band (histogram)
- Turnover trend 24 months (line chart)
- Exit reason breakdown (treemap)
Page 3: Talent Acquisition
- Time-to-Hire trend (line chart by month)
- Offer Acceptance Rate (KPI card)
- Hires by Source Channel (bar chart)
- Open Requisitions by Department (table)
- Hiring funnel (from applications to starts)
- Cost-per-Hire by department
Page 4: Diversity & Inclusion
- Gender balance by level (stacked bar chart)
- Gender pay gap by department (bar chart)
- Diversity hire rate trend (line chart)
- Promotion rate by gender (grouped bar)
- Team diversity index by manager
Page 5: Absence & Wellbeing
- Absence rate by department (heat map)
- Bradford Factor distribution
- Absence by reason (pie chart)
- Absence trend (12-month line chart)
- Absence vs performance correlation scatter plot
Frequently Asked Questions
How do I connect Power BI to Workday or SAP SuccessFactors?
Workday provides a Prism Analytics module and REST API that Power BI can connect to via the Web connector using OAuth authentication. SAP SuccessFactors exposes OData APIs for employee data. For both systems, the recommended architecture for large enterprises is: HRIS → Fivetran or Talend pipeline → Snowflake/Azure Synapse → Power BI. This decouples the analytical layer from the HRIS and avoids API rate limit issues.
How do I protect sensitive employee data in Power BI?
Apply multiple layers of protection: Row-level security restricts which employees' data each viewer sees (e.g., managers see only their direct reports, HRBP sees their assigned business units). Apply Microsoft Information Protection sensitivity labels to datasets containing personal data. Never display salary data at the individual employee level in shared dashboards. For diversity analytics, suppress metrics for groups smaller than 10 employees. Ensure your organization's data privacy policy explicitly permits People Analytics use.
What is the difference between headcount and FTE?
Headcount counts employees regardless of their working hours (a part-time employee counts as 1). FTE (Full-Time Equivalent) weights by working hours — a 50% part-time employee counts as 0.5 FTE. Use headcount for absolute employee counts (e.g., "we have 500 employees"). Use FTE for capacity planning and cost modeling (e.g., "we have 430 FTE worth of capacity"). Both measures are important and serve different purposes.
How do I calculate turnover rate correctly?
Turnover rate = (Number of separations / Average headcount) × 100. The key is the denominator — use the average of beginning and ending headcount for the period, not just the ending headcount. For rolling 12-month turnover, sum the last 12 months of separations and divide by the 12-month average headcount. Many organizations incorrectly use ending headcount, which inflates turnover in growing organizations.
Can Power BI show predictive attrition risk for individual employees?
With Azure Machine Learning integration, yes. Build an attrition prediction model in Azure ML using historical features (tenure, performance rating, engagement score, last promotion date, salary vs market, manager rating) and output an attrition probability score for each current employee. Connect this score to Power BI and display it in a manager dashboard showing their team's flight risk — allowing proactive retention conversations before employees resign.
Next Steps
HR analytics in Power BI gives people leaders the same data-driven decision making that finance and sales teams have had for years. Understanding who is leaving, why, from which teams, and at what tenure gives HR the insight to intervene earlier and retain the talent that matters most.
ECOSIRE's Power BI team builds complete HR analytics platforms — from HRIS data pipeline design to interactive People Analytics dashboards with appropriate privacy controls and role-based access.
Explore our Power BI dashboard development services to understand our HR analytics approach, or contact our team to discuss your workforce analytics requirements and data sources.
Written by
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Unlock Data-Driven Decisions
Custom Power BI dashboards, data modeling, and embedded analytics solutions.
Related Articles
Power BI vs Tableau 2026: Complete Business Intelligence Comparison
Power BI vs Tableau 2026: head-to-head on features, pricing, ecosystem, governance, and TCO. Clear guidance on when to pick each and how to migrate.
Data Warehouse for Business Intelligence: Architecture & Implementation
Build a modern data warehouse for business intelligence. Compare Snowflake, BigQuery, Redshift, learn ETL/ELT, dimensional modeling, and Power BI integration.
Odoo Planning: Resource Scheduling & Shift Management Guide
Master Odoo 19 Planning with shift templates, open shifts, employee availability, conflict detection, and mobile scheduling for workforce management.