I had a colleague approach me at work with an interesting problem. He had a Power BI report using the Gantt chart custom visual however when he used a date slicer to select a date range it was only showing events which started on that date range and he wanted to see any events that were in progress for that date range.
I figured out a way to get this working and I thought it might be helpful to not just show the solution, but also to walk through the process I used to develop it. Let’s start by looking at an example of the issue he was dealing with.
Given the following data, what he wanted was to filter the data for dates between Mar-20 to Apr-10 so that the Gantt chart would show the section in Yellow below:

But he was getting output like the following, where it was only showing the bottom 3 tasks from the image above with a start date between Mar-20 and Apr-10. It was not showing tasks which were already in progress like the first two (Division… and Functional…).

To figure out what options we had to change this default behaviour I turned on the Performance Profiler in Power BI Desktop (I could also have used the All Queries trace in DAX Studio). This captured the following query for the Gantt visual:
// DAX Query
DEFINE VAR __DS0FilterTable =
FILTER(
KEEPFILTERS(VALUES('Table1'[Start Date])),
AND('Table1'[Star Date] >= DATE(2016, 3, 20), 'Table1'[Start Date] < DATE(2016, 4, 11))
)
EVALUATE
TOPN(
1002,
SUMMARIZECOLUMNS(
'Table1'[Task Name],
'Table1'[Task ID],
'Table1'[Start Date],
'Table1'[Resource],
__DS0FilterTable,
"MinEnd_Date", CALCULATE(MIN('Table1'[End Date]))
),
'Table1'[Task ID],
1,
'Table1'[Task Name],
1,
'Table1'[Start],
1,
'Table1'[Resource],
1
)
ORDER BY
'Table1'[Task ID], 'Table1'[Task Name], 'Table1'[Start], 'Table1'[Resource]
There are two important parts to notice from the above query.
First is that the filter is currently explicitly filtering for start dates based on the values selected in the slicer. Obviously this is going to cause an issue as events that are already in-progress will have a start date before the earliest date in the slicer.
To fix this we need to create a separate date table that does not have a relationship to our main fact table. In the demo file I simply created a calculated table using Date Slicer = CALENDARAUTO()
but you can use whatever method you like to create this table.
If we replace the 'Table1'[Start Date]
field used in the slicer that “fixes” our issue of start dates earlier than those in the slicer being filtered out, but now our slicer is not filtering the data at all, but all is not lost, we will fix that next.
The second interesting thing that I noticed from the captured query is that [Start Date]
is being used as a grouping column in the SUMMARIZECOLUMNS()
function, but [End Date]
is getting the earliest end using CALCULATE(MIN('Table1'[End Date]))
. What is happening is that the Gantt chart is creating an implied measure when we pass in the [End Date]
column. So instead of letting the Gantt chart create an implied measure we can create our own measure and use that instead.
Below is the measure I developed
Gantt End Date =
VAR _maxDate =
MAX ( 'Date Slicer'[Date] )
VAR _minDate =
MIN ( 'Date Slicer'[Date] )
VAR _tasks = VALUES(Table1[Task ID])
RETURN
MAXX (
CALCULATETABLE (
SUMMARIZE( Table1, Table1[Start Date], Table1[End Date] ),
Table1[Start Date] <= _maxDate,
Table1[End Date] >= _minDate,
_tasks
),
Table1[End Date]
)
This gives us the following

If you look at the output of this measure in a table all it does is the following:

Note that I’ve force the display of all rows by including a simple row count measure. This lets us see that the [Gantt End Date]
only returns values where the End date is after the start of the selected date range and the start is before the end of the selected date range, otherwise it returns a blank and SUMMARIZECOLUMNS
does not return rows where all the measures return blank.
If you want to look at the Power BI file I used in the screenshots for this post you can download it from here
March 3, 2020 at 7:46 am
Genius! Thanks for sharing.
March 3, 2020 at 9:39 am
Hi!
Nice trick.
There is also another way that solves the problem. In End Date well of Gantt Chart place Table1[End Date] instead of you measure.
Then add the following measure as a filter for this visual. (I slightly modified your measure)
_Include =
VAR _maxDate =
MAX ( ‘Date Slicer'[Date] )
VAR _minDate =
MIN ( ‘Date Slicer'[Date] )
RETURN
If(
ISEMPTY(
CALCULATETABLE (
SUMMARIZE( Table1; Table1[Start Date]; Table1[End Date] );
Table1[Start Date] = _minDate
)
);
BLANK();
1
)
Apply “1” as a filter. The result will be the same, at least as it seems at a first glance 🙂
March 3, 2020 at 10:01 am
Hi Sergy, I think there might be a bug in your CALCULATETABLE() filter where you have
[Start Date] = _minDate
. But I can see how this approach would work – It’s logically a similar approach to my one. However I would be wary of the SUMMARIZETABLE call, it’s difficult to measure in a small “toy” model like the one in this article, but that could introduce a materialization that might cause performance issues on a larger model.March 3, 2020 at 10:19 am
I see that the code is incorrect. Something went wrong during pasting and I didn’t spot that. I’ll try one more time 🙂
CALCULATETABLE (
SUMMARIZE( Table1; Table1[Start Date]; Table1[End Date] );
Table1[Start Date] = _minDate
)
March 3, 2020 at 10:21 am
Don’t know what happens. My comment was distorted again. Sorry.
March 3, 2020 at 10:56 am
Very strange, I’m assuming that you want similar filter to the one in my measure:
Table1[Start Date] <= _maxDate, Table1[End Date] >= _minDate,
Actually I think the following code is probably better than the version in my article above as it gets rid of the SUMMARIZE:
Gantt End Date =
VAR _maxDate =
MAX ( 'Date Slicer'[Date] )
VAR _minDate =
MIN ( 'Date Slicer'[Date] )
RETURN
CALCULATE(
MAX (Table1[End Date]),
Table1[Start Date] <= _maxDate, Table1[End Date] >= _minDate
)
June 10, 2020 at 7:40 pm
Thanks Darren – really useful.
I didn’t realise there was such a useful Gantt chart visual available either . Will definitely be using that!
September 30, 2020 at 11:08 pm
Hi Darren,
This is useful but is there a way to just show snap shot between 2 dates.
In the first image above you said that you just want the Gant chart to show between Mar 20 to Apr 10. But your end result shows Gant chart that is from March 15 to Apr 12 (this is because first two activities start on March 15 and last activity end on Apr 12).
I don’t care if they start before Mar 20 or end after Apr 10. I just want to show all activities that are on going or completed between these 2 dates.
Any help in this are will be appricated.
Thanks,
Rashid
October 5, 2020 at 1:49 pm
Hi Rashid, I’m sorry, but I don’t understand how your requirement for ” I just want to show all activities that are on going or completed between these 2 dates.” is different to what I’m doing in this blog post. Can you provide some sample data, with an activity , start date and end date and then explain which ones you would expect to see for a given date filter? Or even use my example file and give me an example date range where you require different filtering to occur.
October 22, 2021 at 7:30 am
Darren – great solution for End, to Rashid’s question (I have the same one) – in your dataset, ex: Scope runs from Feb 2-Feb 6, so if you set the slicer to start at Feb-4, it will correctly keep Scope on the visual…however, the overall start date for the visual will remain Feb 2, because that’s the earliest start date for an active task being shown. What I suspect Rashid is also looking for is any way to trick the visual into reflecting the Start Date from the slicer, in effect to create a snapshot of just the data the falls immediately in the range specified, bounded by those dates. Development may be easier to replicate with because it’s a longer runway – if I set the range on your file to start at 4/1, the visual will remain starting 3/15.
October 25, 2021 at 8:13 am
Unfortunately, I don’t believe there is currently any way to achieve what you are after. To take the “Development” example the 3/15 date is a column value. To cut this off at 4/1 we would need some way of defining a query scoped calculated column in Power BI and that does not exist at the moment. I don’t think it’s possible to truncate the values in the visual itself since it is not directly aware of the date slicer, it only response to changes in the data set that Power BI feeds it. Maybe if someone were to build a custom Gantt visual that had a special “Start Date” field well this would be possible. But I’m not aware of anything like this.
January 19, 2021 at 8:56 pm
Hi Darren,
This is a very nice way of showing the correct projects. The downside is that the gantt’s granularity does not change anymore.
When the start or enddate of projects is affected by the (time) slicer, the gantt shows the granularity chosen in the slicer (quarter, month, week, …).
However, when a slicer acts upon non-related dates, gantt granularity does not change.
Would you happen to know if there’s a way around this problem?
Kr,
Peter
January 19, 2021 at 10:12 pm
No sorry I don’t actually use the Gantt chart all that much myself, I figured out this technique while helping out a colleague. I’ve never observed the behaviour you describe, I thought the scale had to be set in the chart settings.
December 14, 2022 at 8:40 am
Hello! Thanks for the walk-through. Question: is there any way to roll up the Duration Units to Months? I only see Days, Hours, Minutes, and Seconds. I would like to see the full year in one view without scrolling.
Thanks
January 9, 2023 at 4:18 pm
Yes there is. You can go into the formatting properties of the Gantt visual and change the “Date type” property to “Month”. (I also see Year, Quarter, Month, Week in my example pbix file)