Forum Discussion

markmsc's avatar
markmsc
Icon for Resolver I rankResolver I
1 year ago
Solved

Building a slicer where each slice can contain the same data?

Hello community.

 

I have a slicer based on a date column in a table.  I'd like the user to be able to slice by dates in the last 7 days, last 14 days, last 21 days, and last 28 days.

 

The sinple way to do this would be to have a calculated column on my table that buckets the date column into those groups, e.g.

1-7

8-14

15-21

22-28

 

Then, I can point my slicer at this calculated column, and make it multi-select.  So if I wanted to see the last two weeks in my viz, I'd select both the 1-7 and 8-14 buckets.

 

However, it would be more elegant if my slicer choices could actually be:


Last 7 days

Last 14 days

Last 21 days

Last 28 days

 

The problem here, of course, is that each lower entry in that list includes the values from the higher entries.  So, any date that exists in the "last 7 days" bucket of course also needs to exist in the "last 14 days" bucket.

 

I can't work out a way to make this possible.  If using a single calculated column as the source for the slicer, then that column can obviosuly have only one value per row.  So if my date is in "last 7 days", the column can't also report it as being in "last 14 days".

 

Any way to make this work, or am I stuck with the 1-7, 8-14, etc. approach?

 

Thank you.

  • markmsc One method to make this work would be to create a separate table with no relationships that lists your slicer choices. Then, you could create a measure that returns 1 if a row of data is within the desired date range and 0 otherwise. You could then use this measure in a visual level filter and set it to only display rows/items where the measure is 1. Something like the following might work:

    My Filter Measure = 
    VAR _Days = 
      SWITCH( SELECTEDVALUE( 'Slicer'[Item] ),
        "Last 7 Days", 7,
        "Last 14 Days", 14,
        "Last 21 Days", 21,
        "Last 28 Days", 28,
      )
    VAR _Date = MAX( 'Table'[Date] )
    VAR _Result = IF( _Date <= TODAY() && _Date >= TODAY()-_Days, 1, 0 )
    RETURN _Result
  • Great question!

    1. Create a disconnected slicer table
      Create a small table with your choices. (No relationships needed.)

      Period =
      DATATABLE (
      "Label", STRING, "Days", INTEGER,
      {
      { "Last 7 days", 7 },
      { "Last 14 days", 14 },
      { "Last 21 days", 21 },
      { "Last 28 days", 28 }
      }
      )

      Use Period[Label] in a slicer. I recommend turning Single Select = On

    2. Add a “Selected N” helper measure
      This reads the slicer. If nothing is chosen, it defaults to 7.
      Selected Days :=
      VAR N = MAX ( Period[Days] )
      RETURN IF ( NOT ISBLANK ( N ), N, 7 )

    3. Choose the “as-of” date (respects your date slicer)
      This follows your preferred style (using MAXX with ALLSELECTED) so it anchors on the last selected date if a date slicer is present; otherwise it uses the max date in context.

      Selected Max Date :=
      MAXX ( ALLSELECTED ( 'Date'[Date] ), 'Date'[Date] )

      Replace 'Date'[Date] with your model’s primary date column. (No USERELATIONSHIP needed if your active relationship is already correct.)


    4. Build a reusable date-window measure

      Is In Selected Period :=
      VAR N = [Selected Days]
      VAR MaxDate = [Selected Max Date]
      VAR StartDate = MaxDate - N + 1
      VAR CurrentDate = MAX ( 'Date'[Date] )
      RETURN
      IF ( CurrentDate >= StartDate && CurrentDate <= MaxDate, 1, 0 )

    5. Filter visuals (easy, reusable way)

      Is In Selected Period :=
      VAR N = [Selected Days]
      VAR MaxDate = [Selected Max Date]
      VAR StartDate = MaxDate - N + 1
      VAR CurrentDate = MAX ( 'Date'[Date] )
      RETURN
      IF ( CurrentDate >= StartDate && CurrentDate <= MaxDate, 1, 0 )

      OR

    6. Wrap your core measures

      Sales (Last N Days) :=
      VAR N = [Selected Days]
      VAR MaxDate = [Selected Max Date]
      RETURN
      CALCULATE (
      [Total Sales], -- your base measure
      DATESINPERIOD ( 'Date'[Date], MaxDate, -N, DAY ) -- rolling N-day window
      )

      Use this pattern for any measure (counts, distincts, amounts). DATESINPERIOD is efficient and readable.

      You’re done—an elegant “Last N days” slicer without messy buckets.



9 Replies

  • GeraldGEmerick's avatar
    GeraldGEmerick
    Icon for Memorable Member rankMemorable Member

    markmsc One method to make this work would be to create a separate table with no relationships that lists your slicer choices. Then, you could create a measure that returns 1 if a row of data is within the desired date range and 0 otherwise. You could then use this measure in a visual level filter and set it to only display rows/items where the measure is 1. Something like the following might work:

    My Filter Measure = 
    VAR _Days = 
      SWITCH( SELECTEDVALUE( 'Slicer'[Item] ),
        "Last 7 Days", 7,
        "Last 14 Days", 14,
        "Last 21 Days", 21,
        "Last 28 Days", 28,
      )
    VAR _Date = MAX( 'Table'[Date] )
    VAR _Result = IF( _Date <= TODAY() && _Date >= TODAY()-_Days, 1, 0 )
    RETURN _Result
    • markmsc's avatar
      markmsc
      Icon for Resolver I rankResolver I

      Hi GeraldGEmerick -- this is great, and works perfectly.  I do so much work in standalone semantic models that I forget how useful functions like SELECTEDVALUE can be when used in the pbx itself.  Much obliged.  This did exactly what I needed.

  • Great question!

    1. Create a disconnected slicer table
      Create a small table with your choices. (No relationships needed.)

      Period =
      DATATABLE (
      "Label", STRING, "Days", INTEGER,
      {
      { "Last 7 days", 7 },
      { "Last 14 days", 14 },
      { "Last 21 days", 21 },
      { "Last 28 days", 28 }
      }
      )

      Use Period[Label] in a slicer. I recommend turning Single Select = On

    2. Add a “Selected N” helper measure
      This reads the slicer. If nothing is chosen, it defaults to 7.
      Selected Days :=
      VAR N = MAX ( Period[Days] )
      RETURN IF ( NOT ISBLANK ( N ), N, 7 )

    3. Choose the “as-of” date (respects your date slicer)
      This follows your preferred style (using MAXX with ALLSELECTED) so it anchors on the last selected date if a date slicer is present; otherwise it uses the max date in context.

      Selected Max Date :=
      MAXX ( ALLSELECTED ( 'Date'[Date] ), 'Date'[Date] )

      Replace 'Date'[Date] with your model’s primary date column. (No USERELATIONSHIP needed if your active relationship is already correct.)


    4. Build a reusable date-window measure

      Is In Selected Period :=
      VAR N = [Selected Days]
      VAR MaxDate = [Selected Max Date]
      VAR StartDate = MaxDate - N + 1
      VAR CurrentDate = MAX ( 'Date'[Date] )
      RETURN
      IF ( CurrentDate >= StartDate && CurrentDate <= MaxDate, 1, 0 )

    5. Filter visuals (easy, reusable way)

      Is In Selected Period :=
      VAR N = [Selected Days]
      VAR MaxDate = [Selected Max Date]
      VAR StartDate = MaxDate - N + 1
      VAR CurrentDate = MAX ( 'Date'[Date] )
      RETURN
      IF ( CurrentDate >= StartDate && CurrentDate <= MaxDate, 1, 0 )

      OR

    6. Wrap your core measures

      Sales (Last N Days) :=
      VAR N = [Selected Days]
      VAR MaxDate = [Selected Max Date]
      RETURN
      CALCULATE (
      [Total Sales], -- your base measure
      DATESINPERIOD ( 'Date'[Date], MaxDate, -N, DAY ) -- rolling N-day window
      )

      Use this pattern for any measure (counts, distincts, amounts). DATESINPERIOD is efficient and readable.

      You’re done—an elegant “Last N days” slicer without messy buckets.



    • markmsc's avatar
      markmsc
      Icon for Resolver I rankResolver I

      Hi Ilgar_Zarbali -- Thanks very. much for the detailed reply.  I happened to see the reply from GeraldGEmerick  first, and so it was the first one I tried.  I believe it is conceptually similar to yours, and it worked, so I have not taken this approach, but I understand it and learned quite a bit from parsing it.  I am confident it woud have worked had I gotten to your reply first.  Really grateful for the detailed writeup.  

  • Aburar_123's avatar
    Aburar_123
    Icon for Solution Supplier rankSolution Supplier

    Hi markmsc ,

    Why can't you try this built in feature. is it not you expected?

     

    • markmsc's avatar
      markmsc
      Icon for Resolver I rankResolver I

      Hi Aburar_123 -- Heh, to be perfectly honest: it never occurred to me.  I think I was focused on the exact presentation that I was looking for so this built-in option didn't come to mind.  Ultimately it's a bit fussier from a user perspective than I want, so it's not what I went with, but indeed it would have worked functionally.  Thank you for reminding me that it was an option.

  • Hi,

    This should be possible.  Once you make a slicer selection, what do you want the end result to look like/be?  Share some data to work with and show the expected result.  Share data in a format that can be pasted in an MS Excel file.