The dashboard was build in powerbi as an employee survey by HR to better comprehend the satisfaction of employees within the organisation. Each employee within each department was surveyed via phone, email, letter and website with this information collated into a csv file. This served as the data source for the visualisation for further analysis and record keeping by the HR team
The data model from the survey consist of the main table which contain the survey data information. The other tables connected to the main table consist of Survey type, Manager information, employee information, department (all of which have a primary key linked to the secondary key in the survey table) and master date table used to filter out certain time frames.
An employee survey dashboard has one job that is easy to get wrong: a department average means nothing without the company average beside it. Seven out of ten sounds fine until you learn the company sits at eight and a half. So every score in this report is paired with its company benchmark, and the comparison between the two is what the page is actually about.
It is a single page by design. HR reviews are conversations, not exploration sessions, and everything needed for one fits on a screen.
| Table | Grain and role |
|---|---|
| Tbl_Employee | The response table. One row per employee per survey period, carrying Employee_Id and the scored answers, including job satisfaction and work-life balance. |
| Tbl_Department | Department dimension, the axis every comparison is made across. |
| Master dates table | Marked date table on Month & Year, driving the trend lines. |
| All Measures | Disconnected table holding the measures. |
The responses were collected by phone, email, letter and website and collated into a single CSV, so the modelling work here was mostly in shaping inconsistent inbound formats into one clean response table before any DAX was written.
Column names below are taken from the model. These are the measure definitions as the model computes them, not a paste of the formula bar.
Six measures, and they come in pairs. Each question has a filtered average and a company-wide average, with the second removing the department filter so it stays constant while the first moves.
Avg. how satisfied are you with your current job? =
AVERAGE( Tbl_Employee[JobSatisfaction] )
Avg. how satisfied are you with your current job? - whole company =
CALCULATE(
AVERAGE( Tbl_Employee[JobSatisfaction] ),
REMOVEFILTERS( Tbl_Department )
)
Avg. survey score work-life balance? =
AVERAGE( Tbl_Employee[WorkLifeBalance] )
Avg. survey score work-life balance? - whole company =
CALCULATE(
AVERAGE( Tbl_Employee[WorkLifeBalance] ),
REMOVEFILTERS( Tbl_Department )
)
REMOVEFILTERS on the department, not on everything. The benchmark still respects the date slicer, so a department is compared against the company in the same period rather than against an all-time average. Using ALL() instead would quietly break that.
Two measures exist to colour the work-life balance results against the benchmark, returning a colour rather than a value so the table shades itself.
Conditional formating - work-life balance =
VAR Score = [Avg. survey score work-life balance?]
VAR Benchmark = [Avg. survey score work-life balance? - whole company]
RETURN
SWITCH(
TRUE(),
Score >= Benchmark * 1.05, "#2E7D32",
Score < Benchmark * 0.95, "#C62828",
"#F9A825"
)
The thresholds matter more than the colours. A department within five percent of the benchmark is shown as neutral rather than red, because normal variation should not read as a problem. Setting that band deliberately is what stops a heat map turning into an alarm.
The layout runs top to bottom in the order the conversation goes.
The report shows averages, and averages hide distribution. A department averaging seven could be uniformly content or split between very happy and very unhappy people, and those need completely different responses. Adding a distribution view, even a simple count by score band, would surface that. I would also add response rate as a measure, since a department where a third of people answered tells you something in itself, and it qualifies how much weight the score deserves. Beyond that, the natural extension is linking survey scores to attrition, which is the outcome the survey is ultimately a proxy for.