在 Power BI 报告中创建子弹图

本文翻译自Kurt Buhler的文章—《Building bullet charts in Power BI reports》来源:SQLBI本文介绍了如何在Power BI中将实际值与目标值进行比较时阅读和使用子弹图,以及在Power BI报告中制作这些图表时可用的不同选项。

当报告可视化在有意义的背景下显示信息时,它才具有实用性。这里的背景指的是其他相关数据,这些数据有助于人们解读可视化中的数字,并利用这些数字做出决策或采取行动。提供背景信息最常见的方式是将实际值与目标值进行比较。

有多种方式可以将实际值与目标值进行比较,在本文中,我们将详细介绍一种条形图的变体——子弹图来实现这一目标的方法。

在本文的其余部分,我们将解释此类图表的使用场景、您可以使用哪些不同类型的图表,以及在Power BI报告中构建子弹图的不同方法。一如既往,您可以在文章底部找到.pbix文件和模板,以便将这些图表应用到您自己的报告中。

在报告中提供背景信息

在我们继续之前,重要的是首先要理解为什么我们使用这样的视觉元素来比较实际值和目标值。为什么我们不单独显示实际值,或者将所有内容都放在一个大表格或矩阵中显示呢?

请考虑以下卡片和条形图,它们显示了报告中按产品类别划分的销售金额。当您查看这些视觉元素时,请尝试解释这些数字;它们对您来说意味着什么?

它们到底有多好或多坏?
这些销售额是好是坏?
如果您是这份报告的使用者,您认为这会有用吗?

尝试解读这些视觉元素时,您可能这样想:这对我来说毫无意义;我不知道这是好是坏。这确实如此;除非您对该业务有所了解,否则不可能解读这些数字,因为视觉元素缺乏背景信息。背景信息使视觉元素变得有用,因为它赋予了视觉元素意义。在这种情况下,我们唯一的背景信息是比较各个类别;例如,“电脑”的销量远超其他类别。然而,我们不知道 526,000 的总销量是好是坏(情感倾向),有多好或多坏(程度),以及情况是在改善还是在恶化(随时间变化的趋势)。

一份好的报告会为解读视觉元素提供足够的背景信息,但我们可以展示哪些背景信息呢?

选择展示哪些背景信息

为了提供背景信息,我们可以将销售额与目标进行比较。常见的目标可能是预算、预测、上一时期、或按类别的平均值或中位数。在这种情况下,我们可以将销售额与去年同期的销售额进行比较。为此,我们将计算去年同期的销售额,并在DAX计算中隐藏未来的日期。这样可以确保对当前年度进展与去年进行有效比较(而不使用累计的年初至今计算)。

日期表中包含一个计算列,用于标记仅包含销售的日期:

日期表中的计算列

Dates with Sales =
VAR _LatestDateWithSales =
    MAX ( 'Sales'[Order Date] )
RETURN
    IF (
        'Date'[Date] < _LatestDateWithSales,
        TRUE,
        FALSE
    )

我们在一个用于目标(上一年销售额)的度量值中使用这个计算列:

销售表中的度量值

Sales Amount (PY) =
    CALCULATE (
        [Sales Amount],
        CALCULATETABLE (
            SAMEPERIODLASTYEAR ( 'Date'[Date] ), -- Table of dates for previous year
            'Date'[Dates with Sales] = TRUE      -- Filter to only dates with sales
        )
    )       

然后,我们可以使用这个目标来计算实际值与目标值之间的比较,比如“销售额与上一年相比(%)”,它显示的是百分比差异,或者“销售额与上一年相比(Δ)”,它显示的是美元差异。在这两个选项之间做出选择后,我们就可以将实际值与目标值之间的差异进行可视化,从而提供一些缺失的背景信息。

file

这两个选项都比原来的条形图要好,因为它们能迅速帮助回答销售业绩是好是坏以及每个类别的表现如何的根本问题。根据报告的具体目的,您可以选择第一个或第二个选项:

选项1是展示相对成就的好选择,有助于显示与自身目标相比,哪个类别的表现最差。
选项2是展示差异程度的好选择,有助于确定哪些类别对整体销售业绩的影响最大

然而,这两个选项仍然缺乏重要信息:

选项1缺乏关于差异对总销售业绩影响的背景信息。例如,“游戏和玩具”类别与去年相比下降了38%,但在我们总销售业绩的背景下,这是否有意义?我们应该关注这个类别,还是另一个类别?
选项2缺乏关于类别内销售差异影响的背景信息。例如,“音频”类别超额完成了5,000美元的目标,但对于“音频”类别来说,这是否算多(因此是一项重大成就),还是只是略微超额?
选项1和选项2都缺乏关于绝对销售数字的信息。我们可以说与去年相比,我们下降了36%或296,000美元……但总销售额是多少?

提供这些额外背景信息的一种方法是将其添加到工具提示中。这样,当用户将鼠标悬停在某个类别上时,除了视觉元素中显示的信息外,他们还可以看到其他信息。

file

然而,工具提示的格式选项有限,对于希望在不进行交互的情况下查看这些数字的用户来说可能不太方便。此外,工具提示也不适用于比较视觉元素内部或跨视觉元素的类别。当存在多个目标时,提供适量的上下文信息变得更加具有挑战性。

因此,报告创建者和用户通常会选择使用矩阵和表格视觉元素来一次性展示所有上下文信息,这是非常常见的做法。尽管这看起来直接且方便,但它很快就会变成一个“一统天下的表格”,包含过多的信息。

下面的表格是一个包含单个指标和目标的简单示例;在实际报告中,这样的表格通常包含多个类别、指标和目标。

file

这些表格和矩阵变得难以应对且效率低下,因为用户需要花费太多时间寻找或思考数字。这些表格还常常成为用户导出到Excel的“数据倾泻”的前兆,以便他们更容易地找到所需内容。这种情况并不理想,通常表明你没有充分利用Power BI。

选择展示哪些上下文信息是许多报告开发者面临的共同挑战,因为这个问题没有简单且唯一的答案。展示所有内容效率低下,而选择单一指标又可能遗漏部分用户偏好或需要的信息。这再次强调了优质需求收集的重要性。当你收集到优质的需求时,你就能理解报告应该解决的业务问题和疑问,以及报告应该展示哪些信息来帮助人们完成工作并实现目标。

选择展示什么只是战斗的一半。你还必须选择如何最好地展示它。

选择如何展示上下文

在上一章节中,我们展示了在Power BI中比较实际值与目标值的几种不同方法,比如比较实际结果与预算结果,或比较实际结果与往年结果。你还可以使用更多类型的图表来展示这些信息,如下所示。

file

在Power BI中构建简单且广受欢迎的选择之一是子弹图(位于之前图示的左下角)。子弹图并非Power BI中现成的“核心视觉”元素,因此我们将向您展示几种使用自定义视觉元素制作子弹图的不同方法。

构建子弹图
子弹图(或子弹状图表)最初由Steven Few(2005年)设计,现已成为比较数字与目标的一种常见图表类型。子弹图之所以受欢迎,是因为它简洁易读。同时,它也很紧凑,意味着能够一次有效地展示大量信息。此外,在考虑3-30-300规则时,您既可以在3秒视图中使用子弹图来有效地展示概览,也可以在30秒视图中帮助用户筛选和放大某些类别。

您可以在以下图示中看到子弹图的常见部分解释。

file

请注意,子弹图的可选元素会产生许多可能的变体,具体取决于您决定如何实现它。在Power BI报告中,如果不可用,您可能不包括定性范围。您可以尝试包含一些任意的定性范围,但重要的是,您必须在实现之前先与用户就此达成一致,否则他们可能不理解(或不同意)这些范围。

在本文的其余部分,我们将重点关注为单个目标构建子弹图。由于子弹图不是核心视觉元素,我们需要从之前文章中描述的自定义视觉方法中进行选择。

file

我们将逐一介绍这些方法,但不包括Python、R和Javascript自定义视觉元素。原因是,您通常会在已经熟练掌握这些语言时,或计划在其他应用程序中使用代码时,才选择使用Python、R或Javascript。

利用核心视觉元素构建子弹图(MacGyver式)
在第一种方法中,我们可以利用Power BI中标准条形图视觉元素的格式设置技巧来创建一个基本的子弹图。要从核心视觉元素中“改造”出一个子弹图,我们从原始图表开始,该图表按产品类别显示销售额。

file

接下来,我们只需要添加标记目标的线条。我们可以在启用“误差线”(包括上限和下限)后,将销售额(PY)目标添加到误差线中。误差线通常用于视觉元素中,以显示数据中的不确定性或变化。然而,在这种情况下,我们仅使用它们来强制在目标位置显示一个标记。

一旦我们启用了误差线,就可以将条形和标记的宽度格式化为最大值(10像素),并将边框宽度设置为最小值(0像素)。结果是,我们在销售额(PY)处有一个大的垂直标记,我们可以将其与销售额目标进行比较。

file

这已经给出了我们的结果。但是,我们可以通过一些额外的格式设置来进一步改进它,例如:

增加类别之间的空间以缩小条形。
对条形和数据标签进行条件格式设置,以突出显示表现不佳的类别。
添加网格线,以便在没有标签的情况下视觉上识别值。
修改标题,使其清楚地表明我们正在将销售额与去年进行比较。

我们的子弹图结果将如下所示。

file

利用核心视觉元素制作子弹图(MacGuyver式)非常直接,在简单场景中进行类别比较时,这可能是最佳方法。但是,格式限制可能使您无法使用此方法可视化聚合性能,或添加其他改进,如条形后的定性范围。当您需要更高级的格式设置或自定义时,最好考虑使用其他方法作为替代。

使用现成的子弹图自定义视觉元素
如果已在您的租户中启用,您可以使用AppSource上由其他第三方创建的自定义视觉元素。您可以通过在可视化(构建)窗格中选择省略号(…),然后选择“获取更多视觉元素”来浏览自定义视觉元素。如果看不到此选项,则可能是您的Fabric管理员禁用了自定义视觉元素。在这种情况下,如果您需要自定义视觉元素,请考虑提出一个例外情况的商业案例,解释启用白名单或认证视觉元素的潜在价值。

以下图示显示了如何在AppSource中搜索现成的子弹图自定义视觉元素。

file

当您选择一个自定义视觉元素添加到报表中时,它会在该.pbix文件的可视化窗格中的核心视觉元素之间显示。您可以通过右键单击视觉元素图标并选择“固定到可视化窗格”,将其设置为在所有未来的报表中显示。

有多种不同的自定义视觉元素可用于子弹图,每种都有自己的配置、自定义和限制。重要的是要知道,AppSource上的自定义视觉元素可能有一些功能需要通过购买付费许可证才能解锁。一些自定义视觉元素是开源的(免费),而另一些具有高级自定义功能和特性的则需要付费。

以下图示显示了OKVIZ子弹图的免费版本的一个示例(利益冲突免责声明:OKVIZ是SQLBI的一部分):

file

即使使用OKVIZ子弹图视觉的免费版本,我们也可以更容易地从核心视觉元素中重新创建子弹图。我们还拥有更多的格式选项,比如添加定性范围。如果购买了付费许可证,还可以获得其他选项,比如保存和重用模板、显示差异、额外的标签选项,甚至更快的视觉渲染所需的增量加载。

对于像子弹图这样的常见图表类型,AppSource上的自定义视觉元素可能是一个非常好的选择,因为它们通常更容易设置和维护。对于付费的自定义视觉元素,与其他方法相比,节省的时间可能值得投资。

然而,自定义视觉元素仍然仅限于其开发人员提供的选项。此外,这些自定义视觉元素出现的任何问题都需要开发人员的支持。对于开源的自定义视觉元素,这意味着Power BI更新后,您报告中的一个重要视觉元素可能会停止工作,而您无法修复它,直到该视觉元素的开发人员能够或选择这样做。

如果现成的自定义视觉元素没有您需要的选项,那么您可以考虑自己制作子弹图,例如在Deneb中。

在Deneb中构建子弹图

您可以从AppSource获得的另一个自定义视觉元素称为Deneb。Deneb与其他自定义视觉元素不同,因为它允许您使用Vega或Vega-Lite规范定义自己的视觉元素。除非您之前使用过Deneb,否则这可能对您来说没有意义。简而言之,在Deneb中,您可以使用类似JSON的语法或从模板开始创建自己的视觉元素。这种语法基本上允许您通过在此规范中定义视觉元素的工作方式和外观来创建和格式化视觉元素。但是,创建自己的视觉元素需要花费更多的时间和精力。

已经有一个用于子弹图的Vega-Lite JSON规范,因此我们可以将其作为起点。第一步是从AppSource获取Deneb自定义视觉元素,并将其添加到画布上。完成此操作后,我们应按照空白视觉元素中的说明打开Deneb高级编辑器。在那里,我们可以添加模板(如本文示例文件中的模板)或创建新规范。

当您打开Deneb的高级编辑器时,它看起来与下面的图片相似。

file

当您向Deneb视觉元素中添加字段时,它会为该视觉元素创建一个单表数据集。您在规范中引用此数据集中的字段,并且还可以在高级编辑器的右下角看到该表。规范乍一看可能很复杂,但使用Vega/Vega-Lite示例开始使用却非常直接。此外,还有许多社区资源和模板可供参考,例如Kerry Kolosko、Thys、Andrzej Leszkiewicz、Sentido Analítica等人提供的资源和模板。此外,像ChatGPT这样的大型语言模型(LLM)与这些规范配合得相当好,这意味着即使您对Deneb没有多少或完全没有经验,也能迅速取得不错的进展。

由于Deneb非常灵活,我们可以做一些以前的方法无法实现的事情。例如,我们可以采取综合方法来同时显示子弹图和行动点,包括实际值和目标的标签。行动点是一种有用的方式,可以吸引人们对表现过度或不足者的注意。

file

我们在Deneb中创建的视觉元素性能出色,且对报告中的其他视觉元素和交互具有良好的响应性。然而,我们确实需要花费额外的时间在不同的条件和筛选上下文中对其进行测试,以确保它不会产生意外的结果(例如,在大量筛选、空白或非常小/大的值的情况下)。如果可能的话,测试性能并优化视觉元素也很重要。

当您希望获得实际上的像素级完美视觉元素和报告,而又不依赖于Python或JavaScript中的完整代码时,Deneb是一个不错的选择。然而,您需要自己处理Vega/Vega-Lite规范以获得这种灵活性,这可能会花费额外的时间,除非您利用模板。然而,具有高视觉成熟度水平的团队可以在减轻这种成本的同时从Deneb中大大受益。实际上,他们可以构建和整理自己的模板库,以便在多个报告中重复使用。如果不清楚的话,与迄今为止我们讨论过的其他方法相比,Deneb的学习曲线更陡峭,但它非常强大。

最后,与其他AppSource视觉元素一样,如果自定义视觉元素在您的组织中并不在选择范围内,那么这一选项对您也不适用。此外,如果您只想用子弹图来补充现有的表格或卡片视觉元素,那么您可以考虑在DAX度量值中使用SVG自定义视觉元素。

在DAX度量值中使用SVG自定义视觉元素设计子弹图

所有之前的方法都假设您希望子弹图成为一个完整的视觉元素。然而,在某些情况下,您可能希望使用子弹图来补充现有的表格或矩阵。如果使用得当,这可以大大降低信息密度,并使您的表格和矩阵更加有效和便于人们阅读。

为此,您可以在DAX度量值中使用SVG自定义视觉元素,这是我们在之前的一篇文章中描述的一种方法。这种方法涉及将SVG定义指定为DAX度量值中的有效字符串,然后将数据类别属性设置为ImageUrl,以便其呈现SVG图像。您可以设置向量属性(如位置、大小和颜色)为动态,这就是您创建视觉元素的方式。这种方法还使您能够像使用Deneb一样完全控制视觉格式,但它更加抽象和复杂,这可能会使其耗时更长且更难维护。

为了简化这个过程,我们可以完全在Figma中设计子弹图,然后将SVG定义复制到DAX度量值中。接下来,我们只需将定义转换为有效字符串并替换值以使形状动态化。

此过程的结果如下所示,其中的子弹图可与在Deneb中创建的子弹图相媲美。

file

SVG方法的优势在于,您无需担心标签问题,因为这些标签可以作为列添加到表格或矩阵中。此外,您还可以在其他视觉元素中重复使用SVG,例如新的卡片或新的切片器视觉元素。由于它仅将DAX度量值呈现为图像,因此它支持所有报告,无论管理员设置、安装或许可如何。

然而,该视觉元素较小,且没有空间放置图例或标签,可能会让用户感到困惑。为了缓解这一问题,重要的是要培训用户如何阅读和理解该视觉元素。您应当创建一个指向常见问题解答页面的链接,该页面用于简洁且直观地解释这一点。

此方法的其他注意事项与我们在之前关于使用DAX创建自定义视觉元素的文章中讨论的内容相同。值得注意的是,如果这些度量值没有得到很好的记录,那么它们可能会很难维护。DAX代码错综复杂,难以阅读,如果我们没有充分测试视觉元素,则存在性能问题或漏洞的高风险。如果这些特定于报告的度量值没有与标准模型对象适当隔离,它们还可能污染语义模型。

我们讨论的每种方法都有其自身的优缺点,选择最适合您的方法取决于多种因素。重要的是,您要在解决方案的简洁性和可维护性与其将产生的业务价值之间取得平衡。对于自定义视觉元素,您应确保它们对用户有明显的益处;不要仅仅因为您认为它们看起来不错就选择使用。如果您忽略这一建议,可能会使您的报告变得过于复杂,导致用户难以阅读和使用,开发人员也难以修复和维护。

正如我们常说的,一份报告的好看和好用是两回事。

总结

在DAX评估中,我们通常会谈到与筛选器、行和视觉上下文相关的上下文。然而,上下文在您的视觉元素中也很重要;它赋予了数字意义。具有上下文的视觉元素使您的报告更加有用。在视觉元素中显示上下文的一种方法是将其与目标进行比较,您可以通过使用子弹图有效地做到这一点。虽然这不是Power BI的默认图表类型之一,但您可以使用不同的方法通过自定义视觉元素创建子弹图,在决定实现哪种方法之前,您应该权衡每种方法各自的优点和注意事项。


如果您想深入学习微软Power BI,欢迎登录网易云课堂试听学习我们的“从Excel到Power BI数据分析可视化”系列课程。或者关注我们的公众号(PowerPivot工坊)后猛戳”在线学习”。




长按下方二维码关注“Power Pivot工坊”获取更多微软Power BI、PowerPivot相关文章、资讯,欢迎小伙伴儿们转发分享~


Power Pivot工坊