This is a post I wrote specifically to support my entry to the Storytelling With Data's community monthly challenge for June, which is to create a funnel chart.
The real challenge of doing this in PowerBI is that native funnel diagram visual is terrible. Sure, if you have enough slices it just about looks kinda funnelly. But otherwise you just have a bar chart that’s centre aligned and rarely looks anything like a funnel at all (and is ugly to boot).- Creating a calculated table in DAX to get the data in a format that the native funnel tool can use; where…
- you have sections consisting of many, very thin slices which allows you to get the slope shapes that you want by…
- using maths to using make each slice decreasingly smaller between the values required.
For each date and each of the two campaign I'd get the number of calls who we couldn't contact, the number we contacted and who didn't renew and the number we contacted and they did review.
Funnel Casual =
- VAR k = 25 // (Main sections - must be odd)
- VAR j = 15 // (Sloping sections must be odd)
- VAR FilteredTable1 = Table
- // SECTION A
- /////////////
- VAR TotalOutboundCalls = SUMX(FilteredTable1, 'Table'[Calls])
- VAR LengthValueCalls = TotalTableCalls / k
- VAR SectionA =
- ADDCOLUMNS(
- GENERATESERIES(401, 400 + k, 1),
- "ID", [Value],
- "Length", LengthValueCalls
- )
- //SECTION C
- ////////////
- VAR FilteredTable3 =
- FILTER(
- FilteredTable1,
- 'Table'[Contact] = "Yes"
- )
- VAR TotalTableContacts = SUMX(FilteredTable3, 'Table'[Calls])
- VAR LengthValueContacts = TotalTableContacts / k
- VAR SectionC =
- ADDCOLUMNS(
- GENERATESERIES(201, 200 + k, 1),
- "ID", [Value],
- "Length", LengthValueContacts
- )
- //SECTION E
- ////////////
- VAR FilteredTable5 =
- FILTER(
- FilteredTable1,
- 'Table'[Renewal] = "Yes"
- )
- VAR TotalTableRenewals = SUMX(FilteredTable5, 'Table'[Calls])
- VAR LengthValueRenewals = TotalTableRenewals / k
- VAR SectionE =
- ADDCOLUMNS(
- GENERATESERIES(1, k, 1),
- "ID", [Value],
- "Length", LengthValueRenewals
- )
- //SECTION B
- ////////////
- VAR LengthIncrementB = (LengthValueCalls - LengthValueContacts) / (j - 1)
- VAR SectionB =
- ADDCOLUMNS(
- GENERATESERIES(301, 300 + j, 1),
- "ID", [Value],
- "Length", IF([Value] = 301, LengthValueContacts, LengthValueContacts + (LengthIncrementB * ([Value] - 301)))
- )
- //SECTION D
- ////////////
- VAR LengthIncrementD = (LengthValueContacts - LengthValueRenewals) / (j - 1)
- VAR SectionD =
- ADDCOLUMNS(
- GENERATESERIES(101, 100 + j, 1),
- "ID", [Value],
- "Length", IF([Value] = 101, LengthValueRenewals, LengthValueRenewals + (LengthIncrementD * ([Value] - 101)))
- )
- RETURN
- UNION(SectionA, SectionB, SectionC, SectionD, SectionE)
If you have a more complicated table, or just one in a different format you can use line 4 to create / summarize / format / filter it as you wish first.