mcpField
S
svg-visuals

svg-visuals

github.com/data-goblin数据与数据库1.1k62 次安装今天更新
代码仓库

关于 svg-visuals

svg-visuals 是一项技能,可用 DAX 度量值在 Power BI 报表中生成内嵌 SVG 图形。它通过模板、PBIR 绑定和验证流程,指导作者在支持的原生视觉对象中制作静态图形。

主要功能

  1. 01用 DAX 度量值生成 SVG 标记
  2. 02通过 PBIR 将度量值绑定到视觉对象
  3. 03使用常见图表模式模板
  4. 04编写 DAX 前预览静态 SVG
  5. 05验证报表结构和绑定

适用场景

  1. 01在表格单元格中添加迷你图或数据条
  2. 02在卡片视觉对象中显示 KPI 微型图表
  3. 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.dax
bullet-chart-measure.dax
dumbbell-chart-measure.dax
ibcs-bar-measure.dax
jitter-plot-measure.dax
lollipop-conditional-measure.dax
overlapping-bars-measure.dax
overlapping-bars-with-variance-measure.dax
progress-bar-measure.dax
sparkline-measure.dax
status-pill-measure.dax
waterfall-measure.dax
references/
community-examples.md
svg-accessibility.md
svg-card-slicer.md
svg-elements.md
svg-image-visual.md
svg-table-matrix.md
svg-template-matrix.md

详细介绍

通过 DAX 度量值生成 SVG 图形(PBIR)

所有报表修改都必须使用 pbir。 pbir-format 技能仅提供只读的架构上下文。 如果 CLI 不可用或缺少所需操作,请停止并报告此限制。

使用返回 SVG 标记字符串的 DAX 度量值生成内联 SVG 图形。这些图形会在表格、矩阵、卡片、图像和切片器视觉对象中呈现为图像。将其作为扩展度量值存储在 reportExtensions.json 中。

工作原理

  1. DAX 度量值返回以 data:image/svg+xml;utf8, 为前缀的 SVG 字符串
  2. 度量值的 dataCategory 设置为 ImageUrl
  3. 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 进行视觉设计:

  1. 先查询模型——使用 DAX Studio 或 Tabular Editor CLI,在预期筛选上下文中获取实际值。使用真实数字,不要使用占位符。
  2. 将静态 SVG 写入临时文件——保存到 /tmp/mockup.svg,然后在浏览器中使用 open 打开,以预览布局、颜色和比例。
  3. 转换为 DAX 之前先征求反馈——与 DAX 字符串拼接相比,调整静态 SVG 要容易得多。
  4. 颜色必须使用带 # 的十六进制代码——例如 fill='#2B7A78'。绝不要使用 %23 URL 编码或颜色名称。始终使用十六进制代码。
步骤 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.、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'。在图像视觉对象中,%23 URL 编码会导致错误。不要使用颜色名称。
  • 不使用 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 度量只负责将数字映射为坐标
  • 仅使用十六进制颜色——直接使用 #,绝不使用 %23 URL 编码
  • 图像视觉对象无需 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.SVGJake DuddyUDF 库:面积图、折线图、箱线图、热力图、抖动图、小提琴图
PBI-Core-Visuals-SVG-HTMLDavid Bacci标签、龙卷风图、渐变矩阵、条形 UDF
PowerBI MacGuyver ToolboxStepan Resl / Data Goblins20+ 种条形图、14+ 种折线图、24+ 种 KPI 模板
Dashboard Design UDF LibraryDashboard-Design目标线条形图、胶囊视觉对象
Kerry Kolosko TemplatesKerry Kolosko迷你折线图、数据条、KPI 卡片

相关技能

  • pbi-report-design -- 布局和设计最佳实践
  • deneb-visuals -- 使用 Vega/Vega-Lite 创建复杂交互式可视化
  • python-visuals -- 使用 matplotlib/seaborn 创建统计图表
  • r-visuals -- 使用 ggplot2 创建统计图表
  • pbir-format(pbip 插件)-- PBIR JSON 格式参考(扩展度量值、ImageUrl 绑定)

评论

支持 Markdown