例如股市的蜡烛图表示涨跌,PowerBI原生可视化中并没有这样的视觉对象,本文尝试通过PowerBI原生视觉对象来构造实现动态涨跌分析的可视化。效果如下:
PowerBI 默认视觉对象有些不支持支持的功能,在有些情况下,还是可以加以优化,本文就是一个案例,来优化对于涨跌的显示。
选择时间范围和日期区间后:
显示这个日期期间的业务指标均值
业务指标应该可以动态选择,如:销售额,利润,利润率
日期区间作为坐标轴应该可以动态选择粒度,如:日,周,月,季
涨幅算法及显示方式应该可以动态选择,如:期间内最小最大值,继续上期结果,按平均值分布在上下,只考虑显示最小值
总之,都应该是动态的,而且应该可以按照业务逻辑再设计新的模式,这也是这里的一贯调性。
对于学习了DAX参数表的伙伴,对算法选择应该不陌生,但本例的算法选择将显得自定义化程度更高。
涨跌 算法 初始 =
IF (
[涨跌 本期] - [涨跌 上期]
>= 0,
SWITCH (
TRUE (),
SELECTEDVALUE ( '涨跌算法'[名称] ) = '极值区间', MINX ( VALUES ( '日期'[日期] ), [涨跌 指标] ),
SELECTEDVALUE ( '涨跌算法'[名称] ) = '接上期', [涨跌 上期],
SELECTEDVALUE ( '涨跌算法'[名称] ) = '均值居中', [涨跌 本期]
- [涨跌 差异] / 2,
SELECTEDVALUE ( '涨跌算法'[名称] ) = '最小值起', MINX ( VALUES ( '日期'[日期] ), [涨跌 指标] ),
BLANK ()
),
SWITCH (
TRUE (),
SELECTEDVALUE ( '涨跌算法'[名称] ) = '极值区间', MINX ( VALUES ( '日期'[日期] ), [涨跌 指标] ),
SELECTEDVALUE ( '涨跌算法'[名称] ) = '接上期', [涨跌 上期] - [涨跌 算法 差异],
SELECTEDVALUE ( '涨跌算法'[名称] ) = '均值居中', [涨跌 本期]
- [涨跌 差异] / 2,
SELECTEDVALUE ( '涨跌算法'[名称] ) = '最小值起', MINX ( VALUES ( '日期'[日期] ), [涨跌 指标] ),
BLANK ()
)
)
这里演示了不同组合条件是如何用DAX来完成的,DAX在 条件化动态执行 上并没有很强大的支持(在面向对象等编程语言中,可以通过继承或多态的机制来实现动态执行),对于一般场景还是可以应付,一些相对复杂的业务逻辑分叉,可能需要有些冗余的DAX表达式,勉强可以接受。
日期区间表,并不是一个标准叫法,当业务一旦涉及到,需要 动态决定周期长度 ,(如:日,周,月,季)那么这个结构会很有用。
本案例中使用了两套日期机制:
日期表,参考:日期表终极方法
日期区间表,参考:日期区间表的终极方法
上述两篇文章已经对日期表和日期区间表做了标准实现,可以拿来就用,文章中显示了所有实现细节可以被忽略。
在实际使用上,由日期区间表来驱动日期表,日期表再驱动(业务上的)订单表,实现筛选作用。值得注意的是:日期区间表和日期表之间的关系是多对一,正常情况是无法驱动日期表的,这是一种适合启用双向筛选器的场景。默认大部分情况,在PowerBI DAX数据建模中,应保持单向筛选。所以,本案例再次演示了如何合理使用双向筛选的场景。
本案例继续采用无侵入式的动态数据结构设计,将需要功能对应的各种度量值指标用该功能主题包裹在自己的表中,保持数据结构简单:
主题起名为:涨跌,有:
对于熟悉Excel的伙伴,默认的视觉对象,无法实现预期的显示,但在Excell中的很多技巧在PowerBI依然适用,所以之前花钱学了大量Excel可视化技巧的伙伴,可以做技巧迁移,本例正展示了这样的技巧:
这里需要隐藏白色区域,但仍然保持它的高度,这可以将其设置为与背景色一致的方式来实现。然后通过非常灵活的DAX表达式来判断每个柱子的不同段位的高度。
根据上述视觉对象的技巧思路,这里将一个柱子分为三截:
初始:需要被隐藏的部分
上涨:绿色上涨部分
下跌:红色下跌部分
那么实现逻辑就很清晰了:
对于每个柱子,都应该计算初始高度
若当前柱子表示业务上涨,计算上涨大小与柱子对应,并置下跌对应高度为0
若当前柱子表示业务下跌,计算下跌大小与柱子对应,并置上涨对应高度为0
对应DAX表达式如下:
涨跌 视觉对象 动态 =
IF (
[涨跌 本期] - [涨跌 上期]
>= 0,
SWITCH (
TRUE (),
SELECTEDVALUE ( '涨跌分类'[名称] ) = '上涨', [涨跌 算法 差异],
SELECTEDVALUE ( '涨跌分类'[名称] ) = '下跌', BLANK (),
SELECTEDVALUE ( '涨跌分类'[名称] ) = '初始', [涨跌 算法 初始],
BLANK ()
),
SWITCH (
TRUE (),
SELECTEDVALUE ( '涨跌分类'[名称] ) = '上涨', BLANK (),
SELECTEDVALUE ( '涨跌分类'[名称] ) = '下跌', [涨跌 算法 差异],
SELECTEDVALUE ( '涨跌分类'[名称] ) = '初始', [涨跌 算法 初始],
BLANK ()
)
)
这里涉及到当前时间区间指标与对应的过去日期区间指标进行对比,有几个难点:
要动态知道当前区间范围是日,周,月还是季度
要动态获得上个周期并保持日,周,月还是季度
对应DAX表达式如下:
涨跌 上期 =
VAR PeriodType =
SELECTEDVALUE ( '日期区间'[PeriodTypeCN] )
RETURN
SWITCH (
TRUE (),
PeriodType = '季度', CALCULATE (
AVERAGEX ( VALUES ( '日期'[日期] ), [涨跌 指标] ),
DATEADD ( '日期'[日期], -1, QUARTER ),
ALL ( '日期区间' )
),
PeriodType = '月份', CALCULATE (
AVERAGEX ( VALUES ( '日期'[日期] ), [涨跌 指标] ),
DATEADD ( '日期'[日期], -1, MONTH ),
ALL ( '日期区间' )
),
PeriodType = '周', CALCULATE (
AVERAGEX ( VALUES ( '日期'[日期] ), [涨跌 指标] ),
DATEADD ( '日期'[日期], -7, DAY ),
ALL ( '日期区间' )
),
PeriodType = '日', CALCULATE (
AVERAGEX ( VALUES ( '日期'[日期] ), [涨跌 指标] ),
DATEADD ( '日期'[日期], -1, DAY ),
ALL ( '日期区间' )
),
BLANK ()
)
值得注意的是,这里必须使用 ALL 来忽略外部视觉对象日期区间对日期表的筛选作用,能够灵活做到这些是进入DAX高级阶段并证明彻底掌握筛选上下文与上下文转换的标志。大家可以在示例文件中体会。
大家可以测试不使用 ALL 的效果,并思考如果没有意识的这里需要移除筛选,出现计算出乎意料,如何发现问题并修复问题呢。
有伙伴问,自定义视觉对象里有蜡烛图这样的视觉对象,为什么还要自己做一个。
首选参考:真正的商业图表可视化之道-布道篇
在社区可以看到很多伙伴对PowerBI或类似BI工具惊艳的外表所吸引,但大量第三方自定义视觉对象,往往需要很多的学习时间或产生选择恐惧症,而微软对于发布的产品(及组件)有严格的测试流程,可以确保质量,第三方很多插件是无法做到这些的,尤其是免费插件。所以,如果可以 灵活精通默认视觉对象 便可以帮助大家以不变应万变,在确实需要复杂可视化对象时,再选择第三方可视化效果。
与此类似的还可以参考:
- Power BI加上想象力会是什么样不看绝对猜不到
- 类别中加入参考线
整个案例效果如下:
本案例展示了如下的示范作用:
日期表与日期区间表的联动
合理使用双向筛选器的场景
如何移植Excel技巧进入PowerBI
如果利用技巧改造默认视觉对象来更好地支撑业务
欢迎交流讨论
如果觉得本文有所帮助或需要案例文件研究
可以分享转发截图后私信获取
联系客服