<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Site-Server v@build.version@ (http://www.squarespace.com) on Fri, 10 Apr 2026 17:04:00 GMT
--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://www.rssboard.org/media-rss" version="2.0"><channel><title>Apex Insights: Power BI tips &#x26; tricks</title><link>https://apexinsights.net/</link><lastBuildDate>Fri, 29 Sep 2023 23:37:28 +0000</lastBuildDate><language>en-GB</language><generator>Site-Server v@build.version@ (http://www.squarespace.com)</generator><description><![CDATA[]]></description><item><title>Implementing error checks in Power Query</title><dc:creator>Sam Fischer</dc:creator><pubDate>Tue, 09 May 2023 11:43:42 +0000</pubDate><link>https://apexinsights.net/blog/error-checks-in-power-query</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:625285d5863ebb534e9cb791</guid><description><![CDATA[Allowing incorrect data to appear in a report can diminish trust in your 
organisation’s reporting capability. To avoid incorrect data appearing in 
the first place, we can force refresh errors when certain business rules 
aren’t met (since usually stale data is better than incorrect data). In 
this post, I demonstrate a pattern for applying custom error messages when 
business rules are violated. These messages can be set up to provide error 
details that cut down troubleshooting time.]]></description><content:encoded><![CDATA[<p class="">All too often, I've seen this scenario play out which really slows down Business Intelligence teams…</p><ul data-rte-list="default"><li><p class="">A Power BI solution gets built and delivered to the business. </p></li><li><p class="">Some time passes, and the Power BI developer moves on to other things. In doing so, they lose familiarity with the logic of the report. </p></li><li><p class="">The business users notice that the report is not calculating values as expected, and notifies the BI team. </p></li><li><p class="">A developer (either the original one or a different developer) digs in to the report, and takes a long time to diagnose and correct the issue.</p></li></ul><p class="">While the business is pleased when the issue is resolved, the issue impacts the overall trustworthiness of the reports provided to decision makers. This can become a real roadblock to creating and maintaining a data-driven culture within the organisation.</p><p class="">And these issues can accumulate if Power BI developers don't follow good development practices. Over time, the BI team may become trapped in firefighting mode, with most of their time spent on fixing reports that keep breaking, instead of building new solutions to support the business. </p><h3>How do you stop this from happening?</h3><p class="">Like with many things, prevention is better than cure. </p><p class="">In my experience, following the <a href="https://dataopsmanifesto.org/en/">DataOps Principles</a> as closely as possible is an effective means for delivering effective and robust analytics solutions. </p><p class="">For the scenario above, the following two DataOps Principles are particularly relevant:</p>


  


  
























  
  





<ul data-should-allow-multiple-open-items="true" data-accordion-icon-placement="right" data-is-last-divider-visible="true" data-is-expanded-first-item="" data-is-divider-enabled="true" data-accordion-title-alignment="left" class="accordion-items-container" data-is-first-divider-visible="true" data-accordion-description-alignment="left" data-accordion-description-placement="left"
>
  
    <li class="accordion-item">

      
        
          
        
      

      <h4 aria-level="3" role="heading" class="
          accordion-item__title-wrapper
          
          
          
        "
      >
        <button
          class="accordion-item__click-target"
          aria-expanded="false"
          style="
            padding-top: 15px;
            padding-bottom: 15px;
            padding-left: 0px;
            padding-right: 0px;
          "
        >
          <span class="accordion-item__title"
          >
            Quality is paramount
          </span>
          
            
              
                
                
              
            
          
        </button>
      </h4>
      
        
          <p class="">“Analytic pipelines should be built with a foundation capable of automated detection of abnormalities and security issues in code, configuration, and data, and should provide continuous feedback to operators for error avoidance.”</p>
        
      

      
        
      

    </li>
  
    <li class="accordion-item">

      
        
      

      <h4 aria-level="3" role="heading" class="
          accordion-item__title-wrapper
          
          
          
        "
      >
        <button
          class="accordion-item__click-target"
          aria-expanded="false"
          style="
            padding-top: 15px;
            padding-bottom: 15px;
            padding-left: 0px;
            padding-right: 0px;
          "
        >
          <span class="accordion-item__title"
          >
            Monitor quality and performance
          </span>
          
            
              
                
                
              
            
          
        </button>
      </h4>
      
        
          <p class="">“Our goal is to have performance, security and quality measures that are monitored continuously to detect unexpected variation and generate operational statistics.”</p>
        
      

      
        
      

    </li>
  
</ul>

  
  <p class="">E<span class="sqsrte-text-color--custom">ssentially, these principles speak</span>s to the need to minimise the technical debt caused by ‘waiting for something to break, and dealing with it only when someone in the business complains’. I see this attitude taken all too often, especially when the team feels they are too busy to follow these principles. Ironically enough, it is usually the case that they are so busy becuase they’re cleaning up messes that could have been avoided by following these ideas in the first place!</p><p class="">John Kerski has some amazing articles about <a href="https://www.kerski.tech">implementing DataOps in Power BI</a>. I would highly recommend checking it out if you commonly deal with the scenarios described above in your organisation. </p><h4>Ok great. But seriously, <em>how</em> do you stop this from happening?</h4><p class="">Alright, I’ll get off my soapbox and get to some practical strategies :)</p><h3>Solving with simple error checks</h3>


  


  



<p>A simple way I've found to ensure that quality is always maintained is to use error checks throughout my Power Query logic. </p>
<p>I've worked with a lot of solutions requiring csv extracts rather than databases recently
<sup id="fnref:1" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:1" class="footnote">1</a>
</sup>
, and there can often be instances where the source system isn't capable of enforcing data integrity regarding business rules. So adding these error checks has helped me ensure that, if any business rules are violated, the report does not even refresh—stale data is better than incorrect data.
<sup id="fnref:2" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:2" class="footnote">2</a>
</sup></p>
<p>As an example, let's consider a set of employee work patterns, which indicate how many hours each employee works on each weekday...</p>












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png" data-image-dimensions="970x229" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png?format=1000w" width="970" height="229" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653184436662-8TJZPFREI9P6QDPHVOZG/Work+Pattern+base+table.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


<p>Work patterns are usually recorded cyclically, and in different organisations they may repeat on a weekly, fortnightly or four-weekly basis. We’ll assume a simple weekly work pattern in this example. </p>
<p>In the source system that tracks these patterns, the staff FTEs get entered manually based off of a 40-hour work week
<sup id="fnref:3" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:3" class="footnote">3</a>
</sup>
. The table above shows these manually entered figures, where the FTE's for Alice and Snehal correctly match the hours worked throughout the week. But for Lindsay and David, their work patterns do not match their weekly hours⁠—Lindsay works 8 hours every day, so his FTE should be 1.0 not 0.8. And David only works 4 days a week, so he should have 0.8 FTE not 1.0. </p>
<p>If we want to enforce our business rule that the FTE must be consistent with the weekly work hours, we can intentionally raise an error when this happens, so that any scheduled refreshes will fail and the incorrect data isn’t brought into our data model. </p>
<p>Power Query has a nifty function called Error.Record that helps us accomplish this. Rick de Groot has a very comprehensive documentation article on all the ways you can use the function, <a href="https://powerquery.how/error-record/">as described here</a>. </p>


  
  <p class="">To set up our error checking workflow, we can bring the work pattern data into Power Query and add a nested calculation that does the following:</p><ul data-rte-list="default"><li><p class="">For each row, sum up the work hours for the week, and convert it into an FTE</p></li><li><p class="">Filter down to only rows where this FTE check doesn't match the manually-entered FTE</p></li><li><p class="">Count how many times this data entry error happens</p></li><li><p class="">Return a descriptive error message if any data entry errors were detected</p></li><li><p class="">If no error were detected, return the original table</p></li></ul><p class="">Here's the error that gets returned when we apply this logic in Power Query….</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png" data-image-dimensions="787x267" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png?format=1000w" width="787" height="267" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/71c0d17f-7916-4f75-b73f-4e5490958837/Error+1.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">And here's the full M code for this scenario…</p>


  


  




  
    <font face="Courier" ><p>

  
<span class="constant keyword">let</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;First Step&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">#&quot;Sample Work Patterns&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;FTE Error Check&quot;</span><span class="constant operator operator-equality">&nbsp;=</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant keyword">let</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Add FTE check column&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.AddColumn</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;First Step&quot;</span><span class="constant">,</span>&nbsp;<span class="literal string">&quot;FTE Check&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">each</span>&nbsp;<span class="identifier">Value.Divide</span><span class="constant bracket bracket-1">(</span><span class="identifier">List.Sum</span><span class="constant bracket bracket-2">(</span><span class="constant bracket bracket-0">{</span><span class="constant bracket bracket-1">[</span><span class="identifier">Monday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">Tuesday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">Wednesday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">Thursday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">Friday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant bracket bracket-0">}</span><span class="constant bracket bracket-2">)</span><span class="constant">,</span><span class="literal number">40</span><span class="constant bracket bracket-1">)</span><span class="constant">,</span>&nbsp;<span class="identifier">Int64.Type</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Filter to error rows only&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.SelectRows</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Add FTE check column&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">each</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">FTE for Work Pattern</span><span class="constant bracket bracket-1">]</span><span class="constant operator operator-equality">&nbsp;&lt;&gt;</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">FTE Check</span><span class="constant bracket bracket-1">]</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Error Count&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.RowCount</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Filter to error rows only&quot;</span><span class="constant bracket bracket-0">)</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;in</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant keyword">if</span>&nbsp;<span class="identifier">#&quot;Error Count&quot;</span><span class="constant operator operator-relational">&nbsp;&gt;</span><span class="literal number">&nbsp;0</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;then</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant keyword">error</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Error.Record</span><span class="constant bracket bracket-0">(</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="literal string">&quot;Calculation error&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="literal string">&quot;One or more FTE values were entered incorrectly. Please request for HR to investigate. &quot;</span><span class="constant bracket bracket-0"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else</span>&nbsp;<span class="identifier">#&quot;First Step&quot;</span><span class="constant keyword"><br>in</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;FTE Error Check&quot;</span>
  

  <a href="https://www.durchblick-durch-daten.de/power-query/m-formatter/" target="_blank" title="Powered by powerqueryformatter.com">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 80">
      <rect x="0" width="350" y="0" height="78.836"/>
      <text y="-2"><tspan x="8.646" y="57.799">Power Query</tspan><tspan> </tspan></text>
      <text x="355" y="57.848">Formatter</text>
    </svg>
  </a>


</p></font>
  


  
  <p class="">If these errors get introduced to a published dataset rather than one in Power BI Desktop, you'll get an error message displayed in the Power BI Service that instructs you on how to resolve it.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png" data-image-dimensions="868x344" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png?format=1000w" width="868" height="344" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/996e6634-441a-43e2-922d-133587e9b7b6/Error+in+Power+BI+Service.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">This can help you to diagnose and potentially correct the issue without even having to open up the report in Power BI Desktop. </p><h3>Extending to be more descriptive</h3><p class="">If there is only one mismatching FTE value, it's helpful to also return the Employee ID for the offending record in the error message, to speed up troubleshooting. And when there is more than one mismatch, you can return a count of the mismatches, and a list of the offending Employee IDs. </p><p class="">Here's how you can extend the logic, and the messages returned for both of the above scenarios…&nbsp;</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png" data-image-dimensions="532x105" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png?format=1000w" width="532" height="105" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/2fe4ca8a-d4fd-44c1-9640-ab9750aa0ede/Error+2.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png" data-image-dimensions="532x99" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png?format=1000w" width="532" height="99" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/e193e9fd-b012-4364-aecb-897fbf3cbb59/Error+3.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
    <font face="Courier" >

  
<span class="constant keyword">let</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;First Step&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">#&quot;Sample Work Patterns&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;FTE Extended Error Check&quot;</span><span class="constant operator operator-equality">&nbsp;=</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant keyword">let</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Add FTE check column&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.AddColumn</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;First Step&quot;</span><span class="constant">,</span>&nbsp;<span class="literal string">&quot;FTE Check&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">each</span>&nbsp;<span class="identifier">Value.Divide</span><span class="constant bracket bracket-1">(</span><span class="identifier">List.Sum</span><span class="constant bracket bracket-2">(</span><span class="constant bracket bracket-0">{</span><span class="constant bracket bracket-1">[</span><span class="identifier">Monday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">Tuesday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">Wednesday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">Thursday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">Friday Hours</span><span class="constant bracket bracket-1">]</span><span class="constant bracket bracket-0">}</span><span class="constant bracket bracket-2">)</span><span class="constant">,</span><span class="literal number">40</span><span class="constant bracket bracket-1">)</span><span class="constant">,</span>&nbsp;<span class="identifier">Int64.Type</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Filter to error rows only&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.SelectRows</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Add FTE check column&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">each</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">FTE for Work Pattern</span><span class="constant bracket bracket-1">]</span><span class="constant operator operator-equality">&nbsp;&lt;&gt;</span>&nbsp;<span class="constant bracket bracket-1">[</span><span class="identifier">FTE Check</span><span class="constant bracket bracket-1">]</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Error Count&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.RowCount</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Filter to error rows only&quot;</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;List of Employee IDs with mismatches&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Text.Combine</span><span class="constant bracket bracket-0">(</span><span class="identifier">Table.TransformColumnTypes</span><span class="constant bracket bracket-1">(</span><span class="identifier">#&quot;Filter to error rows only&quot;</span><span class="constant">,</span><span class="constant bracket bracket-2">{</span><span class="constant bracket bracket-0">{</span><span class="literal string">&quot;Employee ID&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">type</span><span class="type">&nbsp;text</span><span class="constant bracket bracket-0">}</span><span class="constant bracket bracket-2">}</span><span class="constant bracket bracket-1">)</span><span class="constant bracket bracket-1">[</span><span class="identifier">Employee ID</span><span class="constant bracket bracket-1">]</span><span class="constant">,</span>&nbsp;<span class="literal string">&quot;, &quot;</span><span class="constant bracket bracket-0">)</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;in</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant keyword">if</span>&nbsp;<span class="identifier">#&quot;Error Count&quot;</span><span class="constant operator operator-equality">&nbsp;=</span><span class="literal number">&nbsp;1</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;then</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant keyword">error</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Error.Record</span><span class="constant bracket bracket-0">(</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="literal string">&quot;Calculation error&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="literal string">&quot;The work pattern for Employee ID = &quot;</span><span class="constant operator operator-arithmetic"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;</span>&nbsp;<span class="identifier">#&quot;List of Employee IDs with mismatches&quot;</span><span class="constant operator operator-arithmetic"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;</span><span class="literal string">&nbsp;&quot; has an incorrectly entered FTE. Please request for HR to investigate. &quot;</span><span class="constant bracket bracket-0"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else</span>&nbsp;<span class="constant keyword">if</span>&nbsp;<span class="identifier">#&quot;Error Count&quot;</span><span class="constant operator operator-relational">&nbsp;&gt;</span><span class="literal number">&nbsp;1</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;then</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant keyword">error</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Error.Record</span><span class="constant bracket bracket-0">(</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="literal string">&quot;Calculation error&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Text.From</span><span class="constant bracket bracket-1">(</span><span class="identifier">#&quot;Error Count&quot;</span><span class="constant bracket bracket-1">)</span><span class="constant operator operator-arithmetic"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;</span><span class="literal string">&nbsp;&quot; work patterns have incorrectly entered FTEs, with these issues occurring for Employee IDs {&quot;</span><span class="constant operator operator-arithmetic"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;</span>&nbsp;<span class="identifier">#&quot;List of Employee IDs with mismatches&quot;</span><span class="constant operator operator-arithmetic"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;</span><span class="literal string">&nbsp;&quot;}. Please request for HR to investigate. &quot;</span><span class="constant bracket bracket-0"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else</span>&nbsp;<span class="identifier">#&quot;First Step&quot;</span><span class="constant keyword"><br>in</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;FTE Extended Error Check&quot;</span>
  

  <a href="https://www.durchblick-durch-daten.de/power-query/m-formatter/" target="_blank" title="Powered by powerqueryformatter.com">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 80">
      <rect x="0" width="350" y="0" height="78.836"/>
      <text y="-2"><tspan x="8.646" y="57.799">Power Query</tspan><tspan> </tspan></text>
      <text x="355" y="57.848">Formatter</text>
    </svg>
  </a>


</font>
  


  
  <p class="">You could also fork the offending rows off into a separate query for inspection. Reza Rad has a good post on this <a href="https://radacad.com/exception-reporting-in-power-bi-catch-the-error-rows-in-power-query">exception reporting approach</a> if you want to go even deeper into this topic.</p><h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/Highlighting-values-with-conditional-formatting.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />
  <ol data-preserve-html-node="true">
    <li id="fn:1" data-preserve-html-node="true">
     <p data-preserve-html-node="true">My preference is always for a database connection, but third party SaaS providers rarely like to expose their databases to customers directly.&nbsp;<a data-preserve-html-node="true" href="#fnref:1" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:2" data-preserve-html-node="true">
     <p data-preserve-html-node="true">Ideally you would also set up monitoring for refresh failures to proactively deal with these issues. That is beyond the scope of this article.&nbsp;<a data-preserve-html-node="true" href="#fnref:2" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:3" data-preserve-html-node="true">
     <p data-preserve-html-node="true">Note that in practice, it would be appropriate to ignore the manually-entered FTE column and calculate the FTE off of the work hours. But bear with me, as this example is just to illustrate the idea of implementing error checks. &nbsp;<a data-preserve-html-node="true" href="#fnref:3" class="reversefootnote">↩</a></p>
    </li>
  </ol>

<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1683362127609-ZG7TB70H1VRIVU3K5F13/Thumbnail.png?format=1500w" medium="image" isDefault="true" width="943" height="729"><media:title type="plain">Implementing error checks in Power Query</media:title></media:content></item><item><title>Make the transition from Excel to Power BI smoother by emulating PivotTables and PivotCharts</title><dc:creator>Sam Fischer</dc:creator><pubDate>Tue, 21 Jun 2022 11:09:00 +0000</pubDate><link>https://apexinsights.net/blog/emulating-pivottables-and-pivotcharts</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:62a43d5f3632687184d08928</guid><description><![CDATA[Migrating users from Excel to Power BI can be a challenge. Even users who 
know their way around a PivotTable may resist the move, despite the similar 
drag-and-drop experience in Power BI. In this post, I show how you can use 
Field Parameters to build a visually-similar experience to Excel 
PivotTables and PivotCharts. This can provide a familiar-looking stepping 
stone for users who have yet to make the jump over to Power BI for 
self-service.]]></description><content:encoded><![CDATA[<p class="">I’ve been playing around with Field Parameters a lot since they were introduced as a Preview Feature in the Power BI Desktop May 2022 release. One interesting use case for them is to enable a guided experience for self-service data exploration. </p><p class="">Using Field Parameters, you can effectively set up an experience similar to PivotTables and PivotCharts in Excel. While Power BI has always had a drag-and-drop report interface that is comparable to Excel, many business users still prefer sticking with what they know in Excel. But by using Field Parameters, I’ll show you how you can set up a visually-similar experience to Excel PivotTables. Providing a familiar interface to your die-hard Excel users can help make the move to Power BI much more seamless for them. </p><p class="">Here’s what we’ll be setting up…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif" data-image-dimensions="1443x808" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif?format=1000w" width="1443" height="808" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655805462467-SJ56APLZK2P20TMHIDQ9/PivotChart.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">This report gives users the chance to visualise a dataset with any combination of line and column charts they’d like.</p><p class="">And for users who prefer a PivotTable, we can also build this…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif" data-image-dimensions="1443x808" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif?format=1000w" width="1443" height="808" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655807029775-CD193WIKXOH02VTRY55D/PivotTable.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">You can <a href="https://apexinsights.net/portfolio/self-service-pivotcharts-and-pivottables">play with the report for yourself here</a>, or read on to learn how to build these for yourself. </p><h3>Building out the basics</h3><p class="">To start building out our customisable chart, let’s first look at our model. We can use the AdventureWorks dataset, which is a basic star schema with measures like Sales, Cost of Goods Sold, Profits, etc. The measures are contained in a disconnected table called ‘Sales Measures’. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png" data-image-dimensions="1453x754" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png?format=1000w" width="1453" height="754" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469071898-KUOWUYZ2FZJYOKUTDPX2/Data+model.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">We can build out our chart by defining four separate Field Parameters:</p><ol data-rte-list="default"><li><p class="">‘Chart Axis’, which contains fields from the dimensions that the user might want to display along the x-axis of the chart.</p></li><li><p class="">‘Chart Legend’, a copy of ‘Chart Axis’ which lets users choose what is shown on the legend.</p></li><li><p class="">‘Column Measure’, which contains measures against the ‘Sales’ fact table to display as the columns of the chart.</p></li><li><p class="">‘Line Measure’, a copy of ‘Column Measure’ which lets users choose what measure is shown as an overlayed line chart. </p></li></ol><p class="">Here are the DAX definitions for ‘Chart Axis’ and ‘Column Measure’. The other two parameters are defined similarly. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png" data-image-dimensions="589x748" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png?format=1000w" width="589" height="748" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469313565-8UXYODGVVWJ97PXJYCWA/Chart+Axis+initial+definition.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png" data-image-dimensions="643x324" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png?format=1000w" width="643" height="324" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655469219049-9CMIFU1D84WSQG6OG9SJ/Column+Measure+initial+definition.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Then we can add a <em>Line and stacked column chart</em> visual on to the canvas. Note that <strong>it needs to be a combo chart</strong> if you want the flexibility to fully customise what kind of chart you end up with.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png" data-image-dimensions="1783x670" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png?format=1000w" width="1783" height="670" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655104447427-11E9V9DBENCY23W9T21A/Drag+chart+onto+canvas.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">We can now drag each of our Field Parameter columns into the approporate field wells in the Visualizations pane…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif" data-image-dimensions="1785x678" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif?format=1000w" width="1785" height="678" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112454722-G659UQSDKXBPI9BH9UOQ/Drag+Field+Parameters+onto+visual.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">In making the visual, you can see that…</p><ul data-rte-list="default"><li><p class="">When no selection is made on any of the Field Parameter slicers, it defaults to the first option for each. This doesn’t apply for the Line Measure though — when unselected, it shows all its measures at once. </p></li><li><p class="">The line chart starts out as disconnected dots rather than actual lines. This happens when the X-axis and Legend have the same field selected. Choosing different fields to appear on the axis and legend solves this.</p></li><li><p class="">The chart automatically sorts based on the sort order applied to the field. In the model, the ‘Date’[Financial Year] column is sorted on another column, so sort order is retained. For your own models, you may find strange sort behaviour if you haven’t explicitly defined the column sort orders. <a href="https://www.youtube.com/watch?ab_channel=AccessAnalytic&amp;v=vo-8p7_3yZk">Wyn Hopkins has a video explaining this issue in more detail. </a></p></li></ul><p class="">This very quickly gets us to the core functionality of the report. For example, we could build a chart showing Sales and Margin by Month, and broken down by Sales Territory…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png" data-image-dimensions="1267x600" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png?format=1000w" width="1267" height="600" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112825152-G45PMUFGRZV447TFSZYT/Example+chart.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">But there are a few more functional items to fine tune to make the user experience better.</p><h3>Showing and hiding chart elements</h3><p class="">Showing all the chart elements at once can be overwhelming, so we’d like the option to omit some of them. This would allow us to show separate line charts and column charts rather than a combo chart of both. </p><p class="">To enable this, we can edit each of the four Field Parameter definitions in DAX to include a ‘blank’ option. We’ll need to add a custom row into each parameter, with the sort order given as -1 for each, so that option always appears at the top of the slicer.</p><p class="">The trick to getting this working smoothly is…</p><ul data-rte-list="default"><li><p class="">The ‘Chart Axis’ and ‘Chart Legend’ parameters need to reference a <em>measure</em> that just returns a blank. See the reference highlighted in red. </p></li><li><p class="">The ‘Column Measure’ and ‘Line Measure’ parameters need to reference a <em>column</em> where all the values are blank. This can just be a one-record table, and in this case the model already has a dummy column in ‘Sales Measures’ that can serve this purpose. See the reference highlighted in maroon. </p></li></ul>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png" data-image-dimensions="922x248" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png?format=1000w" width="922" height="248" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113767129-CCJD6RUO7YCWFDGURC7Y/Blank+Chart+Axis.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png" data-image-dimensions="953x248" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png?format=1000w" width="953" height="248" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113785141-6MPVS0I10BK89YI7UPIG/Blank+Chart+Legend.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png" data-image-dimensions="943x172" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png?format=1000w" width="943" height="172" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113897808-S7RCDL5Z05E1DAYY89ZA/Blank+Column+Measure.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png" data-image-dimensions="949x170" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png?format=1000w" width="949" height="170" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655113916184-2TANN7B3AXNJE00YP66D/Blank+Line+Measure.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">If you apply columns and measures respectively (rather than measures and columns), then the outcome will still work. But you’ll get an explicit mention in the chart title of what’s missing, and it isn’t the cleanest way to present the visual…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png" data-image-dimensions="1246x610" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png?format=1000w" width="1246" height="610" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655112034898-VNH9F9S2J2N2XTIOW84M/Blank+columns+and+measures+wrong+way+around.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">So by setting the parameters according to the DAX above, we can generate visuals like these…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png" data-image-dimensions="1240x589" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png?format=1000w" width="1240" height="589" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463434581-7QK61P4T5RCW1RCIFU8N/Sales+by+Category.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png" data-image-dimensions="1237x589" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png?format=1000w" width="1237" height="589" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463456367-YE6UTJ08FHYY5VHB5LIJ/Profit+by+Fiscal+Quarter.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png" data-image-dimensions="1264x604" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png?format=1000w" width="1264" height="604" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117938182-M6LIHH46RH7KR9QX4U3X/Qty+Sold+by+Category+and+Subcategory.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png" data-image-dimensions="1276x601" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png?format=1000w" width="1276" height="601" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655117974760-HL38LLNFUHLXJ0Q6AIEJ/Sales+measures+by+Fiscal+Qtr.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Adding hierarchies to the field selectors</h3><p class="">For our Chart Axis and Chart Legend selectors, there is a long list of fields to choose from. Some of the fields even have the same names, e.g. Country may refer to the country of the Sales transaction, the Customer or the Reseller. </p><p class="">To make things clearer, we could rename the selected field names in the DAX definitions for the Field Parameters. But to make it even clearer to users, instead we’re going to create a hierarchy, with the name of the Dimension table acting as the parent item. To do this, we can add a calculated column to our Chart Axis and Chart Legend parameters. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png" data-image-dimensions="627x667" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png?format=1000w" width="627" height="667" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463661095-9JNXDTODOCYO42WZ3V6I/Dimension+Calc+Column.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">The column definition above parses the Chart Axis Fields column to get the home table name. It then returns that for any row besides the first row, and in that case it just returns the child name “(No Axis)”. </p><p class="">We can do the same for Chart Legend. Then we can add the new Dimension columns into the Axis and Legend slicers to get our hierarchy. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif" data-image-dimensions="1609x621" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif?format=1000w" width="1609" height="621" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655463746216-X7OWJ59QYPP5DUL7RMUA/Added+Dimension+column+to+slicers.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">The benefit of this hierarchy approach is that you can easily select multiple fields at one. This lets you drill up and down on the Axis, but the combo chart doesn’t let us drill up and down on a Legend. </p><p class="">If you want to limit the user’s ability to select multiple Legends at once, you can change the standard slicer to a Hierarchy Slicer custom visual. I’ve found that visual to be somewhat unstable though, where the slicer selections on one slicer can disappear when selecting another slicer. So sticking with the standard slicers would be preferable to this unstable behaviour.</p><h3>Cleaning up the report page</h3><p class="">With some rearranging of visuals, tweaks to the slicers and a few text boxes, we arrive at a nice clean view that evokes the Excel PivotChart interface…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png" data-image-dimensions="1300x729" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png?format=1000w" width="1300" height="729" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655465841338-7CMUAJVNZNB4A7QSLMPS/PivotChart+output.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>Making a matrix the looks like a PivotTable</h3><p class="">We can also build a PivotTable interface with a matrix visual, by using the baseline logic that we’ve already built up…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png" data-image-dimensions="1426x801" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png?format=1000w" width="1426" height="801" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655467099631-4YHVBKZ27XE7BFH5FU7U/PivotTable+output.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">I’ve intentionally changed the default formatting of the matrix visual to make it look closer to the PivotTable that Excel users are used to.</p><p class="">For the report page above, I’ve repurposed the Chart Axis and Chart Legend parameters to select the matrix Rows and Columns. To ensure that the slicer options still make sense, I’ve adjusted the DAX in the Field Parameters so that the “(No Axis)” option now simply says “(No Selection)”, and similarly for the other slicers.</p><p class="">Since the matrix visual has only one field well that can accept measures, I’ve used just the Column Measures parameter in the matrix and removed the Line Measures slicer. </p><h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/PivotTables-and-PivotCharts-with-Field-Parameters.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />]]></content:encoded><media:content type="image/gif" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1655809236906-KRY9KGSNKAQ3C9SXLQ5A/Thumbnail.gif?format=1500w" medium="image" isDefault="true" width="1081" height="834"><media:title type="plain">Make the transition from Excel to Power BI smoother by emulating PivotTables and PivotCharts</media:title></media:content></item><item><title>Swapping Gantt chart hierarchies with Field Parameters</title><dc:creator>Sam Fischer</dc:creator><pubDate>Thu, 02 Jun 2022 08:51:00 +0000</pubDate><link>https://apexinsights.net/blog/swapping-gantt-charts-with-field-parameters</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:6292f451b6e571209326997c</guid><description><![CDATA[With the new Field Parameters feature, you can now change the presentation 
of your visuals in a number of new ways. One way is to change the order of 
fields shown in a table or matrix, although the standard application of 
field parameters for this use case doesn't allow you to enforce a sort 
order. Here's an approach that allows you to retain your sort order, with 
an application for creating a Gantt chart of different hierarchies with 
overlapping members.]]></description><content:encoded><![CDATA[<p class="">Like most Power BI enthusiasts, I've been playing around with the new <a href="https://docs.microsoft.com/en-us/power-bi/create-reports/power-bi-field-parameters">Field Parameters feature</a> that came as a Preview Feature in the recent May 2022 release of Power BI Desktop. </p><p class="">The most common use cases I’ve seen thus far tend to involve showing different columns based on a slicer selection. But I'm sure that in the coming weeks and months, the Power BI Community will uncover more elaborate and useful techniques using Field Parameters beyond just this. Here’s one such new application I’ve found…</p><p class="">I had a particular requirement from a client, in which their Project Management Office (PMO) wanted to see two Gantt charts, with different hierarchies on the rows of each:</p><ul data-rte-list="default"><li><p class="">One showing the standard Portfolio-Program-Project hierarchy that a PMO considers, and</p></li><li><p class="">Another showing each Business Unit (BU), and each of the BU’s projects</p></li></ul><p class="">They also wanted to be able to swap between each Gantt chart using a slicer. </p><p class="">I had been exploring this just before Field Parameters were released, and it could be done with a Bookmark Navigator. However, I've discovered that (after a bit of tweaking) it can also be done using Field Parameters used against a matrix visual. </p><p class="">&nbsp;Here's what the end result looks like, read on to find out how to implement it. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif" data-image-dimensions="831x416" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif?format=1000w" width="831" height="416" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903792742-2LI6YRQ2VG35YJ5JKLDG/Swapping+hierarchies.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Creating a Gantt chart with a matrix visual</h3><p class="">Before getting in to the Field Parameters implementation, I’ll show you how to create a Gantt chart with the native matrix visual. I’m by no means the first person to come up with such an approach (I first saw this idea in a video by <a href="https://www.youtube.com/watch?ab_channel=EnterpriseDNA&amp;v=SO4mk1H94OA">Sam McKay from Enterprise DNA</a>), but I’ll walk you through how I’ve gone about it. <em>If you already know how to make one of these, feel free to skip ahead to the next section.</em></p><p class="">When dealing with project management information, information about different initiatives is typically stored in a hierarchy structure. Here's the schema that we'll consider:</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png" data-image-dimensions="1255x514" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png?format=1000w" width="1255" height="514" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653800767340-7VNTPZS9MS4B6REMJSSY/PMO+schema.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


<p>In this example, an Initiative can generically refer to a Portfolio, a Program or a Project of work
<sup id="fnref:1" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:1" class="footnote">1</a>
</sup>.
For each Initiative, we list the Portfolio, Program and Project (PPP), as well as the owning Business Unit for each Project, and the Start and End Dates. Note as well that the lowest non-blank values in the PPP columns indicates what level of the PPP hierarchy the initiative falls on. </p>


  
  <p class="">If we want to build a Gantt chart with the standard PPP hierarchy, we can do this with the native matrix visual. </p><ul data-rte-list="default"><li><p class="">For the rows, we can just drag in each of the PPP columns to make a custom hierarchy. </p></li><li><p class="">For the columns, we can bring in the Year and Month Name fields from a date dimension. Note that the date dimension should be disconnected from the Initiatives table, since relating the two tables on Start Date or End Date can make the end result ambiguous for the user. </p></li><li><p class="">For the values, we can create a measure that returns 1 if the Initiative is active within the timeframe, or 0 if it is either yet to start or complete. </p></li></ul><p class="">Here’s the DAX for the measure, and the resulting matrix. </p>


  


  




  
    <font face="Consolas">Gantt&nbsp;Chart&nbsp;Value&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">StartDate</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">MIN</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Start&nbsp;Date]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">EndDate</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">MAX</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[End&nbsp;Date]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">InitiativeActive</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">StartDate</span>&nbsp;&lt;=&nbsp;<span class="Keyword">MIN</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Date'[Date]&nbsp;<span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&amp;&amp;&nbsp;<span class="Variable">EndDate</span>&nbsp;&gt;=&nbsp;<span class="Keyword">MAX</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Date'[Date]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">BlankRowOnMatrix</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ISINSCOPE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Project]&nbsp;<span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>&amp;&amp;&nbsp;<span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Project]&nbsp;<span class="Parenthesis">)</span>&nbsp;=&nbsp;<span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Identifies&nbsp;blank&nbsp;Projects&nbsp;(which&nbsp;are&nbsp;the&nbsp;Portfolio&nbsp;and&nbsp;Program&nbsp;Initiatives)&nbsp;shown&nbsp;in&nbsp;matrix</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>||<span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ISINSCOPE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Program]&nbsp;<span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&amp;&amp;&nbsp;<span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Program]&nbsp;<span class="Parenthesis">)</span>&nbsp;=&nbsp;<span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Identifies&nbsp;blank&nbsp;Programs</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>||<span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ISINSCOPE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Business&nbsp;Unit]&nbsp;<span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&amp;&amp;&nbsp;<span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Business&nbsp;Unit]&nbsp;<span class="Parenthesis">)</span>&nbsp;=&nbsp;<span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Identifies&nbsp;blank&nbsp;Business&nbsp;Units</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SWITCH</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">TRUE</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>,&nbsp;<span class="Variable">BlankRowOnMatrix</span>,&nbsp;<span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>,&nbsp;<span class="Variable">InitiativeActive</span>,&nbsp;<span class="Number">1</span>,&nbsp;<span class="Number">0</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png" data-image-dimensions="994x606" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png?format=1000w" width="994" height="606" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805104446-Y5P3DUQ95QCMILXALQF5/PPP+Gantt+with+1s+and+0s.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Note that the BlankRowOnMatrix variable in the measure definition is used to filter out the Initiative records where the Program or Project are blank. If we don’t add this logic in, we get something like the matrix below, which would be hard for users to make sense of. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png" data-image-dimensions="530x504" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png?format=1000w" width="530" height="504" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654154353379-L9DWQG47VZQMKB2RE93C/Blank+rows+highlighted.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Also note that for the visual layout, we need the grand total row to be showing, which I’ve retitled here to read as ‘All Initiatives’. This is to allow the higher levels of the hierarchy (Portfolio and Program) to display values at the same time as the lowest level of the hierarchy shown (Project). </p><p class="">I'm not aware of a way to show these row total values without also showing the grand total. But even with this limitation, you can set the font and background colour of the grand total row to match the page background colour so you don't notice it. </p><p class="">To make the visual look more like an actual Gantt chart, we can add conditional formatting for the background and font colour of the matrix cells. We can make these both consistent by using a single measure for conditional formatting, and basing the conditional formatting values on that. In the measure below, we’re defining it such that the bars at each hierarchy level in the Gantt chart will have a different colour. </p>


  


  




  
    <font face="Consolas">Gantt&nbsp;Conditional&nbsp;Formatting&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">LevelColour</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SWITCH</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">TRUE</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ISINSCOPE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Project]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="StringLiteral">"#71AFE2"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ISINSCOPE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Program]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="StringLiteral">"#73B761"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ISINSCOPE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Portfolio]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="StringLiteral">"#4A588A"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ISINSCOPE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Initiative[Business&nbsp;Unit]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="StringLiteral">"#8D6FD1"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SWITCH</span><span class="Parenthesis">&nbsp;(</span>&nbsp;[Gantt&nbsp;Chart&nbsp;Value],&nbsp;<span class="Number">1</span>,&nbsp;<span class="Variable">LevelColour</span>,&nbsp;<span class="Number">0</span>,&nbsp;<span class="StringLiteral">"#FFFFFF00"</span>,&nbsp;<span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <p class="">Note that you need to apply conditional formatting to 'Values and totals' in conditional formatting dialogue box. This ensures that each level of the hierarchy can show it’s own bar at the same time. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png" data-image-dimensions="711x319" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png?format=1000w" width="711" height="319" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805571608-S16P9OEBV6B48B40AAKU/Gantt+conditional+formatting+window.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">This gives us the basis for our Gantt chart…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png" data-image-dimensions="607x427" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png?format=1000w" width="607" height="427" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805743230-OXGVNU2V4DQLTE7HXAXX/PPP+Gantt.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">You may have noticed that the measures above include logic for Business Units as well. This allows us to create another Gantt chart based on the Business Unit-Project hierarchy by swapping the fields on the rows of the visual…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png" data-image-dimensions="603x379" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png?format=1000w" width="603" height="379" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653805762904-09M7GZK4UPS2O7FD74EG/BU-Project+Gantt.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Adding a field parameter</h3><p class="">If we want to easily swap between the two Gantt charts above, we can create a field parameter that includes the four fields. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif" data-image-dimensions="1453x859" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif?format=1000w" width="1453" height="859" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806085442-T4JZE67PN4IMXB80TOC0/Create+Field+Parameter.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">You can then manually select which ones you want, with the sort order determined by the order that you make the selection. </p><p class="">Here’s the same PPP Gantt chart as before, but this time created with the Parameter on the rows of the matrix, and with the Field Parameter slicer after selecting Portfolio, then Program, then Project. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png" data-image-dimensions="1432x547" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png?format=1000w" width="1432" height="547" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806358455-E2GWRUSLYLMDDAMB1V8Q/Gantt+with+field+parameter.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Note however that if you don’t select values in the field parameter slicer in the same order as the hierarchy you want, you’ll get an output that can be hard to interpret. For example, if you select the field values in the opposite order (Project, then Program, then Portfolio), you’ll get something like this…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png" data-image-dimensions="940x744" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png?format=1000w" width="940" height="744" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653806710304-19BZ63258CYC3XTHVYOV/Project+then+Program+then+Portfolio.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Since this doesn’t give us very useful information, we’d like to ensure that users can make selections from the Field Parameter slicer than can <em>only</em> result in one of the two Gantt charts we made earlier (PPP and Business Unit-Project). </p><h3>Setting the sort order for the hierarchies</h3>


  


  



<p>If we want to enforce what hierarchy levels can be added, and the order they get applied, here's the trick…<sup id="fnref:2" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:2" class="footnote">2</a>
</sup></p>


  
  <ol data-rte-list="default"><li><p class="">Edit the DAX that defines the Field Parameter to include all the row permutations, including repeats. For us, this means we need to repeat the Project row at the bottom, but increment the Parameter Order field to a new value. </p></li></ol>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png" data-image-dimensions="601x319" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png?format=1000w" width="601" height="319" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653807095476-ELJI1Z1497DRF89G2G9D/Edited+Field+Parameter.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">       2. Add a calculated column to return the name of the hierarchy you want to show.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png" data-image-dimensions="661x292" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png?format=1000w" width="661" height="292" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653812217226-JPEEBV6S297S4AHO69HE/Field+Parameter+Calc+Column.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">       3. Add a slicer to your report page based on the Gantt Hierarchy field, and set it to 'single select only'.</p><p class="">Here’s our final result:</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif" data-image-dimensions="831x416" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif?format=1000w" width="831" height="416" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653903733976-PFKU0ZVX7KU3REHKSOP2/Swapping+hierarchies.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">At the time of writing you unfortunately can’t set a matrix visual to have all levels expanded by default, so you still have to expand each level manually. </p><p class="">The bookmark navigator approach may be better for end users that want all the levels already expanded, but this is a good alternative in situations where performance is critical and you can’t afford to add additional visuals to your report page. </p><h3>Applying this approach to table visual</h3><p class="">You can also use this field parameters pattern to retain the sort order for columns in a table visual, without having the hierarchy-expansion issue that the matrix visual has. The approach (shown below) may not be very useful for this particular data table, but you may find a good application of it for your own use cases.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif" data-image-dimensions="525x400" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif?format=1000w" width="525" height="400" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1653905869915-SZ9KSSDQ2LNLVUZQ9URK/Swapping+columns+in+a+table.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/Swap-matrix-hierarchy-with-Field-Parameters.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />
  <ol data-preserve-html-node="true">
    <li id="fn:1" data-preserve-html-node="true">
     <p data-preserve-html-node="true">This schema is more robust than if it were at the grain of one-row-per-Project (with the other fields as attributes), because this structure also supports ragged and unbalanced hierarchies.&nbsp;<a data-preserve-html-node="true" href="#fnref:1" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:2" data-preserve-html-node="true">
     <p data-preserve-html-node="true">Kane Synder has an good article on <a href="https://tenfingerseddy.wordpress.com/2022/05/20/dynamic-column-sorting-and-switching-columns-and-rows-with-field-parameters/">applying a sort order with field parameters</a>, and this approach could be used to solve this problem. However, it involves creating numerous field parameters and linking them together in the model. The approach described in this article uses only a single field parameter.&nbsp;<a data-preserve-html-node="true" href="#fnref:2" class="reversefootnote">↩</a></p>
    </li>
  </ol>





<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1654156983571-GK6MPD04C963XXDYI4R4/Blog+Thumbnail.png?format=1500w" medium="image" isDefault="true" width="970" height="751"><media:title type="plain">Swapping Gantt chart hierarchies with Field Parameters</media:title></media:content></item><item><title>How to include a legend with a conditionally formatted chart</title><dc:creator>Sam Fischer</dc:creator><pubDate>Mon, 20 Sep 2021 11:20:00 +0000</pubDate><link>https://apexinsights.net/blog/include-legend-with-a-conditionally-formatted-chart</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:611a4442d9f3fe02b069b6cb</guid><description><![CDATA[Conditional formatting is a fairly routine feature to add to a column 
chart. But Power BI doesn’t allow you to display a legend for each of your 
conditionally formatted columns by default. In this post, I show you a 
technique for including a legend to explain what each colour of your 
conditional formatting corresponds to.]]></description><content:encoded><![CDATA[<p class="">I recently had a requirement from a client to create a chart showing the distribution of how many days staff were coming into the office. They wanted this shown not just for every week, but for rolling 4 week periods. So, for a given week (say the week ending Sunday 28th Feb 2021), they wanted to see how many staff came in on all 20 of the working days in February, how many came in only 19 out of 20 days, all the way down to how many people didn’t come in at all. Here’s an example of what such a chart might look like…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG" data-image-dimensions="834x405" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG?format=1000w" width="834" height="405" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632019369028-VL2EBZHPWHLE42CYP7G3/Chart+with+no+colour+coding.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">This was a good starting point, but they also wanted the chart to show who had met their attendance targets. Staff were expected to attend the office for at least 10 days out of every rolling 4 week window. </p><p class="">They also wanted the chart to call out the number of staff who didn’t attend the office at all during the selected period. We settled on the following rules for the chart:</p><ul data-rte-list="default"><li><p class="">Highlight the column for staff who attended 0 out of 20 business days as Red.</p></li><li><p class="">Highlight columns for 1 through 9 days of attendance as Yellow.</p></li><li><p class="">Highlight columns for 10 through 20 days of attendance as Green.</p></li></ul><h3>Conditional formatting columns</h3>


  


  



<p>You can use conditional formatting to achieve this. To build this out, let’s look at our underlying data. </p>
<p>In this example, we’ve got an aggregated table called ‘Staff Attendance Snapshot’ that has one row for each of the possible number of days that staff can attend (0 through 20). It then lists how many staff attended for that many days<sup id="fnref:1" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:1" class="footnote">1</a>
</sup>. </p>












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG" data-image-dimensions="339x877" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG?format=1000w" width="339" height="877" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020184130-Q85PH1LKS2YJ6R60NAUG/All+underlying+data.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">These snapshotted values are provided for multiple weeks. For now, we'll build a chart using only the values for the period ending on 28/02/2021. </p><p class="">To build out our chart, we can use the Days Attended field as the chart axis, and Staff Count field can be used for the chart values (as an implicit measure). It’s also sensible to look at this week by week, so we can add a slicer to our page to select the period of interest. </p><p class="">To apply conditional formatting, we can write a measure that works out which Days Attended value is selected for each column of the chart, and assigns that to a value. </p>


  


  




  
    <font face="Consolas">Attendance&nbsp;Status&nbsp;Conditional&nbsp;Formatting&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">DaysValue</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Staff&nbsp;Attendance&nbsp;Snapshot'[Days&nbsp;Attended]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SWITCH</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">TRUE</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">DaysValue</span>&nbsp;=&nbsp;<span class="Number">0</span>,&nbsp;<span class="Number">1</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">DaysValue</span>&nbsp;&gt;&nbsp;<span class="Number">0</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>&amp;&amp;&nbsp;<span class="Variable">DaysValue</span>&nbsp;&lt;&nbsp;<span class="Number">10</span>,&nbsp;<span class="Number">2</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">DaysValue</span>&nbsp;&gt;=&nbsp;<span class="Number">10</span>,&nbsp;<span class="Number">3</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">4</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">With the chart selected, go to the Format pane and select the conditional format button under Data colours. We’ll format based on the field values returned for our measure…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png" data-image-dimensions="3751x2250" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png?format=1000w" width="3751" height="2250" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020336993-11FDO6JBW0B06WRUJHPD/Applying+conditional+formatting.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">This gives out our conditionally formatted chart... </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG" data-image-dimensions="1074x414" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG?format=1000w" width="1074" height="414" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632022982048-GJ5CB0PKP5A3T27LYQEW/Chart+with+basic+cond+formatting.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>What about when targets change?</h3><p class="">While this addressed the initial requirement, the client followed up with some further requests. </p><p class="">An additional requirement from the client was that the conditionally formatted targets needed to change based on what week is selected. Attendance targets may change week to week based on lockdowns or relaxing of social distancing limits. </p><p class="">In addition to this, the client also wanted the chart to have a legend describing what each colour corresponds to.</p><p class="">To address both of these requirements, we’ll need to take a slightly different approach. This new approach requires us to add a few new tables to our model</p><h3>Extending the data model</h3><p class="">First, we’ll need to build a table called ‘Target Status’ which contains a list of the labels we want to appear in our legend. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png" data-image-dimensions="327x180" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png?format=1000w" width="327" height="180" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202749603-LCGWVNZW4WTDON9DAR64/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">The Target Status Code column will also be used as the Sort By column for Target Status. </p><p class="">Next, we need a table that lists the targets for each period. </p><p class="">We’ve already established that for the 4 week period ending 28/02/2021, staff were expected to attend for 10 of those 20 business days. </p><p class="">But let’s say that a lockdown started on 01/03/2021 that applied to all staff at the company. As such, the next rolling 4 week period for the week ending 07/03/2021 would have a reduced target, since staff aren’t permitted to attend for one of the four weeks. In this case, the target for this new period would be for staff to have attended 5 out of 20 days. In reality, these 5 days would have to have come from their attendances in the last 3 weeks of February.</p><p class="">Here’s what our ‘Weekly Targets’ table would look like…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png" data-image-dimensions="456x246" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png?format=1000w" width="456" height="246" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630202788231-9F7FSD1KLIT1E4V588RB/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Finally, we need a date dimension, which we’ll use as a common dimension between the ‘Staff Attendance Snapshot’ table and the ‘Weekly Targets’. Since this only gets used to show values in the period slicer, I’ve just made a simple table with only the dates that appear in the fact table. In more general cases, you’ll want to use a date dimension with a contiguous list of dates. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png" data-image-dimensions="522x145" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png?format=1000w" width="522" height="145" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203414705-J9X248Q5WKLUTOZWSLFO/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Once we’ve loaded these tables, we’ll need to model them as follows. The ‘Date’ table is relate to each table via the [Period End] columns, and ‘Target Status’ related to ‘Weekly Targets’ on the [Target Status Code] columns. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png" data-image-dimensions="1202x749" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png?format=1000w" width="1202" height="749" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203398694-UMFC9KT2JN6ACXDGORNY/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>Building our new chart</h3><p class="">Now that we’ve built out our data model, we can start building our visuals.</p><p class="">First, we need to create a single-select slicer based on ‘Date’[Period Out] to display the staff attendance for one rolling period at a time. If we don’t do this, we risk returning unmeaningful results by double-counting staff members across different periods. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png" data-image-dimensions="676x349" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png?format=1000w" width="676" height="349" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630203988428-UT4V4SQXHFHXPK9DCFBK/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


<p>As before, we can start building our chart with Days Attended as our Axis field, and Staff Count as an implicit measure for our Values. For this technique, it’s important to make sure we’re using a stacked column chart as our visual<sup id="fnref:2" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:2" class="footnote">2</a>
</sup>. </p>
<p>We need to bring ‘Target Status’[Target Status] into the Legend well in the Format pane. This will allow us to include columns of different colours, while showing each item on the chart legend.</p>
<p>However, when we do this, we get an error. </p>












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png" data-image-dimensions="1613x519" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png?format=1000w" width="1613" height="519" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1630205254871-1YSYHAEJ03AIIBSGBNVM/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">This happens because there is no way for the filter context from the Target Status column to propagate to the ‘Staff Attendance Snapshot’ table through the relationships in the data model. </p><p class="">Instead, we can author a new DAX measure to apply the filters as intended. </p>


  


  




  
    <font face="Consolas">Staff&nbsp;Count&nbsp;with&nbsp;Targets&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">LowerLimit</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">MIN</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Weekly&nbsp;Targets'[Min&nbsp;Limit]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">UpperLimit</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">MAX</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Weekly&nbsp;Targets'[Max&nbsp;Limit]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">AxisValue</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Staff&nbsp;Attendance&nbsp;Snapshot'[Days&nbsp;Attended]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">MeasureValue</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Staff&nbsp;Attendance&nbsp;Snapshot'[Staff&nbsp;Count]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">AxisValue</span>&nbsp;&gt;=&nbsp;<span class="Variable">LowerLimit</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>&amp;&amp;&nbsp;<span class="Variable">AxisValue</span>&nbsp;&lt;=&nbsp;<span class="Variable">UpperLimit</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">MeasureValue</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">The measure follows this logic…</p><ul data-rte-list="default"><li><p class="">It determines what the upper and lower limits of the Target Status for the period we’ve selected in the slicer.</p></li><li><p class="">It then determines which chart column we are evaluating (i.e. which Days Attended values we’re evaluating)</p></li><li><p class="">It works out if the the Days Attended values applies to the Target Status that we’re considering. E.g. If we’re evaluating the Target Status “Staff with no attendance”, then this only applies when we’re evaluating the Days Attended = 0 chart column.</p></li><li><p class="">If the Days Attended value lies in the Target Status range, then it returns the number of staff who attended. Otherwise it returns blank. </p></li></ul><p class="">When we drag this new measure onto the chart (and update the chart colours in the Format pane), here’s our result…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG" data-image-dimensions="1056x390" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG?format=1000w" width="1056" height="390" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020714272-CXAIO9A27A929O1RAN06/Chart+with+slicer+and+legend.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Now our colours will be presented as before, but with our legend showing. Note that I’ve already changed the sort order of the Target Status field, so that the colour order in the legend matches the order displaying left-to-right in the chart.</p><p class="">Finally, we can see that our target values (i.e. our chart colours) update as we change the rolling 4 week period selected in our Period End slicer. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif" data-image-dimensions="1067x424" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif?format=1000w" width="1067" height="424" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632020840330-3U7A1D49733M82FJLZCS/Swap+period+end+values.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Extension: Adding a summary table</h3><p class="">To finish this off, we can also add a table that tells us the number and percent of staff that fall into each Target Status category. </p><p class="">Out table will contain the Target Status’[Target Status] column, as well as two additional measures. </p>


  


  




  
    <font face="Consolas">Staff&nbsp;with&nbsp;Target&nbsp;Status&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">LowerLimit</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">MIN</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Weekly&nbsp;Targets'[Min&nbsp;Limit]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">UpperLimit</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">MAX</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Weekly&nbsp;Targets'[Max&nbsp;Limit]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Staff&nbsp;Attendance&nbsp;Snapshot'[Staff&nbsp;Count]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Staff&nbsp;Attendance&nbsp;Snapshot'[Days&nbsp;Attended]&nbsp;&gt;=&nbsp;<span class="Variable">LowerLimit</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Staff&nbsp;Attendance&nbsp;Snapshot'[Days&nbsp;Attended]&nbsp;&lt;=&nbsp;<span class="Variable">UpperLimit</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br></font>
  


  
    <font face="Consolas">Staff&nbsp;with&nbsp;Target&nbsp;Status&nbsp;(%)&nbsp;=<br><span class="Keyword">DIVIDE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>[Staff&nbsp;with&nbsp;Target&nbsp;Status],<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Staff&nbsp;Attendance&nbsp;Snapshot'[Staff&nbsp;Count]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ALL</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Staff&nbsp;Attendance&nbsp;Snapshot'[Staff&nbsp;Count]&nbsp;<span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">Now we can see our overall summary of staff attendance in the table, and the full distribution in our colour-coded chart. Note that I’ve added some conditional formatting to the table so that it’s easier to compare each Target Status. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif" data-image-dimensions="1249x424" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif?format=1000w" width="1249" height="424" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632021399276-1K4Z6PJYJT9QBXUS1D6P/Summary+table+included.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/Colour-coding-columns-with-a-legend.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />
  <ol data-preserve-html-node="true">
    <li id="fn:1" data-preserve-html-node="true">
     <p data-preserve-html-node="true">In a real-world scenario, you’ll likely have a transaction table that lists every time a staff member enters the office (based on swipe card access for example). In that scenario, you could use a disconnected table for the number of days attended, and use a custom measure to count up how many days each employee attends for. <a href="https://apexinsights.net/blog/histograms-in-power-bi">I’ve previously written about that approach here</a>.&nbsp;<a data-preserve-html-node="true" href="#fnref:1" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:2" data-preserve-html-node="true">
     <p data-preserve-html-node="true">If we use a clustered column chart for this technique instead, then the spacing between the resulting columns will look confusing for the report user.&nbsp;<a data-preserve-html-node="true" href="#fnref:2" class="reversefootnote">↩</a></p>
    </li>
  </ol>





<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1632136660333-QKZAKPBOPZNEGPK667SX/Thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="1059" height="819"><media:title type="plain">How to include a legend with a conditionally formatted chart</media:title></media:content></item><item><title>Dealing with Gaps and Islands in Power Query</title><dc:creator>Sam Fischer</dc:creator><pubDate>Mon, 12 Jul 2021 11:23:00 +0000</pubDate><link>https://apexinsights.net/blog/gaps-and-islands-in-power-query</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:60b8b3ba0e54f1692944e3e9</guid><description><![CDATA[Gaps and Islands analysis is a useful tool for finding distinct periods in 
a list of dates, like if you wanted to know when each customer was active 
or inactive. In this post, I show you a technique for finding gaps and 
islands in a list of dates against multiple categories, and provide custom 
M functions that you can use yourself for these kinds of problems.]]></description><content:encoded><![CDATA[<p class="">In my <a href="https://apexinsights.net/blog/convert-date-range-to-list">last blog post</a>, I discussed how you can take a range of dates defined by a start and end date, and convert that into a complete list of dates. There are some cases where you may want to do the reverse: you may have been provided with a list of dates marked against a number of categories, and you want to group into a start date and end date for each category. </p><p class="">However this situation is a bit trickier — if your date list has gaps where dates are missing, how are you supposed to handle those cases and still get meaningful results? Read on to find out…</p><h3>The simple (but dangerous) solution — Group By</h3><p class="">In the example of school holidays discussed in the last post, getting the holiday start and end dates is straighforward. You can just take your date list, group by the holiday name and return the minimum and maximum dates for each holiday period. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png" data-image-dimensions="886x591" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png?format=1000w" width="886" height="591" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088291870-XGP76Z6TGBWAXS2SVID8/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png" data-image-dimensions="1196x751" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png?format=1000w" width="1196" height="751" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088603443-746E94QC2MMBS96QPXN5/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png" data-image-dimensions="847x178" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png?format=1000w" width="847" height="178" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088117271-0XLFJ0OXIOPDL3K0YG7H/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">This works fine when your dates are contiguous, as is the case for school holiday periods. But you can come across some important issues to consider when this isn’t the case.</p><p class="">In another example, say we were dealing with a retail store, and we want to know which salesperson had the longest streak of days for which they had the highest sales. If we just look at two week's worth of data, here's the top salesperson for each day…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png" data-image-dimensions="531x492" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png?format=1000w" width="531" height="492" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634594116-SCQMCQ33FFG1PHVHBF40/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">If we look at the raw data with each salesperson highlighted, we can clearly see that Natasha has the longest streak of 4 days. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png" data-image-dimensions="532x488" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png?format=1000w" width="532" height="488" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623634896282-SUI6R6YMTMZVFEZB8LSI/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">However, if we were to apply the same Group By technique as above, here's what we get for our start and end dates for each salesperson's streak… </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png" data-image-dimensions="978x321" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png?format=1000w" width="978" height="321" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623635145623-ARA7W60RS295XIKBUMBQ/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">This output would suggest that it was actually Omar who had the longest streak! But clearly this is incorrect, as it hasn’t accounted for the gaps in Omar's tenure as top salesperson. If we want to get this logic working properly, we'll need to use an approach called Gap and Island analysis. </p><h3>&nbsp;What is Gap and Island analysis?</h3><p class="">Whenever we're dealing with an ordered sequence of values (like dates or integers), we may have clusters of values that all occur contiguously, which we'll call islands. Between these islands of values in the sequence, we will have missing values, which we'll call gaps. </p><p class="">When we're dealing with event data (i.e. a dataset with a date/time element), there are plenty of scenarios in which we would want to identify these gaps and islands. Besides the top salesperson streak problem above, we may want to know…</p><ul data-rte-list="default"><li><p class="">All the periods during which a customer was active or inactive.</p></li><li><p class="">Which dates we are missing data for in an incomplete dataset (e.g. when you’ve got hundreds of daily data extracts). </p></li><li><p class="">How many days a city has gone without a case of COVID community transmission.</p></li></ul><p class="">Gap and Island analysis provides approaches for answering these questions. There have been articles written previously on <a href="https://www.red-gate.com/simple-talk/sql/t-sql-programming/introduction-to-gaps-and-islands-analysis/">how to deal with gaps and islands in SQL</a>, but I've yet to come across any other articles that illustrate how to approach it in Power Query. So let’s tackle this challenge together!</p><h3>Identifying islands in a list of dates</h3><p class="">With that context out of the way, let's jump back to our salesperson example. For us to automatically determine which salesperson had the longest streak, we have to identify all the islands during which each staff member had the highest sales. Then we can look at which island had the longest duration, and this will tell us our winner.</p><p class="">Let's start by just looking at the data for Natasha. To group up her dates into islands, we'll need to do the following transforms…</p><p class="">1. Clean up our data by <strong>removing duplicates</strong> and <strong>sorting the dates chronologically</strong>. Note that these steps don't alter our dataset for this example, but if your own datasets are unordered and contain duplicates, then skipping this step may give you incorrect results.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png" data-image-dimensions="2500x1406" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png?format=1000w" width="2500" height="1406" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637397425-CHCQSO34FO0IQVDYXN72/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png" data-image-dimensions="2500x1693" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png?format=1000w" width="2500" height="1693" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623637535024-VW49Q6P1QLG16TVSBHX2/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">2. Duplicate the Date column, and <strong>convert it into an integer</strong>. I’ve renamed this column as Date Value. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png" data-image-dimensions="510x513" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png?format=1000w" width="510" height="513" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626084879592-TBTGEF6A70X35OKM5ZLJ/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png" data-image-dimensions="2500x1406" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png?format=1000w" width="2500" height="1406" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626085271906-90U3QIYJHMH6NY6RRNOX/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png" data-image-dimensions="886x309" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png?format=1000w" width="886" height="309" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626087169820-ACLUN3FXQ99IGXOHFWK6/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">3. <strong>Add an Index Column</strong>. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png" data-image-dimensions="2500x1406" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png?format=1000w" width="2500" height="1406" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623638808766-TIHVRS9OQ2MSY13LYPB3/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">4. Add a <strong>new custom column which subtracts Date Value from Index</strong>. I've called the new column Island ID because it uniquely identifies each cluster of dates. Whenever two dates in the list are contiguous, both the date value and the index increase by 1, so the value for Island ID is the same for both dates. If there is a gap between the dates, then the date value will jump by more than 1, so Island ID will change to a different value.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png" data-image-dimensions="2500x1259" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png?format=1000w" width="2500" height="1259" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1623647764919-ETS6A9EBG3GMG4IGEK97/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">5. <strong>Group each Island ID, returning the min and max Date for each island</strong>. This is the same logic that we initially used, but instead of grouping dates for each staff member, we're grouping them <em>for each island</em> of each staff member.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png" data-image-dimensions="1078x769" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png?format=1000w" width="1078" height="769" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646609204-93790O71MQYWG2SEWNDD/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png" data-image-dimensions="1039x327" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png?format=1000w" width="1039" height="327" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625646810504-0YK1V3TUOKQUTN32XGKW/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">6. <strong>Remove the Island ID column</strong>, since we only needed it to perform this grouping.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png" data-image-dimensions="2500x982" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png?format=1000w" width="2500" height="982" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647549807-WU5XWL0HWB3NE1DC3GGV/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png" data-image-dimensions="780x148" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png?format=1000w" width="780" height="148" sizes="(max-width: 640px) 100vw, (max-width: 767px) 58.333333333333336vw, 58.333333333333336vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625647660015-MX7G7A1W46G1B05AYNTZ/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>&nbsp;Expanding the logic to all staff</h3><p class="">Now that we've got the grouping working for one staff member, we'll have to apply this logic to our list of all staff members. In order to do this, we would need to group up our original list of salespeople, and apply the above logic as a custom function, as seen below. Note how the initial data preview for Natasha groups all her rows, but after applying the custom function we get the same islands as we got when we did this manually above. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif" data-image-dimensions="1497x848" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif?format=1000w" width="1497" height="848" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650063580-YWVM7CQ1L126WO7U0OUR/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">&nbsp;We can then re-expand our table column to get the full list of islands for all our staff members. There’s also some clean up after that to restore the date types to the new columns. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png" data-image-dimensions="2008x1217" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png?format=1000w" width="2008" height="1217" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650889905-JIHZMPM2HAST579P7OKT/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png" data-image-dimensions="783x281" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png?format=1000w" width="783" height="281" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625650934963-ZIRXWJJCWBEED3Q588M0/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">Now that we’ve got each of our separate islands, we can add a column that computes the number of days for each streak. From this, we see that Natasha did indeed have the longest streak of 4 days.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png" data-image-dimensions="1019x284" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png?format=1000w" width="1019" height="284" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625651174582-32FQ6S7T813NJJXDROCT/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>Custom function to return all islands</h3><p class="">If you want to apply all of this in a single step, here’s a custom function I’ve called <em>fn_Date_Islands() </em>that you can use to identify islands among a group of dates.&nbsp;</p><p class="">The function contains the logic both for working out the islands for an individual salesperson (or more generally, an individual category), and for extending this to all salespeople. </p><p class="">I've also generalised it so that you can specify the name of the Category against which islands may exist (i.e. Salesperson in this example), the name of the Date column, and the name of the output columns for Start Date and End Date…</p>


  


  



<p><font face="Courier" data-preserve-html-node="true"></font></p><p data-preserve-html-node="true"></p><font face="Courier" data-preserve-html-node="true">

  
<span data-preserve-html-node="true" class="constant keyword">let</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Function definition</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">fn</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">source_table</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;table</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">category_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;start_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;end_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant operator">&nbsp;=&gt;</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant keyword">let</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Define inner function that returns islands for each eategory</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">fn_Group_Islands_By_Category</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">source_table</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;table</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;start_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;end_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant operator">&nbsp;=&gt;</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant keyword">let</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// If column names are not provided, use defaults.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">date_column_name</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">start_date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Start Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">start_date_column_name</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">end_date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"End Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">end_date_column_name</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Source</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">source_table</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// This step explicitly renames the date column. This ensures that you can consistently reference the column in later steps, no matter what the original name was.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Renamed Columns"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.RenameColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">Source</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// We only need the date list itself.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Removed Other Columns"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.SelectColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Renamed Columns"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// In case dates are entered incorrectly, remove errors.</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Removed Errors"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.RemoveRowsWithErrors</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Removed Other Columns"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Indexing in later step relies on having a unique date list.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Removed Duplicates"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.Distinct</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Removed Errors"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Dates need to be in chronological order to identify gaps and islands.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Sorted Rows"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.Sort</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Removed Duplicates"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Order.Ascending</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Added Index"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.AddIndexColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Sorted Rows"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Index"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal number">0</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal number">1</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Int64.Type</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// The difference between the index and the date (when represented as an integer) uniquely identifies an island.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Added Island ID"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.AddColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Added Index"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Island ID"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Number.From</span><span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><span data-preserve-html-node="true" class="identifier">Date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant operator operator-arithmetic">-</span><span data-preserve-html-node="true" class="constant bracket bracket-1">[</span><span data-preserve-html-node="true" class="identifier">Index</span><span data-preserve-html-node="true" class="constant bracket bracket-1">]</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// The islands are each self-contained, so we're safe to aggregate here to get start and end dates.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Grouped Date by Island"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.Group</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Added Island ID"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Island ID"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="identifier">List.Min</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="constant bracket bracket-1">[</span><span data-preserve-html-node="true" class="identifier">Date</span><span data-preserve-html-node="true" class="constant bracket bracket-1">]</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">nullable</span><span data-preserve-html-node="true" class="type">&nbsp;date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="identifier">List.Max</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="constant bracket bracket-1">[</span><span data-preserve-html-node="true" class="identifier">Date</span><span data-preserve-html-node="true" class="constant bracket bracket-1">]</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">nullable</span><span data-preserve-html-node="true" class="type">&nbsp;date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Removed Island ID"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.RemoveColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Grouped Date by Island"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Island ID"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant keyword"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Removed Island ID"</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// If column names are not provided, use defaults.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">date_column_name</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">start_date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Start Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">start_date_column_name</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">end_date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"End Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">end_date_column_name</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Source</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">source_table</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Grouped by Category"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.Group</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">Source</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="identifier">category_column_name</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="literal string">"All Rows"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="identifier">fn_Group_Islands_By_Category</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">Table.SelectColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="identifier">_</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">category_column_name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;table</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Expanded Islands"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.ExpandTableColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Grouped by Category"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"All Rows"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Restored Date Types"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.TransformColumnTypes</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Expanded Islands"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant keyword"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;in</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Restored Date Types"</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Function documentation</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">fnType</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-primitive">function</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">source_table</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;table</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Table to transform"</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">category_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Name of Category to group into Islands"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.SampleValues</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">{</span><span data-preserve-html-node="true" class="literal string">"Customer"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="literal string">"Assignee"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">}</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Name of Date column"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.SampleValues</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Sales Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">}</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;start_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Name of Start Date column to return"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.SampleValues</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">{</span><span data-preserve-html-node="true" class="literal string">"Start Date"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Start of Island"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">}</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;end_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Name of End Date column to return"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.SampleValues</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">{</span><span data-preserve-html-node="true" class="literal string">"End Date"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"End of Island"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">}</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant bracket bracket-0"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;list</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"fn_Date_Islands"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.Description</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"
                    This function takes a table of categories assigned to dates, and returns a table of contiguous date periods for each category. 
                    By default, the date column in the input table is assumed to be called ""Date"", and the output columns are called ""Start Date"" and ""End Date"". 
                    These column names can be adjusted with the optional input parameters.                       "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="constant bracket bracket-0"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span></span><span data-preserve-html-node="true" class="constant keyword"><br data-preserve-html-node="true">in</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Value.ReplaceType</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">fn</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">fnType</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span>
  

<p></p>
  <a data-preserve-html-node="true" href="https://www.durchblick-durch-daten.de/power-query/m-formatter/" target="_blank" title="Powered by powerqueryformatter.com">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 80" data-preserve-html-node="true">
      <rect x="0" width="350" y="0" data-preserve-html-node="true" height="78.836"></rect>
      <text y="-2" data-preserve-html-node="true"><tspan x="8.646" y="57.799" data-preserve-html-node="true">Power Query</tspan><tspan data-preserve-html-node="true"> </tspan></text>
      <text x="355" y="57.848" data-preserve-html-node="true">Formatter</text>
    </svg>
  </a>


</font><p></p><p></p>


  
  <p class="">&nbsp;We can take our original dataset and apply this function to get our island groupings in a single step…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif" data-image-dimensions="854x572" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif?format=1000w" width="854" height="572" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625878928404-K40QFI50Y7781407SKMN/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>How about identifying gaps in dates?</h3><p class="">Say that instead of working out who had the longest 'hot' streak, we want to work out who had the longest cold streak. We can extend this approach to work out gaps as well. Here's the steps involved in the logic…</p><p class="">1. <strong>Remove duplicates and sort</strong>. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png" data-image-dimensions="4000x2250" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png?format=1000w" width="4000" height="2250" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879161570-73OKNEGHSW9V2GC0VB6K/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png" data-image-dimensions="2500x1693" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png?format=1000w" width="2500" height="1693" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879236776-K5VQZC5LPZS8EB098MMO/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">2. Add an Index column <strong>starting at 0</strong>. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png" data-image-dimensions="1417x897" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png?format=1000w" width="1417" height="897" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625879968151-VD2NPSXRKPQ1IMIM1MIS/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">3. Add a second index <strong>starting at 1</strong>, which I'll call Next Index. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png" data-image-dimensions="1654x839" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png?format=1000w" width="1654" height="839" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880029724-WQNF0GZVHVFXZ20PCH4I/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">4. <strong>Merge the query to itself</strong>, using the join condition <strong>[Next Index] = [Index]</strong>. Then expand the join result and call the resulting column Next Date. You'll see that this reproduces the dates list, but shifts it one row up.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png" data-image-dimensions="1072x959" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png?format=1000w" width="1072" height="959" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880163133-LBITXYOJNB5FEXDC8Q38/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png" data-image-dimensions="1280x350" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png?format=1000w" width="1280" height="350" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625880309260-0GPUDG48IOGUAH34HOZL/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">5. Add a custom column called Gap Start, which <strong>adds one day to the original Date column</strong>.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png" data-image-dimensions="1065x683" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png?format=1000w" width="1065" height="683" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881209582-77HW8822LGA7Y7WXIRLB/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png" data-image-dimensions="1218x360" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png?format=1000w" width="1218" height="360" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881562460-5AGPUWIN5NM9CLGJGSLW/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">6. Add a custom column called Gap End, which <strong>subtracts one day from Next Date</strong>.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png" data-image-dimensions="1064x681" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png?format=1000w" width="1064" height="681" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881264534-9X7AJ11ACRWZITKMJ64E/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png" data-image-dimensions="1223x335" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png?format=1000w" width="1223" height="335" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625881697614-AYV9HAR52A8EKR651D0N/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">7. The pairs of Gap Start and Gap End values will contain Gaps that appear to go backwards in time. These false gaps appear for rows that are part of an island, so we want to remove these rows. Do this by filtering rows with the <strong>filter condition ([Gap Start] &lt;&gt; [Next Date] and [Gap End] &lt;&gt; null)</strong>.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png" data-image-dimensions="2500x400" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png?format=1000w" width="2500" height="400" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882037998-ZJVKH0J9KE4AUPAIWAD9/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">8. Remove the intermediary columns to give us our final result.&nbsp;</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png" data-image-dimensions="1138x184" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png?format=1000w" width="1138" height="184" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882158786-48N5CCH07Z91HD3BP3ZB/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">As before, we can wrap all this into a function and apply it to each staff member. Here’s what we get when we do so…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png" data-image-dimensions="781x220" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png?format=1000w" width="781" height="220" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625882520881-ZAKP6ANF39XI2FLJLVPU/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">Note that in Chris's case, he only has a single streak so there are no gaps returned. These null rows can simply be filtered out.</p><h3>Custom function to return all islands</h3><p class="">Here's the full function that returns all gaps for all staff in one step, which I’ve called <em>fn_Date_Gaps()</em>. As with the islands function, you can define the names of the date column, outputted start date column and outputted end date column names as optional parameters. </p>


  


  



<p><font face="Courier" data-preserve-html-node="true"></font></p><p data-preserve-html-node="true"></p><font face="Courier" data-preserve-html-node="true">

  
<span data-preserve-html-node="true" class="constant keyword">let</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Function definition</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">fn</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">source_table</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;table</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">category_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;start_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;end_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant operator">&nbsp;=&gt;</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant keyword">let</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Define inner function that returns gaps for each category.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">fn_Group_Gaps_By_Category</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">source_table</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;table</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;start_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;end_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant operator">&nbsp;=&gt;</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant keyword">let</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// If column names are not provided, use defaults.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">date_column_name</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">start_date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Start Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">start_date_column_name</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">end_date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"End Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">end_date_column_name</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Source</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">source_table</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// This step explicitly renames the date column. This ensures that you can consistently reference the column in later steps, no matter what the original name was.</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Renamed Columns"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.RenameColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">Source</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// We only need the date list itself.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Removed Other Columns"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.SelectColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Renamed Columns"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// In case dates are entered incorrectly, remove errors.</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Removed Errors"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.RemoveRowsWithErrors</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Removed Other Columns"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Indexing in later step relies on having a unique date list.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Removed Duplicates"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.Distinct</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Removed Errors"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Dates need to be in chronological order to identify gaps and islands.</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Sorted Rows"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.Sort</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Removed Duplicates"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Order.Ascending</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Added Index"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.AddIndexColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Sorted Rows"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Index"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal number">0</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal number">1</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Int64.Type</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Used to join to self with offset.</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Added Next Index"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.AddIndexColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Added Index"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Next Index"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal number">1</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal number">1</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Int64.Type</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Self-join to get next date in list.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Merged Index on Next Index"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.NestedJoin</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Added Next Index"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Next Index"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">#"Added Next Index"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Index"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Join Result"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">JoinKind.LeftOuter</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Expanded Join Result"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.ExpandTableColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Merged Index on Next Index"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Join Result"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Next Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// This new column returns the day after [Date].</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Added Gap Start"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.AddColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Expanded Join Result"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Gap Start"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Date.AddDays</span><span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><span data-preserve-html-node="true" class="identifier">Date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">]</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="literal number">1</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;date</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// This new column returns the day before [Next Date].</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Added Gap End"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.AddColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Added Gap Start"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Gap End"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Date.AddDays</span><span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><span data-preserve-html-node="true" class="identifier">Next Date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">]</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant operator operator-arithmetic">-</span><span data-preserve-html-node="true" class="literal number">1</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;date</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// A row represents a gap in the date sequence when the next date in the sequence is not the next chronological date. The final record (with a null end date) is invalid since it inspects dates outside of the date sequence.</span>&nbsp;&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Filtered to valid gaps"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.SelectRows</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Added Gap End"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><span data-preserve-html-node="true" class="identifier">Gap Start</span><span data-preserve-html-node="true" class="constant bracket bracket-2">]</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;&lt;&gt;</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><span data-preserve-html-node="true" class="identifier">Next Date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">]</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;and</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><span data-preserve-html-node="true" class="identifier">Gap End</span><span data-preserve-html-node="true" class="constant bracket bracket-2">]</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;&lt;&gt;</span><span data-preserve-html-node="true" class="literal null">&nbsp;null</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Return only gap range dates"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.SelectColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Filtered to valid gaps"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="literal string">"Gap Start"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Gap End"</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Rename based on optional parameters.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Renamed gap ranges"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.RenameColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Return only gap range dates"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="literal string">"Gap Start"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="literal string">"Gap End"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span></span><span data-preserve-html-node="true" class="constant keyword"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Renamed gap ranges"</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// If column names are not provided, use defaults.</span>&nbsp;<span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">date_column_name</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">start_date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Start Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">start_date_column_name</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">if</span>&nbsp;<span data-preserve-html-node="true" class="identifier">end_date_column_name</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;is</span><span data-preserve-html-node="true" class="type">&nbsp;null</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;then</span><span data-preserve-html-node="true" class="literal string">&nbsp;"End Date"</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;else</span>&nbsp;<span data-preserve-html-node="true" class="identifier">end_date_column_name</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Source</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">source_table</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Grouped by Category"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.Group</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">Source</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="identifier">category_column_name</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="literal string">"All Rows"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="identifier">fn_Group_Gaps_By_Category</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">Table.SelectColumns</span><span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="identifier">_</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">category_column_name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;table</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Expanded Gaps"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.ExpandTableColumn</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Grouped by Category"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"All Rows"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Restored Date Types"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.TransformColumnTypes</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Expanded Gaps"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="constant bracket bracket-1">{</span><span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">Start_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">{</span><span data-preserve-html-node="true" class="identifier">End_Date_Column_Name</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">}</span><span data-preserve-html-node="true" class="constant bracket bracket-1">}</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Filtered Categories with no gaps"</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="identifier">Table.SelectRows</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">#"Restored Date Types"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">each</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><span data-preserve-html-node="true" class="identifier">Start Date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">]</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;&lt;&gt;</span>&nbsp;<span data-preserve-html-node="true" class="literal null">null</span><span data-preserve-html-node="true" class="constant keyword operator operator-keyword">&nbsp;and</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><span data-preserve-html-node="true" class="identifier">End Date</span><span data-preserve-html-node="true" class="constant bracket bracket-2">]</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;&lt;&gt;</span><span data-preserve-html-node="true" class="literal null">&nbsp;null</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span><span data-preserve-html-node="true" class="constant keyword"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;in</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">#"Filtered Categories with no gaps"</span><span data-preserve-html-node="true" class="constant">,</span></span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="comment">// Function documentation</span><span data-preserve-html-node="true"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">fnType</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword">type</span>&nbsp;<span data-preserve-html-node="true" class="constant type type-primitive">function</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">source_table</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;table</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Table to transform"</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">category_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Name of Category to group into Gaps"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.SampleValues</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">{</span><span data-preserve-html-node="true" class="literal string">"Customer"</span><span data-preserve-html-node="true" class="constant">,</span><span data-preserve-html-node="true" class="literal string">"Assignee"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">}</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Name of Date column"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.SampleValues</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">{</span><span data-preserve-html-node="true" class="literal string">"Date"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Sales Date"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">}</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;start_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Name of Start Date column to return"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.SampleValues</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">{</span><span data-preserve-html-node="true" class="literal string">"Start Date"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"Start of Island"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">}</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant type type-modifier">optional</span><span data-preserve-html-node="true" class="identifier">&nbsp;end_date_column_name</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-1">(</span><span data-preserve-html-node="true" class="constant keyword">type</span><span data-preserve-html-node="true" class="type">&nbsp;text</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-2">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.FieldCaption</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"Name of End Date column to return"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.SampleValues</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">{</span><span data-preserve-html-node="true" class="literal string">"End Date"</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="literal string">"End of Island"</span><span data-preserve-html-node="true" class="constant bracket bracket-0">}</span><span data-preserve-html-node="true" class="constant bracket bracket-2"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span data-preserve-html-node="true" class="constant bracket bracket-1">)</span><span data-preserve-html-node="true" class="constant bracket bracket-0"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span>&nbsp;<span data-preserve-html-node="true" class="constant keyword operator operator-keyword">as</span><span data-preserve-html-node="true" class="type">&nbsp;list</span><span data-preserve-html-node="true" class="constant keyword">&nbsp;meta</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="constant bracket bracket-0">[</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.Name</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"fn_Date_Gaps"</span><span data-preserve-html-node="true" class="constant">,</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Documentation.Description</span><span data-preserve-html-node="true" class="constant operator operator-equality">&nbsp;=</span><span data-preserve-html-node="true" class="literal string">&nbsp;"
                    This function takes a table of categories assigned to dates, and returns a table of date periods that represent gaps between contiguous date periods. 
                    When a category has only a single contiguous date range with no gaps, this category is removed from the function output. 
                    By default, the date column in the input table is assumed to be called ""Date"", and the output columns are called ""Start Date"" and ""End Date"". 
                    These column names can be adjusted with the optional input parameters.                       "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="constant bracket bracket-0"><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span></span><span data-preserve-html-node="true" class="constant keyword"><br data-preserve-html-node="true">in</span><br data-preserve-html-node="true">&nbsp;&nbsp;&nbsp;&nbsp;<span data-preserve-html-node="true" class="identifier">Value.ReplaceType</span><span data-preserve-html-node="true" class="constant bracket bracket-0">(</span><span data-preserve-html-node="true" class="identifier">fn</span><span data-preserve-html-node="true" class="constant">,</span>&nbsp;<span data-preserve-html-node="true" class="identifier">fnType</span><span data-preserve-html-node="true" class="constant bracket bracket-0">)</span>
  

<p></p>
  <a data-preserve-html-node="true" href="https://www.durchblick-durch-daten.de/power-query/m-formatter/" target="_blank" title="Powered by powerqueryformatter.com">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 80" data-preserve-html-node="true">
      <rect x="0" width="350" y="0" data-preserve-html-node="true" height="78.836"></rect>
      <text y="-2" data-preserve-html-node="true"><tspan x="8.646" y="57.799" data-preserve-html-node="true">Power Query</tspan><tspan data-preserve-html-node="true"> </tspan></text>
      <text x="355" y="57.848" data-preserve-html-node="true">Formatter</text>
    </svg>
  </a>


</font><p></p><p></p>


  
  <p class="">&nbsp;When we apply the function against our original dataset, we get all the gaps. Note that the function filters out all categories/salespeople that have no gaps. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif" data-image-dimensions="797x569" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif?format=1000w" width="797" height="569" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1625883398270-DKD4OP2SVZ37TU3G03R9/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>Summary</h3><p class="">Knowing how to deal with Gaps and Islands is a good tool to have in your data analysis toolkit. </p><p class="">There are ways to accomplish this with SQL as well, and in cases where you can push the logic upstream to SQL, I find it best to do so. But in cases where you don’t have that luxury, like when your data comes from csv files, then you can use the above functions to solve it with Power Query. </p><h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/Gaps-and-Islands-in-Power-Query.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1626088815805-YQTZMS39VG4IIMHDSNU0/Thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="1057" height="819"><media:title type="plain">Dealing with Gaps and Islands in Power Query</media:title></media:content></item><item><title>Convert a date range to a list of dates with Power Query</title><dc:creator>Sam Fischer</dc:creator><pubDate>Mon, 07 Jun 2021 12:00:00 +0000</pubDate><link>https://apexinsights.net/blog/convert-date-range-to-list</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:60ba092ed1c2cc04f2511b54</guid><description><![CDATA[In this post, I’ll show you how you can take a range of dates (defined by a 
start date and end date), and convert it into a full list of dates. This 
technique is by no means new, but we’ll expand this approach by converting 
the logic into a custom function in Power Query so you can repeat the logic 
in separate queries.]]></description><content:encoded><![CDATA[<p class="">In this post, I’ll show you how you can take a range of dates (defined by a start date and end date), and convert it into a full list of dates. This technique is by no means new, but we’ll expand this approach by converting the logic into a custom function in Power Query so you can repeat the logic in separate queries. </p><h3>The logic behind creating the date list</h3><p class="">I was recently working on a report where I needed to add a slicer that filtered values down to different school holiday periods. To achieve this, I needed a list of all the dates where school holidays fell, and also the name of the school holiday period (so that they could be distinguished). </p><p class="">Instead of the full date list, online sources typically report on the start and end dates for school holidays. Here’s what such a list of holidays may look like:</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png" data-image-dimensions="843x178" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png?format=1000w" width="843" height="178" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622806300084-4HUFYB0284RU9K4CDWBR/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">To get this into a complete list of all school holiday dates, I followed <a href="https://www.poweredsolutions.co/2019/07/23/fill-dates-between-dates-with-power-bi-power-query/">an approach described by Miguel Escobar</a> which I’ll summarise from his post below:</p><p class="">1. Change the data type for the two date columns from Dates to Integers. This makes the next step simple to implement. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png" data-image-dimensions="2500x1406" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png?format=1000w" width="2500" height="1406" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622952014681-EFHOCCO1M5KM4HX0HFVY/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">2. Add a new column that contains the list of integers between the two columns. Power Query has an easy syntax to create this sequence of numbers…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png" data-image-dimensions="1374x763" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png?format=1000w" width="1374" height="763" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622807976272-0BZZWYZ41EDKKHI1KL4F/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">3. Expand the new Date list column, then convert the data type of the column from Integer to Date. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png" data-image-dimensions="4000x2250" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png?format=1000w" width="4000" height="2250" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622946655678-U84INQF4VICZ2HHGOEEG/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">4. Delete the original Start Date and End Date columns, giving us our final result.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png" data-image-dimensions="1381x490" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png?format=1000w" width="1381" height="490" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622808732256-VANVP37ZCCYPLPGEAIKL/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>Pushing the logic into a custom function</h3><p class="">The approach above works well to create the date range. But as I continued to develop the report, I had more requests come in to include additional date ranges to slice on, like promotional periods and COVID lockdown periods. In keeping with the ‘Don’t Repeat Yourself’ principle, at this point I decided to translate the logic above into a single function to be used as a step in each query. Here’s the function that I built…</p>


  


  




  
    

  
   <font face="Courier" ><p>
<span class="constant keyword">let</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Main function</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">fn</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant bracket bracket-0">(</span><span class="identifier">source_table</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><span class="type">&nbsp;table</span><span class="constant">,</span>&nbsp;<span class="constant type type-modifier">optional</span><span class="identifier">&nbsp;start_date_column_name</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><span class="type">&nbsp;text</span><span class="constant">,</span>&nbsp;<span class="constant type type-modifier">optional</span><span class="identifier">&nbsp;end_date_column_name</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><span class="type">&nbsp;text</span><span class="constant">,</span>&nbsp;<span class="constant type type-modifier">optional</span><span class="identifier">&nbsp;date_column_name</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><span class="type">&nbsp;text</span><span class="constant bracket bracket-0">)</span><span class="constant operator">&nbsp;=&gt;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant keyword">let</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// If column names are not provided, use defaults</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Start_Date_Column_Name</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant keyword">if</span>&nbsp;<span class="identifier">start_date_column_name</span><span class="constant keyword operator operator-keyword">&nbsp;is</span><span class="type">&nbsp;null</span><span class="constant keyword">&nbsp;then</span><span class="literal string">&nbsp;&quot;Start Date&quot;</span><span class="constant keyword">&nbsp;else</span>&nbsp;<span class="identifier">start_date_column_name</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">End_Date_Column_Name</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant keyword">if</span>&nbsp;<span class="identifier">end_date_column_name</span><span class="constant keyword operator operator-keyword">&nbsp;is</span><span class="type">&nbsp;null</span><span class="constant keyword">&nbsp;then</span><span class="literal string">&nbsp;&quot;End Date&quot;</span><span class="constant keyword">&nbsp;else</span>&nbsp;<span class="identifier">end_date_column_name</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Date_Column_Name</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant keyword">if</span>&nbsp;<span class="identifier">date_column_name</span><span class="constant keyword operator operator-keyword">&nbsp;is</span><span class="type">&nbsp;null</span><span class="constant keyword">&nbsp;then</span><span class="literal string">&nbsp;&quot;Date&quot;</span><span class="constant keyword">&nbsp;else</span>&nbsp;<span class="identifier">date_column_name</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Follows approach taken in this blog... https://www.poweredsolutions.co/2019/07/23/fill-dates-between-dates-with-power-bi-power-query/</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Source</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">source_table</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// This step explicitly renames the columns containing start and end dates. It ensures that you can consistently reference these columns in the later step where the date list is generated as integers.</span>&nbsp;<span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Renamed Columns&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.RenameColumns</span><span class="constant bracket bracket-0">(</span><span class="identifier">Source</span><span class="constant">,</span><span class="constant bracket bracket-1">{</span><span class="constant bracket bracket-2">{</span><span class="identifier">Start_Date_Column_Name</span><span class="constant">,</span>&nbsp;<span class="literal string">&quot;Start Date for Date Range&quot;</span><span class="constant bracket bracket-2">}</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-2">{</span><span class="identifier">End_Date_Column_Name</span><span class="constant">,</span>&nbsp;<span class="literal string">&quot;End Date for Date Range&quot;</span><span class="constant bracket bracket-2">}</span><span class="constant bracket bracket-1">}</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// This provides an easier way to generate a date list, as you just need to generate the list of numbers between two integers.</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Changed Date Ranges to Integers&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.TransformColumnTypes</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Renamed Columns&quot;</span><span class="constant">,</span><span class="constant bracket bracket-1">{</span><span class="constant bracket bracket-2">{</span><span class="literal string">&quot;Start Date for Date Range&quot;</span><span class="constant">,</span>&nbsp;<span class="identifier">Int64.Type</span><span class="constant bracket bracket-2">}</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-2">{</span><span class="literal string">&quot;End Date for Date Range&quot;</span><span class="constant">,</span>&nbsp;<span class="identifier">Int64.Type</span><span class="constant bracket bracket-2">}</span><span class="constant bracket bracket-1">}</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// In case dates are entered incorrectly, remove errors.</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Removed Errors&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.RemoveRowsWithErrors</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Changed Date Ranges to Integers&quot;</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-1">{</span><span class="literal string">&quot;Start Date for Date Range&quot;</span><span class="constant">,</span>&nbsp;<span class="literal string">&quot;End Date for Date Range&quot;</span><span class="constant bracket bracket-1">}</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Add the list of relevant dates to each row as integers.</span>&nbsp;<span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Added Date Integer List&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.AddColumn</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Removed Errors&quot;</span><span class="constant">,</span>&nbsp;<span class="identifier">Date_Column_Name</span><span class="constant">,</span>&nbsp;<span class="constant keyword">each</span>&nbsp;<span class="constant bracket bracket-1">{</span><span class="constant bracket bracket-2">[</span><span class="identifier">Start Date for Date Range</span><span class="constant bracket bracket-2">]</span><span class="constant operator">..</span><span class="constant bracket bracket-2">[</span><span class="identifier">End Date for Date Range</span><span class="constant bracket bracket-2">]</span><span class="constant bracket bracket-1">}</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Expanded Date List&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.ExpandListColumn</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Added Date Integer List&quot;</span><span class="constant">,</span>&nbsp;<span class="identifier">Date_Column_Name</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Changed Dates to Date Type&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.TransformColumnTypes</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Expanded Date List&quot;</span><span class="constant">,</span><span class="constant bracket bracket-1">{</span><span class="constant bracket bracket-2">{</span><span class="literal string">&quot;Start Date for Date Range&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">type</span><span class="type">&nbsp;date</span><span class="constant bracket bracket-2">}</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-2">{</span><span class="literal string">&quot;End Date for Date Range&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">type</span><span class="type">&nbsp;date</span><span class="constant bracket bracket-2">}</span><span class="constant">,</span>&nbsp;<span class="constant bracket bracket-2">{</span><span class="identifier">Date_Column_Name</span><span class="constant">,</span>&nbsp;<span class="constant keyword">type</span><span class="type">&nbsp;date</span><span class="constant bracket bracket-2">}</span><span class="constant bracket bracket-1">}</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Removed Start and End Dates&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Table.RemoveColumns</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Changed Dates to Date Type&quot;</span><span class="constant">,</span><span class="constant bracket bracket-1">{</span><span class="literal string">&quot;Start Date for Date Range&quot;</span><span class="constant">,</span>&nbsp;<span class="literal string">&quot;End Date for Date Range&quot;</span><span class="constant bracket bracket-1">}</span><span class="constant bracket bracket-0">)</span><span class="constant keyword"><br>&nbsp;&nbsp;&nbsp;&nbsp;in</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Removed Start and End Dates&quot;</span><span class="constant">,</span></span><br><span class="comment">// Function Documentation</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">fnType</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant keyword">type</span>&nbsp;<span class="constant type type-primitive">function</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-0">(</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">source_table</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-1">(</span><span class="constant keyword">type</span><span class="type">&nbsp;table</span><span class="constant keyword">&nbsp;meta</span>&nbsp;<span class="constant bracket bracket-2">[</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Documentation.FieldCaption</span><span class="constant operator operator-equality">&nbsp;=</span><span class="literal string">&nbsp;&quot;Table to transform&quot;</span><span class="constant bracket bracket-2"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span class="constant bracket bracket-1">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant type type-modifier">optional</span><span class="identifier">&nbsp;start_date_column_name</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-1">(</span><span class="constant keyword">type</span><span class="type">&nbsp;text</span><span class="constant keyword">&nbsp;meta</span>&nbsp;<span class="constant bracket bracket-2">[</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Documentation.FieldCaption</span><span class="constant operator operator-equality">&nbsp;=</span><span class="literal string">&nbsp;&quot;Name of Start Date column&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Documentation.SampleValues</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant bracket bracket-0">{</span><span class="literal string">&quot;Start of Period&quot;</span><span class="constant">,</span><span class="literal string">&quot;Sales Promotion Start Date&quot;</span><span class="constant bracket bracket-0">}</span><span class="constant bracket bracket-2"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span class="constant bracket bracket-1">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant type type-modifier">optional</span><span class="identifier">&nbsp;end_date_column_name</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-1">(</span><span class="constant keyword">type</span><span class="type">&nbsp;text</span><span class="constant keyword">&nbsp;meta</span>&nbsp;<span class="constant bracket bracket-2">[</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Documentation.FieldCaption</span><span class="constant operator operator-equality">&nbsp;=</span><span class="literal string">&nbsp;&quot;Name of End Date column&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Documentation.SampleValues</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant bracket bracket-0">{</span><span class="literal string">&quot;End of Period&quot;</span><span class="constant">,</span><span class="literal string">&quot;Sales Promotion End Date&quot;</span><span class="constant bracket bracket-0">}</span><span class="constant bracket bracket-2"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span class="constant bracket bracket-1">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant type type-modifier">optional</span><span class="identifier">&nbsp;date_column_name</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-1">(</span><span class="constant keyword">type</span><span class="type">&nbsp;text</span><span class="constant keyword">&nbsp;meta</span>&nbsp;<span class="constant bracket bracket-2">[</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Documentation.FieldCaption</span><span class="constant operator operator-equality">&nbsp;=</span><span class="literal string">&nbsp;&quot;Name of Date column to return&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Documentation.SampleValues</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant bracket bracket-0">{</span><span class="literal string">&quot;Date in Period&quot;</span><span class="constant">,</span><span class="literal string">&quot;Sales Promotion Date&quot;</span><span class="constant bracket bracket-0">}</span><span class="constant bracket bracket-2"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span><span class="constant bracket bracket-1">)</span><span class="constant bracket bracket-0"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><span class="type">&nbsp;list</span><span class="constant keyword">&nbsp;meta</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-0">[</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Documentation.Name</span><span class="constant operator operator-equality">&nbsp;=</span><span class="literal string">&nbsp;&quot;fn_Expand_Date_Range_To_List&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Documentation.Description</span><span class="constant operator operator-equality">&nbsp;=</span><span class="literal string">&nbsp;&quot;
                    This function takes a table with columns for start date and end date of a period, and returns a table with one record for each date within that period. 
                    By default, the columns to transform are assumed to be called &quot;&quot;Start Date&quot;&quot; and &quot;&quot;End Date&quot;&quot;, and the output date column is called &quot;&quot;Date&quot;&quot;.
                    These column names can be adjusted with the optional input parameters.                     
                    &quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="constant bracket bracket-0"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]</span></span><span class="constant keyword"><br>in</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Value.ReplaceType</span><span class="constant bracket bracket-0">(</span><span class="identifier">fn</span><span class="constant">,</span>&nbsp;<span class="identifier">fnType</span><span class="constant bracket bracket-0">)</span>
  


  <a href="https://www.durchblick-durch-daten.de/power-query/m-formatter/" target="_blank" title="Powered by powerqueryformatter.com">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 80">
      <rect x="0" width="350" y="0" height="78.836"/>
      <text y="-2"><tspan x="8.646" y="57.799">Power Query</tspan><tspan> </tspan></text>
      <text x="355" y="57.848">Formatter</text>
    </svg>
  </a>
  </p>
  </font> 





  












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png" data-image-dimensions="1365x900" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png?format=1000w" width="1365" height="900" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622949086421-D5QD0DX6WOI92QFORFUC/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Here are a few considerations that I baked into the function definition, which are good to bear in mind whenever you define your own custom functions. </p><ul data-rte-list="default"><li><p class="">I made sure to document the function, both with comments in the M code to explain steps and by explicitly defining documentation. If you aren’t in the practice of documenting your custom functions, <a href="https://ssbi-blog.de/writing-documentation-for-custom-m-functions/">Lars Schreiber has a good blog series on how to go about it</a>.  </p></li><li><p class="">I provided optional parameters so that you can identify which columns to use as your <em>Start Date</em> and <em>End Date</em>, for when the names in your query vary from these generic names. </p></li><li><p class="">While I was thinking about different column names, I also added the option to define what the output name for the final Date column would be, if you don’t want to generically call it <em>Date</em>. </p></li><li><p class="">I also added a step to remove errors from your input date columns if they happen to contain them. Depending on why the errors occured, it may be more useful to replace the errors before applying the function. Adding in the error-removing logic ensures that the function doesn’t break if errors happen to occur.</p></li></ul><p class="">If you find yourself in a situation where you have to expand a date range into a full list, feel free to give this one a go!</p>


  


  



<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1622982998870-LJ38XJES29RBV5BELBDQ/Blog+thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="1058" height="818"><media:title type="plain">Convert a date range to a list of dates with Power Query</media:title></media:content></item><item><title>How to reset calculation groups in a custom tooltip or drillthrough page</title><dc:creator>Sam Fischer</dc:creator><pubDate>Wed, 07 Apr 2021 11:34:00 +0000</pubDate><link>https://apexinsights.net/blog/reset-calculation-groups</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:60645907b08308554f3782ea</guid><description><![CDATA[Using calculation groups in visuals can make your life a lot easier. But 
when you try to use custom tooltips or drillthroughs on these visuals, the 
calculation groups get applied to those as well. This can be challenging 
when you want your tooltip to show calculation items besides the one you’re 
hovering over. In this post, I’ll show you how you can address this issue, 
so you can reset and reapply your calculation groups for tooltips and 
drillthrough pages.]]></description><content:encoded><![CDATA[<p>I was faced with an interesting challenge with calculation groups recently. Say you’ve got a standard time intelligence matrix built out using calculation groups 
<sup id="fnref:1" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:1" class="footnote">1</a>
</sup>
. In this case, we’ve got a matrix which shows the current year sales, prior year sales and year-on-year change for each month. Using the Contoso dataset, it might look something like this…</p>












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png" data-image-dimensions="562x678" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png?format=1000w" width="562" height="678" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617340617363-7D8J0AM7L8GUAIJHE1YU/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Adding a custom tooltip</h3><p class="">I wanted to add a custom tooltip, to allow users to dig even deeper. I was aiming to show how these values broke down across different product categories. </p><p class="">The simplest implementation is to copy this same matrix into a custom tooltip page, and replace the months on the rows with the product category. In doing this, you can see the category breakdown, but only for the calculation item that you’re currently hovering over, as highlighted below. </p><p class="">Note how the total value in the tooltip matches the value that we hover over in the main matrix. The tooltip calculates the correct values, but unfortunately filters the values down to just a single calculation item at a time. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png" data-image-dimensions="1131x674" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png?format=1000w" width="1131" height="674" sizes="(max-width: 640px) 100vw, (max-width: 767px) 41.66666666666667vw, 41.66666666666667vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787092601-VOELFC26W64B92VK1GJJ/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png" data-image-dimensions="1222x625" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png?format=1000w" width="1222" height="625" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617787171541-L19N8ROD3K9MYRW38J2B/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Showing multiple calculation items at once</h3><p class="">If we want to show all of the calculation items, we can create a measure that directly applies a given calculation group. For example, we can define this measure to return the Total Sales in the previous year, using the logic in the <em>PY</em> calculation item. </p>


  


  




  
    <font face="Consolas">Total&nbsp;Sales&nbsp;PY&nbsp;=<br><span class="Keyword">FORMAT</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;[Total&nbsp;Sales],&nbsp;'Time&nbsp;Intelligence'[Calculation]&nbsp;=&nbsp;<span class="StringLiteral">"PY"</span>&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="StringLiteral">"$#,##0"</span><br><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">The FORMAT part is important to make sure the measure doesn’t inherit any format strings from the calculation items in the matrix. </p><p class="">The same can be done for our current year sales. </p>


  


  



<font face="Consolas" data-preserve-html-node="true">Total&nbsp;Sales&nbsp;CY&nbsp;=<br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Keyword">FORMAT</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Keyword">CALCULATE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span>&nbsp;[Total&nbsp;Sales],&nbsp;'Time&nbsp;Intelligence'[Calculation]&nbsp;=&nbsp;<span data-preserve-html-node="true" class="StringLiteral">"Current"</span>&nbsp;<span data-preserve-html-node="true" class="Parenthesis">)</span>,<br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="StringLiteral">"$#,##0"</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true"></font>

  
  <p class="">With these defined, we can remove the calculation group for the columns of the matrix in our tooltip. Then we can add our measure for the current and previous year sales. This will give us the correct values when we hover over our current year sales column…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png" data-image-dimensions="1073x607" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png?format=1000w" width="1073" height="607" sizes="(max-width: 640px) 100vw, (max-width: 767px) 58.333333333333336vw, 58.333333333333336vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337678856-KOPQ14J67ZK7437MX047/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">But we get some strange results when we inspect the other columns…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png" data-image-dimensions="1449x609" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png?format=1000w" width="1449" height="609" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617337760536-IUAKQ212XQ3CO8EM6T8D/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">In particular, when we hover over YOY, the tooltip is telling us that there were no sales last year! Something’s definitely gone wrong here.</p><h3>What’s the problem? Filter context (as usual)</h3>


  


  



<p>The reason we’re getting the wrong calculation is that the tooltip is generating it’s results based on the values made available to it in the current filter context. </p>
<p>When we hover over YOY, the columns in the tooltip have two calculation items applied. </p>
<ul>
<li><p>For Total Sales CY, it has both the Current item (in the tooltip) and the YOY item (from the main matrix) applied. But since Current is just defined as SELECTEDMEASURE(), the net result is to return the YOY values in the Total Sales CY column. </p>
</li>
<li><p>For Total Sales PY, it has values for the previous year (in the tooltip) inserted as the current year values when evaluating the YOY item (from the main matrix). Looking at the calculation item definitions
<sup id="fnref:1" data-preserve-html-node="true">
<a data-preserve-html-node="true" href="#fn:1" class="footnote">1</a>
</sup>
, you can substitute the definition for PY into YOY whenever SELECTEDMEASURE() appears. This will show you why the result ends up as zero for every value. </p>
</li>
</ul>


  
  <h3>How can we solve this?</h3><p class="">To get this working as intended, we need a way to remove the filter context of the calculation group in the main matrix. I.e. when we hover over YOY, the YOY calculation item shouldn’t be passed through to the tooltip as a filter. </p><p class="">If all this talk of removing filter contexts made you think of applying an ALL function, you’ve earned the right to be quite chuffed with yourself :)</p><p class="">To negate the effect of the main Time Intelligence calculation group, we have to use the ALL filter from within a second calculation group. We can use this new group to toggle the effect of the first group on and off. </p><p class="">This simpler group, which I’ve called ‘Disable Time Intelligence’[State], has a single calculation item named “Disabled”…</p>


  


  




  
    <font face="Consolas"><span class="Comment">---------------------------------------------------------</span><br><span class="Comment">--&nbsp;Calculation&nbsp;Group:&nbsp;'Disable&nbsp;Time&nbsp;Intelligence'[State]</span><br><span class="Comment">--&nbsp;Precedence:&nbsp;2</span><br><span class="Comment">---------------------------------------------------------</span><br><span class="Comment">--&nbsp;Calculation&nbsp;Item:&nbsp;Disabled</span><br><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">SELECTEDMEASURE</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>,&nbsp;<span class="Keyword">ALL</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Time&nbsp;Intelligence'&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <p class="">For this to work correctly in your tooltip, you need to do two things…</p><ol data-rte-list="default"><li><p class="">Ensure that this calculation group <strong>has a higher precedence</strong> than the orginal Time Intelligence group. This means that this calculation item will get applied by the Vertipaq engine <em>before</em> the time intelligence calculation item in the matrix. So even though the tooltip may be hovering over a matrix cell in the PY column, the ALL statement over the calculation group overrules the PY calculation. </p></li><li><p class="">Add ‘Disable Time Intelligence’[State] group to the page-level filters for the tooltip, and select “Disabled” as below. </p></li></ol>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png" data-image-dimensions="1058x697" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png?format=1000w" width="1058" height="697" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617791145588-TQUYCAEPCH6QQC2LHOUI/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">Once you’ve set these up, here’s what the tooltip looks like in action. When the same month is selected on the matrix rows, the tooltip always returns the same calculations no matter which matrix row is selected. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif" data-image-dimensions="1011x388" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif?format=1000w" width="1011" height="388" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339297054-NTE9JWMPOJSPE0ASPBUD/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Wait, how does this work exactly? </h3><p class="">Why does ‘Disable Time Intelligence’ apply to the main matrix, but not to the tooltip?</p><p class="">This is because the ALL statement allows us to ignore any filters applied to the Time Intelligence calculation group. So the main matrix has the selected calculation item filtered out.</p><p class="">But then the measures in the tooltip page (Total Sales CY and Total Sales PY) use CALCULATE to<em> reapply</em> the calculation items, <em>after</em> having removed them with the ALL statement in the “Disabled” calculation item. </p><h3>What about drillthrough pages?</h3><p class="">Fortunately, this logic applies equally well to drillthrough pages. If we duplicate our tooltip page and make it a drillthrough page instead (drilling down on the Total Sales measure), we get the same result…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif" data-image-dimensions="1276x812" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif?format=1000w" width="1276" height="812" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617339708900-YYX8MVZ5W0MKSU4VXVW4/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>Summary</h3><p class="">Calculation groups can be confusing at times, espacially when you start trying to apply multiple groups or items at once. Like most instances when DAX calculations don’t return the expected values, one of your best tools to solve the problem is to carefully consider what the filter context for the calculation is. Once you have that figured out, solving the problem can be much easier - it certainly was for me when I tackled this problem!</p><h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/Disabling-Calculation-Groups.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />
  <ol data-preserve-html-node="true">
    <li id="fn:1" data-preserve-html-node="true">
     <p data-preserve-html-node="true">Here are the full definitions for the 'Time Intelligence' calculation group and calculation items used in this example.&nbsp;<a data-preserve-html-node="true" href="#fnref:1" class="reversefootnote">↩</a></p></li>

<font face="Consolas" data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">---------------------------------------------------------</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;Calculation&nbsp;Group:&nbsp;'Time&nbsp;Intelligence'[Calculation]</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;Precedence:&nbsp;1</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">---------------------------------------------------------</span><br data-preserve-html-node="true"><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;Calculation&nbsp;Item:&nbsp;Current</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;    &nbsp;Format&nbsp;String&nbsp;=&nbsp;"$#,##0"</span><br data-preserve-html-node="true">
<span data-preserve-html-node="true" class="Keyword">SELECTEDMEASURE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true"><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;Calculation&nbsp;Item:&nbsp;PY</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;    &nbsp;Format&nbsp;String&nbsp;=&nbsp;"$#,##0"</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Keyword">CALCULATE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span>&nbsp;<span data-preserve-html-node="true" class="Keyword">SELECTEDMEASURE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span>,&nbsp;<span data-preserve-html-node="true" class="Keyword">SAMEPERIODLASTYEAR</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span>&nbsp;Calendar[DateKey]&nbsp;<span data-preserve-html-node="true" class="Parenthesis">)</span>&nbsp;<span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true"><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;Calculation&nbsp;Item:&nbsp;YOY</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;    &nbsp;Format&nbsp;String&nbsp;=&nbsp;"$#,##0"</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Keyword">VAR</span>&nbsp;<span data-preserve-html-node="true" class="Variable">CurrentMeasure</span>&nbsp;=<br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Keyword">SELECTEDMEASURE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Keyword">VAR</span>&nbsp;<span data-preserve-html-node="true" class="Variable">PriorMeasure</span>&nbsp;=<br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Keyword">CALCULATE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span>&nbsp;<span data-preserve-html-node="true" class="Keyword">SELECTEDMEASURE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span>,&nbsp;'Time&nbsp;Intelligence'[Calculation]&nbsp;=&nbsp;<span data-preserve-html-node="true" class="StringLiteral">"PY"</span>&nbsp;<span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Keyword">RETURN</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Keyword">IF</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Variable">CurrentMeasure</span>&nbsp;=&nbsp;<span data-preserve-html-node="true" class="Keyword">BLANK</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>||&nbsp;<span data-preserve-html-node="true" class="Variable">PriorMeasure</span>&nbsp;=&nbsp;<span data-preserve-html-node="true" class="Keyword">BLANK</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span>,<br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Keyword">BLANK</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span>,<br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Variable">CurrentMeasure</span>&nbsp;-&nbsp;<span data-preserve-html-node="true" class="Variable">PriorMeasure</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true"><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;Calculation&nbsp;Item:&nbsp;YOY%</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Comment">--&nbsp;&nbsp;&nbsp;Format&nbsp;String&nbsp;=&nbsp;"0.00%"</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Keyword">DIVIDE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Keyword">CALCULATE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span>&nbsp;<span data-preserve-html-node="true" class="Keyword">SELECTEDMEASURE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span>,&nbsp;'Time&nbsp;Intelligence'[Calculation]&nbsp;=&nbsp;<span data-preserve-html-node="true" class="StringLiteral">"YOY"</span>&nbsp;<span data-preserve-html-node="true" class="Parenthesis">)</span>,<br data-preserve-html-node="true"><span data-preserve-html-node="true" class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span data-preserve-html-node="true" class="Keyword">CALCULATE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span>&nbsp;<span data-preserve-html-node="true" class="Keyword">SELECTEDMEASURE</span><span data-preserve-html-node="true" class="Parenthesis">&nbsp;(</span><span data-preserve-html-node="true" class="Parenthesis">)</span>,&nbsp;'Time&nbsp;Intelligence'[Calculation]&nbsp;=&nbsp;<span data-preserve-html-node="true" class="StringLiteral">"PY"</span>&nbsp;<span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true"><span data-preserve-html-node="true" class="Parenthesis">)</span><br data-preserve-html-node="true">
</font>
  </ol>

<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617794464463-6JO80TD926A5PZZOPB1C/Blog+Thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="907" height="699"><media:title type="plain">How to reset calculation groups in a custom tooltip or drillthrough page</media:title></media:content></item><item><title>10 ways you can use Calculation Groups in Power BI</title><dc:creator>Sam Fischer</dc:creator><pubDate>Tue, 30 Mar 2021 12:01:00 +0000</pubDate><link>https://apexinsights.net/blog/10-uses-for-calculation-groups</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:606049cbf46c0d32750b1aea</guid><description><![CDATA[When I first started learning about Calculation Groups, I could certainly 
see how much potential this new DAX feature would eventually have. The 
global Power BI community has certainly proven me right, as they’ve 
discovered plenty of great uses for them! Here are my top 10 use cases for 
them, spanning time intelligence, dynamic formatting, controlling 
relationships and enhancing the user experience…]]></description><content:encoded><![CDATA[<p class="">When I first started learning about Calculation Groups, I could certainly see how much potential this new DAX feature would eventually have. Out of the gate however, there were a limited number of examples that they could be obviously applied to. Fortunately, the very engaged global Power BI Community has been actively using Calculation Groups, and discovered even more great uses for them!</p><p class="">My intention with this article is not to go through each technique in a huge amount of detail, but to give you an overview of each approach so you can link to other sources that cover the details. This post also focuses on applications of Calculations Groups, rather than how to set them up in the first place. If you’re not familiar with how to define calculation groups in Power BI using Tabular Editor, check out this video from Guy in a Cube to learn how. </p>


  


  



&nbsp;&nbsp;
  
  <p class="">Alright, now after those disclaimers, let’s dig into our list of 10 awesome applications of calculation groups, starting with the most obvious…</p><h3>1. Time Intelligence</h3><p class="">This is the standard application of calculation groups. If you have a Sales measure, you may want to implement time intelligence to see how your Sales stack up as far as week to date, year to date, month on month change, same period last year, etc. Defining each of these calculations for Sales is fine, but if you want to also perform these calculations against your Margins or your Cost of Goods Sold, you’ll end up with way more measures that become harder and harder to maintain. </p><p class="">The alternative is to create a calculation group and define these calculations once. Each of the time intelligence calculations can then be accomplished by filtering your visuals to use only one calculation item. You can also slice between them, or show them all together at once (see below). SQLBI have a great article that introduces you to calculation groups for time intelligence, <a href="https://www.sqlbi.com/articles/introducing-calculation-groups/">check it out here</a>. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          <a class="
                sqs-block-image-link
                
          
        
              " href="https://www.sqlbi.com/articles/introducing-calculation-groups/"
              
          >
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png" data-image-dimensions="1219x818" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png?format=1000w" width="1219" height="818" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616998647659-VBRIHQMG4Y95O3LGZUXQ/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          </a>
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>2. Switch measures</h3><p class="">A switch measure is a tried and true technique for changing what measure is represented in a visual using a slicer. This is typically achieved with a disconnected table and a measure that references other measures using the SWITCH function. </p><p class="">Be aware though that a limitation of a conventional switch measure is around how the measure is formatted. By default, a switch measure may refer to measures with different data types. Instead of dynamically updating the data type, a standard switch measure will inherit a Text type, which limits your ability to aggregate values and easily display them in the manner that you want (i.e. with $ and % signs where relevant).</p><p class="">Calculation groups offer a more robust alternate approach for switching between measures being displayed. Using the custom format strings that can be defined against each calculation item, you can set a measure to display as intended. Matt Allington has an article that <a href="https://exceleratorbi.com.au/dynamic-formatting-of-switch-measures/">takes you through this approach in detail</a>. Here’s a preview of what Matt’s finished product ends up looking like… </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          <a class="
                sqs-block-image-link
                
          
        
              " href="https://exceleratorbi.com.au/dynamic-formatting-of-switch-measures/"
              
          >
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif" data-image-dimensions="750x346" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif?format=1000w" width="750" height="346" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616976431905-3SNIKUQZI3LW3QRRWZVY/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          </a>
        

        
      
        </figure>
      

    
  


  


<p>The trick to implementing switch measures with calculation groups is to create an arbitrary dummy measure<sup id="fnref:1" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:1" class="footnote">1</a>
</sup> to use in your visuals. You can then define each of your measures that you want to slice between as calculation items. Now when you use the calculation group as your slicer, the dummy measure will be replaced by your selected measure instead.</p>


  
  <h3>3. Dynamic format strings</h3><p class="">The ability to define a custom format string for each calculation item is very powerful. Beyond using them to implement switch measures, you can also use them to change between different units of measurement. </p><p class="">For example, if you’re dealing with converting metric to imperial values, SQLBI have a tutorial on <a href="https://www.sqlbi.com/articles/dynamic-format-strings-with-calculation-groups/">converting pounds and ounces to grams dynamically with format strings</a>. </p><p class="">A more common use case in Business Intelligence is to convert between currencies. Bas Dohmen (at How to Power BI) has a cool video on how you can use format strings to display the correct currency symbol for the selected country in a matrix…</p>


  


  



&nbsp;&nbsp;
  
  <h3>4. Extend category breakdowns with custom measures</h3><p class="">You can extend the switch measure approach above to analyse a category breakdown and provide even more insights. For example, you may have a matrix that shows product spend broken down by year. Besides spend per year, you may also want to include some calculations in the same matrix that compare sales between years, as in the example below.</p><p class="">Matt Allington covers this application in his post <a href="https://exceleratorbi.com.au/building-a-matrix-with-asymmetrical-columns-and-rows-in-power-bi/">Building a Matrix with Asymmetrical Columns and Rows in Power BI</a>. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          <a class="
                sqs-block-image-link
                
          
        
              " href="https://exceleratorbi.com.au/building-a-matrix-with-asymmetrical-columns-and-rows-in-power-bi/"
              
          >
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png" data-image-dimensions="597x497" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png?format=1000w" width="597" height="497" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616983976119-3O6TOAGBGCQURLD5WS0B/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          </a>
        

        
      
        </figure>
      

    
  


  



  
  <h3>5. Displaying basic summary statistics</h3><p class="">When you have a distribution of values in a matrix, you may want to know some summary statistics about the values - i.e. minimum, maximum, sum and average values. This can help to explore the data quickly, without having to drill down into the full details. </p><p class="">Kane Snyder has an interesting technique for <a href="https://tenfingers.medium.com/combining-calculation-groups-in-power-bi-to-create-powerful-reports-cc06f85e8de6">exploring summary statistics for values in a matrix visual</a>. For Margin values broken down by category in a matrix, he has a tooltip that displays what the minimum, maximum and average margin was over the last 6 months. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          <a class="
                sqs-block-image-link
                
          
        
              " href="https://tenfingers.medium.com/combining-calculation-groups-in-power-bi-to-create-powerful-reports-cc06f85e8de6"
              
          >
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png" data-image-dimensions="700x411" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png?format=1000w" width="700" height="411" sizes="(max-width: 640px) 100vw, (max-width: 767px) 83.33333333333334vw, 83.33333333333334vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616986283664-HD4GIV8IYWMTK1JH6PGE/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          </a>
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>6. Changing which relationships are active</h3><p class="">It can be quite common to have multiple different dates marked against a fact table record, e.g. Order Date and Delivery Date. If you want to relate your fact table to a date dimension, you can create a relationship for each of Order and Delivery Date, but you can only have one active at any given time. To use the date table against both dates, you could duplicate the date dimension and use it as a role playing dimension. But a more succinct alternative is to use the USERELATIONSHIP function to change the active relationship in a CALCULATE statement. Calculation groups can allow you to change the active relationship dynamically with a slicer. SQLBI have a video tutorial on this use case…</p>


  


  



&nbsp;&nbsp;
  
  <h3>7. Activating bidirectional filters</h3><p class="">Besides changing the active relationship, you can also change the filtering direction of a relationship. Including bidirectional relationships by default in your model can help with some calculations, but they can introduce ambiguity in your model, and increase your measure evaluation time as unnecessary filtering occurs. </p><p class="">Ideally you would want a way to only activate a bidirectional relationship when you need it. The CROSSFILTER function helps you do this, and by incorporating it into a calculation group, you can change the filtering direction dynamically with a slicer. Erik Svensen has an article that walks you through this topic - <a href="https://eriksvensen.wordpress.com/2021/03/18/using-calculation-groups-in-powerbi-to-implement-a-many-2-many-m2m-filter/">Using Calculation Groups in #PowerBI to implement a Many 2 Many (M2M)&nbsp;filter</a>. </p><p class="">Beyond this many-to-many approach, you could also use CROSSFILTER as Erik has done to deactivate a relationship entirely. </p><h3>8. Controlling bars, lines and labels in charts</h3><p class="">You can also give users the ability to control what chart elements are displayed. Using an analogous approach to switch measures, you can use a slicer to change the measures that are shown in the columns and line values for a combination chart. But you can customise charts even more, like letting users control what chart labels appear, since showing them for both columns and lines can make your chart somewhat cluttered. Here’s what Kane Snyder has set up for a combo chart, which he has <a href="https://tenfingers.medium.com/allowing-users-to-choose-any-two-different-metrics-to-compare-in-a-single-chart-with-calculation-297bfc1f3e98">blogged about</a> and described on a <a href="https://youtube.com/watch?ab_channel=HavensConsulting&amp;v=IH4bcHhxunw">live stream with Reid Havens</a>. </p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          <a class="
                sqs-block-image-link
                
          
        
              " href="https://tenfingers.medium.com/allowing-users-to-choose-any-two-different-metrics-to-compare-in-a-single-chart-with-calculation-297bfc1f3e98"
              
          >
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif" data-image-dimensions="1297x721" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif?format=1000w" width="1297" height="721" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616985481356-04LFD7O6K8LNV7NDQ247/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          </a>
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h3>9. Highlight different subsets of data in charts</h3><p class="">Another cool technique is to highlight values in a chart, like the minimum and maximum values. This can already be achieved with a switch measure, but calculation groups allow you to dynamically control the labels as well. The labels can be set to only show the highlighted values, and even add some commentary to them as well. Here’s the kind of charts you can build with the approach, which you can read about in Kane Snyder’s post on <a href="https://tenfingers.medium.com/dynamic-chart-labels-with-calculation-groups-bcd81483c696">Dynamic Chart Labels with Calculation Groups</a>.  </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          <a class="
                sqs-block-image-link
                
          
        
              " href="https://tenfingers.medium.com/dynamic-chart-labels-with-calculation-groups-bcd81483c696"
              
          >
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png" data-image-dimensions="700x268" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png?format=1000w" width="700" height="268" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996878087-CFWRLOK707U8S28GA9LT/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          </a>
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          <a class="
                sqs-block-image-link
                
          
        
              " href="https://tenfingers.medium.com/dynamic-chart-labels-with-calculation-groups-bcd81483c696"
              
          >
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png" data-image-dimensions="700x254" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png?format=1000w" width="700" height="254" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616996938664-UP537T9V4883ZLSHBJUM/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          </a>
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Besides the labels above, you can set up your visuals to highlight values above the threshold, or your top N values. If you want to learn how to identify and highlight these values, check out my blog post on <a href="https://apexinsights.net/blog/direct-attention-with-conditional-formatting">directing attention with conditional formatting</a>. </p><h3>10. Slice on multiple columns without unpivoting</h3><p class="">In Power BI, you want to aim to have the right table structure from the start. If for whatever reason you can’t set up your tables as needed, you can use calculation groups to fill the gap instead. </p><p class="">For example, say you have a table containing costs over separate categories like this…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          <a class="
                sqs-block-image-link
                
          
        
              " href="https://forum.enterprisedna.co/t/unpivot-columns-to-shown-energy-split/12726"
              
          >
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png" data-image-dimensions="666x585" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png?format=1000w" width="666" height="585" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1616997603936-B2RGTGLL9DVOL1X9GX3W/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          </a>
        

        
      
        </figure>
      

    
  


  


&nbsp;<p>If you wanted to slice a chart showing costs to only show the Mining Costs, it wouldn't be straightforward to set up with this table structure. </p>
<p>Unpivoting is the obvious solution here, so you could also load an unpivoted version of the table<sup id="fnref:2" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:2" class="footnote">2</a>
</sup>. Including two separate tables with the same data at different grains may make separate sets of calculations easier, but can have unintended side effects - If I were an end user, how would I know which table to build my visuals off of?</p>
<p>An alternate solution to this is to keep the one fact table, and use calculation groups to accomplish the same outcome as unpivoting would. You can define separate calculation items that aggregate over each cost category, and use the calculation group as a slicer to control which costs are shown. Mudassir Ali at Enterprise DNA walks though this approach below…</p>

&nbsp;&nbsp;
  
  <h3>Summary</h3><p class="">These are just some of the uses for calculation groups that have been uncovered so far. Have there been any other useful applications I’ve missed? Let me know in the comments below, and in future we may be able to assemble a follow up list with even more ways to implement this great feature!</p><h3>Full list of references</h3><ul data-rte-list="default"><li><p class="">Guy in a Cube - <a href="https://www.youtube.com/watch?ab_channel=GuyinaCube&amp;v=vlnx7QUVYME">REDUCE the # of measures with Calculation Groups In Power BI</a></p></li><li><p class="">SQLBI - <a href="https://www.sqlbi.com/articles/introducing-calculation-groups/">Introducing Calculation Groups</a></p></li><li><p class="">SQLBI - <a href="https://www.sqlbi.com/articles/dynamic-format-strings-with-calculation-groups/">Dynamic format strings with calculation groups</a></p></li><li><p class="">SQLBI - <a href="https://www.sqlbi.com/articles/using-calculation-groups-to-switch-between-dates/">Using calculation groups to switch between dates</a></p></li><li><p class="">Matt Allington @ Excelerator BI - <a href="https://exceleratorbi.com.au/dynamic-formatting-of-switch-measures/">Dynamic Formatting of Switch Measures</a></p></li><li><p class="">Matt Allington @ Excelerator BI - <a href="https://exceleratorbi.com.au/building-a-matrix-with-asymmetrical-columns-and-rows-in-power-bi/">Building a Matrix with Asymmetrical Columns and Rows in Power BI</a></p></li><li><p class="">Bas Dohmen @ How to Power BI - <a href="https://www.youtube.com/watch?ab_channel=HowtoPowerBI&amp;v=-REAQDqdz0A">Dynamic NUMBER FORMATTING using CALCULATION GROUPS in Power BI</a></p></li><li><p class="">Kane Snyder @ Ten Fingers - <a href="https://tenfingers.medium.com/combining-calculation-groups-in-power-bi-to-create-powerful-reports-cc06f85e8de6">Combining calculation groups in Power BI to create powerful reports</a></p></li><li><p class="">Kane Snyder @ Ten Fingers - <a href="https://tenfingers.medium.com/allowing-users-to-choose-any-two-different-metrics-to-compare-in-a-single-chart-with-calculation-297bfc1f3e98">Allowing users to choose any two different metrics to compare in a single chart with calculation groups.</a></p></li><li><p class="">Kane Snyder @ Ten Fingers - <a href="https://tenfingers.medium.com/dynamic-chart-labels-with-calculation-groups-bcd81483c696">Dynamic Chart Labels with Calculation Groups</a></p></li><li><p class="">Havens Consulting - <a href="https://www.youtube.com/watch?ab_channel=HavensConsulting&amp;v=IH4bcHhxunw">Calculation Groups (with Kane Snyder)</a></p></li><li><p class="">Erik Svensen - <a href="https://eriksvensen.wordpress.com/2021/03/18/using-calculation-groups-in-powerbi-to-implement-a-many-2-many-m2m-filter/">Using Calculation Groups in #PowerBI to implement a Many 2 Many (M2M)&nbsp;filter</a></p></li><li><p class="">Mudassir Ali @ Enterprise DNA - <a href="https://www.youtube.com/watch?ab_channel=EnterpriseDNA&amp;v=GH1n0hfqbBw">Avoid Unpivoting Columns With Calculation Groups - DAX Tutorial</a></p></li></ul>


  


  



<hr />
  <ol data-preserve-html-node="true">
    <li id="fn:1" data-preserve-html-node="true">
     <p data-preserve-html-node="true">In Matt's post, he defines his dummy measure as SELECTEDMEASURE(). However, as Kane Snyder kindly pointed out to me, it doesn't matter what you define as your dummy measure since the applied calculation item will overwrite it.&nbsp;<a data-preserve-html-node="true" href="#fnref:1" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:2" data-preserve-html-node="true">
     <p data-preserve-html-node="true">In this scenario, I’d have structured the main table as unpivoted in the first place. Excluding the overall cost column is also ideal, since this can be calculated with a measure. It’s still worthwhile being across these techniques though, as you may find yourself in a scenario where it is difficult to shift away from an established data model structure.&nbsp;<a data-preserve-html-node="true" href="#fnref:2" class="reversefootnote">↩</a></p>
    </li>
  </ol>


<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1617105486980-2TKASAMKC14GJTYN9C9C/Blog+thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="1018" height="787"><media:title type="plain">10 ways you can use Calculation Groups in Power BI</media:title></media:content></item><item><title>Displaying ordinal numbers in your Power BI Smart Narratives</title><dc:creator>Sam Fischer</dc:creator><pubDate>Mon, 15 Mar 2021 11:53:00 +0000</pubDate><link>https://apexinsights.net/blog/ordinal-numbers-smart-narratives</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:6045eccbd8f374020f0271dd</guid><description><![CDATA[In using the Smart Narratives feature for Power BI, I’ve found a few tricks 
to make your narratives even easier to read. For example, say you used 
Smart Narratives to show the sales performance for a given state. If that 
state came up 3rd best, how could you get your narrative to describe it as 
having the “3rd” highest selling sales, including the ‘rd’ after the 3? 
With a bit of DAX, you can get the right suffix showing for these ranked 
values, and make your Smart Narratives even smarter!]]></description><content:encoded><![CDATA[<p class="">In using the Smart Narratives feature for Power BI, I’ve found a few tricks to make your narratives even easier to read. One trick I’ve used is to show values in a ranking in a more readable fashion. For example, say you used Smart Narratives to show the sales performance for a given state. If the state of Victoria came in 3rd best for sales by each state, then you might want your narrative to return something like this…</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG" data-image-dimensions="642x267" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG?format=1000w" width="642" height="267" sizes="(max-width: 640px) 100vw, (max-width: 767px) 50vw, 50vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615803551776-OMXRRCOJTJAV0M8N1RJX/Victoria+sales.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <p class="">So how can you get this to read as the “<em>3rd</em>” highest selling sales, including that ordinal suffix (the ‘<em>rd</em>’ after the 3) on the end?  With a bit of DAX, you can get the right suffix showing for these ranked values, and make your Smart Narratives even smarter!</p><h3>How you can present ordinal suffixes</h3><p class="">Besides the above example, I’ve used this kind of technique to add context to a cohort analysis with a custom tooltip page. </p><p class="">In the report screenshot below, I’ve got a matrix visual that shows the first month that a customer made purchases on the rows (i.e. the cohort) and the number of months after their first purchase on the columns. The measure in the matrix shows how many customers from that cohort made a purchase in that month. </p><p class="">When you hover over each cell in the matrix, a custom tooltip appears which generates a smart narrative to explain the cohort’s behavior in more detail. In the tooltip, the highlighted line indicates that we’re considering the column indexed at 4, i.e. the customers 4th month after their first purchase. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png" data-image-dimensions="937x490" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png?format=1000w" width="937" height="490" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615612040921-3456TA2DMU5WJ2KFXB3V/Cohort+Analysis+tooltip.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">If you want to play with this report yourself, you can <a href="https://apexinsights.net/portfolio/retail-customer-analytics">check it out here</a>.</p><h3>Using DAX to display suffixes</h3><p class="">To build out a measure to include the ordinal suffix, we need a field that returns a list of numbers. To keep things simple, we can generate this list using a calculated table. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG" data-image-dimensions="538x502" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG?format=1000w" width="538" height="502" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614361512-GLRNADHT311L2SIG7ZV9/Table.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Now we can define a measure that takes each number in the current context and works out what suffix to use. The measure will then append the suffix to the number using the FORMAT function. He’s what the full measure looks like. </p>


  


  




  
    <font face="Consolas">Ordinal&nbsp;text&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">Last2Digits</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">RIGHT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Table'[Value]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="Number">2</span>&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">LastDigit</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">RIGHT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Table'[Value]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="Number">1</span>&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">Suffix</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SWITCH</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">TRUE</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">Last2Digits</span>&nbsp;<span class="Keyword">IN</span>&nbsp;{&nbsp;<span class="StringLiteral">"11"</span>,&nbsp;<span class="StringLiteral">"12"</span>,&nbsp;<span class="StringLiteral">"13"</span>&nbsp;},&nbsp;<span class="StringLiteral">"th"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">LastDigit</span>&nbsp;=&nbsp;<span class="StringLiteral">"1"</span>,&nbsp;<span class="StringLiteral">"st"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">LastDigit</span>&nbsp;=&nbsp;<span class="StringLiteral">"2"</span>,&nbsp;<span class="StringLiteral">"nd"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">LastDigit</span>&nbsp;=&nbsp;<span class="StringLiteral">"3"</span>,&nbsp;<span class="StringLiteral">"rd"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="StringLiteral">"th"</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FORMAT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Table'[Value]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="StringLiteral">"0"</span>&nbsp;&amp;&nbsp;<span class="Variable">Suffix</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <p class="">Here’s how the measure looks when we apply it against our values in a table visual.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG" data-image-dimensions="228x586" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG?format=1000w" width="228" height="586" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615614387249-1H81BVAXJ1ZGSVSNT9BI/Measure+in+table+visual.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Working out which suffix to use</h3><p class="">The <em>Suffix </em>variable is what ensures we display the right suffix. The standard rule is that “if a number ends in a 1, then the suffix should be ‘<em>st</em>’, as in ‘<em>first</em>’ “, and similarly for 2nd and 3rd. But the exception to this rule is for 11, 12 and 13, which should read as <em>11th</em>,<em> 12th</em> and <em>13th</em>, respectively. So the variable checks the selected value for this exception, then it checks for the standard 1-2-3 rule, and if it doesn’t need to apply either of those it will return the standard ‘<em>th</em>’ suffix. </p><h3>Allowing for aggregations</h3><p class="">Note here that I’ve chosen to use a SUM aggregation in my measure, rather than using SELECTEDVALUE. This is intentional, since we may want to do some calculations and arrive at a new number before finding and applying the suffix. You can see the effect of this in the totals row of the visual. The sum of all the values in the table is computed as 20100, and then the logic in the measure determines that the appropriate suffix for this measure is ‘<em>th</em>’, so it presents the final output as a string that reads “20100th”. </p><h3>Try it out for yourself!</h3><p class="">You can take the exact same logic and apply it to any of your own calculations. All you have to do is replace the references to <em>SUM(‘Table’[Value])</em> with your own measure. </p>


  


  



<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1615805508495-URXI6DCLUQP1LV0OHBV4/Thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="815" height="630"><media:title type="plain">Displaying ordinal numbers in your Power BI Smart Narratives</media:title></media:content></item><item><title>Top 5 tips to reduce your Power BI data model size</title><dc:creator>Sam Fischer</dc:creator><pubDate>Sun, 21 Feb 2021 10:27:00 +0000</pubDate><link>https://apexinsights.net/blog/top-5-tips-to-optimise-data-model</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:5ffab5ed2851cd63e1ad4d00</guid><description><![CDATA[If you’re building Power BI reports on the regular, then you’ve probably 
built a few reports that are on the large side. My usual rule of thumb is 
that if a model is getting beyond 100MB in size, then you should probably 
start thinking about how you can optimise it. To that end, here are 5 tips 
to ensure that your data model can stay compact while still delivering all 
the insights you need.]]></description><content:encoded><![CDATA[<p class="">If you’re building Power BI reports on the regular, then you’ve probably built a few reports that are on the large side. My usual rule of thumb is that if a model is getting beyond 100MB in size, then you should probably start thinking about how you can optimise it. Reducing your model size brings both performance improvements and faster upload speeds to the Power BI Service — if you’re working from home, low upload speeds may be a real headache. Waiting half an hour or more for a report to be published can be an issue when you’re facing a deadline, so it’s better to have your report optimised so the upload file isn’t that big to begin with. To that end, here are 5 tips to ensure that your data model can stay compact while still delivering all the insights you need. </p><h4>1.​ Remove columns that you don’t need</h4><p class="">Okay, this one should be obvious — more columns means more data. There are columns that you’ll absolutely need in your model, but often times there are some that aren’t actually being used at all. I often find that I have unneeded columns in my reports for one of two reasons: either I’m too lazy to remove them (I’m only human), or because I anticipate that I might need it later. It can certainly be tempting to have a full sandbox with all the fields you could possibly need. But I’ve found that whenever I’ve built a sandbox in the past, the complexity of the report becomes a real barrier for making progress. </p><p class="">My preference has become to start building a model with only the bare minimum number of columns required, and only bring in new columns as they’re needed. Every time I add a new column in, I have the opportunity to reflect on whether or not the data is still appropriately modelled for the scenario at hand. As your stakeholders ask for more report features, you may need to remodel to satisfy their requirements, and this practice helps to identify that need earlier on in development. </p><p class="">If you want to easily work out which fields can be removed without breaking your report, you can use tools like this <a href="https://powerbi.tips/2020/01/power-bi-field-finder/">Power BI Field Finder report developed by Stephanie Bruno</a>. </p><h4>2. Remove or replace columns with high cardinality</h4><p class="">Even if you are using a column in your report, it may be worthwhile to remove or replace it. Columns with high cardinality (i.e. they have many unique values) are often responsible for a bloated model, and this is a result of how the Vertipaq engine inside Power BI works. Vertipaq compresses the data model in a column oriented manner, which means that columns with fewer unique values can be easily compressed, but columns with many unique values cannot. </p><p class="">You can inspect how much space each column takes up in the model using Vertipaq Analyzer, which is an embedded feature in DAX Studio. This feature can help you easily identify which columns may be ideal to delete from the model to reduce the file size. For example, the model analysed below has <em>over 80%</em> of it’s file size taken up by an Invoice Line ID column in an Invoice table at line item level. Since this surrogate key is only in a model as a carry-over from the source system, we can reduce our model size by 80% by removing this single column!</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output" data-image-dimensions="1407x347" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output?format=1000w" width="1407" height="347" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613801604439-WY2VSTKTORZ09U6M0HNC/Vertipaq+Analyzer+output?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


<p>If you’ve never used Vertipaq Analyzer before, SQLBI have a video showing how to <a data-preserve-html-node="true" href="https://www.youtube.com/watch?v=ylYCerZ3vDc">Read Performance Analyzer metrics in DAX Studio</a>.<sup id="fnref:1" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:1" class="footnote">1</a>
</sup></p>
<p>However, if you can’t remove high cardinality columns, you may be able to split them into separate columns that give more compression than the sum of their parts. Datetime columns are especially useful to decompose into separate columns for the date and time.<sup id="fnref:2" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:2" class="footnote">2</a>
</sup> 
But besides splitting the columns, in some scenarios you may prefer to round your datetimes to the nearest minute or hour; I’ve previously written about <a data-preserve-html-node="true" href="https://apexinsights.net/blog/rounding-datetimes">how you can do this with Power Query</a>. </p>
<p>The technique of splitting high cardinality columns isn’t limited to datetime columns. Gilbert Quevauvilliers has previously written about a novel approach of <a data-preserve-html-node="true" href="https://www.fourmoo.com/2019/11/27/how-i-saved-40-on-my-power-bi-dataset-size/">reducing data model size by splitting a column of decimals into two columns</a>: one for the digits before the decimal point, and one for the digits after. Calculations can then be performed with custom measures that stitch the decimal values back together. </p>


  
  <h4>3. Remove rows that you don’t need</h4>


  


  



<p>Another obvious one. It can be tempting to include a complete dataset with a large date range and every category so users can slice and dice to their heart’s content. But in reality, when decision makers are referring to your reports, they don’t always need to see data before a few years ago. The business context may have significantly changed since then, and including these data may actually tell an inaccurate story if they don’t have that context.
<sup id="fnref:3" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:3" class="footnote">3</a>
</sup></p>
<p>If you can’t remove certain date ranges, then you can often omit particular categories, like irrelevant regions or product types. If they’re outside the scope of your analysis, then including these records on the off-chance that your stakeholders might want to report on them may not be worthwhile if report performance is becoming an issue. </p>
<p>You also have the option of aggregating up to a different grain. For example, including hundreds of millions of rows of sales transactions may not be as performant as rolling this up to daily snapshots by product category or store. </p>


  
  <h4>4. Turn off Auto Date/Time</h4><p class="">One of the things that Power BI does by default in the background is it will automatically generate date dimension tables. These tables define the hierarchy that gets created when you use date fields in visuals, and also help to create time intelligence calculations. In practice, you can usually accomplish all the same things yourself with your own date dimension and time intelligence measures. </p><p class="">A major issue with including these is that a new table is automatically generated for each date column in your model. Each table will contain a row for each of the dates between the earliest and latest dates in the corresponding date field. So if your data warehouse has slowly changing dimensions that use nominal dates like ‘31/12/9999’ to mark the record end date, then not accounting for the Auto Date/Time functionality can lead to large date tables generated in the background. Guy In A Cube have a <a href="https://www.youtube.com/watch?v=RnDdDlozcdo">great video on the impacts of these tables</a>, and how you can reduce a report in size by over a gigabyte (yes, a gigabyte!) just by disabling Auto Date/Time. </p><p class="">To turn off this feature, simply go to<em> File &gt; Options and Settings &gt; Options</em>. You can turn off Auto Date/Time under Data Load, and have this apply either just to the current report file, or globally to all newly created reports.</p>


  


  



&nbsp;










































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting" data-image-dimensions="1047x1008" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting?format=1000w" width="1047" height="1008" sizes="(max-width: 640px) 100vw, (max-width: 767px) 66.66666666666666vw, 66.66666666666666vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613800149701-LHB4UF2EQJL6OBMJSKPL/Auto+datetime+setting?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


&nbsp;
  
  <h4>5. Create extra columns in Power Query over DAX</h4><p class="">As you’re loading queries into your model, the Vertipaq engine determines the optimal partitioning scheme to minimise data model size. However, this optimisation step is performed based only on the columns loaded from Power Query, and not based on any Calculated Columns created in DAX. If the partitioning was determined with these columns in mind, then Vertipaq may be able to compress the full table further, but the engine only performs this step once (before considering any DAX calculations). This means that the partitioning scheme selected by the engine may no longer be the best one, and it can mean that the model takes up more space than it would otherwise. </p><p class="">For this reason, you should create additional columns for your model in Power Query rather than DAX, to ensure that you’re getting as much compression of your data as possible. There are practical exceptions to this rule, such as when your calculations rely on relationships, or when the time to reload your data from Power Query is unreasonably slow compared to adding a single new column in DAX. But in general, your aim should be to push the calculations upstream where you can. </p><h3>Summary</h3><p class="">If you’ve got a large data model, you’ve got a number of options to optimise the model size. You can try each of these and see which is most effective. I’ve found that as I’ve gotten more practice with optimising models, the more quickly I’ve become able to identify which approach will work best. I’ve also found that this practice teaches you to keep these considerations in mind as you build your model, so by learning these best practices you can avoid the need to optimise you model in the first place. </p><p class="">PS: If you’re stumped on where to start with optimisations, Michael Kolvasky at Microsoft has recently released a set of <a href="https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules">best practice rules for your Power BI model</a>. These rules can be loaded into Tabular Editor, allowing it to scan your model and point out various suggestions to optimise your model, even beyond the approaches we’ve discussed above. Check out this video from Guy in a Cube to see how to use the <a href="https://www.youtube.com/watch?v=1Qan0_VmZRw">Best Practice Analyzer in Tabular Editor</a>. </p>


  


  



<hr />
  <ol data-preserve-html-node="true">
    <li id="fn:1" data-preserve-html-node="true">
     <p data-preserve-html-node="true">In fact, SQLBI have a <a href="https://www.sqlbi.com/p/dax-tools-video-course/">free online course</a> on using DAX Studio and Vertipaq Analyzer which you should definitely check out if these tools aren’t already part of your Power BI toolbox.&nbsp;<a data-preserve-html-node="true" href="#fnref:1" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:2" data-preserve-html-node="true">
     <p data-preserve-html-node="true">Since one year’s worth of datetime values can give you over 31 million distinct values, storing this as datetimes can result in high cardinality. When that same year's worth of values are split into separate date and time columns, you have a total of about 87,000 distinct values across both columns, so they compress much better. &nbsp;<a data-preserve-html-node="true" href="#fnref:2" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:2" data-preserve-html-node="true">
     <p data-preserve-html-node="true">Besides, storing all historical data is a job for a data warehouse, not for an individual report.&nbsp;<a data-preserve-html-node="true" href="#fnref:2" class="reversefootnote">↩</a></p>
    </li>
  </ol>





<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1613902784110-CLY8AVAQBDQWGJ6LUU7I/Optimise+model+blog+thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="882" height="679"><media:title type="plain">Top 5 tips to reduce your Power BI data model size</media:title></media:content></item><item><title>Rounding datetimes to nearest minute or hour in Power Query</title><dc:creator>Sam Fischer</dc:creator><pubDate>Mon, 18 Jan 2021 11:43:00 +0000</pubDate><link>https://apexinsights.net/blog/rounding-datetimes</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:5fe160f600a6e529c8063d8b</guid><description><![CDATA[One of the most common culprits behind a large data model in Power BI is 
the presence of columns with a high cardinality. A common scenario where 
this occurs is when you’re dealing with event data, where you have precise 
datetimes down to the second for a series of events. For many applications, 
knowing the precise second that an event occurs isn’t as important as 
knowing what minute or hour it occurred in. In this post, I’ll introduce a 
Power Query function you can use to round a datetime field down to the 
nearest minute, 15 minutes or hour. This can reduce cardinality and lead to 
a more compact report file size.]]></description><content:encoded><![CDATA[<p class="">One of the most common culprits behind a large data model in Power BI is the presence of columns with a high cardinality. When a column has a lot of unique values (hundreds of thousands, or more), the Vertipaq engine has a hard time compressing the data and allowing for a compact model. </p><p class="">A common scenario for experiencing high cardinality columns is when you’re dealing with event data, where you have precise datetimes down to the second for a series of events. In a single year alone, you may have as many as 31,622,400 unique datetime values (this is the number of seconds in a leap-year), so your cardinalities can easily come an issue for large datasets.</p><p class="">A useful technique for dealing with this is to store the dates and times in separate columns in your model, which reduces you down to 86,766 unique values for a leap year (number of seconds in a day plus number of days in a leap-year). But this won’t be helpful for every scenario. For example, many of the publicly-available custom visuals oriented around process mining require that you supply a datetime field. In these scenarios, I’ve found it best to aggregate your timestamps by rounding to the nearest minute. For many applications, knowing the precise second that an event occurs isn’t as important as knowing what minute or hour it occurred in. Rounding your datetimes where possible can help Vertipaq to compress your model much better. </p><h3>Rounding to the nearest minute</h3><p class="">If you have a report where you could sacrifice a small amount of precision for big improvements in report file size, then you may find the following Power Query function helpful. This function, which I call <em>RoundDateTime</em> in my reports, takes a datetime column and rounds it to the nearest minute…</p>


  


  




  
    <font face="Consolas">

  
<font face="Consolas">

<span class="constant bracket bracket-0">(</span><span class="identifier">DateTimeToRound</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><span class="type">&nbsp;datetime</span><span class="constant">,</span>&nbsp;<span class="constant type type-modifier">optional</span><span class="identifier">&nbsp;NearestMinutes</span>&nbsp;<span class="constant keyword operator operator-keyword">as</span><span class="type">&nbsp;number</span><span class="constant bracket bracket-0">)</span><span class="constant operator">&nbsp;=&gt;</span><br>&nbsp;&nbsp;<span class="constant keyword">let</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Make function round to nearest minute by default</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Rounding</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="constant keyword">if</span>&nbsp;<span class="identifier">NearestMinutes</span><span class="constant keyword operator operator-keyword">&nbsp;is</span><span class="type">&nbsp;null</span><span class="constant keyword">&nbsp;then</span><span class="literal number">&nbsp;1</span><span class="constant keyword">&nbsp;else</span>&nbsp;<span class="identifier">NearestMinutes</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Source</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">DateTimeToRound</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Convert to number of days since 30/12/1899. Decimal component stores the time component of the datetime</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Convert datetime to decimal&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Number.From</span><span color: Black;" class="constant bracket bracket-0">(</span><span class="identifier">Source</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Convert number from representing days to representing minutes</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Upscale number&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">#&quot;Convert datetime to decimal&quot;</span><span class="constant operator operator-arithmetic">*</span><span class="constant bracket bracket-0">(</span><span class="literal number">24</span><span class="constant operator operator-arithmetic">*</span><span class="literal number">60</span><span class="constant operator operator-arithmetic">/</span><span class="identifier">Rounding</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Round to nearest minute&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">Number.Round</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Upscale number&quot;</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Convert back to days since 30/12/1899</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Downscale number&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">#&quot;Round to nearest minute&quot;</span><span class="constant operator operator-arithmetic">&nbsp;/</span>&nbsp;<span class="constant bracket bracket-0">(</span><span class="literal number">24</span><span class="constant operator operator-arithmetic">*</span><span class="literal number">60</span><span class="constant operator operator-arithmetic">/</span><span class="identifier">Rounding</span><span class="constant bracket bracket-0">)</span><span class="constant">,</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Convert back to datetime&quot;</span><span class="constant operator operator-equality">&nbsp;=</span>&nbsp;<span class="identifier">DateTime.From</span><span class="constant bracket bracket-0">(</span><span class="identifier">#&quot;Downscale number&quot;</span><span class="constant bracket bracket-0">)</span><span class="constant keyword"><br>in</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Convert back to datetime&quot;</span>
  
  
</font>
  <br>
  </span>

  <a href="https://powerqueryformatter.com" target="_blank" title="Powered by powerqueryformatter.com">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 80">
      <rect x="0" width="350" y="0" height="78.836"/>
      <text y="-2"><tspan x="8.646" y="57.799">Power Query</tspan><tspan> </tspan></text>
      <text x="355" y="57.848">Formatter</text>
    </svg>
  </a>

  
</font>
  <br>
  </span>

  <a href="https://powerqueryformatter.com" target="_blank" title="Powered by powerqueryformatter.com">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 80">
      <rect x="0" width="350" y="0" height="78.836"/>
      <text y="-2"><tspan x="8.646" y="57.799">Power Query</tspan><tspan> </tspan></text>
      <text x="355" y="57.848">Formatter</text>
    </svg>
  </a>


  


  
  <p class="">To use this function, you just need to add a single step to your query…</p>


  


  




  
    
  
<font face="Consolas">
<span class="identifier">#&quot;Round to nearest minute&quot;</span><span class="constant operator operator-equality"><br>&nbsp;&nbsp;=</span>&nbsp;<span class="identifier">Table.TransformColumnTypes</span><span class="constant bracket bracket-0">(</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">Table.TransformColumns</span><span class="constant bracket bracket-1">(</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="identifier">#&quot;Changed Type&quot;</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-2">{</span><span class="constant bracket bracket-0">{</span><span class="literal string">&quot;Timestamp&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">each</span>&nbsp;<span class="constant keyword">if</span>&nbsp;<span class="identifier">_</span><span class="constant keyword operator operator-keyword">&nbsp;is</span><span class="type">&nbsp;null</span><span class="constant keyword">&nbsp;then</span><span class="literal null">&nbsp;null</span><span class="constant keyword">&nbsp;else</span>&nbsp;<span class="identifier">RoundDateTime</span><span class="constant bracket bracket-1">(</span><span class="identifier">_</span><span class="constant bracket bracket-1">)</span><span class="constant bracket bracket-0">}</span><span class="constant bracket bracket-2">}</span><span class="constant bracket bracket-1"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span><span class="constant">,</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-1">{</span><span class="constant bracket bracket-2">{</span><span class="literal string">&quot;Timestamp&quot;</span><span class="constant">,</span>&nbsp;<span class="constant keyword">type</span><span class="type">&nbsp;datetime</span><span class="constant bracket bracket-2">}</span><span class="constant bracket bracket-1">}</span><span class="constant bracket bracket-0"><br>&nbsp;&nbsp;&nbsp;&nbsp;)</span>
</font>
  
<br>

  <a href="https://powerqueryformatter.com" target="_blank" title="Powered by powerqueryformatter.com">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 80">
      <rect x="0" width="350" y="0" height="78.836"/>
      <text y="-2"><tspan x="8.646" y="57.799">Power Query</tspan><tspan> </tspan></text>
      <text x="355" y="57.848">Formatter</text>
    </svg>
  </a>



  


  
  <p class="">The step has two nested transformations within it. The inner transformation applies the custom function, with some extra logic to avoid rows with nulls returning errors. The result is wrapped in a second function that restores the datetime type, which is stripped away when applying the custom function. The two transformations are applied as a single step to make it easier to add to an M query than two separate steps. </p><p class="">Here’s what the function looks like when applied to a column of datetimes…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG" data-image-dimensions="1314x589" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG?format=1000w" width="1314" height="589" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610760093288-DSEFE1951I7II7JE8TFH/Rounded+to+nearest+minute+highlighted.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Rounding to other timeframes</h3><p class="">If rounding to the nearest minute doesn’t reduce your model size enough, then you can use this function to round datetimes even further. By adjusting the NearestMinute parameter, you can round datetimes to the nearest 5 minutes, nearest 15 minutes or nearest hour. For example, to implement rounding to the nearest hour, you’d simply adjust the step where you apply the rounding function to use the expression <em>RoundDateTime(_,60) </em>instead of <em>RoundDateTime(_)</em>. </p><p class="">This function can also be adapted to work on time columns rather than just datetimes. To do so, you’d just need to change any references to the datetime type in the function definition to refer to the time type instead. </p>


  


  



<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610970172943-U1W7QUBZJ97XYD5T5A70/Thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="459" height="355"><media:title type="plain">Rounding datetimes to nearest minute or hour in Power Query</media:title></media:content></item><item><title>Calculating business hours between activities using DAX</title><dc:creator>Sam Fischer</dc:creator><pubDate>Thu, 07 Jan 2021 04:07:00 +0000</pubDate><link>https://apexinsights.net/blog/business-hours-between-activities</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:5fed24e6ac5ecf06b6c738d7</guid><description><![CDATA[Whenever you're working with event data, you often have data on activities 
performed, and the time at which they were performed. This data is useful 
for process mining, where you can track durations of cases that follow a 
process, identify bottlenecks in the process and identify instances where 
the intended process is not followed. In this article, I'll walk you 
through how you can track the time between events, so you can note how long 
something spends in a given state.]]></description><content:encoded><![CDATA[<p class="">Whenever you're working with event data, you often have data on activities performed, and the time at which they were performed. This data is useful for process mining, where you can track durations of cases that follow a process, identify bottlenecks in the process and identify instances where the intended process is not followed. In this article, I'll walk you through how you can track the time between events, so you can note how long something spends in a given state.</p><h3>Our challenge</h3>


  


  



<p>Here we have an event log which describes a compensation request process for an airline 
<sup id="fnref:1" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:1" class="footnote">1</a>
</sup>
. Each row represents an activity for a particular case, with the time of the activity and the airline staff member undertaking the activity also recorded. </p>












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG" data-image-dimensions="389x426" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG?format=1000w" width="389" height="426" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664709801-QTWCZP86SUYQ94LB04JX/Event+Log.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  


<p>Using the timestamp for each case, we can trace the history of activities that each request moves through. For example, the first case has it's request registered and examined, then once the airline ticket is checked, a decision is made to reject the request. </p>
<p>If we want to understand this process in more detail, we may want to know how long each request spent waiting to complete this activity since the previous one was performed. In a simple linear process, this corresponds to the time spent in each state, where the states might be called something like 'waiting on ticket check', 'waiting on decision', etc 
<sup id="fnref:2" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:2" class="footnote">2</a>
</sup>
. </p>


  
  <p class="">To determine the time between activities, we will tackle this in three steps by creating three calculated columns...</p><ol data-rte-list="default"><li><p class="">Create an index that orders the events in time for each case.</p></li><li><p class="">Use this index to determine the timestamp for the previous event in the process.</p></li><li><p class="">Calculate the time between these two timestamps, represented as either hours elapsed or business hours elapsed. </p></li></ol><h3>Adding an Activity Index</h3><p class="">For this column, we will use the RANKX function to define the order in which each activity occurs. This will be done separately for each case, so that the first activity for each case (‘<em>register request</em>’) will always be indexed as 1. </p>


  


  




  
    <font face="Consolas">Activity&nbsp;Index&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">CurrentCase</span>&nbsp;=&nbsp;'Event&nbsp;Log'[Case&nbsp;ID]<br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">RANKX</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Rank&nbsp;activities</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATETABLE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log',<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">REMOVEFILTERS</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Event&nbsp;Log'&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Look&nbsp;at&nbsp;all&nbsp;rows,&nbsp;not&nbsp;just&nbsp;current&nbsp;row</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Case&nbsp;ID]&nbsp;=&nbsp;<span class="Variable">CurrentCase</span>&nbsp;<span class="Comment">//&nbsp;Filter&nbsp;down&nbsp;to&nbsp;just&nbsp;this&nbsp;Case&nbsp;ID</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Timestamp],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>ASC,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Order&nbsp;datetime&nbsp;ascending</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DENSE</span>&nbsp;<span class="Comment">//&nbsp;Dense&nbsp;rank,&nbsp;so&nbsp;that&nbsp;simultaneous&nbsp;events&nbsp;don't&nbsp;cause&nbsp;index&nbsp;to&nbsp;skip</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">And here’s what our result looks like…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG" data-image-dimensions="491x429" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG?format=1000w" width="491" height="429" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1610003998390-KTUHXLLARGCL50Y9MMZI/Event+Log+with+Activity+Index.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Adding Timestamp of previous Activity</h3><p class="">For this column, we will create a lookup to the previous activity by referencing the previous index for each case.</p>


  


  




  
    <font face="Consolas">Timestamp&nbsp;of&nbsp;previous&nbsp;Activity&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">CurrentCase</span>&nbsp;=&nbsp;'Event&nbsp;Log'[Case&nbsp;ID]<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">CurrentIndex</span>&nbsp;=&nbsp;'Event&nbsp;Log'[Activity&nbsp;Index]<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">PreviousIndex</span>&nbsp;=&nbsp;<span class="Variable">CurrentIndex</span>&nbsp;-&nbsp;<span class="Number">1</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Event&nbsp;Log'[Timestamp]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">REMOVEFILTERS</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Event&nbsp;Log'&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Start&nbsp;from&nbsp;all&nbsp;activities</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Case&nbsp;ID]&nbsp;=&nbsp;<span class="Variable">CurrentCase</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Filter&nbsp;to&nbsp;just&nbsp;current&nbsp;case</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Activity&nbsp;Index]&nbsp;=&nbsp;<span class="Variable">PreviousIndex</span>&nbsp;<span class="Comment">//&nbsp;Filter&nbsp;to&nbsp;next&nbsp;case&nbsp;only</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br></font>
  












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG" data-image-dimensions="678x428" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG?format=1000w" width="678" height="428" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609663997480-VV6RSCTL65BNQX9PHRKM/Event+Log+with+Timestamp+of+previous+Activity.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Note that we have a blank timestamp for the first activity in each case, since we’re not concerned how long the customer took to register their request. </p><h3>Adding Hours to complete Activity</h3><p class="">For this column, we’ll report the hours between activities, since that is a suitable time scale for this event log. Different types of processes will have better-suited timescales, e.g. tracking a user’s clicks on a website is best described in seconds, whereas milestones in a large project are better described in days or weeks. </p><p class="">We’ll also ensure that we track hours as a decimal rather than an integer, so that if we aggregate this value then we will get more accurate results. We can accomplish this by calculating the time difference in units of seconds, then converting to hours. </p>


  


  




  
    <font face="Consolas">Hours&nbsp;to&nbsp;complete&nbsp;Activity&nbsp;=<br><span class="Keyword">DIVIDE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DATEDIFF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Timestamp&nbsp;of&nbsp;previous&nbsp;Activity],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Timestamp],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SECOND</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>,<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Seconds&nbsp;between&nbsp;timestamps</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">60</span>&nbsp;*&nbsp;<span class="Number">60</span>&nbsp;<span class="Comment">//&nbsp;Convert&nbsp;seconds&nbsp;to&nbsp;hours&nbsp;as&nbsp;a&nbsp;decimal</span><br><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span><br><span class="Comment">//&nbsp;Mark&nbsp;final&nbsp;activity&nbsp;as&nbsp;having&nbsp;zero&nbsp;duration</span><br></font>
  












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG" data-image-dimensions="844x428" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG?format=1000w" width="844" height="428" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609664736879-4T2FOC0BKV5HAMZYNMJZ/Event+Log+with+Hours+to+complete+Activity.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Representing as Business Hours to complete Activity</h3><p class="">In a real world scenario, you may not be concerned about the hours spent waiting to complete an activity if those hours are outside business hours. To give a clearer picture of the process, we can adapt an established technique for <a href="https://exceleratorbi.com.au/calculating-business-hours-using-dax/">Calculating Business Hours Using DAX</a>, as written about previously by Matt Allington. Our event log has events happened between 9AM and 5PM, 7 days a week, so we’ll include weekends as Matt has done in his example (we will also not remove public holidays for simplicity). </p>


  


  




  
    <font face="Consolas">Business&nbsp;Hours&nbsp;to&nbsp;complete&nbsp;Activity&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">WorkDayStart</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">TIME</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Number">9</span>,&nbsp;<span class="Number">0</span>,&nbsp;<span class="Number">0</span>&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;9AM</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">WorkDayEnd</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">TIME</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Number">17</span>,&nbsp;<span class="Number">0</span>,&nbsp;<span class="Number">0</span>&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;5PM</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">BusinessHoursPerDay</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">VALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Variable">WorkDayEnd</span>&nbsp;-&nbsp;<span class="Variable">WorkDayStart</span>&nbsp;<span class="Parenthesis">)</span>&nbsp;*&nbsp;<span class="Number">24</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">PreviousDate</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DATEVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Event&nbsp;Log'[Timestamp&nbsp;of&nbsp;previous&nbsp;Activity]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">PreviousTime</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">TIMEVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Event&nbsp;Log'[Timestamp&nbsp;of&nbsp;previous&nbsp;Activity]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">CurrentDate</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DATEVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Event&nbsp;Log'[Timestamp]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">CurrentTime</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">TIMEVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Event&nbsp;Log'[Timestamp]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">FullWorkDays</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DATEDIFF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Timestamp&nbsp;of&nbsp;previous&nbsp;Activity],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Timestamp],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DAY</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;-&nbsp;<span class="Number">1</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">FirstDayElapsedHours</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Work&nbsp;out&nbsp;how&nbsp;many&nbsp;hours&nbsp;before&nbsp;end&nbsp;of&nbsp;day&nbsp;that&nbsp;the&nbsp;previous&nbsp;activity&nbsp;took&nbsp;place</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DIVIDE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DATEDIFF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Timestamp&nbsp;of&nbsp;previous&nbsp;Activity],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">PreviousDate</span>&nbsp;+&nbsp;<span class="Variable">WorkDayEnd</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;5PM&nbsp;on&nbsp;day&nbsp;of&nbsp;previous&nbsp;activity</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SECOND</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">60</span>&nbsp;*&nbsp;<span class="Number">60</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">LastDayElapsedHours</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Work&nbsp;out&nbsp;how&nbsp;many&nbsp;hours&nbsp;into&nbsp;the&nbsp;day&nbsp;the&nbsp;current&nbsp;activity&nbsp;took&nbsp;place</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DIVIDE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">DATEDIFF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">CurrentDate</span>&nbsp;+&nbsp;<span class="Variable">WorkDayStart</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;9AM&nbsp;on&nbsp;day&nbsp;of&nbsp;current&nbsp;activity</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Timestamp],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SECOND</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">60</span>&nbsp;*&nbsp;<span class="Number">60</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Event&nbsp;Log'[Timestamp&nbsp;of&nbsp;previous&nbsp;Activity]&nbsp;&lt;&gt;&nbsp;<span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">FirstDayElapsedHours</span>&nbsp;+&nbsp;<span class="Variable">FullWorkDays</span>&nbsp;*&nbsp;<span class="Variable">BusinessHoursPerDay</span>&nbsp;+&nbsp;<span class="Variable">LastDayElapsedHours</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">0</span>&nbsp;<span class="Comment">//&nbsp;Return&nbsp;0&nbsp;for&nbsp;first&nbsp;activity</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br></font>
  












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG" data-image-dimensions="1051x429" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG?format=1000w" width="1051" height="429" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609665106625-8ENM1NKYCP7HHAWA29R7/Event+Log+with+Business+Hours+to+complete+Activity.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Final considerations</h3>


  


  



<p>Breaking the steps into separate columns as we have done can help us  understand the logic behind the calculation. In practice, you’ll want to consolidate the logic into a single calculated column rather than three, as this avoids storing unneccessary fields<sup id="fnref:3" data-preserve-html-node="true">
  <a data-preserve-html-node="true" href="#fn:3" class="footnote">3</a>
</sup>
. This can be accomplished by replacing the first two calculated columns with variables in the definition of the total hours column.</p>


  
  <p class="">Once we have the business hours to complete each activity, we can visualise this to see where our process faces the most delays.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG" data-image-dimensions="586x335" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG?format=1000w" width="586" height="335" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609666077354-FIL1BE0LXQQ7ZHAHO28P/Average+Business+Hours+distribution.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Upon inspection, I wouldn’t consider it particularly surprising that the activity of ultimately paying compensation to customers is the longest step for a reimbursement process. But there are other insights to note here as well — for example, the duration of the ‘examine casually’ and ‘examine thoroughly’ appear to take about the same amount of time on average. In reality, the ‘examine casually’ activity is undertaken for all cases, but sometimes they are then examined more thoroughly. This is a symptom of the process actually not being a linear one, as different cases may follow a different chain of activities. Techniques have been developed in the field of process mining to address such scenarios, and I imagine they’ll form the topic of future blog posts. </p>


  


  



<hr />
  <ol data-preserve-html-node="true">
    <li id="fn:1" data-preserve-html-node="true">
     <p data-preserve-html-node="true">The dataset is as described in the book <a href="https://www.amazon.com.au/Process-Mining-Data-Science-Action/dp/3662498502">Process Mining: Data Science in Action</a> by Wil van der Aalst, and can be <a href="http://www.processmining.org/event_logs_and_models_used_in_book">downloaded here</a>.&nbsp;<a data-preserve-html-node="true" href="#fnref:1" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:2" data-preserve-html-node="true">
     <p data-preserve-html-node="true">Note that in more complicated processes with branching paths that a process can follow, tracking states may not be so simple. But for the purpose of this article, the assumption of a simple linear process will do just fine.&nbsp;<a data-preserve-html-node="true" href="#fnref:2" class="reversefootnote">↩</a></p>
    </li>
    <li id="fn:3" data-preserve-html-node="true">
     <p data-preserve-html-node="true">Creating unneeded columns isn’t best practice with Power BI, especially when one of the fields is a datetime. Datetime fields often have a big impact on your file size, as the high cardinality makes it hard for the Vertipaq engine to compress them.&nbsp;<a data-preserve-html-node="true" href="#fnref:3" class="reversefootnote">↩</a></p>
    </li>
  </ol>





<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1609977287442-JF5DBXQMDWNXC5794L0L/Blog+thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="924" height="713"><media:title type="plain">Calculating business hours between activities using DAX</media:title></media:content></item><item><title>How to improvise What If Parameters in Power BI Live Connection models</title><dc:creator>Sam Fischer</dc:creator><pubDate>Mon, 21 Dec 2020 10:55:00 +0000</pubDate><link>https://apexinsights.net/blog/improvised-what-if-parameters-for-histograms</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:5fc22f0e9b1ed035382522f1</guid><description><![CDATA[In my last blog post, I explained a flexible technique you can use to build 
histograms in Power BI using measures and What If parameters. But one issue 
with that approach is that it assumes you have the ability to add a new 
table to your model. Fortunately, for many users this is no longer an 
issue, thanks to the recent release of DirectQuery over Azure Analysis 
Services models as a preview feature for Power BI Desktop. However if your 
reporting data is stored on premises, whether in SQL Server Analysis 
Services or Power BI Report Server, it may be a while until you can make 
use of this feature. In this post, I'll take you through a technique that 
I've used to build a histogram visual even when you don't have the ability 
to alter the data model used by your report.]]></description><content:encoded><![CDATA[<p class="">In my <a href="https://apexinsights.net/blog/histograms-in-power-bi">last blog post</a>, I explained a flexible technique you can use to build histograms in Power BI using measures and <em>What If</em> parameters. But one issue with that approach is that it can’t be applies to data models with a Live Connection, as these don’t allow you to add a new table to your model. Fortunately, for many users this is no longer an issue, thanks to the release of <a href="https://powerbi.microsoft.com/en-us/blog/directquery-for-power-bi-datasets-and-azure-analysis-services-preview/">DirectQuery over Azure Analysis Services models</a> for Power BI Desktop. However if your reporting data is stored on premises, whether in SQL Server Analysis Services or Power BI Report Server, it may be a while until you can make use of this feature. </p><p class="">In this post, I'll take you through a technique that I've used to build a histogram visual even when you don't have the ability to alter the data model used by your report. The situation described is admittedly quite niche, so I would recommend that you treat this article as a learning resource to show you some creative ways to apply DAX to sidestep modelling constraints, rather than expecting to immediately find a practical application of the technique in your own reports. </p><h3>Our challenge</h3><p class="">As a reminder, last time we created a histogram describing a retail chain’s sales performance. Our histogram showed the count of stores by how many months they sold under target. We built our final histogram using a What If parameter for the axis values, and a custom measure to count the number of stores underperforming for each of the possible months. Our final solution ended up looking like this…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram" data-image-dimensions="633x489" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram?format=1000w" width="633" height="489" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607163932483-4ZPK9EWWGULEZGX1LNZR/Histogram?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">If you’re working off of an Analysis Services Tabular model, this method proves to be ineffective due to the inability to add What If parameters. However, we don’t fundamentally need a What If parameter for this purpose, we just need a field that has the values 0 through 12. As long as there is such a field in our model, we can use that field as the axis of our histogram. Even though there may be relationships in place which would filter the calculated values, we can still write a measure for our histogram which can ignore this filtering. </p><h3>Our situation</h3><p class="">For this example, we’ll work off of a dataset made in Power BI rather than a Tabular model — this will give us better visibility on what’s going on under the hood. Despite this, the approach we’ll take works equally well on a Tabular model, when it comes time to implement it yourself. </p><p class="">Just as in <a href="https://apexinsights.net/blog/histograms-in-power-bi">the last post</a>, we've got a data table with sales performance data by month and store. This time around, I've added a date dimension, which is related to our main data table on the month column (which is a date type field). </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model" data-image-dimensions="604x411" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model?format=1000w" width="604" height="411" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113913072-FUZSQ217CXEJXCYZII34/Data+model?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Here are some of the fields in <em>Dim Date</em>…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date" data-image-dimensions="1070x468" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date?format=1000w" width="1070" height="468" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607166802191-TMF4LTA28BP068KL8745/Dim+Date?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">At first glance, it would seem as though a simple integer field like <em>Day</em> or <em>Month</em> may be suitable to use for the histogram axis. However, recall that our histogram varied between 0 and 12, so we’d be missing the 0 value by using either of those fields. Instead we can use the <em>Relative Day</em> field, which is used to denote how many days it is between the date in the current row and today (or more accurately, the last refresh date). Your own models may not have such a field, so you may have to do your own analysis of the fields in your model to find a suitable one. </p><p class="">Note that in the context of an Analysis Services connection, you won't have the ability to see the underlying tables to find a suitable field. In this case, you can explore the values in the tables by either dragging them onto the report page canvas to see the distinct values as a table, or you can use DAX Studio to connect to the model and query the full table. If you haven't used DAX Studio for this before, Matt Allington has a <a href="https://exceleratorbi.com.au/getting-started-dax-studio/">great blog post</a> to teach you the basics. </p><p class="">Now that we have identified the field to use for our axis, we can define the corresponding measure for the histogram columns. We can start by defining the measure as we did in the last post, but this time with <em>Relative Day</em> as the selected field instead. For those who need a refresher, this measure creates a virtual table of the total number of months where sales were below target by store. It then counts how many stores underperformed for the selected number of months. Here’s how our measure is defined…</p>


  


  




  
    <font face="Consolas">Store&nbsp;Count&nbsp;on&nbsp;Tabular&nbsp;Model&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">HistogramColumn</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Dim&nbsp;Date'[Relative&nbsp;Day]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Store&nbsp;the&nbsp;currently&nbsp;selected&nbsp;histogram&nbsp;axis&nbsp;value</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">StorePerformance</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUMMARIZE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Fact&nbsp;Sales&nbsp;Snapshot',&nbsp;<span class="Comment">//&nbsp;Group&nbsp;our&nbsp;snapshot&nbsp;table...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Fact&nbsp;Sales&nbsp;Snapshot'[Store],&nbsp;<span class="Comment">//&nbsp;By&nbsp;store...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="StringLiteral">"Months&nbsp;below&nbsp;target"</span>,&nbsp;<span class="Comment">//&nbsp;And&nbsp;return&nbsp;the&nbsp;number&nbsp;of&nbsp;months&nbsp;below&nbsp;target...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="Comment">//&nbsp;By&nbsp;counting&nbsp;the&nbsp;number&nbsp;of&nbsp;months&nbsp;remaining...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">VALUES</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="Comment">//&nbsp;After&nbsp;filtering&nbsp;our&nbsp;months&nbsp;down...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>[Sales&nbsp;to&nbsp;Target]&nbsp;&lt;&nbsp;<span class="Number">1</span>&nbsp;<span class="Comment">//&nbsp;To&nbsp;only&nbsp;include&nbsp;months&nbsp;under&nbsp;target</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNTROWS</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Comment">//&nbsp;Count&nbsp;the&nbsp;rows...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Comment">//&nbsp;After&nbsp;filtering&nbsp;down...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">StorePerformance</span>,&nbsp;<span class="Comment">//&nbsp;The&nbsp;StorePerformance&nbsp;virtual&nbsp;table...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>[Months&nbsp;below&nbsp;target]&nbsp;=&nbsp;<span class="Variable">HistogramColumn</span>&nbsp;<span class="Comment">//&nbsp;To&nbsp;just&nbsp;stores&nbsp;in&nbsp;the&nbsp;current&nbsp;histogram&nbsp;column</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span><br></font>
  


  
  <p class="">Now we can drag <em>Relative Day</em> into the chart axis well, and Store Count into the values well, giving us the following…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis" data-image-dimensions="630x472" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis?format=1000w" width="630" height="472" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607168550942-D1ODJKNBMPJ6CUIDLH5N/Result+after+adding+new+axis?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Okay, this is admittedly looking a bit odd. The first thing we’ll need to do to make this return something more sensible is to limit the <em>Relative Day</em> values on the axis just to our 0 through 12 values. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values" data-image-dimensions="849x481" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values?format=1000w" width="849" height="481" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1607240179437-O3OMFYCLTG1GB96DWR84/Limiting+the+axis+values?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">After limiting our axis values, we find that the measure returns 0 for all columns, rather than a distribution of values. What’s going on here?! Well, we’ll have to take a brief step into DAX theory land before we can tackle this problem. </p><h3>A quick lesson in how DAX measures work</h3><p class="">To get around this, we need to understand how measures get evaluated by the Vertipaq engine, which is the brains behind DAX. Before the engine does any arithmetic to count our rows, it follows a sequence of steps to filter the data model…</p><ol data-rte-list="default"><li><p class="">First, it will consider all of the filters being applied to the visual element. E.g. for a cell in a pivot table. it will consider the selected column and row, and any external filters applied. </p></li><li><p class="">Then, it will modify those filters according to any applied filter context modifiers, like CALCULATE or CALCULATETABLE.  </p></li><li><p class="">Next, it will then apply those filters to the data model. </p></li><li><p class="">And finally, it will follow any active relationships to further filter the rows in the model. </p></li></ol><p class="">Only at that point will it perform the arithmetic operations to give us our measure value.</p><p class="">If that sounded confusing, that's probably because it is! You don’t necessarily have to understand all that the first time you read it, as understanding how DAX expressions are evaluated can be somewhat challenging. But it is one of the challenges in learning Power BI with the biggest payoff, as it will make many of the problems you face in developing reports so much easier to solve. You can learn more about how DAX expressions get evaluated in Rob Collie and Avi Singh's incredibly digestible book <a href="https://www.amazon.com/Power-Pivot-BI-Excel-2010-2016/dp/1615470395">Power Pivot and Power BI</a> (look at Chapter 7 in particular).</p><h3>Back to our scenario…</h3><p class="">With that extra context, we can figure out what’s going on with our measure.  The evaluation step that causes us problems is in <em>following the active relationships</em>. When we are looking at the histogram column equal to 1, recall that this is actually referring to the values where relative day equals 1. Since this is one day in the future, and all our sales performance data is historical, this filters the model down to exclude all our sales data. In other words, we’ve reduced our row count to zero before we even have a chance to evaluate the measure! </p><p class="">So how can we get around this problem? Well, we could delete the relationship, but then we wouldn’t be able to filter using other date fields. Instead, we can remove the filtering effect from <em>Relative Day</em> by using a DAX function that is (fittingly enough) called REMOVEFILTERS. We’ll need to use this wherever filtering would occur when the measure gets evaluated — this ensures that the filtering via the relationship will be ignored. In our case, the filtering occurs when the <em>StorePerformance</em> variable and the final measure output are evaluated. Here’s what our measure looks like when we add these extra clauses (marked by comments)… </p>


  


  




  
    <font face="Consolas">Store&nbsp;Count&nbsp;on&nbsp;Tabular&nbsp;Model&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">HistogramColumn</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Dim&nbsp;Date'[Relative&nbsp;Day]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">StorePerformance</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUMMARIZE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATETABLE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>'Fact&nbsp;Sales&nbsp;Snapshot',<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">REMOVEFILTERS</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Dim&nbsp;Date'[Relative&nbsp;Day]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Ignore&nbsp;Relative&nbsp;Day&nbsp;filter</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Fact&nbsp;Sales&nbsp;Snapshot'[Store],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="StringLiteral">"Months&nbsp;below&nbsp;target"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">VALUES</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,&nbsp;[Sales&nbsp;to&nbsp;Target]&nbsp;&lt;&nbsp;<span class="Number">1</span>&nbsp;<span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNTROWS</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Variable">StorePerformance</span>,&nbsp;[Months&nbsp;below&nbsp;target]&nbsp;=&nbsp;<span class="Variable">HistogramColumn</span>&nbsp;<span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">REMOVEFILTERS</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Dim&nbsp;Date'[Relative&nbsp;Day]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Ignore&nbsp;Relative&nbsp;Day&nbsp;filter</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">Now when we use this new measure in our histogram, we will get the same histogram as we made in the last post, but this time without relying on any custom tables.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram" data-image-dimensions="633x489" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram?format=1000w" width="633" height="489" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608547721625-71WVMNU7PJXNFX97VMW9/Histogram?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Additional considerations</h3><p class="">When building out a report page with this visual, it may be quite natural to want to add a date slicer to your page. This is still an option in this scenario, however you’ll have to use the date field from the fact table in the slicer, rather than the field in your date dimension. Introducing a filter context from the date table here will potentially filter the <em>Relative Day</em> values before the histogram columns can even be evaluated. </p><p class="">Also recall that the last time we built this histogram, we also built a tooltip to list the stores represented in each histogram. The histogram with the tooltip ended up looking like this…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip" data-image-dimensions="633x489" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip?format=1000w" width="633" height="489" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608113613403-38JV84H0UFAFIUUJ0WTY/Histogram+with+tooltip?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">If we want to get this tooltip working for our new histogram as well, we need to modify the measure that indicates whether or not to include a given store in the tooltip. We can use REMOVEFILTERS for this again…</p>


  


  




  
    <font face="Consolas">Tooltip&nbsp;Filter&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">HistogramColumn</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Histogram&nbsp;Axis'[Histogram&nbsp;Axis]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">UnderperformingMonths</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATETABLE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">VALUES</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,&nbsp;[Sales&nbsp;to&nbsp;Target]&nbsp;&lt;&nbsp;<span class="Number">1</span>&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">REMOVEFILTERS</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Dim&nbsp;Date'[Relative&nbsp;Day]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Ignore&nbsp;Relative&nbsp;Day&nbsp;Filter</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">MonthsBelowTarget</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNTROWS</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Variable">UnderperformingMonths</span>&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Variable">MonthsBelowTarget</span>&nbsp;=&nbsp;<span class="Variable">HistogramColumn</span>,&nbsp;<span class="Number">1</span>,&nbsp;<span class="Number">0</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <h3>Summary</h3><p class="">Even in scenarios where you aren't able to alter your data model, you can often still find ways to solve problems that would conventionally involve new tables, columns or relationships. In this case, we were able to use an established field in our model, and alter the evaluation context of our measures in a few places to adapt the field into a What If parameter. </p><p class="">I will caution that having to write complicated DAX expressions can often be a warning sign of the need to remodel your dataset. But even star schemas can’t address every scenario; they are built to cater to generalised situations. When you’re working off of a static model meant to service many reports or users, that general scenario may not cut it for you. As you get more familiar with DAX, you can pull off these kinds of tricks to sidestep the constraints of working with static data models. </p><h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/Improvised-What-If-parameters-for-Histograms.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1608548752878-8H479TVS0W2H1UY9OAL1/Blog+thumbnail.PNG?format=1500w" medium="image" isDefault="true" width="430" height="336"><media:title type="plain">How to improvise What If Parameters in Power BI Live Connection models</media:title></media:content></item><item><title>How to make Histograms in Power BI to answer business questions</title><dc:creator>Sam Fischer</dc:creator><pubDate>Mon, 07 Dec 2020 05:43:00 +0000</pubDate><link>https://apexinsights.net/blog/histograms-in-power-bi</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:5fb4d7535b8fff05b375e7cd</guid><description><![CDATA[Histograms are commonly used in statistics, but they can also be useful for 
answering business questions. However it’s not immediately obvious how to 
set them up in Power BI, so we’re going to go through a few techniques for 
how to build them to address a business scenario. Our end result will have 
the flexibility to slice on different values, and will give us a custom 
tooltip with additional insights.]]></description><content:encoded><![CDATA[<p class="">A histogram is a common tool in statistics to describe the distribution of values across a dataset. They can show you the most common values, the outliers, and the spread of your values, all at a single glance. Histograms can be useful not just within statistics, but also for answering business questions.  However it’s not immediately obvious how to set them up in Power BI, so we’re going to go through a few techniques for how to build them to address a business scenario. We’ll start with a simple implementation, then build out a more sophisticated one with additional flexibility and insight into our scenario. </p><h3>What is a histogram again? Isn't that just a column chart?</h3><p class="">Histograms, quite simply, are a type of column chart. For many people, they may seem like one in the same, but while all histograms are column charts, not all column charts are histograms (similar to how all humans are mammals, but not all mammals are human). While you may be used to column charts that display financial measure like profits, histograms are column charts that give you information on the frequency of values, often times using a COUNT measure in Power BI. Histograms have a number of particular features that not all column charts have...</p><ul data-rte-list="default"><li><p class="">The x-axis contains continuous values (i.e. numbers) rather than categorical values (i.e. names of groupings), and the y-axis contains frequency / count data.</p></li><li><p class="">The values on the x-axis can be individual values (ages 0, 1, 2, 3, etc.) or binned values (ages 0-9, 10-19, 20-29, etc.). An item represented in a column of a histogram could have any value within that bin. We’ll only focus on histograms using individual integer values, since there are a number of articles already written by others on using binning for segmentation. </p></li><li><p class="">Histograms include bins that have a count of zero. The context of the situation may make it reasonable to omit empty bins at the top or bottom end of the distribution if they are not between two nonempty bins, e.g. you don't need to include ages 0-9 when describing staff at a company.</p></li></ul><h3>Using a histogram to answer business questions</h3><p class="">Histograms aren’t just useful in statistics — they can also be used effectively in business scenarios to provide useful insights. In this example, we will be answering questions about a hypothetical retail company based in Melbourne, Australia. We have been given data about how each of the company's 16 stores have performed in each month of the 2019-2020 financial year. This dataset contain the Sales and Sales Targets, with an underlying table that looks like this…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
              
              
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG" data-image-dimensions="363x377" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG?format=1000w" width="363" height="377" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605694216265-6I7I4XB5MD083CMJ9XP0/Fact+table.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
            
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Since the table contains a snapshot of the sales up to the end of each month, let's call this table <em>Fact Sales Snapshot</em>. Note here that the Month column is a date type field, but I've changed the formatting to make it more readable.</p><p class="">Based on the data in <em>Fact Sales Snapshot</em>, we've been asked to answer this question:</p><h4>For how many months did each store sell below their sales targets?</h4><p class="">If we want to answer this question, we're faced with a problem. Usually in Power BI, we build visuals by dragging and dropping fields onto the report page to form our axis and values. But if we want number of months to appear on our column chart axis, what field in our dataset would we use to make this axis? It's not immediately clear, since there is no field in our dataset with just integer values for our month counts. To deal with this problem, we're going to build out a table with these month values ourselves. And using this new table, we're going to build a histogram that shows the count of stores against the number of months that they were performing below their target.</p><p class="">We'll be tackling this problem in two different ways. The first approach will be a so-called static solution, which relies on a calculated table which aggregates our existing snapshot table. The second will be a dynamic solution using a What-If parameter and a custom measure instead. And finally we'll extend our dynamic solution with a custom tooltip to tell us which stores are represented in each column of our histogram. As a taster for what’s to come, here’s what our final solution will look like…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram" data-image-dimensions="633x489" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram?format=1000w" width="633" height="489" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552282780-ZF12H1F51R6HOVB1GW41/Histogram?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Static solution using calculated tables</h3><p class="">To being answering this question, we need to calculate the Sales to Target for each store's monthly sales. To do this, we can define a simple DAX measure as follows, and define it as a percentage.</p>


  


  




  
    <font face="Consolas">Sales&nbsp;to&nbsp;Target&nbsp;=<br><span class="Keyword">DIVIDE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Sales]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Target]&nbsp;<span class="Parenthesis">)</span><br><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span><br><span class="Comment">//&nbsp;The&nbsp;'+&nbsp;0'&nbsp;ensures&nbsp;that&nbsp;empty&nbsp;values&nbsp;return&nbsp;a&nbsp;0.&nbsp;This&nbsp;is&nbsp;more&nbsp;succinct&nbsp;than&nbsp;a&nbsp;COALESCE&nbsp;function</span><br></font>
  


  
  <p class="">Now using this new measure, we're going to build a new calculated table in DAX, which returns a unique list of stores, and for each store it counts how many months the Sales to Target measure is less than 100%.</p>


  


  




  
    <font face="Consolas">Store&nbsp;Performance&nbsp;=<br><span class="Keyword">SUMMARIZE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>'Fact&nbsp;Sales&nbsp;Snapshot',<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Group&nbsp;our&nbsp;snapshot&nbsp;table...</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>'Fact&nbsp;Sales&nbsp;Snapshot'[Store],<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;By&nbsp;store...</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="StringLiteral">"Months&nbsp;below&nbsp;target"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;And&nbsp;return&nbsp;the&nbsp;number&nbsp;of&nbsp;months&nbsp;below&nbsp;target...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;By&nbsp;counting&nbsp;the&nbsp;number&nbsp;of&nbsp;months&nbsp;remaining...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">VALUES</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;After&nbsp;filtering&nbsp;our&nbsp;months&nbsp;down...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>[Sales&nbsp;to&nbsp;Target]&nbsp;&lt;&nbsp;<span class="Number">1</span>&nbsp;<span class="Comment"><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;To&nbsp;only&nbsp;include&nbsp;months&nbsp;under&nbsp;target</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span><br><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">The output of our new Store Performance table looks like this...</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
              
              
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png" data-image-dimensions="237x368" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png?format=1000w" width="237" height="368" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695273619-NQMV3M91OAKWFCNY3F6Q/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
            
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">And we can drag these two fields into a column chart visual to get something like the following…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
              
              
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png" data-image-dimensions="357x265" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png?format=1000w" width="357" height="265" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605695639996-GZACL2W0VY0ELOL4YHCT/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
            
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">And here we have our histogram! It certainly answers our business question of how many months each store sold below target. But it has a few shortcomings that means it may not be the best approach for us to apply to other similar situations…</p><ul data-rte-list="default"><li><p class="">We've added a new table which will take up more space in our model and increase the file size, especially if we had a lot more stores or were doing this analysis for something like products which would likely have many different unique values. </p></li><li><p class="">We can't slice this table based on other attributes like month or store region. </p></li><li><p class="">For us, we could be content with not showing months 11 and 12, but we may want to give our report audience confidence that there are no stores that performed under target for more than 10 months. </p></li></ul><p class="">Given all those shortcomings, we're going to tackle this problem again, but this time using a more scalable approach. Our new approach will not only address these issues, but will also allow us to include other features in later sections which will be significant value-adds for describing our business situation. </p><h3>Dynamic solution using What If parameters and measures</h3><p class="">This new solution will rely on building a dynamic measure that we will still be able to slice our data model on. This is a more robust approach that our first attempt, since our aggregated values are calculated as required based on filter context rather than being stored as fixed values in the model. However, this new solution still need to address the problem we identified earlier around needing a field for our histogram axis.</p><p class="">This time around we're going to to make another calculated table, albeit a much simpler one. We’ll define a What If parameter called Histogram Axis, and allow it to take values between 0 and 12.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter" data-image-dimensions="722x556" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter?format=1000w" width="722" height="556" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606540694567-OUDFEZTN6SKDLH0NVC4S/Creating+What+If+parameter?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Note that we’ve deselected ‘Add slicer to this page’, since we won’t be slicing on this value. We also won’t need the Histogram Axis Value measure that is automatically generated, as we’ll be creating a new custom measure instead. We’re simply using the parameter to define a calculated table with the values that should appear on the x-axis of our histograms, which we could have equally well defined manually as a DAX table.</p><p class="">Now that we have our histogram axis, we can define the measure that we’ll use to generate the values for our histogram. In this measure, we will generate our Store Performance table as a virtual table variable, so that it gets evaluated within the measure rather than being stored in the model. We then filter the table down to stores with sales performance corresponding to the currently selected Histogram Axis value. Finally, the measure returns the row count for this filtered table.</p>


  


  




  
    <font face="Consolas">Store&nbsp;Count&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">HistogramColumn</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Histogram&nbsp;Axis'[Histogram&nbsp;Axis]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Store&nbsp;the&nbsp;currently&nbsp;selected&nbsp;histogram&nbsp;axis&nbsp;value</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">StorePerformance</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Virtual&nbsp;table&nbsp;defined&nbsp;the&nbsp;same&nbsp;as&nbsp;our&nbsp;calculated&nbsp;table</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUMMARIZE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Fact&nbsp;Sales&nbsp;Snapshot',<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Fact&nbsp;Sales&nbsp;Snapshot'[Store],<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="StringLiteral">"Months&nbsp;below&nbsp;target"</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">VALUES</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,&nbsp;[Sales&nbsp;to&nbsp;Target]&nbsp;&lt;&nbsp;<span class="Number">1</span>&nbsp;<span class="Parenthesis">)</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNTROWS</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Count&nbsp;the&nbsp;rows...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;After&nbsp;filtering&nbsp;down...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">StorePerformance</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;The&nbsp;StorePerformance&nbsp;virtual&nbsp;table...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span>[Months&nbsp;below&nbsp;target]&nbsp;=&nbsp;<span class="Variable">HistogramColumn</span>&nbsp;<span class="Comment"><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;To&nbsp;just&nbsp;stores&nbsp;that&nbsp;belong&nbsp;in&nbsp;the&nbsp;current&nbsp;histogram&nbsp;column</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>&nbsp;+&nbsp;<span class="Number">0</span><br></font>
  


  
  <p class="">We can now use this measure to generate the same histogram as before, but since it is dynamically calculated from the values in <em>Fact Sales Snapshot</em>, we can now we can use slicers on the histogram. E.g. we may want to limit our analysis to stores in a particular region, or just to certain months of the year.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers" data-image-dimensions="930x437" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers?format=1000w" width="930" height="437" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606546031477-LWIIK3BPGSVHIEW2J1DP/Interacting+with+slicers?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Note that when we use the slicers, our original static solution is not affected.</p><h3>Formatting our histogram</h3><p class="">Next we’ll format our histogram in a conventional manner where there are no gaps between the columns — this acts as a visual cue to enforce the idea that the columns represent continuous values. </p><p class="">To do this, we (ironically) have to change our x-axis from continuous type to categorical. While our data represent a continuous series of numbers, for some unknown reason column chart visuals only allow you to adjust the width between columns when the data on the x-axis are marked as categorical. We can change this setting in the Format pane. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical" data-image-dimensions="629x322" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical?format=1000w" width="629" height="322" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544361302-BVQLADP82UNQRWRKTXU5/Changing+x+axis+to+categorical?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">But unfortunately, when we make this change, our column ordering changes! The axis now gets sorted descending based on the measure value, but this is easy for us to correct.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order" data-image-dimensions="729x347" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order?format=1000w" width="729" height="347" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606544916927-TDLDQUNYO05EKEZ664U2/Fixing+sort+order?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Finally, we can adjust the width between the columns using the Inner padding option in the Format pane. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding" data-image-dimensions="640x338" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding?format=1000w" width="640" height="338" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606545099256-6QLYDNAURSYNUEEXZXZ8/Removing+inner+padding?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Adding a tooltip to list stores represented in each column</h3><p class="">Now that we have the distribution of monthly store performance, the next thing we'd probably want to know is which stores are the ones performing well and which aren't. An effective way to show this information would be with a tooltip that tells us which stores are represented in each column of our histogram.</p><p class="">We can do this by creating a custom tooltip. To do this we can create a new page in our report, then define the page as a Tooltip page in the Format pane and reduce the page size to something small enough to use as a tooltip.<strong> </strong></p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page" data-image-dimensions="1258x550" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page?format=1000w" width="1258" height="550" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606686791835-RUKEZ1WOJELW2RB877JA/Creating+tooltip+page?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">On our tooltip page, we can build a simple table visual using the Store field in <em>Fact Sales Snapshot</em>. By default, this will show all of our stores, but we only want it to display the stores for the currently selected histogram column. To accomplish this, we'll create another measure, which will be used as a visual-level filter on our visual. For each row in our table of stores, it will determine how many months the store underperformed. It will then compare that to the histogram column that is currently selected in creating the tooltip, and will only include the store if the store's performance matches the histogram column value.</p>


  


  




  
    <font face="Consolas">Tooltip&nbsp;Filter&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">HistogramColumn</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Histogram&nbsp;Axis'[Histogram&nbsp;Axis]&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">MonthsBelowTarget</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Defined&nbsp;as&nbsp;before</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">COUNT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">VALUES</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Month]&nbsp;<span class="Parenthesis">)</span>,&nbsp;[Sales&nbsp;to&nbsp;Target]&nbsp;&lt;&nbsp;<span class="Number">1</span>&nbsp;<span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Variable">MonthsBelowTarget</span>&nbsp;=&nbsp;<span class="Variable">HistogramColumn</span>,&nbsp;<span class="Number">1</span>,&nbsp;<span class="Number">0</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <p class="">To enable this filter logic, we just have to drag the measure into the visual level filters for our tooltip table, and only include values for which the measure returns 1.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif" data-image-dimensions="662x466" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif?format=1000w" width="662" height="466" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547685443-4TEQZAZ01MUTNA4S49EQ/Applying+Tooltip+Filter.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">After setting all this up, we can navigate back to our main report page, and format the histogram visual to refer to our tooltip page as a report page tooltip.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram" data-image-dimensions="628x388" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram?format=1000w" width="628" height="388" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606547899862-TOQZ8HE0EA9TVIECRN5X/Assigning+custom+tooltip+to+histogram?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">And with that, we can now see our dynamic histogram with tooltip in action!</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip" data-image-dimensions="633x458" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip?format=1000w" width="633" height="458" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606548317848-LTQM92MX77RJ4LICK7AP/Histogram+with+tooltip?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Other scenarios to use histograms in</h3><p class="">These techniques of building histograms for analysis can be very powerful when used effectively. With these insights, a report user may be able to identify the stores with poor sales performance and used that to investigate (and hopefully resolve) the key factors driving their underperformance. You could even extend this scenario to analysing sales of individual products and identify stores where that product has underperformed (rather than considering the sales performance across all products in store as we have done). Customers shopping at these stores may offer valuable insights to help your company to improve its product offering.</p><h3>Summary</h3><p class="">In this article, we built a histogram in Power BI which showed us the distribution of store performance, based on how many months each store’s sales were below target. We first made our histogram using an aggregate table in DAX, and then we extended our solution to use a measure and a What If parameter. We then formatted our histogram to remove the space between columns, and added a custom tooltip to show which stores were represented in each histogram column. </p><p class="">As a final note, bear in mind that the approaches we've discussed both rely on you having the ability to define a calculated table in your model. However, if you happen to be working off of a report connected to an Analysis Services model, you probably won't have the same kind of flexibility to create additional tables. In my next blog post, I'll take you through an implementation you can use to <a href="https://apexinsights.net/blog/improvised-what-if-parameters-for-histograms">create histograms when you can't actually create a new table in your model</a>, so stay tuned!</p><h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/Histograms.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />]]></content:encoded><media:content type="image/gif" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606552606414-2XX8VP44D8Y4GCPMJSIW/Histogram.gif?format=1500w" medium="image" isDefault="true" width="633" height="489"><media:title type="plain">How to make Histograms in Power BI to answer business questions</media:title></media:content></item><item><title>Top 3 ways to direct attention with   conditional formatting for column charts in Power BI</title><dc:creator>Sam Fischer</dc:creator><pubDate>Mon, 23 Nov 2020 20:33:00 +0000</pubDate><link>https://apexinsights.net/blog/direct-attention-with-conditional-formatting</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:5fb5f54b60f5752b07f0c01b</guid><description><![CDATA[Conditional Formatting can be a powerful tool for giving your audience 
context, as long as it is used appropriately. In this post, we’re going to 
discuss 3 ways that you can use colour and conditional formatting in column 
charts to direct your audience’s towards the data points that matter.]]></description><content:encoded><![CDATA[<p class="">One thing that I find many people don’t pay enough attention to is the idea that numbers on a chart don’t mean anything unless they’re presented in context. If you show a measure that has doubled since last month, that may be very good news if the measure reports company profits, but very bad new if it represents workplace injuries. And besides that, if workplace injuries doubled from 2 to 4 this month for a small business with 10 staff, that’s much more concerning than it would be for a large company with 10,000 staff. So if you don’t provide context for the audience of your data visualisations, how do they know whether what they’re seeing is a good thing or a bad thing? In this post, we’re going to discuss 3 ways that you can use colour and conditional formatting in column charts to direct your audience’s towards the data points that matter.  </p><h3>Standard Conditional Formatting for Column Charts</h3><p class="">As with other visuals, you can use conditional formatting in your column charts to encode colour based on column height. This technique will draw attention towards the higher values in your chart. You can easily enable this feature from the Data Colors section of the Format pane. Let’s see how we can apply conditional formatting to a chart of sales performance. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting" data-image-dimensions="980x676" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting?format=1000w" width="980" height="676" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605997204108-EPPFZ4MQR7WLL00JW4I1/Setting+up+standard+Conditional+Formatting?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">For this chart, we’ve format based on a colour scale using the sum of our sales as below. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting" data-image-dimensions="407x404" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting?format=1000w" width="407" height="404" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605857983121-CMD1ZCOYYTXU169FZ35O/Standard+Conditional+Formatting?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">While the chart does look visually appealing at first, there are a number of reasons that I try to avoid using this feature…</p><ul data-rte-list="default"><li><p class="">Discrete colour steps are easier to tell apart than the continuous colour gradient we’ve used. Cognitive psychology tells us that people struggle to accurately tell the difference between more than <a href="https://medium.com/stylumia/the-magical-number-7-2-how-to-grab-attention-8864e0f5592b">about 7 different&nbsp;colours at once</a>. </p></li><li><p class="">It’s <a href="http://www.storytellingwithdata.com/blog/2020/2/19/what-is-a-bar-chart">easy to notice a difference in height between two columns</a>, but harder to tell two different colour hues apart. You can see this for yourself if you look at the last 3 columns of the chart - the heights clearly tell them apart, but could you work out which of them has the highest value based on colour alone?</p></li><li><p class="">Relying on the colour gradient alone can also be deceptive. Looking at the column for March, it has almost the same height as the column for January. However, March looks darker despite being the (slightly) lower value because it has light colours on either side to contrast against. Meanwhile our brains compare January to the darkest column in December, and trick us into thinking January is lighter than it actually is. </p></li></ul><p class="">Given these issues, there are a few alternate techniques you can use that I find more effective for directing your audiences attention towards high values.</p><h3>Highlighting the Top N values</h3><p class="">With a bit of DAX, we can define a measure to help us conditionally format our chart to emphasize the highest values. To build such a measure, we must first consider how our sales performance data is structured. In this example, we have a table called <em>Fact Sales Snapshot</em>, which shows how each retail store for a company based in Melbourne have performed in each month of the 2019-2020 financial year. </p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot" data-image-dimensions="218x354" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot?format=1000w" width="218" height="354" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605852676654-8OTEYH5N29L5Q243OL6P/Fact+Sales+Snapshot?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">We’ve also got a date dimension in our model, related to our sales data on the Month field. </p><p class="">To give us some flexibility here, we’re going to define a What If parameter so we can vary how many values to highlight. Let’s call this parameter <em>Top N</em>, allowing it to vary between 1 and 12. I’ve also renamed the created measure from it’s default name of <em>Top N Value</em> to simply call it <em>N</em>. </p><p class="">Now we’ll create a measure which will identify whether a given column is within our top N sales months. To create this measure, we need to do three things…</p><ol data-rte-list="default"><li><p class="">Create a virtual table containing the data presented in our chart</p></li><li><p class="">Filter that table to the top N sales months</p></li><li><p class="">Check if the month currently selected in our column chart is within those top N sales months</p></li></ol><p class="">Our measure that does all of this is defined below.</p>


  


  




  
    <font face="Consolas">Conditional&nbsp;Formatting&nbsp;Top&nbsp;N&nbsp;Values&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">StorePerformance</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUMMARIZE</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">ALL</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'&nbsp;<span class="Parenthesis">)</span>,&nbsp;</span><span class="Comment">//&nbsp;Group&nbsp;our&nbsp;snapshot&nbsp;table...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'Dim&nbsp;Date'[Date],&nbsp;</span><span class="Comment">//&nbsp;By&nbsp;date&nbsp;(or&nbsp;rather&nbsp;by&nbsp;month&nbsp;since&nbsp;we&nbsp;only&nbsp;have&nbsp;months&nbsp;in&nbsp;our&nbsp;fact&nbsp;table)...</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="StringLiteral">"Sales"</span>,&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Sales]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;And&nbsp;return&nbsp;total&nbsp;months&nbsp;sales</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">TopValues</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">TOPN</span><span class="Parenthesis">&nbsp;(</span>&nbsp;[N],&nbsp;<span class="Variable">StorePerformance</span>,&nbsp;[Sales],&nbsp;<span class="Keyword">DESC</span>&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Filter&nbsp;to&nbsp;months&nbsp;with&nbsp;top&nbsp;N&nbsp;sales</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">TopMonths</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTCOLUMNS</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Variable">TopValues</span>,&nbsp;<span class="StringLiteral">"Month"</span>,&nbsp;'Dim&nbsp;Date'[Date]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Make&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;top&nbsp;N&nbsp;months</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">CurrentMonth</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Dim&nbsp;Date'[Date]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Currently&nbsp;selected&nbsp;column&nbsp;in&nbsp;chart</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Variable">CurrentMonth</span>&nbsp;<span class="Keyword">IN</span>&nbsp;<span class="Variable">TopMonths</span>,&nbsp;<span class="Number">1</span>,&nbsp;<span class="Number">0</span>&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Flag&nbsp;if&nbsp;current&nbsp;column&nbsp;is&nbsp;one&nbsp;of&nbsp;our&nbsp;top&nbsp;N&nbsp;months</span><br></font>
  


  
  <p class="">Finally, we can use this measure to define conditional formatting for our column chart. This time around, we’ll format based on rules defined by the values of our new measure…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values" data-image-dimensions="984x685" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values?format=1000w" width="984" height="685" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859005288-B1R9W7KNLZBEOD7AT3OB/Setting+up+Conditional+Formatting+of+Top+N+values?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">And now we will have our top N months highlighted in our chart! We can even vary our What If parameter and see the highlighting update in real time…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns" data-image-dimensions="367x475" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns?format=1000w" width="367" height="475" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859407698-XKNEQZ99WZO8X6MAEP2X/Changing+the+number+of+highlighted+columns?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">In some situations, this approach is more effective than standard conditional formatting, since the bolder colours draw attention more definitively than a colour gradient. While it can be very effective when the ranking of columns is important, it isn’t always ideal when values are very similar. For example, if you were highlighting the top 4 sales months above, you wouldn’t pay much attention to the October column as the month with the 5th most sales, even though it has almost the same sales as March, having the 4th highest sales.</p><h3>Highlighting values above a threshold</h3><p class="">An alternate way to highlight vales that doesn’t have this shortcoming is to highlight values above a particular threshold. This is most effective when you have targets that you need to quickly know when you’re operating above or below them. </p><p class="">To demonstrate this approach, we’re going to define another What If parameter, this time called Target. We’ll give it a range between $0 and $4 million, in steps of $10,000. Now we could bring the measure for this parameter into our chart as a line, but let’s see what happens when we do…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values" data-image-dimensions="439x414" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values?format=1000w" width="439" height="414" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859822595-WBEN8HK8R05OVQSGDY55/Target+over+all+date+values?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">Since our What If measure returns a value even for months when there are no sales, it has thrown off our chart axis. To correct this, we can redefine the measure to only return the target value for months with sales.</p>


  


  




  
    <font face="Consolas">Target&nbsp;Value&nbsp;=<br><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Sales]&nbsp;<span class="Parenthesis">)</span>&nbsp;&lt;&gt;&nbsp;<span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>,&nbsp;<span class="Comment">//&nbsp;If&nbsp;date&nbsp;has&nbsp;sales&nbsp;marked&nbsp;against&nbsp;it</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Target&nbsp;Value'[Target]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="Comment">//&nbsp;Return&nbsp;the&nbsp;parameter&nbsp;selection</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">BLANK</span><span class="Parenthesis">&nbsp;(</span><span class="Parenthesis">)</span>&nbsp;<span class="Comment">//&nbsp;Else&nbsp;return&nbsp;blank</span><br><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">And now we get an updated chart…</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only" data-image-dimensions="433x419" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only?format=1000w" width="433" height="419" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605859923575-LMQQBCV56WXF1HKO3JBW/Target+over+dates+with+sales+only?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">With our updated chart, we can define a measure to flag the columns above our threshold, and set the conditional formatting as we did earlier. </p>


  


  




  
    <font face="Consolas">Conditional&nbsp;Formatting&nbsp;for&nbsp;Above&nbsp;Target&nbsp;=<br><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Fact&nbsp;Sales&nbsp;Snapshot'[Sales]&nbsp;<span class="Parenthesis">)</span>&nbsp;&gt;&nbsp;[Target&nbsp;Value],&nbsp;<span class="Number">1</span>,&nbsp;<span class="Number">0</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <p class="">And now our chart will update the highlighted values, depending on where the threshold is set.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold" data-image-dimensions="358x482" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold?format=1000w" width="358" height="482" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605860284957-4TOCXWHLCO9GY2F3R8ET/Highlighting+values+above+a+threshold?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">If you prefer, you can remove the target line from the visual and the conditional formatting logic will still work all the same. </p><h3>Summary</h3><p class="">Depending on the context that your data exists in, there are multiple approaches you can use to highlight the data that matters. Besides the standard conditional formatting options for charts, you can emphasise the highest ranking values, or highlight any columns above a particular threshold. When you pick the right approach for highlighting values for your situation, then that can make it a lot easier for your audience to work out whether or not they need to take action based on your visual. </p><h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/Highlighting-values-with-conditional-formatting.pbix">Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />]]></content:encoded><media:content type="image/gif" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1606002320527-OZGPPPCCLUVUDGBGVPYS/Top+3+conditional+formatting+options.gif?format=1500w" medium="image" isDefault="true" width="379" height="293"><media:title type="plain">Top 3 ways to direct attention with   conditional formatting for column charts in Power BI</media:title></media:content></item><item><title>Slicing based on OR and XOR conditions in Power BI</title><dc:creator>Sam Fischer</dc:creator><pubDate>Thu, 12 Nov 2020 22:06:00 +0000</pubDate><link>https://apexinsights.net/blog/or-xor-slicing</link><guid isPermaLink="false">5fb2fda6f519ed622e8f5565:5fb2fdf24b72177acb14d40c:5fb352d27f660d78badee98c</guid><description><![CDATA[Slicers on a report page in Power BI are an effective way to slice and dice 
your data under different conditions. But one situation that can be 
challenging to implement effectively is being able to apply multiple 
slicers, and show the rows that satisfy one condition or the other, not 
just the rows that satisfy both. In this blog post, I'll show you a simple 
implementation to allow you to address this scenario.]]></description><content:encoded><![CDATA[<p class="">Slicers on a report page in Power BI are an effective way to slice and dice your data under different conditions. But one situation that can be challenging to implement effectively is being able to apply multiple slicers, and show the rows that satisfy one condition <em>or</em> the other, not just the rows that satisfy both. In this blog post, I'll show you a simple implementation to allow you to address this scenario.</p><h3>How do slicers usually work?&nbsp;</h3><p class="">The way that slicers work by default is based on filtering data using a logical AND condition. Whenever a visual is generated, the calculation engine in Power BI will consider any filters or slicers applied to the visual, and use those conditions to filter the data model. It will then apply filter context modifiers from any defined CALCULATE statements, and finally it will perform the DAX operation in the measure based on whatever data is remaining after this filtering.&nbsp;</p><p class="">The default filtering behaviour follows an intersect set operation, where it only considers the rows that satisfy <em>all</em> filter conditions at once. Filtering in this manner works well for many situations, but if instead we want to filter based on rows that satisfy one condition <em>or</em> another (i.e. a union operation), then we need to use an alternative approach. I've seen other blogs go through different approaches to achieve this, but they often involve writing complicated measures that can be hard to interpret. Here, I'll take you through a simple implementation of applying this OR logic, and then we'll generalise this approach to XOR conditions (where we only include rows that satisfy one slicer condition or the other, but not both at once) and to aggregated data.&nbsp;</p><h3>Our scenario</h3><p class="">The situation we'll consider comes from a Power BI question that I recently answered online. In this scenario, we have a simple table in our model that looks like the following...</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png" data-image-dimensions="157x456" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png?format=1000w" width="157" height="456" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605588098831-7GI0KTJ7N9TNFDA6FHUO/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">For anyone following along at home, the M code to define the table is also below:</p>


  


  




  
    <span class="constant keyword">let</span><br>&nbsp;&nbsp;<span class="identifier">Source</span>&nbsp;<span class="constant operator operator-equality">=</span>&nbsp;<span class="identifier">Table</span><span class="operator operator-dot">.</span><span class="identifier method-call">FromColumns</span><span class="constant bracket bracket-0">(</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-1">{</span><span class="identifier">List</span><span class="operator operator-dot">.</span><span class="identifier method-call">Generate</span><span class="constant bracket bracket-2">(</span><span class="constant bracket bracket-0">(</span><span class="constant bracket bracket-0">)</span>&nbsp;<span class="constant operator">=&gt;</span>&nbsp;<span class="literal number">0</span><span class="constant">,</span>&nbsp;<span class="constant keyword">each</span>&nbsp;<span class="identifier">_</span>&nbsp;<span class="constant operator operator-relational">&lt;</span>&nbsp;<span class="literal number">20</span><span class="constant">,</span>&nbsp;<span class="constant keyword">each</span>&nbsp;<span class="identifier">_</span>&nbsp;<span class="constant operator operator-arithmetic">+</span>&nbsp;<span class="literal number">1</span><span class="constant bracket bracket-2">)</span><span class="constant">,</span>&nbsp;<span class="identifier">Text</span><span class="operator operator-dot">.</span><span class="identifier method-call">ToList</span><span class="constant bracket bracket-2">(</span><span class="literal string">&quot;ABCDEFGHIJKLMNOPQRST&quot;</span><span class="constant bracket bracket-2">)</span><span class="constant bracket bracket-1">}</span><span class="constant">,</span>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-1">{</span><span class="literal string">&quot;Numbers&quot;</span><span class="constant">,</span>&nbsp;<span class="literal string">&quot;Letters&quot;</span><span class="constant bracket bracket-1">}</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="constant bracket bracket-0">)</span><br><span class="constant keyword">in</span><br>&nbsp;&nbsp;<span class="identifier">Source</span>
  


  
  <p class="">Our aim is to have a table visual for these data on our report page, and we want to slice the data based on whether the row contains one of the numbers <em>or</em> one of the letters. The way that one would typically add these slicers is to drag the fields onto the canvas as slicers, and use them to filter the visual. However, this will follow the default filtering behaviour of showing rows satisfying both conditions simultaneously, so we will observe something like this...</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif" data-image-dimensions="371x368" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif?format=1000w" width="371" height="368" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605591958958-UHIJLD09NRKETWD17C7P/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <p class="">In this situation, when we select options on both slicers, we only see the number-letter combinations that satisfy both slicer conditions (i.e. the letter I and number 8). And whenever we make a selection on a slicer, not only does the data table get filtered but the other slicer gets filtered as well. There are straightforward solutions to this issue, such as disabling the interactions between slicers or building the model out as a star schema. But even if we went down one of those paths, our table would still get filtered based on that pesky AND condition.</p><h3>Adding an OR filter</h3><p class="">To achieve OR filtering instead, we have to play a few tricks using some DAX measures and calculated tables. To start with, we'll need to generate two disconnected tables in DAX, which contain all the unique letters and numbers in our main data table...</p>


  


  




  
    <font face="Consolas">Letters = <span class="Keyword">VALUES</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Letters]&nbsp;<span class="Parenthesis">)</span><br>
Numbers&nbsp;= <span class="Keyword">VALUES</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Numbers]&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <p class="">Note that you can do this in Power Query if you prefer, but it doesn't make a significant difference here.</p><p class="">These new tables will ultimately be used as our slicers, but in this scenario it is important to ensure that these new tables <em>do not</em> have a relationship with the main data table. Conventional filtering would require a relationship between the tables for filters to propagate between them, but remember that we are not doing conventional filtering.&nbsp;</p><p class="">If we were to drag these new fields onto the canvas as slicers at this stage, we would find that there is no interaction between our slicers and the data table. This should make sense, since there is no relationship between them. In order to apply our desired OR behaviour, we must now write a custom measure as follows:</p>


  


  




  
    <font face="Consolas">OR&nbsp;Filter&nbsp;=<br><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">OR</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Letters]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Keyword">IN</span>&nbsp;<span class="Keyword">ALLSELECTED</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Letters[Letters]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;Checks&nbsp;if&nbsp;current&nbsp;letter&nbsp;is&nbsp;in&nbsp;slicer&nbsp;selection</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Numbers]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Keyword">IN</span>&nbsp;<span class="Keyword">ALLSELECTED</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Numbers[Numbers]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Comment"><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Comment">//&nbsp;As&nbsp;above&nbsp;for&nbsp;current&nbsp;number</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span>,<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">1</span>,<span class="indent4">&nbsp;</span><span class="Comment">//&nbsp;Return&nbsp;1&nbsp;if&nbsp;value&nbsp;is&nbsp;selected&nbsp;in&nbsp;one&nbsp;or&nbsp;both&nbsp;of&nbsp;the&nbsp;slicers</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">0</span>&nbsp;<span class="Comment">&nbsp;//&nbsp;Else&nbsp;return&nbsp;0</span><br><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">Once we have this measure, we need to drag it into the visual-level filters for out table visual, and apply the condition of only including rows where the filter equals 1 (i.e. those that satisfy the OR condition). It is important for this to be defined as a measure and not as a calculated column, since the slicers will be changed dynamically and we need our OR logic to also change dynamically. With this filter condition applied, our table visual will now only show rows that follow our desired OR condition.</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif" data-image-dimensions="367x397" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif?format=1000w" width="367" height="397" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593446512-YOTDJW36ZBEXPO6IB7TA/OR+slicer.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Extending this to XOR conditions</h3><p class="">If you instead wanted to apply an XOR (or exclusive OR) operation, then you can tweak the measure above to satisfy this. We'll just need to add a clause that excludes the rows that satisfy both filter conditions at once. For readability, we'll use variables for the logical filtering conditions in this instance.</p>


  


  




  
    <font face="Consolas">XOR&nbsp;Filter&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">One_or_both_slicers</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">OR</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Letters]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Keyword">IN</span>&nbsp;<span class="Keyword">ALLSELECTED</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Letters[Letters]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Numbers]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Keyword">IN</span>&nbsp;<span class="Keyword">ALLSELECTED</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Numbers[Numbers]&nbsp;<span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">Both_slicers</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">AND</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Letters]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Keyword">IN</span>&nbsp;<span class="Keyword">ALLSELECTED</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Letters[Letters]&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">SELECTEDVALUE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Numbers]&nbsp;<span class="Parenthesis">)</span>&nbsp;<span class="Keyword">IN</span>&nbsp;<span class="Keyword">ALLSELECTED</span><span class="Parenthesis">&nbsp;(</span>&nbsp;Numbers[Numbers]&nbsp;<span class="Parenthesis">)</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">IF</span><span class="Parenthesis">&nbsp;(</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Variable">One_or_both_slicers</span>&nbsp;&amp;&amp;&nbsp;<span class="Keyword">NOT</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Variable">Both_slicers</span>&nbsp;<span class="Parenthesis">)</span>,<br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">1</span>,&nbsp;<span class="Comment">//&nbsp;Return&nbsp;1&nbsp;if&nbsp;value&nbsp;is&nbsp;selected&nbsp;in&nbsp;only&nbsp;one&nbsp;of&nbsp;the&nbsp;slicers</span><br><span class="indent8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Number">0</span>&nbsp;<span class="Comment">&nbsp;//&nbsp;Else&nbsp;return&nbsp;0</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Parenthesis">)</span><br></font>
  


  
  <p class="">Now we can apply this measure as a visual-level filter as before to get the following...</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif" data-image-dimensions="508x397" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif?format=1000w" width="508" height="397" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605593856628-I2HO6FL3C525HJAHTMC0/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Generalising to aggregated data</h3><p class="">This technique works fine when your slicers are at the same grain as the data you are hoping to display. But what about when you want to apply an OR condition to aggregated data? For example, you may want to know the total sales of products that are either sold in Australia or coloured blue. Or in our example, perhaps we want to know the sum of the numbers in rows that fulfil the OR condition, or the first letter alphabetically that fulfils the condition.&nbsp;</p><p class="">The approaches we used above won't work out-of-the-box if we tried to apply it to a visual with aggregated data. This is because the measures we wrote earlier only work when they are evaluated against a single row of the data table, as indicated by the presence of the SELECTEDVALUE statements in their definitions. To apply our logic more generally, we have to dynamically iterate through the table row by row within a single measure evaluation, and then calculate our final output based on the resulting filtered table.</p><p class="">The FILTER function can be used as our iterator here to return a table with only the rows that fulfil our OR condition. Once we have our table, we can use CALCULATE to determine the aggregated value, considering only the rows in the filtered table. Here is how this implementation looks if we calculate the sum of all numbers from rows fulfilling our OR condition...</p>


  


  




  
    <font face="Consolas">Sum&nbsp;under&nbsp;OR&nbsp;condition&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">OR_Rows</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table',&nbsp;[OR&nbsp;Filter]&nbsp;=&nbsp;<span class="Number">1</span>&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">SUM</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Numbers]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="Variable">OR_Rows</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <p class="">We can define a similar measure to determine the first letter alphabetically...</p>


  


  




  
    <font face="Consolas">First&nbsp;Letter&nbsp;under&nbsp;OR&nbsp;condition&nbsp;=<br><span class="Keyword">VAR</span>&nbsp;<span class="Variable">OR_Rows</span>&nbsp;=<br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">FILTER</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table',&nbsp;[OR&nbsp;Filter]&nbsp;=&nbsp;<span class="Number">1</span>&nbsp;<span class="Parenthesis">)</span><br><span class="Keyword">RETURN</span><br><span class="indent4">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="Keyword">CALCULATE</span><span class="Parenthesis">&nbsp;(</span>&nbsp;<span class="Keyword">MIN</span><span class="Parenthesis">&nbsp;(</span>&nbsp;'Data&nbsp;Table'[Letters]&nbsp;<span class="Parenthesis">)</span>,&nbsp;<span class="Variable">OR_Rows</span>&nbsp;<span class="Parenthesis">)</span><br></font>
  


  
  <p class="">And of course, we could similarly use the XOR condition instead if it was what the situation demanded. Here's what these implementations end up looking like...</p>


  


  














































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif" data-image-dimensions="732x395" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif?format=1000w" width="732" height="395" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605594078073-39JDPNAVPTVIQ0IG115L/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
  <h3>Summary</h3><p class="">While filtering based on AND conditions is the default in Power BI, you can still easily achieve filtering based on OR and XOR conditions using a few calculated tables, measures and a bit of DAX know-how. Relationships and star schemas are of course still best practice to follow in general, but in specific scenarios you can achieve more by intentionally straying outside of these guidelines.</p><h3>Try it out for yourself!</h3><p class="">Download the <a href="https://apexinsights.net/s/OR-and-XOR-conditions.pbix">sample Power BI report file I used in this post</a> to play around and build your own understanding hands-on.</p>


  


  



<hr />]]></content:encoded><media:content type="image/gif" url="https://images.squarespace-cdn.com/content/v1/5fb2fda6f519ed622e8f5565/1605595977033-D3TUWVWCVYSOL5DZSA8X/OR+cropped.gif?format=1500w" medium="image" isDefault="true" width="367" height="270"><media:title type="plain">Slicing based on OR and XOR conditions in Power BI</media:title></media:content></item></channel></rss>