129_Power Pivot&Power BI DAX不同维度动态展示&动态坐标轴
博客:www.jiaopengzi.com
一、背景
某天在和那还是叫我大铁吧 交流关于季度&月度同时展示的问题,感概中国式报表真的需求很微妙。
下面来看看到底是什么。
A、效果图

B、动态效果
[video width="852" height="608" mp4="https://jiaopengzi.com/wp-content/uploads/2020/03/129_2.mp4"][/video]
接下来我们用三种度量的写法来说明。
方法3由那还是叫我大铁吧 提供,我们感谢他。
二、数据源
1、日期表:calendar

因为是日期时间维度的不同展现,都围绕着日期表做文章,所以建立一个合适的日期表很重要。
个人喜欢用pq生成日期表code如下:
let
    date_start=#date(2018, 1, 1),//开始日期
    date_end=#date(2019, 12, 31),//结束日期
    count=Duration.Days(date_end-date_start),//间隔天数
    calendar = #table
        (
        type table
            [
                dates=date
                ,year=Int64.Type
                ,month=Int64.Type
                ,day=Int64.Type
                ,year_m=Int64.Type
                ,quarter=Int64.Type
                ,year_q=Int64.Type
                ,weeknumber=Int64.Type
                ,weekday=Int64.Type
                ,weekus=text
                ,weekcn=text
                ,weekcna=text
                ,M=text
                ,YM=text
                ,Q=text
                ,YQ=text
            ]
        ,List.Transform({0..count},(n)=>
            let d=Date.AddDays(date_start,n) in
                    {
                        d//日期
                        ,Date.Year(d)//年
                        ,Date.Month(d)//月
                        ,Date.Day(d)//天
                        ,Date.Year(d)*100+Date.Month(d)//年月组合
                        ,Date.QuarterOfYear(d)//季度
                        ,Date.Year(d)*100+Date.QuarterOfYear(d)//年季度组合
                        ,Date.WeekOfYear(d,1)//周一开始的一年第几周
                        ,Date.DayOfWeek(d,1)//星期几
                        ,Date.DayOfWeekName(d, "en-US")//星期几英文
                        ,Date.DayOfWeekName(d, "zh-CN")//星期几中文
                        ,Text.End(Date.DayOfWeekName(d, "zh-CN"),1)//星期几简写
                        ,"M"&Date.ToText(d,"MM")
                        ,Date.ToText(d,"Yyy")&"M"&Date.ToText(d,"MM")
                        ,"Q"&Number.ToText(Date.QuarterOfYear(d))
                        ,Date.ToText(d,"Yyy")&"Q"&Number.ToText(Date.QuarterOfYear(d))
                    }
                        )
        )
in
    calendar
2、事实表:data

用pq生成的随机数据(拿到附件后,若数据和文章截图不一样是正常的。)
3、维度表


分别为事实表维度表,以及季度&月度辅助表。
4、关系视图
A、方法1&方法3的关系视图

B、方法2的关系视图

注意:方法2中两条虚线的使用。
三、上DAX
1、基础度量:total
total = SUM(data[value]) 
2、方法1:test0
test0 =
VAR N =MAX ( 'CALENDAR'[MONTH] )
VAR T1 =
    SUMMARIZE (
        FILTER ( ALL ( 'CALENDAR' ), 'CALENDAR'[MONTH] <= N ),
        'CALENDAR'[M],
        'CALENDAR'[Q],
        'CALENDAR'[MONTH],
        'CALENDAR'[QUARTER]
    )
VAR T2 =ADDCOLUMNS ( T1, "@QM", IF( N / 3 <= [QUARTER], [M], [Q] ) )//是否显示整季度关键:"<="
VAR T3 =SUMMARIZE ( T2, [@QM] )
VAR TQ =FILTER ( T3, LEN ( [@QM] ) <= 2 )
VAR TM =FILTER ( T3, LEN ( [@QM] ) > 2 )
VAR I =SUM ( 'aux0'[INDEX] )
RETURN
    SWITCH (
        TRUE ()
       , I >= 1&& I <= 4
	       , CALCULATE (
		            'Measure'[total]//基础度量
		            ,TREATAS ( TQ, 'CALENDAR'[Q] )
		            ,TREATAS ( VALUES ( 'aux0'[QM] ), 'CALENDAR'[Q] )
		            ,ALL ( 'CALENDAR'[M] )
		        )
        ,I >= 5&& I <= 16
	        , CALCULATE (
		            'Measure'[total]//基础度量
		            ,TREATAS ( TM, 'CALENDAR'[M] )
		            ,TREATAS ( VALUES ( 'aux0'[QM] ), 'CALENDAR'[M] )
		            ,ALL ( 'CALENDAR'[M] )
		        )
        ,BLANK ()
    )
3、方法1:test1
test1 =
VAR N =MAX ( 'CALENDAR'[MONTH] )
VAR T1 =
    SUMMARIZE (
        FILTER ( ALL ( 'CALENDAR' ), 'CALENDAR'[MONTH] <= N ),
        'CALENDAR'[M],
        'CALENDAR'[Q],
        'CALENDAR'[MONTH],
        'CALENDAR'[QUARTER]
    )
VAR T2 =ADDCOLUMNS ( T1, "@QM", IF( N / 3 < [QUARTER], [M], [Q] ) )//是否显示整季度关键:"<="
VAR T3 =SUMMARIZE ( T2, [@QM] )
VAR TQ =FILTER ( T3, LEN ( [@QM] ) <= 2 )
VAR TM =FILTER ( T3, LEN ( [@QM] ) > 2 )
VAR I =SUM ( 'aux0'[INDEX] )
RETURN
    SWITCH (
        TRUE ()
       , I >= 1&& I <= 4
	       , CALCULATE (
		            'Measure'[total]//基础度量
		            ,TREATAS ( TQ, 'CALENDAR'[Q] )
		            ,TREATAS ( VALUES ( 'aux0'[QM] ), 'CALENDAR'[Q] )
		            ,ALL ( 'CALENDAR'[M] )
		        )
        ,I >= 5&& I <= 16
	        , CALCULATE (
		            'Measure'[total]//基础度量
		            ,TREATAS ( TM, 'CALENDAR'[M] )
		            ,TREATAS ( VALUES ( 'aux0'[QM] ), 'CALENDAR'[M] )
		            ,ALL ( 'CALENDAR'[M] )
		        )
        ,BLANK ()
    )
4、方法2:test0
test0 =
VAR N =MAX ( 'CALENDAR'[MONTH] )
VAR IQ=MAX('calendar'[quarter])
VAR I =SUM ( 'aux0'[INDEX] )
RETURN
    SWITCH (
        TRUE ()
       , I < IQ
	       , CALCULATE (
		            'Measure'[total]//基础度量
		            ,USERELATIONSHIP('calendar'[Q],'aux0'[QM])
		            ,ALL ( 'CALENDAR'[M] )
		        )
        ,I<=IQ*3+4&& I >(IQ-1)*3+4&&I<=N+4
	        , CALCULATE (
		            'Measure'[total]//基础度量
		            ,USERELATIONSHIP('calendar'[M],'aux0'[QM])
		            ,ALL ( 'CALENDAR'[M] )
		        )
        ,BLANK ()
    )
5、方法2:test1
test1 =
VAR N =MAX ( 'CALENDAR'[MONTH] )
VAR IQ=MAX('calendar'[quarter])
VAR I =SUM ( 'aux0'[INDEX] )
VAR TF=MOD(N,3)
RETURN
    SWITCH (
        TRUE ()
       , I <= IQ && NOT(TF)
	       , CALCULATE (
		            'Measure'[total]//基础度量
		            ,USERELATIONSHIP('calendar'[Q],'aux0'[QM])
		            ,ALL ( 'CALENDAR'[M] )
		        )
        , I < IQ && TF
	       , CALCULATE (
		            'Measure'[total]//基础度量
		            ,USERELATIONSHIP('calendar'[Q],'aux0'[QM])
		            ,ALL ( 'CALENDAR'[M] )
		        )
        ,I<IQ*3+4&& I >(IQ-1)*3+4 && TF
	        , CALCULATE (
		            'Measure'[total]//基础度量
		            ,USERELATIONSHIP('calendar'[M],'aux0'[QM])
		            ,ALL ( 'CALENDAR'[M] )
		        )
        ,BLANK ()
    )
6、方法3:test0
test0 =
VAR FindQ =FIND ( "Q", SELECTEDVALUE ( aux0[QM] ),, 0 ) //是否存在Q
VAR DQ =CALCULATE (MIN ( 'calendar'[Q] ),FILTER ( 'calendar', [Q] = SELECTEDVALUE ( 'calendar'[Q] ) ) ) //当前季度
VAR DM =CALCULATE (MIN ( 'calendar'[M] ),FILTER ( 'calendar', [M] = SELECTEDVALUE ( 'calendar'[M] ) )) //当前月份
VAR DQMinMonth =CALCULATE ( MIN ( 'calendar'[M] ), FILTER ( ALL ( 'calendar' ), [Q] = DQ ) ) //当前季度最小月份
VAR RQ =FILTER ( VALUES ( 'aux0'[QM] ), LEN ( [QM] ) = 2 )//季度
VAR RM =FILTER ( VALUES ( 'aux0'[QM] ), LEN ( [QM] ) > 2 )//月
RETURN
SWITCH (
	TRUE ()
        ,FINDQ > 0&& SELECTEDVALUE ( 'aux0'[QM] ) < DQ
		        , CALCULATE (
		            SUM ( DATA[VALUE] )
		            ,TREATAS ( RQ, 'calendar'[Q] )
		            ,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[Q] )
		            ,ALL ( 'calendar'[M] )
		        )
        ,FINDQ = 0&& SELECTEDVALUE ( aux0[QM] ) <= DM&& SELECTEDVALUE ( aux0[QM] ) >= DQMINMONTH
		        , CALCULATE (
		            SUM ( DATA[VALUE] )
		            ,TREATAS ( RM, 'calendar'[M] )
		            ,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[M] )
		            ,ALL ( 'calendar'[M] )
		        )
   ,BLANK ()
)</code></pre>
7、方法3:test1
test1 =
VAR TF=MOD(AVERAGE('calendar'[month]),3)//季度月末显示季度or月度
VAR FindQ =FIND ( "Q", SELECTEDVALUE ( aux0[QM] ),, 0 ) //是否存在Q
VAR DQ =CALCULATE (MIN ( 'calendar'[Q] ),FILTER ( 'calendar', [Q] = SELECTEDVALUE ( 'calendar'[Q] ) ) ) //当前季度
VAR DM =CALCULATE (MIN ( 'calendar'[M] ),FILTER ( 'calendar', [M] = SELECTEDVALUE ( 'calendar'[M] ) )) //当前月份
VAR DQMinMonth =CALCULATE ( MIN ( 'calendar'[M] ), FILTER ( ALL ( 'calendar' ), [Q] = DQ ) ) //当前季度最小月份
VAR RQ =FILTER ( VALUES ( 'aux0'[QM] ), LEN ( [QM] ) = 2 )//季度
VAR RM =FILTER ( VALUES ( 'aux0'[QM] ), LEN ( [QM] ) > 2 )//月
RETURN
SWITCH (
	TRUE ()
        ,FINDQ > 0 && SELECTEDVALUE ( 'aux0'[QM] ) <= DQ&& NOT(TF)
		        , CALCULATE (
		            SUM ( DATA[VALUE] )
		            ,TREATAS ( RQ, 'calendar'[Q] )
		            ,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[Q] )
		            ,ALL ( 'calendar'[M] )
		        )
        ,FINDQ > 0 && SELECTEDVALUE ( 'aux0'[QM] ) < DQ
		        , CALCULATE (
		            SUM ( DATA[VALUE] )
		            ,TREATAS ( RQ, 'calendar'[Q] )
		            ,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[Q] )
		            ,ALL ( 'calendar'[M] )
		        )
        ,FINDQ = 0&& SELECTEDVALUE ( aux0[QM] ) <= DM&& SELECTEDVALUE ( aux0[QM] ) >= DQMINMONTH && TF
		        , CALCULATE (
		            SUM ( DATA[VALUE] )
		            ,TREATAS ( RM, 'calendar'[M] )
		            ,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[M] )
		            ,ALL ( 'calendar'[M] )
		        )
   ,BLANK ()
)</code></pre>
四、总结
1、思维依然是业务转换是筛选上下文;
2、方法1&方法3都是利用TREATAS创建虚拟关系来实现目的;
3、方法2中利用的虚线关系USERELATIONSHIP实现目的,同时方式2兼容PP,目前TREATAS不兼容PP,(更新:office365支持TREATAS)
4、本案例可以衍生如:动态坐标轴、动态维度展示等,可以举一反三的。
彩蛋:季度&月度动态坐标轴
相对比较简单就不单独赘述;见文章素材附件。
[video width="1064" height="924" mp4="https://jiaopengzi.com/wp-content/uploads/2020/03/129_9.mp4"][/video]
by 焦棚子
129_Power Pivot&Power BI DAX不同维度动态展示&动态坐标轴的更多相关文章
- 123_Power Pivot&Power BI DAX函数说明速查
		
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 说明 1.基于DAX Studio 2.9.2版本导出整理: 2.DAX Studio网站,及时更新下载,DAX学习利器: ...
 - 127_Power Pivot&Power BI DAX计算订单商品在库时间(延伸订单仓储费用)
		
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 前面已经写过一个先进先出的库龄案例,在业务发生又有这样一个需求:先进先出前提,需要按照订单计算每个商品在库时间, ...
 - 124_Power Pivot&Power BI DAX优化计算最大连续次数
		
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 最大连续次数或者是最大连续子序列问题,在DAX中如何快速计算呢? 思路 1.N-1:按照INDEX错位 2.ST ...
 - 设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示(2.Azure Functions实战)
		
本案例适用于开发者入门理解Azure Functions/ IoT Hub / Service Bus / Power BI等几款产品. 主要实战的内容为: 将设备遥测数据上传到物联网中心, 将遥测数 ...
 - 设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示(1.准备工作)
		
本案例适用于开发者入门理解Azure Functions/ IoT Hub / Service Bus / Power BI等几款产品. 主要实战的内容为: 将设备遥测数据上传到物联网中心, 将遥测数 ...
 - 122_Power Pivot&Power BI不连续日期的日环比
		
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 这两天有朋友在交流,dax中使用时间智能函数写日环比,一个 dateadd 就可以了.但是有些业务不是每天都连续 ...
 - .NET平台开源项目速览(19)Power BI神器DAX Studio
		
PowerBI更新频繁,已经有点更不上的节奏,一直在关注和学习中,基本的一些操作大概是没问题,更重要的是注重Power Query,M函数,以及DAX的使用,这才是核心. 上个月研究了DAX的一些 ...
 - PowerBI开发 第十五篇:Power BI的行级安全
		
Power BI支持行级安全(Row-Level Security,RLS)的权限控制,用于限制用户对Dashboard.报表和DataSet的访问.用户浏览的报表是相同的,但是看到的数据却是不同的. ...
 - 数据可视化之 图表篇(四) 那些精美的Power BI可视化图表
		
之前使用自定义图表,每次新打开一个新文件时,都需要重新添加,无法保存,在PowerBI 6月更新中,这个功能得到了很大改善,可以将自定义的图表固定在内置图表面板上了. 添加自定义图表后,右键>固 ...
 
随机推荐
- 浅析CSS定位
			
position 属性指定了html元素的定位类型. position 属性有 4 种值:1. static(default)表示没有定位,元素出现在正常的文档流中.为静态定位的元素设置 top|bo ...
 - hql常用查询语句
			
// HQL: Hibernate Query Language.// 特点:// >> 1,与SQL相似,SQL中的语法基本上都可以直接使用.// >> 2,SQL查询的是表 ...
 - 新版vue作用域插槽的使用
			
2.6开始,作用域插槽的使用有了不同的地方: 作用域插槽的个人理解就是让子组件的数据可以在父组件中使用: 也是一个数据传递的方式了: 不多说,上代码 子组件定义一个插槽,并且定义一个需要传递到父组件 ...
 - 理解Promise函数中的resolve和reject
			
看了promise的用法,一直不明白里面的resolve和reject的用法: 运行了这两段代码之后彻底理解了promise的用法: var p = new Promise(function (res ...
 - css3,css的基础全局运用
			
浮动 1.浮动起来的盒子不占用位置,浮动了一个盒子下面的标准流的盒子会顶上来  可用清除浮动的方法来解决标准流会顶替位置的问题 清除浮动给父盒子加overflow: hidden; 鼠标经过事件 : ...
 - SpringMVC-获得Restful风格的参数
			
使用@PathVariable注解:接收请求路径中占位符的值 @RequestMapping("/report18/{username}") @ResponseBody publi ...
 - 使用ABP SignalR重构消息服务(二)
			
使用ABP SignalR重构消息服务(二) 上篇使用ABP SignalR重构消息服务(一)主要讲的是SignalR的基础知识和前端如何使用SignalR,这段时间也是落实方案设计.这篇我主要讲解S ...
 - mongodb replication
			
官方文档:https://docs.mongodb.com/manual/replication/ 启动参数: 通过linux的包管理器(例如:yum)安装的mongodb会产生一个默认的配置文件:/ ...
 - C++五子棋(三)——判断鼠标有效点击
			
分析 在鼠标左键点击时,我们不能让新棋子在已有棋子的位置落下,同时我们还要让棋子在规定位置落下--棋盘线的交点处. 功能实现 创建数据类型 创建头文件chessData.h和源文件chessData. ...
 - vue预渲染及其cdn配置
			
VUE SEO方案一 - 预渲染及其cdn配置 项目接入VUE这样的框架后,看起来真是太漂亮了,奈何与MCV框架比起来,单页应用程序却满足不了SEO的业务需求,首屏渲染时间也是个问题.总不能白学VUE ...