How can I force only two selection out of 5 available on slicer visual? - powerbi

Can someone please help me get a fix for this please.
I want to let people make only two selection at a time, no more no less from the given options. The intention is to get data on matrix dynamic column based on these two selections.
Thanks
Avi

You did not make clear what the purpose of this exercise is and how the result should look like ("get data on matrix dynamic column"), but you could
Create 2 single selection slicers based on copies of your category column
Make sure they are not related to the rest of your data model
Get the selected rows via the SELECTEDVALUE() function
You may have to consider the case where both selections are the same.

This would be a feature of a slicer visual, but I don't know of any built-in or custom slicer visual that does this.
As a workaround you can show a warning and instruction to select two items, eg a big Card visual with red text and a transparent background in front of your other visuals displaying a measure like:
AreTwoCategoriesSelected =
IF (
DISTINCTCOUNT ( DimProductCategory[ProductCategoryName] ) <> 2,
"Select 2 Categories for this report",
""
)
Which might look like
and
You can't easily use the trick where you have the measure conditionally return BLANK because most evaluations of the measure will have a filter context with just one of the selected values.

Related

Top N and Others in Power BI

I have a simple database with a doctors table and a detail table with their patients.
How can I efficiently group doctors with less than 300 patients into an other doctors category to obtain a pie chart like the picture below?
What I end up doing is to create a DAX table
DoctorsWithPatientsCount = SUMMARIZE(Patient, Patient[Doctor.FullName], "PatientCount", COUNT(Patient[Id]))
with the following calculated column
TopDoctor = SWITCH(TRUE(), 'DoctorsWithPatientsCount '[Count] > 300, DoctorsWithPatientsCount[Doctor.FullName], "Other doctors combined")
and have that ploted.
As you can see it does work, however, is there another more direct and efficient way to achieve this? Thanks!
TopN and Others has been a long requested feature in PBI which you can vote on here: https://ideas.powerbi.com/ideas/idea/?ideaid=08369fa0-5152-4d55-b858-e36c06737d10
There are currently a few ways of achieving this.
Your way which has the disadvantage of not being dynamic and responding to slicers because it is a calculated table. Usually, you would use a RANKX or TOPN rather than your DAX.
If you want the TopN to be dynamic, you need a disconnected table. There are simple implementations described here: https://goodly.co.in/top-n-and-others-power-bi/ or more complicated but versatile approaches described here: https://www.sqlbi.com/articles/filtering-the-top-products-alongside-the-other-products-in-power-bi/
You can use a custom visual like Deneb to perform a window transform that calculates the TopN for you and displays it automatically.
As an addendum, your pie chart should really only display 5 or 6 categories max to be useful to end users.
In doctors table, you can define a new computed column "computed doctor"; then use this new computed column to make pie chart.

Struggling with PowerBI slicer logic and process

I've tried to be "clever" setting up a slicer for improved visual experience, but it is not working as expected.
The slicer is based on a manually created table with two options:
This leads to a slicer which is compact and intuitive for report users (multi-select allowed):
I can then create a couple of measures that record all possible truth states of the slicer, e.g.
HideInactivePathSelected = --Truth status of slicer selection
IF (NOT ISFILTERED(SlicerHideOption),FALSE, --If no slicer options selected
IF(SELECTEDVALUE(SlicerHideOption[Options]) = "Hide inactive/former pathologists",TRUE, --Specific option selected
IF(COUNTROWS(VALUES(SlicerHideOption)) = 2,TRUE, --If both slicer options selected
FALSE --If all else fails
) ) )
This can be confirmed using a simple table, which updates instantly and correctly when the slicer is changed e.g.:
The problem is, at this point, if I try to refer to the state of the measure HideInactivePathSelected, things no longer work.
For instance, if I create a calculated column that refers to the measure state, this does not work. Consider this simplified example:
test_value =
IF([HideInactivePathSelected] = True, 2, 0)
If I then make a test table or chart based off test_value, changing the slicer has absolutely no effect.
I suspect I have tried to be "too clever" and perhaps I have misunderstood the (non)dynamic nature of calculated columns. Can some kind soul tell me what I have done wrong? Is this approach salvagable or do I need to start again?
Using PowerBI RS Desktop May 2021 edition.
Measures in calculated column do not see the row context, so you have to do context transition using Calculate function, e.g.:
test_value =
IF( CALCULATE( [HideInactivePathSelected] ) = True, 2, 0)
It should be easier to solve your issue if you provide some example data. There are better and more efficient ways to achieve the goal of filtering data in whole page, than using the measure and then calculated column.

How to dynamically change column source of a card to another one in Power BI

For a report in Power BI I have two column with name 'A' and 'B'. I want to show summation of values of column 'A' or 'B' in one card based on the selection of the user.
I Want to know can I change column source of a card in report view in Power BI. A simple solution is to have two cards, each one for each column. But I want one card such that the user defines source column of it.
Thanks
First you have to see if you have any data that helps you to identify if column A or B is selected.
If you havn't you can create an auxiliar table as I did to this solution like this:
Use this column to create a filter visualization
Then create the following DAX measure:
SUM = IF( SELECTEDVALUE( AuxTable[Auxiliar] ) = "A", SUM('Table'[A]), SUM('Table'[B] ) )
Don't forget to change the select options on your filter visualization to only be able to select 1 option if is necessary.
Hope it helps you.
Another possible solution without using DAX is to take advantage of Buttons and Bookmarks.
In your scenario, you could create a Button corresponding to the possible use choices. When the user click on one button it will direct to the bookmark showing the visualization calculated using that data source.
In practice, this means you will have two Cards in your report, but only one visible at a time.

Displaying nothing in card values until a single slicer selection is made

Current setup:
I have a basic report with a number of charts on the page that are all controlled by once Slicer element at the top of the page.
As required, the default selection of the slicer is "All", which shows all data across the charts as is required. Once you filter on this value, the charts all filter as normal to the value of said slicer. All good so far, all working and happy with that.
Issue:
At the top of the page, I have 4 cards, these are all counts and sums. These cards behave the same way. When no value is selected in the slicer, ALL of the data in these cards is summed and counted (as you would rightly expect) and when the slicer has a value, these cards display the correct values as per the slicer selection.
This default behaviour is not what I am looking for with respect to the cards. I only want the cards to display a value when the slicer has one single selection. Multiple selections or "All" should display blank, 0, n/a or something of the sort in the cards values.
As far as I understand, the default way of handling this is to create another measure which sets "Y" or "N" and then add this in as a visual level filter, only showing values when the measure is set to Y: EG
SlicerCheck = if(calculate(distinctcount([SlicerColumn]),allselected([SlicerColumn]))=1,"Y","N")
Other options suggest using functions that are not available in Direct Query mode.
This does not work for cards by default. Does anyone know a good way to achieve this solution?
Thanks
Damon
I would approach this by adding conditions to my count and sum measures. E.g.
SumForCard = IF(HASONEVALUE([SlicerColumn]), SUM(TableName[ColumnToSum]), BLANK())
What you can do with the new feature of Field Parameters (check in Preview features):
Create a Column Called None with all blank values of ""
Create a Field Parameter to select None field as well as the other fields you want (this lets you combine the fields together into 1 Slicer).
Make Field Parameter into a Slicer.
Now you will have a Slicer with None option that will give a blank result. Select for this as the default to not show any results. Save the dashboard in this state to keep the selection this way. You can select the other fields to populate data.

How can I have dynamic axis which is responsive on slicer value, without using bridge table, use just DAX

Hi everyone, I have a chart which I need that the x value (Axis) changes by changing the slicer value (this slicer is the yellow one that has all the Dims (x values)) and it comes from DimList table. For example, at the moment the chart is totalfreight by custid, but I need if I check the empid from the yellow slicer the chart value changed to totalfreight by empid. This happens for all of the slicer values.
But I don't like bridge table or any method that has a bad effect on performance because the FactTable has a billion rows and I modeled it in SSAS, tabular model and has a live connection. Thanks in advance.
I assume you're referring to the approach that uses a bridge table described in this article. I agree that you may face some performance problems given the amount of data in your model.
First of all, you should try to see if there's some other Power BI frontend functionality that you can use directly in the report, without changing your data model. Perhaps you can use Power BI bookmarks, links or maybe a custom visual?
If not, there's another approach you can use in the data model, that does not rely on bridge tables. Disclaimer: I haven't tested this - there could be other performance issues involved.
Construct a new dimension table with all the members from your individual dimensions. Ie. create a union of all EmpIDs, CustIDs, etc. Make sure you indicate the type of ID in a separate column. The table should look like this:
DimensionId MemberId
categoryid 1
categoryid 2
categoryid 3
custid 1
custid 2
custid 3
...
Let's name this table 'All Dimensions'. The table should not have any relationships to other tables (this is similar to the Parameter Table pattern.
Change your measures to apply a virtual relationship whenever something is selected on the 'All Dimensions' table, to properly filter the fact table:
SUM('factSale'[Freight])
would become:
SWITCH(
SELECTEDVALUE('All Dimensions'[DimensionId]),
"categoryid", CALCULATE(SUM('factSale'[Freight]),
KEEPFILTERS(TREATAS(VALUES('All Dimensions'[MemberId]), 'factSale'[CategoryId])),
"custid", CALCULATE(SUM('factSale'[Freight]),
KEEPFILTERS(TREATAS(VALUES('All Dimensions'[MemberId]), 'factSale'[CustId])),
"empid", CALCULATE(SUM('factSale'[Freight]),
KEEPFILTERS(TREATAS(VALUES('All Dimensions'[MemberId]), 'factSale'[EmpId])),
// ... etc. for all dimensions ...
, // Fallback, when nothing is selected on 'All Dimensions'
IF(NOT ISFILTERED('All Dimensions'[MemberId]),
SUM('factSale'[Freight])
)
)
Put the [DimensionId] column into a slicer and use the [MemberId] column as the axis on your bar chart. Note that the chart will not show anything unless exactly one item has been filtered on the [DimensionId] slicer.
Explanation: The SWITCH statement determines if any selection has been made on the [DimensionId] column of the 'All Dimensions' table. In that case, a filter is applied to the fact table, depending on which dimension has been selected, using the TREATAS function. We're using KEEPFILTERS to make sure that any existing filters made directly on the individual dimensions are kept as-is.
In case no selection has been made on the [DimensionId] column, we want to fall back to the standard measure SUM('factSale'[Freight]) but since we don't want to repeat this measure for all items on the [MemberId] column, we use IF(NOT ISFILTERED( ... to make sure that we return only a blank value, if [MemberId] is currently used on the chart axis.