优化Power BI指标达成差异分析瀑布图

2021-11-10 17:20:54 浏览数 (2)

采总那里看到一个非常实用的Power BI瀑布图用法,如下图所示:

指标是多少,达成状况如何,每个人对指标达成的贡献如何,一目了然。本文基于采总文章的灵感,尝试进行优化,优化的核心点有三个:

  • 无需建立辅助表
  • 可以对达成贡献进行排序
  • 目标和实际标签加粗显示

优化后的展示效果如下:

模拟数据:

基础度量值:

代码语言:javascript复制
目标 = SUM('表'[销售目标]) 
实际 = SUM('表'[实际业绩])
差异 = [实际]-[目标]

接着DAX嵌入SVG的方式新建以下度量值,拖入Image by CloudScope图表插件即可实现上图的效果:

代码语言:javascript复制
瀑布图 = 
VAR Item_Count=CALCULATE(DISTINCTCOUNT('表'[店铺]),ALL('表'))
VAR Actual=CALCULATE([实际],ALL('表')) //总实际值
VAR Target=CALCULATE([目标],ALL('表')) //总目标值
VAR ALL_GapaboveTarget=SUMX(FILTER(ALL('表'),'表'[实际业绩]>='表'[销售目标]),'表'[实际业绩]-'表'[销售目标])
VAR MAX_Value=IF(Actual>=Target,Actual,Target) ALL_GapaboveTarget
VAR Width_Gross=40
VAR Width_Net=30 //柱子的宽度
VAR Width_Line=Width_Gross-Width_Net //柱子中间连线的宽度
VAR Target_Height=150*Target/MAX_Value //目标值柱子的高度,150像素是图形区域的整体高度
VAR Target_Y=150-Target_Height
VAR Actual_Height=150*Actual/MAX_Value //实际值柱子的高度
VAR Actual_Y=150-Actual_Height
VAR Table_Index=SUMMARIZE('表',[店铺],"索引",RANKX(ALL('表'),[差异]),"差异",[差异])
VAR Table_SVG=ADDCOLUMNS(Table_Index,
"类别标签",
"<text x='"&Width_Net/2 [索引]*Width_Gross &"' y='155' font-size='8' writing-mode='tb' textLength='45' text-anchor='Start' >" & [店铺] & "</text>",
"柱形",
"<rect x='"&[索引]*Width_Gross&"' y='"&IF([差异]>0, 150-(Target_Height 150*SUMX(FILTER(Table_Index,EARLIER([索引])>=[索引]),[差异])/MAX_Value),150-(Target_Height 150*(SUMX(FILTER(Table_Index,EARLIER([索引])>=[索引]),[差异]) ABS([差异]))/MAX_Value))&"' height='"&150*ABS([差异])/MAX_Value&"' width='"&Width_Net&"' fill='"&IF([差异]>=0,"Green","Red")&"'/>",
"连接线",
"<rect x='"&[索引]*Width_Gross-Width_Line&"' y='"&
IF([差异]>0, 150-(Target_Height 150*SUMX(FILTER(Table_Index,EARLIER([索引])>=[索引]),[差异])/MAX_Value) 150*ABS([差异])/MAX_Value,150-(Target_Height 150*(SUMX(FILTER(Table_Index,EARLIER([索引])>=[索引]),[差异]) ABS([差异]))/MAX_Value))&"' height='0.2' width='"&Width_Line&"' fill='Grey'/>",
"数据标签",
"<text x='"&Width_Net/2 [索引]*Width_Gross&"' y='"&IF([差异]>0, 150-(Target_Height 150*SUMX(FILTER(Table_Index,EARLIER([索引])>=[索引]),[差异])/MAX_Value),150-(Target_Height 150*(SUMX(FILTER(Table_Index,EARLIER([索引])>=[索引]),[差异]) ABS([差异]))/MAX_Value)) 8&"' font-size='8' text-anchor='Middle' >"&ROUND([差异]/10000,0)& "</text>"
)
VAR SVG= //补充目标和实际的柱子
"data:image/svg xml;utf8,"&"
<svg xmlns='http://www.w3.org/2000/svg' height='200' width='"&Width_Gross*(Item_Count 2)&"'>"& CONCATENATEX(Table_SVG,[类别标签]&[柱形]&[连接线]&[数据标签],)&
"<rect x='0' y='"&Target_Y&"' height='"&Target_Height&"' width='"&Width_Net&"' fill='Green'/>"&
"<text x='15' y='155' font-size='8' font-weight='bold' writing-mode='tb' textLength='45' text-anchor='Start'>目标</text>"&
"<text x='15' y='"&Target_Y 8&"' font-size='8' text-anchor='Middle'>"&ROUND(Target/10000,0)&"</text>"&
"<rect x='"&(Item_Count 1)*Width_Gross&"' y='"&Actual_Y&"' height='"&Actual_Height&"' width='"&Width_Net&"' fill='Orange'/>"&
"<rect x='"&(Item_Count 1)*Width_Gross-Width_Line&"' y='"&Actual_Y&"' height='0.2' width='"&Width_Line &"' fill='Orange'/>"&
"<text x='"&15 (Item_Count 1)*Width_Gross &"' y='155' font-size='8' font-weight='bold' writing-mode='tb' textLength='45' text-anchor='Start'>实际</text>"&
"<text x='"&15 (Item_Count 1)*Width_Gross &"' y='"&Actual_Y 8&"' font-size='8' text-anchor='Middle'>"&ROUND(Actual/10000,0)&"</text>"
&"</svg> "
RETURN
SVG

草拟,有可以简化的地方,后续也许更新。

0 人点赞