Filtering other tables based on cross-highlighting a filtered measure - powerbi

I want to count records in a certain condition and allow people to filter down to the relevant records, but selecting a measure value (which filters so it only counts certain rows) isn't cross-filtering others as I'd expect. Maybe ths isn't possible or maybe I'm just doing it wrong, but I'd appreciate help.
I have a single table:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45Wci4tLsnPTS1SMFTSUTJUitVBEjICChmgChljCplgajSFCMUCAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [#"Customer Name" = _t, #"Ordered Recently" = _t]),
#"Change to INT" = Table.TransformColumnTypes(Source,{{"Ordered Recently", Int64.Type}}),
#"Change to T/F" = Table.TransformColumnTypes(#"Change to INT",{{"Ordered Recently", type logical}})
in
#"Change to T/F"
The result looks like this:
Customer Name Ordered Recently
Customer 1 True
Customer 2 False
Customer 3 False
Customer 4 True
Customer 5 True
I added two measures:
Count Total = COUNTROWS(Customers)
Count Recent = CALCULATE([Count Total], filter(Customers, Customers[Ordered Recently]))
If I put both measures in a bar chart and highlight the "Count Recent" measure, I'd expect it to know to filter other visuals based on the FILTER statement present in the measure, but that doesn't happen. Selecing this value doesn't impact anything else on my page (including just a count of rows).
The goal is to allow people to select a measure that counts rows and then to see the makeup of the data in those rows (select a count of late projects and filter other visuals to describe those late projects).
Is this possible or am I doing something wrong?
EXAMPLE:
Here's what it looks like now, with nothing selected:
When I select the black bar (the "Ordered Recently" measure), nothing changes right now - but here's what I want to happen (actually achieved with a slicer off screen on the T/F field):
I understand if my measure is a SUM of an integer field, it includes every row in the calculation - even when the row value is zero - and there's no way to filter my dataset based on that. However, in this case, my measure is actually using a FILTER on the dataset so that it only counts rows with a certain criteria set - given that, it should be able to filter the requested table, and then flow that filter through the rest of my dataset (the same way it would if I selected a bar from a chart where I had used that same field as the series - exactly how it works when I do this:
PBIX file to download as an example

No, I don't believe it's possible to make a measure value cross-filter other visuals based on filters within the measure definition.
You can, however, click on i.e. row header Customer 3 and it should cross-filter the other visuals to only include that customer. Any table column you set for the rows or columns of a matrix visual should behave this way.
Here's a hacky workaround:
Create a measure that shows the right values when you use the column you want to use as a filter as the Legend or Axis (like in your last image). For example, in this case, you could do this:
Total Customers =
VAR TF = SELECTEDVALUE ( Customers[Ordered Recently] )
RETURN
COUNTROWS (
FILTER (
ALLSELECTED ( Customers ),
IF ( TF, TF, TF || Customers[Ordered Recently] )
)
)
This behaves how you want, but isn't labeled as you want. To achieve that create a calculated column with the labels you want. For example,
Label = IF(Customers[Ordered Recently], "Ordered Recently", "Total Customers")
Then take Ordered Recently off the axis and put the Label column in the Legend box to get this:

Your Filter argument is really Filter(All(Customers, Customers[Ordered Recently])
You remove all filters on the Customer Table, and then specify Ordered Recently Column as the filter.
Try
[MeasureName] =Calculate([Count Total], All(Customer), Values(Customer[Recently Ordered]), Customer[Recently Ordered] = “True”)

Related

Conditionally format a table based on average of dataset, but adhering to slicer selections

I have a simple CSV data set such as this.
ID,MainCategory,SubCategory,Type,Value
1,E,E1,Demo,5
2,N,N3,Install,2
3,E,E1,Demo,4
4,E,E2,Install,7
5,D,D1,Install,3
6,S,S2,PM,4
7,N,N2,Install,7
8,N,N2,Demo,1
9,E,E2,Demo,2
10,D,D2,Install,6
11,D,D3,PM,4
12,S,S1,PM,8
13,N,N1,Install,5
14,S,S3,Install,8
15,S,S1,Demo,9
16,E,E3,Demo,5
17,N,N2,Install,3
18,E,E2,PM,6
19,D,D2,PM,6
20,N,N3,Demo,6
21,S,S2,Demo,7
22,E,E3,Install,2
23,S,S1,Install,4
24,S,S2,PM,8
25,D,D1,Install,5
In my Power BI Desktop, I'd like to load this into a table, and conditionally format the Value column based on whether the value in each row is greater than or less than the average for the currently selected data set.
For instance, the average of Value considering the entire table is 5.08, so if there are no filters applied (as in, all my slicers are set to select nothing), I'd like all rows whose Value is 6 or more to be background colored in one color, and the others in another color. For this, I created two measures like so:
AvgOfVal = DIVIDE( SUM(G2G[Value]), COUNTA(G2G[ID]) )
BGColor = IF(SUM(G2G[Value]) > [AvgOfVal], "Light Pink", "Light Blue")
Then I tried to apply the BGColor measure for conditionally formatting the background, but this doesn't work as expected, and instead produces the result below.
I realize that this is due to the fact that the measure is calculated per row, so when conditional formatting is applied, as seen in the AvgOfVal column in the table, it calculates average per row instead of for the entire data set. How can I calculate a measure that takes into account the entire data set (considering slicers), and do the conditional formatting as I need.
Please keep in mind that if a user were to select a slicer filter (say, MainCategory = D), then I want the conditional formatting to reflect this. So in this case, given that AvgOfVal = 4.80 for MainCategory = D entries, I'd like all rows whose Value >= 5 to be in one color, and others in another color.
I realize that this is due to the fact that the measure is calculated per row
Yes. The key is understanding how that happens. When the measure is calculated a "context transition" happens and the current row is added to the filter context.
So what you want is a calculation that removes the row filter that was added in the context transition. So you need ALLSELECTED(), which does precisely that. eg
AvgOvVAl = CALCULATE( AVERAGE('data'[Value]), ALLSELECTED() )
Removing the "innermost" filter which in this case is the filter on the row, but leaving all other filters, ie filters added on the report, page, visual, or filters coming from interactions with other visuals like slicers.

Making column reference via slicer

I have a table with two choices 'FLOW_CONTEXT' and 'TEST_NAME'.
I want to let the user select one of these values using a slicer. I then want to have a calculated formula point to either the 'FLOW_CONTEXT' or the 'TEST_NAME' column in another table. There is a 1:1 relationship between the 'FLOW_CONTEXT' and the 'TEST_NAME' columns in the table.
Here is the column formula I have, which always defaults to false, even though the SELECTEDVALUE part of the IF statement does work (checked via a card):
COLUMN_POINTER = IF(
SELECTEDVALUE(TEST_NAME_FIELD[TEST_NAME_FIELD]) = "FLOW_CONTEXT",
CCD_BINNING_TEST_RESULTS_LAST_RANK[FLOW_CONTEXT],
CCD_BINNING_TEST_RESULTS_LAST_RANK[TEST_NAME]
)
I have tried doing this with a measure but measures only see non-categorical columns. Thx much.
Columns are only calculated at refresh time - they do not respond to slicers filters in this way. You cannot re-calculate a column based on a selected value in a table visual.
You need to transform your use-case into a measure-friendly approach.

How to select the last value of the day with DAX in Power BI

I am new to power BI and stuck with an issue. I have my model as follows:
Date Dimension
Measurement Fact
The date column in Date Dimension is link to measuredate in Measurement Fact
Below is a sample data:
NB: In edit query, I have changed the type of measuredate to Date only.
I have tried the measure below but it doesn't work the way I want. It will sum all the values of the day but what I want is the last value of the day:
day_fuel_consumption =
CALCULATE (
SUM ( measurement[measurementvalue] ),
FILTER (
measurement,
measurement[metername] = "C-FUEL"
&& measurement[measuredate] = MAX ( measurement[measuredate] )
)
)
My Goal is to get 29242, i.e the last value of the day. Remember that measuredate is a Date field and not Datetime (I changed to Date field so that my Year and Month filter can work correctly). I have changed the type in edit query.
Changing your measure to use a variable could be the solution:
DFC =
var maxDate = MAX(measurement[measuredate])
return
CALCULATE(
SUM(measurement[measurementvalue]),
measurement[measuredate] = maxDate
)
However, you should keep the datetime format for measureDate. If you don't want to see the time stamp just change the format I power bi. Otherwise power bi will see two values with max date and sum them, instead of taking the last one.
Well, if you want to avoid creating a measure, you could drag the fields you are filtering over to the visual filters pane. Click your visual, and scroll a tiny bit and you will see the section I am referring to. From there, just drag the field you are trying to filter In this case, your value. Then select "Top N". It will allow you to select a top (number) or bottom (number) based on another field. Strange enough, it does allow you to do top value by top value. It doesn't make sense when you say it out loud, but it works all the same.
This will show you the top values for whatever value field you are trying to use. As an added bonus, you can show how little or how many you want, on the fly.
As far as DAX goes, I'm afraid I am a little DAX illiterate compared to some other folks that may be able to help you.
I had to create two separate measures as shown below for this to work as I wanted:
max_measurement_id_cf = CALCULATE(MAX(measurement[measurementid]), FILTER(measurement, measurement[metername] = "C-FUEL"))
DFC =
var max_id_cf = [max_measurement_id_cf]
return
CALCULATE(SUM(measurement[measurementvalue]), measurement[measurementid] = max_id_cf)

Group by a column and count, but with filters

I have a documents table being displayed in my report, then I added a slicer to filter these data using a date range. This is working as expected, but now I need to create a donut chart that should display the summarization.
I've created a calculated table using the SUMMARIZE function like this:
grouped_docs = SUMMARIZE(documents;documents[user_id];"DocCount"; COUNTROWS('documents'))
However, the slicer is ignored.
I also tried to create a measure with the following code:
DocCount = CALCULATE(GROUPBY(documents; documents[user_id]; "GroupByUser"; COUNTROWS(CURRENTGROUP())); ALLSELECTED('documents'))
But it says that that the GROUPBY needs to have aggregation functions on CURRENTGROUP.
My documents table structure is like this:
document_id (auto increment field)
scanDate
title
user_id
How can I get the count of documents grouped by user_id?
I don't think you need any DAX for this. Just add the field: document_id to the Values well for the Donut Chart visual, and set it's summarization to Count.
If you do want a Measure, it would be something like this:
# Documents = DISTINCTCOUNT ( documents[document_id] )
Try a Treemap visual instead of a Donut Chart - the results are much clearer if you have more than 2 user_id values.

power BI diaplay one value

I am using Power BI to bring together data from several systems and display a dash board with data from all of the systems.
The dashboard has a couple of filters which are then used to display the data relating to one object across all systems.
When the dashboard is first loaded and none of the filter have been selected, the data cards display information from all rows in the table.
Is there a way to make a data card only display one row of data?
or
Be blank if there are more than one row of data?
There's no direct way to look at the number of rows in the visual, count them, and do something different if there's more than 1.
That said, there are a few things you can do.
HASONEFILTER
If you have a specific column in your table that, when selected, filters your results to a single row, then you can check if there's a filter on that column using HASONEFILTER. (If you have multiple alternative columns,any of which filter to a single row, that's ok too.)
You could then create a measure for each column that tests HASONEFILTER. If true, return the MAX of the column. (The reason for MAX is because measures always have to aggregate, but the MAX of a 1-row column will be the same as the value in that column.) If false, return either BLANK() or an empty string, depending on your preference.
E.g.
ColumnAMeasure = IF(HASONEFILTER(Sheet1[Slicer Column]),MAX(Sheet1[COLUMN A]), "")
ColumnBMeasure = IF(HASONEFILTER(Sheet1[Slicer Column]),MAX(Sheet1[COLUMN B]), "")
where Sheet1 is the name of the table and "Slicer Column" is the name of the column being used as a slicer
HASONEVALUE
If you have multiple columns that could be used as filters in combination (meaning that having a filter applied on "Slicer Column" doesn't guarantee only 1 row in the table), then rather than testing HASONEFILTER, you can test HASONEVALUE.
ColumnAMeasure = IF(HASONEVALUE(Sheet1[COLUMN A]),MAX(Sheet1[COLUMN A]), "")
ColumnBMeasure = IF(HASONEVALUE(Sheet1[Column B]),MAX(Sheet1[COLUMN B]), "")
Notice that HASONEVALUE tests the current column you're trying to display, rather than a slicer column like HASONEFILTER.
One side-effect of HASONEVALUE is that, if you're filtered to 3 rows, but all 3 rows have the same value for column A, then column A will display that value. (Whereas with HASONEFILTER, column A would stay blank until you're filtered to one thing.)
Low Tech
Both answers above depend on a measure existing for every column you want to display, so that you can test whether to display a blank row or not. That could become a pain if you have dozens of columns.
A lower-tech alternative is to add in an additional row with blanks for each column and then sort your table so that that row always appears first. (And shorten your visual so only the top row is visible.) Technically the other rows would be underneath and there'd be a scrollbar, but at least the initial display would be blank rather than showing a random row.
Hopefully something here has helped. Other people might have better solutions too. More information:
HASONEFILTER documentation: https://msdn.microsoft.com/en-us/library/gg492135.aspx
HASONEVALUE documentation: https://msdn.microsoft.com/en-us/library/gg492190.aspx