计算组和字段参数打造全动态日期轴
在之前的文章有介绍过怎么打造全动态的日期轴(Power BI动态日期轴方法总结),文章总结了一些常见的实现动态坐标轴的方法,计算表、计算组、字段参数。最近又收到同事的另一个需求,他需要选择MAT的时候,坐标轴上的所有年份都是MAT,但是之前另一拔人的需求是只当年的数据是MAT,历史的还都是完整年。。。再次感叹指标库的重要性,整个公司一定要有统一的指标计算逻辑。
但是,从技术上来说,能不能全都要呢,嗯,当然是可以的,先来看最终效果。
这里设置了很多种类型,
- 当选择MTD时显示最近12个月的数据
- 当选择QTD时显示最近12个季度的数据
- 当选择YTD时,历年为全年数据,当年为YTD
- 当选择ALLYTD时,所有年份均为YTD
- 当选择ALLMAT时,所有年份均为MAT
- 当选择MAT时,历年为全年数据,当年为MAT
字段参数坐标轴
不考虑其它,要实现坐标轴可以年月季切换,我们应该先创建一个字段参数,这里新建了一列名称,是为了解决(Power BI动态日期轴方法总结)中提到的切片器同步的问题。
PTime = {
("Date", NAMEOF('Dates'[Date]), 0, "CUR"),
("YearMonth", NAMEOF('Dates'[YearMonth]), 1, "MTD"),
("YearQuarter", NAMEOF('Dates'[YearQuarter]), 2, "QTD"),
("Year", NAMEOF('Dates'[Year]), 3, "YTD"),
("AllYTD", NAMEOF('Dates'[Year]), 4, "ALLYTD"),
("AllMAT", NAMEOF('Dates'[MATYear]), 5, "ALLMAT"),
("MAT", NAMEOF('Dates'[Year]), 6, "MAT")
}
此外日期表中还新建了一个叫MATYear,这里的判断逻辑也比较简单,比如当年的数据只到7月份,那么所有MAT年的数据应该为前一年的8月到当年的7月,MAT2017为2016.8–2017.7,这样也会有一个问题,首年的数据就不足以为一年MAT年了,比如首年为2016,2016.8–2016.12已被分到MAT2017了,这里为了简单后面处理的时候直接过滤掉了不足一个MAT年的数据。
MatYear =
VAR LastMonth = MONTH( MAX ( 'Dates'[Date] ) )
var MinYear = MIN( 'Dates'[Year] )
return
"MAT" & IF( 'Dates'[Month] > LastMonth, 'Dates'[Year] +1 , 'Dates'[Year] )
为了坐标轴可以按顺序排序,还需要一个排序列
列 =
VAR LastMonth = MONTH( MAX ( 'Dates'[Date] ) )
var MinYear = MIN( 'Dates'[Year] )
return
IF( 'Dates'[Month] > LastMonth, 'Dates'[Year] +1 , 'Dates'[Year] )
计算组指标切换
这里的方法同上篇文章中介绍的一样,新建计算组,包含各个时间智能指标的计算项即可
MTD
var YM = calculate( max('Dates'[YearMonthNum]), REMOVEFILTERS ())
return
if(
max('Dates'[YearMonthNum]) >= YM-11,
CALCULATE ( SELECTEDMEASURE (), DATESMTD ( 'Dates'[Date] ) )
)
QTD
var YQ = calculate( max('Dates'[YearQuarterNum]), REMOVEFILTERS ())
return
if(
max('Dates'[YearQuarterNum]) >= YQ-11,
CALCULATE ( SELECTEDMEASURE (), DATESQTD ( 'Dates'[Date] ) )
)
YTD
CALCULATE ( SELECTEDMEASURE (), DATESYTD ( 'Dates'[Date]) )
ALLYTD
当年数据只到7月,历史数据计算YTD时也只到7月
VAR LM =MONTH( CALCULATE( MAX ( 'Dates'[Date] ),REMOVEFILTERS() ) )
VAR LY = MAX ( 'Dates'[Year] )
VAR Result =
CALCULATE (
SELECTEDMEASURE(),
REMOVEFILTERS ( 'Dates' ),
'Dates'[Month] <= LM,
'Dates'[Year] = LY
)
RETURN
Result
MAT
CALCULATE (
selectedmeasure(),
DATESINPERIOD (
'Dates'[Date],
MAX ( 'Dates'[Date] ),
-1,
year
)
)
ALLMAT
过滤不足一个完整MAT的首年数据
var Y = calculate( min('Dates'[列]), REMOVEFILTERS ())
return
IF( min('Dates'[列]) > Y, selectedmeasure() )
计算组与字段参数同步
为了让选择字段参数中的指标类型时,坐标轴上的范围也会变化,就还需要同步计算组和字段参数。
新建另一个计算组,
var _sel =
maxx(
summarize('PTime', 'PTime'[PTime], 'PTime'[PTime Filed],'PTime'[Value4] ),
[Value4]
)
return
calculate( selectedmeasure(), 'CalTime2'[Name]=_sel )
这样就可以实现一开始看到的效果了。
总结
整个操作下来,会发现其实动态坐标轴的核心不过是控制日期显示的范围,不同的时间指标下,显示不同的日期范围仅此而已。
不过,这里还有一点需要改进的地方是,当选择MAT时,表格里显示的并非是MAT2019的数据,如果要显示为MAT的时间范围就需要再新建一张日期表,然后判断新的日期表中的日期是否在柱状图上的日期范围,这里不再展开。
就像这样