Hi all. Here’s my submission for Data Challenge 14, Emergency Services Analytics. I chose to concentrate on the technical infrastructure rather than focus on the ultimate utility of the final report, and proceeded with the following goals:
- To gain experience using two separate dataset and report PBIX files
- To evaluate all of the best practices listed in my recent Enterprise DNA YouTube series and comment on how they applied to this challenge submission
- To gain experience using JSON theme files and try to do as little formatting via the UI as possible
NOTE:
Unfortunately, it looks like Publish-to-Web is not supported when using shared datasets:
What I liked:
- I’m extremely happy with the use of separate PBIX files for the dataset and the report. Although their use did not serve any purpose for this challenge, I can easily see that this is an exceptional way to develop where others can make use of your dataset; I wholeheartedly recommend it for any organization that has multiple people working on a reporting project, as it both facilitates the separation of duties and the dataset endorsement process.
- I’m quite happy with the content of my YouTube series on the best practices; I was able to gain first-hand experience trying to use only those best practices and have come up with quite a satisfactory (on the surface) looking report.
- I’m quite happy with the time saved by using a custom JSON theme file, as I didn’t have to change any fonts, font sizes, font colours, or background colours during development; I plan to use this technique for future development to both save time and standardize the consistency of the output
What I didn’t like / needs more work:
- I’m not happy with the final report, and would have liked to spend much more time on creating a more insightful report, but the extra time required to flip back and forth between the separate dataset and report PBIX files consumed more than I thought, and with the technical focus of this submission, I ran out of the time I had allotted for this challenge
Findings / Notes:
- I was unable to find the correct syntax to set the custom properties I wanted for minimal shadows for visuals by JSON, so I ended-up using the UI to set the custom properties
- I was unable to find the correct syntax to set the style I wanted for matrix and table visuals by JSON, so I ended-up using the UI to set the style to “None”
- I was unable to find the correct syntax to set the default and on-hover behaviour for the “Reset Filters” button, so I ended-up using the UI to set the on-hover behaviour
- although I set the summarization to NONE in the “thick” dataset PBIX, the changes were not (not always) reflected in the “thin” report PBIX, and I needed to set the summarization again using the ribbon
Review of Best Practices:
Pillar | ID | Best Practice | Notes |
---|---|---|---|
Pre-Development Setup | 1 | Auto date/time: Disable | Done |
2 | Auto detect relationships: Disable | Done | |
3 | Use cross filtering instead of cross highlighting: Enable | Done | |
4 | Separate dataset from report | Done | |
Data Loading and Transformation | 5 | Use dedicated [Dates] table and mark as a date table | Done |
6 | Source: Use existing report/dataset before developing new | N/A | |
7 | Stage and reference data | Done | |
8 | Performance - Data Volume: Reduce as much as possible | N/A | |
9 | Performance - Query Folding: Enable as much as possible | N/A | |
10 | Performance - Data Connectivity Mode: Use Import if possible | Done | |
11 | Location/Shape | N/A | |
12 | Naming/Data Types | Done | |
13 | Granularity: Strive to source data at coinsistent granularity | N/A | |
Data Modelling | 14 | Star Schema | Done |
15 | Waterfall Layout: Lookup tables above fact tables | Done | |
16 | Waterfall Layout: Measure tables at top-right (columns) | Done | |
17 | Waterfall Layout: Supporting tables at bottom-left (rows) | Done | |
18 | Use Manage Relationships dialog | Done | |
19 | Use Edit Relationships dialog | Done | |
20 | Use 1-to-many relationships/avoid bi-directional relationships | Done | |
21 | Use Active and Inactive Relationships | Done | |
22 | Use Measure Tables | Done | |
23 | Rename linking columns (Key) | Done | |
24 | Column Visibility: hide key, sort | Done | |
DAX Calculations | 25 | Format DAX | Done |
26 | Comment DAX | N/A | |
27 | Variables: Use verbose variable names | Done | |
28 | Variables: Use underscore prefix | Done | |
29 | Variables: Use RETURN _result | Done | |
30 | Qualification: columns are; measures are not | Done | |
31 | Use CALCULATE: To change the context of a calculation | Done | |
32 | Use DATEADD: Most versatile / easy copy-and-paste | Done | |
33 | Use DIVIDE instead of arithmetic division; error handling | Done | |
34 | Use SWITCH TRUE instead of nested IF statements | Done | |
35 | Virtual Tables: Use SUMMARIZE to construct the base table | Done | |
36 | Virtual Tables: Use ADDCOLUMNS to construct the extended table | Done | |
37 | Virtual Tables: Use @ prefix on extended columns | Done | |
38 | Use USERELATIONSHIP: To activate inactive relationships | N/A | |
39 | Measures: Use Measures instead of calculated columns where possible | Done | |
40 | Measures: Use Measure Branching | Done | |
41 | Measures: Use Measure Groups (Measure Tables) | Done | |
42 | Context | N/A | |
43 | Aggregation / Iteration (e.g., SUM, SUMX, etc.) | N/A | |
Reports and Visualizations | 44 | Use FORMAT / GENERAL to adjust X/Y/Width/Height to multiples of 10 px | Done |
45 | Use Model View to turn off summarization | Done | |
46 | Keep Selection pane and Bookmarks pane visible at all times | Done | |
47 | Set format of date columns to dd-mmm-yyyy | Done | |
48 | Set Matrix column width | N/A | |
49 | Think in grids / align visuals | Done | |
50 | Use transparent colours | N/A | |
51 | Use table-first development (TFD) | Done | |
52 | Use Reset Slicers bookmark and button | Done | |
53 | Use Slicer Selection echo area | N/A | |
54 | Use button On Hover behaviour to add interactivity | Done | |
55 | Use textboxes with measures to add dynamic narratives | Done | |
56 | Set the data category for location fields | N/A | |
57 | Use Edit Interactions to modify filter effect on visuals | N/A | |
58 | Use Selection pane to name and order all visuals | Done | |
59 | Identifiers: add report ID, version, version date, last refresh date | Done | |
60 | Performance: Minimize number of visuals per page | Done | |
61 | Performance: Use dropdown slicers in lieu of list slicers | N/A | |
62 | Performance: Collapse filter pane before saving | Done |
Here’s the notes I kept during development:
Dataset PBIX
- ensured options for “Import relationships from data sources on first load” and “Auto-detect new relationships after data is loaded” were unchecked (disabled)
- (from File \ Options and settings \ Options \ Current File\ Data Load \ Relationships)
- ensured option for “Change default visual interaction from cross highlighting to cross filtering” was checked (enabled)
- (from File \ Options and settings \ Options \ Current File\ Report Settings \ Visual Options)
- created parameters for source path name and file name
- loaded all data from source Excel workbook as staging queries, using [parameterSourcePath] and [parameterSourceFile]
- *** NOTE: while setup with a local folder only, the use of parameters for source path and file would allow the use of online files (OneDrive for Business) and, if the dataset is deployed to DEV, TEST, and PROD workspaces, the dataset in each workspace could be easily configured in the Power BI Service to use the appropriate folder and file ***
- added parameters for source path and source file
- updated staging queries to use source path and source file parameters, including check for ending ""
- renamed all “…ID” fields to use “… Key” suffix to improve clarity in linking
- created reference for each table from staging queries
- added [Dates] table from Enterprise DNA M Code Showcase (Extended Dates table):
- [Dispatch Codes]:
- replaced #(tab) with empty string
- replaced #(cr) with empty string
- replaced #(lf) with empty string
- split [Protocol] column and removed left or colon; renamed [Protocol Full]
- added new calculated column in DAX to shorten the protocol description to make visuals easier to read
Protocol =
TRIM(
SWITCH( TRUE(),
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Abdominal" ), "Abdominal",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Allergies" ), "Allergies",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Animal" ), "Animal",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Assault" ), "Assault",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Back" ), "Back",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Breathing" ), "Breathing",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Burns" ), "Burns",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Inhalation" ), "Inhalation",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Cardiac" ), "Cardiac/Respiratory",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Chest Pain" ), "Chest Pain",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Diabetic" ), "Diabetic",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Drowning" ), "Drowning",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Electrocution" ), "Electrocution",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Eye" ), "Eye",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Heart" ), "Heart",
CONTAINSSTRING( 'Dispatch Codes'[Protocol Full], "Exposure" ), "Exposure",
'Dispatch Codes'[Protocol Full]
)
)
- [Dates]:
- marked as a date table
- changed date format to dd-mmm-yyyy
- [Hospitals]:
- split [Hospital] column by right-most space, renamed [Hospital.1] column to [Hospital], removed [Hospital.2] column
- [Patients]:
- renamed [Gender] to [Gender Code]
- added calculated column for [Gender] (Female, Male, Other)
- [Calls]:
- renamed columns:
- [DateTimeOfCall] to [Call DateTime]
- [Ambulance DepartureTime] to [Station DateTime]
- [Ambulance ArrivalTimePatient] to [Patient DateTime]
- [Ambulance ArrivalTimeHospital] to [Hospital DateTime]
- [Ambulance JobCompleteTime] to [Complete DateTime]
- used “Change Type \ Using Locale…” to change type of [Call DateTime] column from “Text” to “Date/Time” (used locale “English (United Kingdom)”)
- split [Call DateTime] by delimiter (space) into [Call Date] and [Call Time]
- created custom columns for durations in minutes (whole number) between:
- Call to Station
- Station to Patient
- Patient to Hospital
- Hospital to Complete
- Call to Complete
- created custom column for [Call Time Key] in HHmm format (24-hour clock) (for subsequent linking)
- renamed columns:
- added [Times] table from Enterprise DNA M Code Showcase:
- added [Last Refresh] table from Enterprise DNA M Code Showcase
- Adding a Last Refresh date to your Report
- hid [Last Refresh] table
- added [Dataset Measures] measures table
- added measures for dataset identifiers: ID, Version, Version Date
- added [Last Refresh] measure
- added measures for dataset maximum and minimum date
- added measures for [Total Calls], [Response Time (Call to Patient)], [Transport Time (Patient to Hospital)], [Ambulance Time (Station to Complete)]
- used measure branching to create measures for [Call Time]
Report PBIX
General:
- ensured options for “Import relationships from data sources on first load” and “Auto-detect new relationships after data is loaded” were unchecked (disabled)
- (from File \ Options and settings \ Options \ Current File\ Data Load \ Relationships)
- ensured option for “Change default visual interaction from cross highlighting to cross filtering” was checked (enabled)
- (from File \ Options and settings \ Options \ Current File\ Report Settings \ Visual Options)
- used theme JSON file to set all font family for all visuals to Segoe, text colour to white
- retrieved Power BI dataset (to make this a “thin” report)
- added [_Report Measures] measures table to this “thin” report
- browsed PowerPoint and chose dark red abstract slide design and exported as PNG; used exported PNG as page background for PBIX
- used the “Image to Colours” function of the Colour Theme Generator app on the Enterprise DNA Analyst Hub to extract the HEX codes from the page background image; chose #481818 (dark maroon) as a “base” colour
- used the “Colours Fan” function of the Colour Theme Generator app of the Enterprise DNA Analyst Hub with #481818 to generate an 8-colour theme
- used “Just Color Picker” to grab the HEX codes of the colour theme and saved as a text file
- used Visual Studio Code to update the “dataColors” section of the JSON theme file with the extracted HEX codes
- used Visual Studio Code to update the “visualStyles” section of the JSON theme file with visual title font colour, visual title background colour, and visual background colour
- used “View \ (Themes downarrow) \ Browse for themes” and selected the JSON theme file
- edited the JSON theme file to adjust the title font size as needed, then re-applied the JSON theme file
Visualizations:
Header:
- used textbox at left for title
- used button for “Reset Slicers”
- actions the “Reset Slicers” bookmark
- altered the on-hover behavior of the button to implement button interactivity
- used date slicer
- used rectangle for background with custom shadow (bottom, grey, minimal) [theme colour 7, 50% transparency]
Body:
- used bar chart for “Calls by Hospital”
- used table with data bars for “Calls by Dispatch Code”
- used column chart for “Calls by Time” (2-hour intervals)
- used multi-row card for [Total Calls], [Average Response Time], [Average Ambulance Time], [Average Transport Time], and [Average Handover Time] measures
- used stacked bar chart for “Handover Times by Hospital” with gender as stacks/legend
- used table with data bars for “Response Time by Staff”
- used matrix for “Calls by Hospital and Station”; used [Matrix Spacer] measure and auto-size column width property to make matrix column with consistent
Footer:
- used textbox at left with measures for dataset admin (id, version, version date) and report admin (id, version, version date)
- used textbox at right with measures for dataset date range (to, from) and dataset last refresh date
- used rectangle for background with custom shadow (top, grey, minimal) [theme colour 7, 50% transparency]
C14 Theme.json (1.8 KB)
Contents of JSON Theme file:
{
"name": "C14 Theme",
"dataColors": [
"#D78888",
"#CC6666",
"#C14444",
"#A13636",
"#7E2A2A",
"#5C1F1F",
"#481818",
"#260D0D"
],
"visualStyles": {
"*": {
"*": {
"title": [
{
"fontColor": {
"solid": {
"color": "#FFFFFF"
}
},
"background": {
"solid": {
"color": "#481818"
}
}
}
],
"background": [
{
"color": {
"solid": {
"color": "#481818"
}
},
"transparency": 50
}
]
}
}
},
"textClasses": {
"callout": {
"fontSize": 30,
"fontFace": "Segoe UI Bold",
"color": "#FFFFFF"
},
"title": {
"fontSize": 12,
"fontFace": "Segoe UI Bold",
"color": "#FFFFFF"
},
"header": {
"fontSize": 12,
"fontFace": "Segoe UI Semibold",
"color": "#FFFFFF"
},
"label": {
"fontSize": 10,
"fontFace": "Segoe UI",
"color": "#FFFFFF"
},
"largeLabel": {
"fontSize": 16,
"fontFace": "Segoe UI Bold",
"color": "#FFFFFF"
}
},
"firstLevelElements": "#FFFFFF",
"secondLevelElements": "#FFFFFF"
}