PowerBI visual with cumulative total over quarters and another field - powerbi

I have the following graph created. It tracks the count of a certain even in a quarter by groups (i erased the group names and renamed them (ABC's due to sensitive data).
I need the graph to show the cumulative value that is to say for example. Q1 A=1, Q2 A=3, Q3 A=5.
I have played around with quick measures but I can't seem to make them breakdown the accumulation by group, Only quarter (Q1 =1, Q2 =6, etc).
I think i need to create a quick-measure of a quick-measure but I am not sure the order and what the measures would look like.
There are only 2 relevant fields: date_of_event and group
X axis: date of event (by year and quarter), group
y axis: count of date_of event
Thanks

For this, you'll definitely benefit from a date dimension and a dimension for your group. There are many template date dimensions out there, but I'm partial to mine. A group dimension for you may be as simple as just taking the distinct values of your existing [Group] field.
Time intelligence is basically always easier when your model is dimensionalized.
With that, you'd set up relationships as below:
'DimDate'[Date] -1:N-> 'YourEventTable'[Date_Of_Event]
'DimGroup'[Group] -1:N-> 'YourEventTable'[Group]
With that in place, you can use the built-in time intelligence functions or roll your own (examples of rolling your own in my linked date dimension repo).
Events = COUNTROWS ( 'YourEventTable' )
Events YTD = TOTALYTD ( [Events], 'DimDate'[Date] )
If you need an all-time cumulative, instead, you can use this:
Events All-time Cumulative =
VAR CurrentDate = MAX ( 'DimDate'[Date] )
RETURN
CALCULATE (
[Events],
ALL ( 'DimDate' ),
'DimDate'[Date] <= CurrentDate
)
Make sure to always use dimension fields for axis labels and such, and never the same from the fact table.

I had encounter it early this week and below is my DAX for the Cumulative total measure,
Cumulative Total =
CALCULATE (
SUMX (
Table,
IF ( DISTINCTCOUNT ( Table[UserID] ) > 0, 1, 0 ) //Put your Group Here
),
FILTER (
ALLSELECTED ( Table ),
Table[InitialAccessDate] //Date of event
<= MAX ( Table[InitialAccessDate] ) //Date of event
)
)
I hope it helps!! Cheers!!

Related

DAX formula to find second minimum with filters

I have asked a similar question a while back to which I received an answer at this page : DAX formula to find second minimum with extra criteria
My problem has changed slightly and I cannot find a solution.
I have a table with cities, types of expenses and Value of said expense.
I want to create a calculated measure that finds the 2nd minimum value between the different cities for a given expense. Cities can be filtered down with a slicer and 2nd min needs to adjust to this change.
The goal is to have a chart showing expenses and cities as rows and value/2ndmin as values.
The chart would show the first expense on the left with all the cities and 2nd min value for these, the second expense with all the cities and 2nd min value for these etc. Chart should be able to show many expenses and 2nd min should adjust to any of these.
Some code was provided in the other post which worked fine for my first request, but I haven't been able to tweak it in order to make it work for this.
I work through power pivot on Excel which doesn't allow all functions like RemoveFilters, but I found that "All" seems to work the same for the purpose described in the other post.
Can anyone help ?
Thank you very much !
This is the measure from the previous answer reworked to ignore categories and to use the slicer selection
SecondMin =
VAR CurrentExpense =
SELECTEDVALUE ( Costs[Expense] )
RETURN
IF (
NOT ISBLANK ( CurrentExpense ),
VAR CostsSelected =
FILTER ( ALLSELECTED ( Costs ), Costs[Expense] = CurrentExpense )
VAR MinValue =
MINX ( CostsSelected, Costs[Value] )
VAR Min2Value =
MINX ( FILTER ( CostsSelected, Costs[Value] > MinValue ), Costs[Value] )
VAR Result =
IF (
COUNTROWS ( FILTER ( CostsSelected, Costs[Value] = MinValue ) ) > 1,
MinValue,
Min2Value
)
RETURN
IF ( NOT ISEMPTY (Costs), Result + 0 )
)
The resulting table adapts automatically to the slicer

How can I get DAX to return just the record with a date closest to the slicer?

I'm hoping someone can help as I've completely run out of ideas.
I'm working on performance reporting data, producing a number of visuals to summarise the most recent data. To allow users to retrospectively produce reports from previous quarters, I have added a date slicer as a way to "View data as at xxxx date".
Here's a rough representation of my data table - the due dates are in English format (dd/mm/yyyy):
The ratings are calculated in another system (based on a set of targets), so there are no calculated columns here. In reality, there are a lot more measures that report on different time periods (some weekly, some annually, etc) and there are different lags before the data is "due".
I eventually managed to get a measure that returned the latest actual:
MostRecentActual =
VAR SlicerDate = MAX ( Dates[Day] )
RETURN
CALCULATE (
SUM ( Data[Actual] ),
Data[Data due] <= SlicerDate,
LASTDATE ( Data[Data due] )
)
I'm not completely sure I've done it right but it seems to work. I'd be happier if I understood it properly, so explanations or alternatives would be welcomed.
What I'm trying to do now is a basic summary pie chart at the beginning which shows the proportion of the measures that were red, amber, green or unrated as at the date selected. So I would need it to count the number of each rating, but only one for each measure and only for the date that is closest to (but before) the slicer date, which would vary depending on the measure. So using the above three measures, if the slicer was set to 10/10/2019 (English format - dd/mm/yyyy), it would count the RAGs for Q3 2019/20 for measures A an C and for Q2 2019/20 for measure B as there is a time lag which means the data isn't ready until the end of the month. Results:- A: Amber, B: Green, C:Red.
If I were able to create the measure that counted these RAGs, I would then want to add it to a pie chart, with a legend that is "Rating", so it would split the chart up appropriately. I currently can't seem to be able to do that without it counting all dates before the slicer (not just the most recent) or somehow missing ratings from the total for reasons I don't understand.
Any help would be very gratefully received.
Many thanks
Ben
Further update. I've been working on this for a while!
I have created a COUNTAX measure to try to do what I was wanting to do. In some circumstances, it works, but not all and not in the crucial ones. My measure is:
TestCountaxpt2 =
VAR SlicerDate = MAX ( Dates[Date] )
VAR MinDiff =
MINX (
FILTER (
ALL ( Data ),
Data[Ref] IN VALUES ( Data[Ref] ) &&
Data[Data due] <= SlicerDate
),
ABS ( SlicerDate - Data[Data due] )
)
VAR thisdate =
MINX (
FILTER (
ALL ( Data ),
Data[Ref] IN VALUES ( Data[Ref] ) &&
ABS ( SlicerDate - Data[Data due] ) = MinDiff
),
Data[Data due]
)
RETURN
COUNTAX (
FILTER ( Data, Data[Data due] = thisdate && Data[Ref] IN VALUES ( Data[Ref] ) ),
Data[RAG]
)
It produces the following table for a subset of the performance measures, which looks almost ok:
Table showing the result of the TestCountaxpt2 measure:
The third column is the measure above and it seems to be counting one RAG per measure and the dates look correct as the slicer is set to 3rd January 2020. The total for column 3 confuses me. I don't know what that is counting and I don't understand why it doesn't add up to 7.
If I add in the RAG column from the data table, it goes a bit more wrong:
Same table but with RAG Rating added:
The pie chart that is produced is also wrong. It should show 2 Green, 2 Red, 2 Grey (no rating) and 1 Amber. This is what happens.......
Pie chart for the DAX measure, with RAG Rating in the legend:
I can see what it is doing, which is to work out the most recent due date to the slicer in the whole table and using that (which is 1st Jan 2020) whereas I want it to calculate this separately for each measure.
Link to PBIX:
https://drive.google.com/file/d/1RTokOjAUADGHNXvZcnCCSS3Dskgc_4Cc/view?usp=sharing
Reworking the formula to count the ratings:
RAGCount =
VAR SlicerDate =
MAX ( Dates[Day] )
RETURN
COUNTAX (
ADDCOLUMNS (
SUMMARIZE (
FILTER ( Data, Data[Data due] <= SlicerDate ),
Data[Ref],
"LastDateDue", LASTDATE ( Data[Data due] )
),
"CountRAG", CALCULATE (
COUNTA ( Data[RAG] ),
Data[Data due] = EARLIER ( [LastDateDue] )
)
),
[CountRAG]
)
Here's the table it produces:
The reason for Total = 4 for the third column is straightforward. The SelectDate is maximal over all of the Refs in the table and there are only four Refs that match that date.
To fix this and get the totals you're after, you'll need to iterate over each Ref and calculate the SlicerDate for each independently and only then do your lookups or sums.
I haven't tested this code but it should give you an idea of a direction to try:
MostRecentActual =
VAR SlicerDate = MAX ( Dates[Day] )
RETURN
SUMX (
ADDCOLUMNS (
SUMMARIZE (
FILTER ( Data, Data[Data due] <= SlicerDate ),
Data[Ref],
"LastDateDue", LASTDATE ( Data[Data due] )
),
"SumActual", CALCULATE (
SUM ( Data[Actual] ),
Data[Data due] = EARLIER ( [LastDateDue] )
)
),
[SumActual]
)
Going inside to outside,
FILTER the table to ignore any dates beyond the SlicerDate.
Calculate the LastDateDue for each Ref using SUMMARIZE.
Sum the Actual column for each Ref value using its specific LastDateDue.
Iterate over this summary table to add up SumActual across all Refs in the current scope.
Note that for 4, only the Total row in your visual will contain multiple Refs since the innermost Data table inside FILTER is not the entire Data table but only the piece visible in the local filter context.

PowerBI - Aggregate multiple rows using combination of fixed and variable calculations mapped to ID in separate table

I have a rather complicated data set, but will attempt to simplify it for this post.
I have contract data in table F1_Contract with a simplified format of:
I am attempting to calculate the expected profit from contracts.
The first thing that I needed is to calculate the incremental Volume from each contract that was valid between the Current Date and the Next Date, depending upon the date slicer used in the view. After much pain and anguish, someone pointed me to a post on StackOverflow that resolved my issue:
Create a Disconnected Date table, use that as the Date Slicer, then calculate the date difference between the Current Date, START_DATE of the slicer, Next Date, and END_DATE of the slicer.
The resulting Measure is
DELTA DATE =
CALCULATE (
SUMX (
F1_Contract,
DATEDIFF (
MAX ( MAX ( F1_Contract[CURRENT_CONTRACT_DATE] ), [Disconnected_MIN_Date] ),
MIN ( MAX ( F1_Contract[NEXT_CONTRACT_DATE] ), [Disconnected_MAX_Date] ),
DAY
)
),
FILTER (
F1_Contract,
F1_Contract[CURRENT_CONTRACT_DATE] <= [Disconnected_MAX_Date]
&& F1_Contract[NEXT_CONTRACT_DATE] >= [Disconnected_MIN_Date]
)
)
I then take that Measure and multiply it by the VOLUME_PER_DAY to get the incremental Volume for the view with the following formula:
Incremental Cumulative VOLUME =
CALCULATE(SUMX(F1_Contract,F1_Contract[VOLUME_PER_DAY]* [DELTA DATE]))
To calculate F1 Revenue and F1 Cost, I take the F1 Unit Cost and the appropriate F1 price based on the Incremental Volume and derive the following measures:
Incremental F1 Revenue =
CALCULATE (
MAX (
SUMX (
F1_Contract,
[Incremental Cumulative VOLUME] * [F1 Sell Rate # GAD Per Shipment]
),
[Calc F1 MinCharge]
)
)
Incremental F1 Cost =
CALCULATE (
SUMX ( F1_Contract, [Incremental Cumulative VOLUME] * F1_Contract[F1_Cost] )
)
This all works great! I can create a report at the ID level, Indicator level, or the Lane level and all of the numbers are correct.
The problem is that I have a second revenue table, F2_Contract_Revenue, that consists of F2 revenues formatted like the following (note there may be 0 to 15 rows in F2_Contract_Revenue for any given ID in F1_Contract)
F2_Contract_Revenue:
Although the ID in F1_Contract is unique, just to be on the safe side I have a separate DISTINCT_ID table that I have used to link the ID from F1_Contract and F2_Contract_Revenue.
Now I need to calculate the F2 revenue for each ID; using a visual formula of:
If(BASIS = “FLAT”, F2_Unit_Rev, MAX(F2_Min, (Incremental Volume * F2_Unit_Rev))
The Measure I created after about 30 attempts is:
F2 Revenue =
CALCULATE (
(
SUMX (
F2_Contract_Revenue,
(
MAX (
[Incremental Cumulative VOLUME]
* IF ( F2_Contract_Revenue[BASIS] = "RATE",
F2_Contract_Revenue[F2_Unit_Rev], 0 ),
F2_Contract_Revenue[F2_Min]
)
)
+ IF ( F2_Contract_Revenue[BASIS] = "FLAT",
F2_Contract_Revenue[F2_Unit_Rev], 0 )
)
),
FILTER (
F2_Contract_Revenue,
F2_Contract_Revenue[ID] = RELATED ( F1_Contract[ID] )
)
)
This works correctly at the Lane level. However, in the views at the ID level, it is slightly off (I have not been able to track down why) and at the Indicator level is it exponentially off.
I need to use this in a formula that will be represented as
F1 Revenue + F2 Revenue – F1 Cost which is of course also exponentially off at the INDICATOR level (note there are multiple rows of INDICATOR = 1 and a single row of INDICATOR = 2).
The data is proprietary, so I cannot share the PowerBI file, however, I can answer more specific questions with the data that I’ve cleaned up here.
Any advice, thoughts, corrections, help is greatly anticipated and appreciated!!!
[Suggest you show the moedel with Relation direction]
At a quick view of this, I think the problem is the data model - relation direction.
you work fine on [Incremental F1 Revenue] (ID level, Indicator level, or the Lane level).
these are all in 'F1 table'.
But, when it comes to [F2 Revenue], you get the Problem.
(measure is involve 'F1 table' & 'F2 table').
FILTER (
F2_Contract_Revenue,
F2_Contract_Revenue[ID] = RELATED ( F1_Contract[ID] )
Also you said that you
just to be on the safe side I have a separate DISTINCT_ID table
so I like point out is, may you show your model (dimTable - factTable) for problem shooting.
In Dax, its all about Relation and Model XD
(after you know about dax so much, model might be the really problem.)
after reading a lot more posts and going through helpful videos, I determined the problem was in the ordering of the values in my aggregation statement as well as insufficient bounding of the time dimension.
I have three steps
a) for each row of the F2 table, determine if the value is a FLAT or RATE; if FLAT, use that value, if RATE, then multiply that value by the dynamic measure that is determining volume based on the report Date Slicer
b) compare the FLAT or RATE outcome to a MIN value in the table
c) aggregate those values using the link between the F1 and F2 tables.
The calculation that works is:
F2 =
CALCULATE
(SUMX(F2_Contract_Revenue,
((MAX(IF(F2_Contract_Revenue[BASIS]="RATE",F2_Contract_Revenue[F2_Unit_Rev]* [Incremental Cumulative Volume],F2_Contract_Revenue[F2_Unit_Rev]),F2_Contract_Revenue[F2_MIN]))) )
,FILTER(F2_Contract_Revenue,F2_Contract_Revenue[ID]=RELATED(F1_Contract[ID]))
,FILTER ( F1_Contract,
F1_Contract[CURRENT_CONTRACT_DATE] <= [Disconnected_MAX_Date]
&& F1_Contract[NEXT_CONTRACT_DATE] >= [Disconnected_MIN_Date] ))
I appreciate the response and for the next issue I will create a generic modle that I can post as an example.

If a exists pick a else pick b power bi

I have forecast and budget values for the year, and a new forecast is created every quarter. I need PowerBI to pick up the Metric Value (can be Budget, Q1F, Q2F and Q3F) for a given date based on data availability.
Example - If for a given date, data for Q3F is available, pick Q3F, else pick Q2F else Q1F else budget.
This is what my data looks like:
Date Metric Value
1/1/11 Budget 1.1
1/1/11 Q3F 1.2
1/1/11 Q2F 1.3
In this case the function should pick up Q3F since it's available.
One way to solve this would be by using both a SUMX and a SWITCH Statements.
To start with assign a constant to your forecasts, e.g. budget = 1, Q1F = 2 and so on as a column on your data. The idea more recent forecast will have a higher number, it will be used in the switch statement late. I am going to refer to it as forecast_ID in this example.
I am also assuming you have a calendar table, also that your forecasts are entered in entirely for the business and not in waves. E.g. Category A is still on budget, Category B is an updated forecast.
The idea of below, is that the SUMX iterates though each quarter that you are looking at, e.g. 2018 would run Q1, Q2, Q3, Q4 separately.
Within the context of each quarter, it is getting the MAX of your forecast IDs, which is then used in the switch to select the most recent forecast.
Measure :=
SUMX (
VALUES ( Calendar[Quarter] ),
SWITCH (
MAX ( table1[forecast_ID] ),
1, CALCULATE ( SUM ( table1[value] ), table1[Metric] = "Budget" ),
2, CALCULATE ( SUM ( table1[value] ), table1[Metric] = "Q1F" )
)
)
You could also then do something like MAX ( table1[forecast_ID] - 1) for finding the previous forecast dynamically.
If you always want to pull the most recent value then you can use LASTNONBLANK
As Marcus mentioned, the first step is to create a constant for your forecasts. I set up a separate table for this example.
Then you can create a relationship between the two tables based on Metric. Add a calculated column to your original table
MetricConstant = RELATED(Table2[Constant])
Now create a measure to pull the most recent value within each date period
Measure =
SUMX (
VALUES ( Table1[Date] ),
CALCULATE ( SUM ( Table1[Value] ), LASTNONBLANK ( Table1[MetricConstant], 1 ) )
)
Now when you pull in the Date and the Measure it will only show you the most recent available
EDIT-Updated based on comments. If you want to view which Metric is being used you need another measure
MetricMeasure = CALCULATE(MAX(Table1[Metric]),LASTNONBLANK(Table1[MetricConstant],1))
You could create an area chart based on that, and add this to the tooltip.

DAX measure: project duration (days) from dimension starting & ending date

I have following scenario which has been simplified a little:
Costs fact table:
date, project_key, costs €
Project dimension:
project_key, name, starting date, ending date
Date dimension:
date, years, months, weeks, etc
I would need to create a measure which would tell project duration of days using starting and ending dates from project dimension. The first challenge is that there isn't transactions for all days in the fact table. Project starting date might be 1st of January but first cost transaction is on fact table like 15th on January. So we still need to calculate the days between starting and ending date if on filter context.
So the second challenge is the filter context. User might want to view only February. So it project starting date is 1.6.2016 and ending date is 1.11.2016 and user wants to view only September it should display only 30 days.
The third challenge is to view days for multiple projects. So if user selects only single day it should view count for all of the projects in progress.
I'm thankful for any help which could lead towards the solution. So don't hesitate to ask more details if needed.
edit: Here is a picture to explain this better:
Update 7.2.2017
Still trying to create a single measure for this solution. Measure which user could use with only dates, projects or as it is. Separate calculated column for ongoing project counts per day would be easy solution but it would only filter by date table.
Update 9.2.2017
Thank you all for your efforts. As an end result I'm confident that calculations not based on fact table are quite tricky. For this specific case I ended up doing new table with CROSS JOIN on dates and project ids to fulfill all requirements. One option also was to add starting and ending dates as own lines to fact table with zero costs. The real solution also have more dimensions we need to take into consideration.
To get the expected result you have to create a calculated column and a measure, the calculated column lets count the number of projects in dates where projects were executed and the measure to count the number of days elapsed from [starting_date] and [ending_date] in each project taking in account filters.
The calculated column have to be created in the dim_date table using this expression:
Count of Projects =
SUMX (
FILTER (
project_dim,
[starting_date] <= EARLIER ( date_dim[date] )
&& [ending_date] >= EARLIER ( date_dim[date] )
),
1
)
The measure should be created in the project_dim table using this expression:
Duration (Days) =
DATEDIFF (
MAX ( MIN ( [starting_date] ), MIN ( date_dim[date] ) ),
MIN ( MAX ( [ending_date] ), MAX ( date_dim[date] ) ),
DAY
)
+ 1
The result you will get is something like this:
And this if you filter the week using an slicer or a filter on dim_date table
Update
Support for SSAS 2014 - DATEDIFF() is available in SSAS 2016.
First of all, it is important you realize you are measuring two different things but you want only one measure visible to your users. In the first Expected result you want to get the number of projects running in each date while in the Expected results 2 and 3 (in the OP) you want the days elapsed in each project taking in account filters on date_dim.
You can create a measure to wrap both measures in one and use HASONEFILTER to determine the context where each measure should run. Before continue with the wrapping measure check the below measure that replaces the measure posted above using DATEDIFF function which doesn't work in your environment.
After creating the previous calculated column that is required to determine the number of projects in each date, create a measure called Duration Measure, this measure won't be used by your users but lets us calculate the final measure.
Duration Measure = SUMX(FILTER (
date_dim,
date_dim[date] >= MIN ( project_dim[starting_date] )
&& date_dim[date] <= MAX ( project_dim[ending_date] )
),1
)
Now the final measure which your users should interact can be written like this:
Duration (Days) =
IF (
HASONEFILTER ( date_dim[date] ),
SUM ( date_dim[Count of Projects] ),
[Duration Measure]
)
This measure will determine the context and will return the right measure for the given context. So you can add the same measure for both tables and it will return the desired result.
Despite this solution is demonstrated in Power BI it works in Power Pivot too.
First I would create 2 relationships:
project_dim[project_key] => costs_fact[project_key]
date_dim[date] => costs_fact[date]
The Costs measure would be just: SUM ( costs_fact[costs] )
The Duration (days) measure needs a CALCULATE to change the filter context on the Date dimension. This is effectively calculating a relationship between project_dim and date_dim on the fly, based on the selected rows from both tables.
Duration (days) =
CALCULATE (
COUNTROWS ( date_dim ),
FILTER (
date_dim,
date_dim[date] >= MIN ( project_dim[starting_date] )
&& date_dim[date] <= MAX ( project_dim[ending_date] )
)
)
I suggest you to separate the measure Duration (days) into different calculated column/measure as they don't actually have the same meaning under different contexts.
First of all, create a one-to-many relationship between dates/costs and projects/costs. (Note the single cross filter direction or the filter context will be wrongly applied during calculation)
For the Expected result 1, I've created a calculated column in the date dimension called Project (days). It counts how many projects are in progress for a given day.
Project (days) =
COUNTROWS(
FILTER(
projects,
dates[date] >= projects[starting_date] &&
dates[date] <= projects[ending_date]
)
)
P.S. If you want to have aggregated results on weekly/monthly basis, you can further create a measure and aggregate Project (days).
For Expected result 2 and 3, the measure Duration (days) is as follows:
Duration (days) =
COUNTROWS(
FILTER(
dates,
dates[date] >= FIRSTDATE(projects[starting_date]) &&
dates[date] <= FIRSTDATE(projects[ending_date])
)
)
The result will be as expected: