在上一篇文章中介绍了如何实现同时展示所选年份的年汇总与季度明细的柱形图,但这需要切片器选择多个年份,并且所选年份下的所有季度等子类别也都会展示出来,有时候可能并不是想要的效果。
因此本篇文章将介绍年汇总与明细柱形图的另一种展示效果。
问题描述
绘制同时展示所选月份的最近三年的年汇总及最后一年的月明细的柱形图,截止至所选月份,效果如下图所示:
本案例所用的初始数据是使用DAX函数生成的计算表,如下图所示:
计算表的表达式如下:
Fact = ADDCOLUMNS(CALENDAR(dt"2016-1-1",dt"2022-1-1"),"Value",RANDBETWEEN(1,100))
解题要点
由于需要在柱形图的单个X轴字段中同时展示年份与月份,因此必须先构造一个包含所有年份和月份的字段来作为辅助表,然后剩下的常规套路就是使用度量值来控制哪些柱子应该展示。
最后,还需要以正确的顺序来显示年份与月份,因此还需要给辅助表再加一个排序字段,以便设置按列排序。
解决方案
首先,使用以下计算表表达式创建一个标准的日期表:
Calendar =
var startdate=DATE(YEAR(MIN('Fact'[Date])),1,1)
var enddate=DATE(YEAR(MAX('Fact'[Date])),12,31)
RETURN
ADDCOLUMNS(
CALENDAR(startdate,enddate),
"Year Number",YEAR([Date]),
"Year",FORMAT([Date],"yyyy"),
"Month Number",MONTH([Date]),
"Month",FORMAT([Date],"mmmm"),
"Quarter Number",ROUNDUP(MONTH([Date])/3,0),
"Quarter","Q"&ROUNDUP(MONTH([Date])/3,0),
"WeekNum",WEEKNUM([Date],2),
"WeekDay Number",WEEKDAY([Date],2),
"WeekDay",SWITCH(WEEKDAY([Date],2),1,"周一",2,"周二",3,"周三",4,"周四" ,5,"周五",6,"周六" ,7,"周日"),
"YearMonth Number",YEAR([Date])*100+MONTH([Date]),
"YearMonth",FORMAT([Date],"yyyy.mm"),
"YearQuarter Number",YEAR([Date])*10+ROUNDUP(MONTH([Date])/3,0),
"YearQuarter",YEAR([Date])&"Q"&ROUNDUP(MONTH([Date])/3,0)
)
然后再使用以下计算表表达式来创建用于柱形图X轴的辅助表:
Calendar_Show =
SELECTCOLUMNS(
UNION(
ADDCOLUMNS(ALL('Calendar'[Year Number],'Calendar'[Year]),"Type","Year"),
ADDCOLUMNS(ALL('Calendar'[YearMonth Number],'Calendar'[YearMonth]),"Type","YearMonth")
),
"Index",'Calendar'[Year Number],
"Item",'Calendar'[Year],
"Type",[Type]
)
该辅助表的表结构如下图所示:
然后将日期表与事实表连接关系,辅助表则不需要连接任何关系,最终的模型关系如下图所示:
然后,创建如下度量值:
度量值 =
VAR N = 3
VAR DatePeriods = DATESBETWEEN('Calendar'[Date],STARTOFYEAR(DATEADD('Calendar'[Date],-N+1,YEAR)),MAX('Calendar'[Date]))
VAR SelectedYear = MAX('Calendar'[Year Number])
VAR CurIndex = MAX('Calendar_Show'[Index])
VAR CurType = MAX('Calendar_Show'[Type])
RETURN
IF(NOT(CurType="YearMonth" && LEFT(CurIndex,4)*1<>SelectedYear),
IF(CurType="Year",
CALCULATE(SUM('Fact'[Value]),DatePeriods,'Calendar'[Year Number]=CurIndex),
CALCULATE(SUM('Fact'[Value]),DatePeriods,'Calendar'[YearMonth Number]=CurIndex)
)
)
然后创建一个切片器和一个柱形图,切片器所用字段为日期表的YearMonth字段,柱形图的X轴为辅助表的Item字段,最后再将上面的度量值作为柱形图的Y轴即可,如下图所示:
下面简单介绍下该度量值的计算逻辑:
首先获取截止至切片器所选月份最近三年的日期范围,并将其作为其中一个筛选器,目的是为了限制计算范围。
然后再对柱形图X轴的字段类型进行分类处理,添加另一个年份或月份的筛选器,然后两个筛选器相交即可让最近三年范围内的柱子计算出对应结果。如下图所示:
然后从上面的图也可以看到,的确是显示了截止至切片器所选月份的最近三年范围内的柱子,但是过去两年的月份也显示出来了,而这不是我们想要的。
因此还需要再添加一个判断条件来过滤过去两年的月份柱子,找出这些不需要的柱子的逻辑为:字段类型为月份并且对应年份不等于切片器所选月份的年份,然后相应的取反即可找出应显示的柱子,也就是上图中的注释部分。
总结
以上方法仅供参考,若有更优雅的解决方案,欢迎留言讨论,或者加入我们的技术交流群,一起享受这种思维碰撞的快乐吧!
PBI/DAX技术交流群(QQ):344353627