关于 svg-visuals
svg-visuals 是一项技能,可用 DAX 度量值在 Power BI 报表中生成内嵌 SVG 图形。它通过模板、PBIR 绑定和验证流程,指导作者在支持的原生视觉对象中制作静态图形。
主要功能
- 01用 DAX 度量值生成 SVG 标记
- 02通过 PBIR 将度量值绑定到视觉对象
- 03使用常见图表模式模板
- 04编写 DAX 前预览静态 SVG
- 05验证报表结构和绑定
适用场景
- 01在表格单元格中添加迷你图或数据条
- 02在卡片视觉对象中显示 KPI 微型图表
- 03在报表中展示进度或状态指示器
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ data-goblin/ power-bi-agentic-development --skill svg-visuals安装后在 Claude Code 中输入/svg-visuals确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/boxplot-measure.daxbullet-chart-measure.daxdumbbell-chart-measure.daxibcs-bar-measure.daxjitter-plot-measure.daxlollipop-conditional-measure.daxoverlapping-bars-measure.daxoverlapping-bars-with-variance-measure.daxprogress-bar-measure.daxsparkline-measure.daxstatus-pill-measure.daxwaterfall-measure.daxreferences/community-examples.mdsvg-accessibility.mdsvg-card-slicer.mdsvg-elements.mdsvg-image-visual.mdsvg-table-matrix.mdsvg-template-matrix.md详细介绍
通过 DAX 度量值生成 SVG 图形(PBIR)
所有报表修改都必须使用
pbir。pbir-format技能仅提供只读的架构上下文。 如果 CLI 不可用或缺少所需操作,请停止并报告此限制。
使用返回 SVG 标记字符串的 DAX 度量值生成内联 SVG 图形。这些图形会在表格、矩阵、卡片、图像和切片器视觉对象中呈现为图像。将其作为扩展度量值存储在 reportExtensions.json 中。
工作原理
- DAX 度量值返回以
data:image/svg+xml;utf8,为前缀的 SVG 字符串 - 度量值的
dataCategory设置为ImageUrl - Power BI 会在受支持的视觉对象中将 SVG 渲染为图像
支持的视觉对象
- 表格(
tableEx):grid.imageHeight/grid.imageWidth——references/svg-table-matrix.md - 矩阵(
pivotTable):与表格相同——references/svg-table-matrix.md - 图像(
image):sourceType='imageData'+sourceField——references/svg-image-visual.md - 卡片/新版(
cardVisual):image对象(图像区域)或cardImage(标注图像)——references/svg-template-matrix.md,模式见references/svg-card-slicer.md - 切片器/新版(
advancedSlicerVisual):通过图像“从数据中选择”槽位为每个按钮添加一个图像——references/svg-template-matrix.md
从模板开始
手动编写 DAX 之前,请查看 references/svg-template-matrix.md:该文档将每种模式(项目符号、进度条、药丸标签、迷你折线图、哑铃图、发散图、增量、图钉、仪表)映射到适用的承载视觉对象(独立的 SVG 应放入图像视觉对象,卡片用于显示数字),展示每种视觉对象经验证的 PBIR 接线方式,并提供可将模式写入精简报表度量值并完成接线的一步式 pbir visuals svg / pbir add gauge-card 命令。仅当没有模板涵盖所需图形时,才手动编写 SVG DAX。
工作流:创建 SVG 度量值
步骤 0:设计并预览
编写 DAX 之前,先对 SVG 进行视觉设计:
- 先查询模型——使用 DAX Studio 或 Tabular Editor CLI,在预期筛选上下文中获取实际值。使用真实数字,不要使用占位符。
- 将静态 SVG 写入临时文件——保存到
/tmp/mockup.svg,然后在浏览器中使用open打开,以预览布局、颜色和比例。 - 转换为 DAX 之前先征求反馈——与 DAX 字符串拼接相比,调整静态 SVG 要容易得多。
- 颜色必须使用带
#的十六进制代码——例如fill='#2B7A78'。绝不要使用%23URL 编码或颜色名称。始终使用十六进制代码。
步骤 1:创建扩展度量值
手动在 reportExtensions.json 中创建扩展度量值(JSON 结构请参阅 pbip 插件中的 pbir-format 技能)。
# Example using pbir_object_model (if available):
report.add_extension_measure(
table="Orders",
name="Sparkline SVG",
expression='''
VAR _Prefix = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 30'>"
VAR _Bar = "<rect x='0' y='0' width='50' height='30' fill='#2196F3'/>"
VAR _Suffix = "</svg>"
RETURN _Prefix & _Bar & _Suffix
''',
data_type="Text",
data_category="ImageUrl",
display_folder="SVG Charts",
)
report.save()
步骤 1b:审查
向用户展示度量值之前,先调用 svg-reviewer Agent,验证语法并提供设计反馈。
步骤 2:绑定到视觉对象
扩展度量值在 SourceRef 中使用 "Schema": "extension":
{
"field": {
"Measure": {
"Expression": {
"SourceRef": {"Schema": "extension", "Entity": "Orders"}
},
"Property": "Sparkline SVG"
}
}
}
对于图像视觉对象,通过 pbir add visual image --image 绑定 SVG 度量值;请参阅
references/svg-image-visual.md。
步骤 3:验证
使用 pbir validate "Report.Report" --all 进行验证,并使用
pbir visuals bind "...Visual" --show 检查绑定。
优先使用 UDF 库,而不是自定义 DAX
在从头编写自定义 SVG 度量值之前,先检查现有 UDF 库是否已提供所需的图表类型:
- PowerofBI.IBCS(Andrzej Leszkiewicz)——符合 IBCS 标准的条形图、柱形图、瀑布图、图钉图、小多图和损益表图表。适用于包含 AC/PY/BU/FC 对比的业务报告。安装地址:https://daxlib.org/package/PowerofBI.IBCS/
- DaxLib.SVG(Jake Duddy)——通用迷你图、条形图、箱线图、热力图、抖动图、小提琴图、进度条和胶囊图。安装地址:https://daxlib.org/package/DaxLib.SVG/——源代码:https://github.com/daxlib/dev-daxlib-svg
- PowerBI MacGuyver Toolbox(Stepan Resl / Data Goblins)——可通过表格编辑器生成 SVG 度量值的 C# 脚本
要检查是否已安装某个库,请查找以 PowerofBI.IBCS.、Viz.、Compound. 或 Element. 开头的函数或度量值。只有在没有库函数支持所需可视化效果时,才编写自定义 SVG DAX。完整函数列表和更多库请参阅 references/community-examples.md。
安装 UDF 库
UDF 库安装在语义模型中,而非报表中。请使用以下工具之一:
- Tabular Editor CLI(
te命令)——参阅te-docs技能获取指导 - Power BI MCP 服务——如果可用,请用它直接修改模型
connect-pbid技能——通过 TOM/PowerShell 连接到 Power BI Desktop 的本地 Analysis Services 实例tmdl技能——直接编辑 PBIP 项目中的 TMDL 文件(最后手段)
DAX SVG 约定
度量值结构(VAR 模式)
每个 SVG 度量值都必须遵循严格的 VAR 结构。将代码组织成清晰分隔的区域:
SVG Measure =
-- CONFIG: Input fields and visual parameters
VAR _Actual = [Sales Amount]
VAR _Target = [Sales Target]
VAR _Scope = ALLSELECTED ( 'Product'[Category] )
-- CONFIG: Colors
VAR _BarColor = "#5B8DBE"
VAR _TargetColor = "#333333"
-- NORMALIZATION: Scale values to SVG coordinate space
VAR _AxisMax = CALCULATE( MAXX( _Scope, [Sales Amount] ), REMOVEFILTERS( 'Product'[Category] ) ) * 1.1
VAR _AxisRange = 100
VAR _ActualNormalized = DIVIDE( _Actual, _AxisMax ) * _AxisRange
-- SVG ELEMENTS: One VAR per visual element
VAR _SvgPrefix = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 25'>"
VAR _Sort = "<desc>" & FORMAT( _Actual, "000000000000" ) & "</desc>"
VAR _Bar = "<rect x='0' y='5' width='" & _ActualNormalized & "' height='15' fill='" & _BarColor & "'/>"
VAR _TargetLine = "<rect x='" & DIVIDE( _Target, _AxisMax ) * _AxisRange & "' y='2' width='2' height='21' fill='" & _TargetColor & "'/>"
VAR _SvgSuffix = "</svg>"
-- ASSEMBLY: Combine in rendering order (back to front)
VAR _SVG = _SvgPrefix & _Sort & _Bar & _TargetLine & _SvgSuffix
RETURN _SVG
关键约定:
- 首先是 CONFIG 区域——输入度量值、范围列、颜色、字体设置。用户只需更改此区域。
- NORMALIZATION 区域——将原始值缩放到 SVG 坐标空间(见下文)
- SVG ELEMENTS——每个
<rect>、<circle>、<text>、<line>等各使用一个 VAR - ASSEMBLY——按文档顺序拼接元素(第一个在后层,最后一个在前层)
<desc>排序技巧——在<desc>标签中嵌入FORMAT(_Actual, "000000000000"),以便表格/矩阵按 SVG 列排序
坐标轴归一化(关键)
SVG 坐标必须归一化到固定范围。原始度量值(例如 1,234,567)不能直接用作像素坐标。标准模式如下:
-- 1. Define the SVG coordinate range
VAR _BarMin = 0 -- leftmost position (or offset for labels)
VAR _BarMax = 100 -- rightmost position
-- 2. Find the maximum value across all rows in the visual's filter context
VAR _Scope = ALLSELECTED( 'Table'[GroupColumn] )
VAR _MaxInScope = CALCULATE( MAXX( _Scope, [Measure] ), REMOVEFILTERS( 'Table'[GroupColumn] ) )
VAR _AxisMax = _MaxInScope * 1.1 -- 10% padding
-- 3. Normalize each value to the SVG range
VAR _AxisRange = _BarMax - _BarMin
VAR _Normalized = DIVIDE( _Actual, _AxisMax ) * _AxisRange
如果图表应响应切片器上下文,请对范围使用 ALLSELECTED。如果要在所有筛选上下文中固定坐标轴,请使用 ALL。* 1.1 留出的余量可防止条形触及边缘。
HASONEVALUE 防护
表格/矩阵 SVG 度量值必须处理小计/总计行,以防多个类别同时处于范围内:
IF( HASONEVALUE( 'Table'[GroupColumn] ),
-- SVG code here
)
如果没有此防护,度量值会在总计行上计算,得到毫无意义的聚合值。
转义和颜色规则
- SVG 属性使用单引号——避免 DAX 双引号转义:
fill='#2196F3' - DAX 中的双引号:转义为
""(DAX 约定) - 响应式缩放使用
viewBox:viewBox='0 0 100 25' <svg>元素必须包含xmlns- 十六进制颜色只使用
#——例如fill='#2196F3'。在图像视觉对象中,%23URL 编码会导致错误。不要使用颜色名称。 - 不使用 JavaScript——SVG 必须完全采用声明式编写
SVG 坐标系
- Y=0 位于顶部——图表中的值需反转:
_Height - _Value - 使用范围为 0-100 的
viewBox来表示归一化坐标 - 元素按文档顺序渲染(第一个在后层,最后一个在前层)
使用 CONCATENATEX 处理系列数据
对于迷你图和多点图表,请使用 CONCATENATEX 构建坐标字符串:
VAR _Points = CONCATENATEX(
_SparklineTable,
[X] & "," & (100 - [Y]),
" ",
[Date], ASC
)
-- Produces: "0,80 10,60 20,40 30,20"
-- Use in: <polyline points='...'/>
最佳实践
- 先检查 UDF 库——编写自定义 DAX 前,先使用 DaxLib.SVG 或 MacGuyver Toolbox 函数
- 必须采用 VAR 模式——每个配置值使用一个 VAR,每个 SVG 元素使用一个 VAR,并在最后进行组装
- 规范化所有值——原始度量值必须缩放到 SVG 坐标范围
- HASONEVALUE 防护——在表格/矩阵上下文中,始终防止总计/小计行;对于嵌套层级,使用
ISINSCOPE <desc>排序技巧——在<desc>中嵌入格式化后的值,以便 SVG 列可排序- 使用
viewBox实现响应式缩放,而不是固定的 width/height - 将坐标四舍五入为整数以提升性能(字符串更短,FORMAT 调用开销更低)
- 将其存储为扩展度量——SVG 度量不属于语义模型
- 使用
display_folder整理 SVG 度量(例如"SVG Charts") - 先预览——将静态 SVG 保存到
/tmp/,在浏览器中打开并迭代,然后再编写 DAX - 每个单元格渲染后的 SVG 字符串长度上限为 32K 个字符(不是 DAX 表达式);诊断和缓解方法见
references/svg-table-matrix.md - 在模型度量中预先聚合——让存储引擎缓存聚合结果;SVG 度量只负责将数字映射为坐标
- 仅使用十六进制颜色——直接使用
#,绝不使用%23URL 编码 - 图像视觉对象无需
query块——只需使用objects.image,并设置sourceType='imageData'和sourceField - 无障碍访问:每个用于编码主要数据的 SVG 都需要相邻的可读列和动态替代文本度量;见
references/svg-accessibility.md
reportExtensions.json 格式
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/reportExtension/1.0.0/schema.json",
"name": "extension",
"entities": [{
"name": "ExistingTable",
"measures": [{
"name": "Sparkline SVG",
"dataType": "Text",
"dataCategory": "ImageUrl",
"expression": "...",
"displayFolder": "SVG Charts"
}]
}]
}
限制
- 不支持交互——SVG 图像是静态的(无悬停、点击或工具提示)
- 不支持 JavaScript——内嵌脚本会被移除
- 每个渲染后单元格字符串长度上限为 32K 个字符(不是 DAX 表达式);对 30 个以上系列点使用
CONCATENATEX很容易接近此上限;优先使用<polyline>而非单独的形状、使用整数坐标,并预先聚合系列;完整诊断见references/svg-table-matrix.md - 每个单元格都有公式引擎开销——每个可见单元格都会计算字符串构建表达式;将聚合放入模型度量中,使 SVG 组装仅负责坐标映射
- 无障碍访问方面的不足——屏幕阅读器无法从 SVG URI 中获取每个单元格的数据;可通过相邻的可读列和动态替代文本缓解;见
references/svg-accessibility.md - 经典卡片(
card)不支持 SVG——请改用cardVisual
何时使用 SVG 度量
SVG 度量是嵌入表格、矩阵、卡片和图像视觉对象的简单内嵌图形的首选方案。以下场景适合使用 SVG:
- 在表格/矩阵单元格中显示迷你趋势图、数据条、进度条或状态指示器
- 在卡片视觉对象中显示 KPI 迷你图表
- 不需要交互或复杂数据转换的轻量级视觉对象
- 无需注册额外的自定义视觉对象(可与原生视觉对象配合使用)
对于复杂的交互式可视化(交叉筛选、工具提示、悬停状态)或需要大量数据转换的图表类型,请改用 Deneb。对于统计分析图表(分布、回归、相关性),请改用 Python/R。
参考资料
社区示例和库
references/community-examples.md—— 按目标视觉对象类型(表格/矩阵、图像、卡片)整理的社区 SVG 模板,包括 DaxLib.SVG 函数、Kerry Kolosko 模板和 PowerBI MacGuyver Toolbox 模式
按视觉类型
references/svg-table-matrix.md-- 表格/矩阵模式:数据条、子弹图、哑铃图、重叠条形图、棒棒糖图、状态胶囊、迷你折线图、条形迷你图、面积迷你图、UDF 模式;坐标轴归一化、排序技巧、图像尺寸配置以及单元格性能指南references/svg-image-visual.md-- 图像视觉对象模式:KPI 标题、带端点的迷你折线图、仪表板磁贴;sourceType 绑定、动态/条件布局、响应式宽度指南references/svg-card-slicer.md-- 卡片/切片器模式:箭头指示器、迷你仪表、迷你圆环图、进度条、叙述句;通过callout.imageFX绑定卡片
无障碍
references/svg-accessibility.md-- SVG 度量值的无障碍设计:相邻的可读列、动态替代文本、仅用颜色编码、对比度要求,以及审计问题的严重程度指南
通用
references/svg-elements.md-- SVG 元素参考(rect、circle、line、polyline、text、path、gradient、group)
示例
examples/ 中可直接使用的 DAX 度量值表达式:
sparkline-measure.dax-- 折线迷你图(polyline + CONCATENATEX)progress-bar-measure.dax-- 条件进度条dumbbell-chart-measure.dax-- 实际值与目标值哑铃图bullet-chart-measure.dax-- 带情绪指示动作点的子弹图overlapping-bars-measure.dax-- 带差异标签的重叠条形图boxplot-measure.dax-- 箱线图(灵感来自 DaxLib.SVG)ibcs-bar-measure.dax-- 符合 IBCS 标准的水平条形图(灵感来自 avatorl)jitter-plot-measure.dax-- 带抖动效果的点带图(灵感来自 DaxLib.SVG)overlapping-bars-with-variance-measure.dax-- 带差异条、箭头图标和百分比标签的重叠条形图(Kurt Buhler / Data Goblins)lollipop-conditional-measure.dax-- 带缩放圆点和自动格式化标签的棒棒糖图(Kurt Buhler / Data Goblins)waterfall-measure.dax-- 使用累积 OFFSET 定位并带连接线的瀑布图(Kurt Buhler / Data Goblins)status-pill-measure.dax-- 带类别颜色和文本标签的圆角胶囊徽标(Kurt Buhler / Data Goblins)
辅助库
| 库 | 作者 | 主要功能 |
|---|---|---|
| DaxLib.SVG | Jake Duddy | UDF 库:面积图、折线图、箱线图、热力图、抖动图、小提琴图 |
| PBI-Core-Visuals-SVG-HTML | David Bacci | 标签、龙卷风图、渐变矩阵、条形 UDF |
| PowerBI MacGuyver Toolbox | Stepan Resl / Data Goblins | 20+ 种条形图、14+ 种折线图、24+ 种 KPI 模板 |
| Dashboard Design UDF Library | Dashboard-Design | 目标线条形图、胶囊视觉对象 |
| Kerry Kolosko Templates | Kerry Kolosko | 迷你折线图、数据条、KPI 卡片 |
相关技能
pbi-report-design-- 布局和设计最佳实践deneb-visuals-- 使用 Vega/Vega-Lite 创建复杂交互式可视化python-visuals-- 使用 matplotlib/seaborn 创建统计图表r-visuals-- 使用 ggplot2 创建统计图表pbir-format(pbip 插件)-- PBIR JSON 格式参考(扩展度量值、ImageUrl 绑定)