人生没有彩排
每一天都是现场直播

自定义函数-图表函数

前言

这些自定义的图表函数使用HTML或SVG等语言进行扩展,每一个函数对应一种图表效果,可以通过函数参数来调整图表样式或效果。只需要传入度量值指标与相关样式参数,并放入HTML Content视觉对象或其他支持图像的视觉对象中,就能绘制出对应的图表。

需要注意,本图表函数库里的函数有两类,使用细节并不一致,具体如下:

1、HTML命名空间中的函数最终输出的是HTML代码,只能在支持显示HTML内容的视觉对象中使用,如HTML Content视觉对象。

2、SVG命名空间中的函数最终输出的是SVG代码,使用时需要先将度量值的数据类别设置成图像URL,然后可在任意能显示图像的视觉对象中使用,如矩阵、新卡片图、按钮切片器、HTML Content等视觉对象。

使用方式

方式一:DAX查询

复制以下DAX查询代码,粘贴到PowerBI的查询视图中运行,即可导入图表函数库。

关于每个函数的具体语法与介绍,请参考左边菜单栏的具体函数页面。

DEFINE
/// 同时展示指标值与同比值的卡片,同比值位于指标值同一行的右下角,将根据指标数值大小自动调整显示位置。MainValue参数:指标主值,MainColor参数:指标主值颜色,YoYValue参数:右下角同比值,YoYColor参数:同比值的颜色。注意:MainValue与YoYValue参数请传入格式化后的文本,该函数将原样展示传递的值。另外,如果同比值需要动态颜色,请在YoYColor参数中使用表达式来动态返回不同颜色
FUNCTION XF.HtmlChart.KPICard = (MainValue:string,MainColor:string,YoYValue:string,YoYColor:string) => 
  VAR MainFontSize = "28px"                // 主值字号(推荐28-40px,使用px单位保证基准尺寸)
  VAR MainFontWeight = "600"               // 主值字重(400=正常,600=半粗,700=加粗)
  VAR YoYFontSize = "1em"                  // 同比值字号(推荐0.4-0.6em,基于主值字号的比例)
  VAR YoYFontWeight = "600"                // 同比值字重(通常比主值小100-200权重)
  VAR HorizontalGap = "0.6em"              // 水平间距(主值与同比值间距,推荐0.3-1em)
  VAR VerticalAdjust = "0.15em"            // 垂直微调(正值下移/负值上移,推荐±0.3em内)
  RETURN
  "<div class='xifeng' style='
      display: flex;                       /* 启用flex布局 */
      justify-content: center;             /* 水平居中 */
      align-items: center;                 /* 垂直居中 */
      width: 100%;                         /* 撑满容器宽度 */
      height: 100%;                        /* 撑满容器高度 */
      line-height: 1;                      /* 消除行高影响 */
  '>
      <div style='
          display: flex;                   /* 嵌套flex布局 */
          align-items: baseline;           /* 基线对齐 */
          gap: " & HorizontalGap & ";      /* 元素间距 */
          transform: translateY(           /* 垂直位置微调 */
              " & VerticalAdjust & "       /* 微调量(基于em单位) */
          );
      '>
          <!-- 主值 -->
          <span style='
              font-size: " & MainFontSize & ";
              font-weight: " & MainFontWeight & ";
              color: " & MainColor & ";
              line-height: 1;              /* 防止行高影响 */
          '>" & MainValue & "</span>

          <!-- 同比值 -->
          <span style='
              font-size: " & YoYFontSize & ";
              font-weight: " & YoYFontWeight & ";
              color: " & YoYColor & ";
              line-height: 1;              /* 保持行高一致 */
              white-space: nowrap;         /* 防止换行 */
          '>" & YoYValue & "</span>
      </div>
  </div>"

/// 根据expression参数的值的正负返回不同的上升或下降Icon,可用在矩阵/表格的条件格式图标中。可选的Icon图标有:1:实心圆,2:空心圆,3,五角星,4:上下斜箭头,5:上下三角。另外,颜色默认为:绿色:expression>0,红色:expression<0,黄色:expression=0
FUNCTION XF.SvgChart.ShapeIcon = (expression:scalar,icon:int64,size:int64) => 
    VAR CurVal = expression
    VAR Color_Green = "rgb(41, 175, 97)"
    VAR Color_Yellow = "rgb(255, 192, 0)"
    VAR Color_Red = "rgb(231, 76, 60)"
    VAR ShowColor = SWITCH(TRUE(),CurVal>0,Color_Green,CurVal<0,Color_Red,CurVal=0,Color_Yellow)
    VAR ShowIcon = 
        SWITCH(
            Icon,
            1,"●",
            2,"○",
            3,"★",
            4,SWITCH(TRUE(),CurVal>0,"↗",CurVal<0,"↘",CurVal=0,"-"),
            5,SWITCH(TRUE(),CurVal>0,"▲",CurVal<0,"▼",CurVal=0,"-"),
            ERROR("Icon图标参数错误,请选择以下图标:1:实心圆,2:空心圆,3,五角星,4:上下斜箭头,5:上下三角")
        )
    RETURN
    IF(NOT ISBLANK(CurVal),
        "data:image/svg+xml;utf8,
        <svg class='xifeng' xmlns='http://www.w3.org/2000/svg' version='1.1' height='100' width='100'>
            <text x='50' y='50' font-size='"&size&"' fill='"&ShowColor&"' text-anchor='middle' dominant-baseline='central'>"&ShowIcon&"</text>
        </svg>"
    )

/// 在矩阵或表格中返回美化后的文本标签。textContent参数:用分隔符连接的文本标签,delimiter参数:分隔符,textSize参数:文本大小(建议10-14),textColor参数:文本颜色。将按分隔符拆分textContent参数,得到各个标签,然后以胶囊卡片的形式进行美化,可使用在矩阵或表格的值字段中。使用前提:将矩阵或表格的图形尺寸设置为:高20,宽512,并将对应度量值的分类设置为图形URL
FUNCTION XF.SvgChart.TextLabels = (textContent:string,delimiter:string,textSize:int64,textColor:string) => 
    VAR CurText = SUBSTITUTE(SUBSTITUTE(textContent,delimiter,"|"),"&","&")
    VAR Space = 15
    VAR Width_Factor = 7
    VAR TextWeight = "Bold"
    VAR FillColor = Textcolor
    VAR FillColorOpacity = 0.1
    VAR TextList_AddIndex = 
        SELECTCOLUMNS(
            GENERATESERIES(1,PATHLENGTH(CurText)),
            "Text",PATHITEM(CurText,[Value]),
            "Index",[Value]
        )
    VAR TextList_AddCumLen = 
        ADDCOLUMNS(
            TextList_AddIndex,
            "CumLen",
                VAR CurIndex = [Index]
                RETURN
                SUMX(
                    FILTER(TextList_AddIndex,[Index]<=CurIndex),
                    LEN([Text])
                )
        )
    VAR TagChart = 
        ADDCOLUMNS(
            TextList_AddCumLen,
            "Tag",
                VAR CurIndex = [Index]
                VAR CurText = [Text]
                VAR CurCumLen = [CumLen]
                RETURN
                "<rect x='"&Width_Factor*(CurCumLen-LEN(CurText))+Space*(3*CurIndex-2)&"' y='0' rx='10' ry='10' width='"&Width_Factor*LEN(CurText)+Space*2&"' height='20' 
                    fill='"&FillColor&"' fill-opacity='"&FillColorOpacity&"'/>
                <text x='"&Width_Factor*(CurCumLen-LEN(CurText))+Space*(3*CurIndex-2)+(Width_Factor*LEN(CurText)+Space*2)/2&"' y='15' font-size='"&textSize&"' fill='"&textColor&"' font-weight='"&TextWeight&"' text-anchor='middle' >"&(CurText)&"</text>"
        )
    RETURN
    "data:image/svg+xml;utf8,
    <svg class='xifeng' xmlns='http://www.w3.org/2000/svg' version='1.1' height='20' width='512'>"&
        IF(CurText<>BLANK(),CONCATENATEX(TagChart,[Tag],""))
    &"</svg>"

/// 返回水印背景。textContent:水印文本(如"微信公众号:简说PowerBI");textSize:文本大小(建议20-28);textColor:文本颜色(如"Gray"或"#808080");opacity:透明度0-1(建议0.1-0.3);rotateDegree:旋转角度(建议-30~-45);canvasWidth:画布宽度(建议1280或1920);canvasHeight:画布高度(建议720或1080);xGap:X方向间距(建议220-260);yGap:Y方向间距(建议180-220)
Function XF.SvgChart.WatermarkBackground = (textContent:string,textSize:int64,textColor:string,opacity:double,rotateDegree:int64,canvasWidth:int64,canvasHeight:int64,xGap:int64,yGap:int64) => 
    VAR __WatermarkText      = textContent
    VAR __FontSize           = textSize
    VAR __FontColor          = textColor
    VAR __Opacity            = opacity
    VAR __RotateDegree       = rotateDegree
    VAR __CanvasWidth        = canvasWidth
    VAR __CanvasHeight       = canvasHeight
    VAR __XGap               = xGap
    VAR __YGap               = yGap
    VAR __FontFamily         = "Segoe UI"
    VAR __RepeatXCount       = ROUNDUP( DIVIDE( __CanvasWidth, __XGap ), 0 ) + 1 
    VAR __RepeatYCount       = ROUNDUP( DIVIDE( __CanvasHeight, __YGap ), 0 ) + 1
    VAR __GridTotalWidth     = ( __RepeatXCount - 1 ) * __XGap
    VAR __GridTotalHeight    = ( __RepeatYCount - 1 ) * __YGap
    VAR __StartOffsetX       = DIVIDE( __CanvasWidth - __GridTotalWidth, 2 )
    VAR __StartOffsetY       = DIVIDE( __CanvasHeight - __GridTotalHeight, 2 )
    VAR __TextBlocks =
        CONCATENATEX (
            GENERATESERIES ( 0, __RepeatYCount - 1 ),
            VAR RowIndex = [Value]
            RETURN
                CONCATENATEX (
                    GENERATESERIES ( 0, __RepeatXCount - 1 ),
                    VAR ColIndex = [Value]
                    VAR XPos = __StartOffsetX + ColIndex * __XGap
                    VAR YPos = __StartOffsetY + RowIndex * __YGap
                    RETURN
                        "<text x=""" & XPos & """ y=""" & YPos & """ " &
                        "fill=""" & __FontColor & """ " &
                        "fill-opacity=""" & FORMAT ( __Opacity, "0.00" ) & """ " &
                        "font-family=""" & __FontFamily & """ " &
                        "font-size=""" & __FontSize & """ " &
                        "text-anchor=""middle"" " & 
                        "dominant-baseline=""middle"" " &
                        "transform=""rotate(" & __RotateDegree & " " & XPos & " " & YPos & ")"">" &
                        __WatermarkText &
                        "</text>",
                    "",
                    ""
                ),
            "",
            ""
        )
    RETURN
    "data:image/svg+xml;utf8," &
    "<svg class='xifeng' xmlns=""http://www.w3.org/2000/svg"" " &
    "width=""" & __CanvasWidth & """ height=""" & __CanvasHeight & """>" &
        "<rect width=""100%"" height=""100%"" fill=""white"" fill-opacity=""0"" />" &
        __TextBlocks &
    "</svg>"

/// 返回纵向分割线,用于矩阵或表格的条件格式图标中,以进行列或区块的分割。lineColor:线条颜色(如"#3498db");strokeWidth:线条粗细(建议100);lineStyle:样式("solid"实线, "dashed"虚线);position:位置("center"居中, "left"靠左, "right"靠右)
Function XF.SvgChart.MatrixSplitLine = (lineColor:string,strokeWidth:int64,lineStyle:string,position:string) => 
    VAR __InputColor    = COALESCE( lineColor, "Gray" )
    VAR __SafeColor     = SUBSTITUTE( __InputColor, "#", "%23" )
    VAR __SafeWidth     = IF( strokeWidth <= 0, 2, strokeWidth )
    VAR __SafeStyle     = IF( LOWER( lineStyle ) = "dashed", "dashed", "solid" )
    VAR __SafePosition  = LOWER( position )
    VAR __CanvasWidth   = 480
    VAR __CanvasHeight  = 480
    VAR __XPos = 
        SWITCH(
            TRUE(),
            __SafePosition = "left", 0,
            __SafePosition = "right", __CanvasWidth,
            __CanvasWidth / 2
        )
    VAR __DashAttribute = 
        IF(
            __SafeStyle = "dashed", 
            "stroke-dasharray='30, 30'", 
            ""
        )
    RETURN
    "data:image/svg+xml;utf8," &
    "<svg class='xifeng' xmlns='http://www.w3.org/2000/svg' " &
    "width='" & __CanvasWidth & "' height='" & __CanvasHeight & "'>" &
        "<line " &
            "x1='" & __XPos & "' y1='0' " &
            "x2='" & __XPos & "' y2='" & __CanvasHeight & "' " &
            "stroke='" & __SafeColor & "' " &
            "stroke-width='" & __SafeWidth & "' " &
            __DashAttribute & 
        "/>" &
    "</svg>"

方式二:外部工具

还可以使用配套的PowerBI外部工具来导入已发布的所有自定义函数,如下图所示:

该外部工具会自动联网获取最新的DAX自定义函数列表,可搜索或选择要导入的DAX自定义函数,然后选择对应的PowerBI实例后,点击开始导入即可。

另外,该外部工具还支持导入SQLBI的DaxLib平台的函数,并支持本地函数库功能,而且除了下拉选择模式外还支持模糊搜索模式。

该外部工具的获取方式如下:

资源下载
免费资源
PowerBI外部工具-XIFEGN-UDF-TOOL.zip点击下载

关于该外部工具的安装与使用方式,可阅读附带的 README.txt 文件,如下图所示:

其他

如果有任何问题或想法,欢迎在评论区提交你的需求与改进建议,一起完善该函数库!

赞(0) 打赏
版权声明:本文为夕枫的原创文章,著作权归作者所有,未经允许不得转载
文章名称:《PowerBI DAX自定义函数-图表函数》
文章链接:https://www.ximaple.com/posts/1317.html
订阅评论
提醒
guest
0 评论
最新
最久 最赞
内联反馈
查看所有评论

觉得文章有用的话就支持一下吧~

感谢您的打赏支持,我将持续输出有价值的内容!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册

Operation don't support