作者:来自 Elastic Tim Bosman 及 Miloš Mandić

有兴趣在 Kibana 中为 Vega 可视化添加交互式过滤器吗?了解如何利用 "kibanaAddFilter" 函数轻松创建动态且响应迅速的 Sankey 可视化。
在这篇博客中,我们将了解如何启用 Vega Sankey 可视化来创建 Kibana 过滤器。
Vega 是数据可视化领域的杰出工具,可让你创建详细的交互式数据可视化显示。使用简单的 JSON 语法,Vega 允许你定义可视化的外观和行为。它是 Kibana 生态系统的重要组成部分,这意味着你可以在仪表板中与其他 Kibana 可视化一起使用它。你可以在这篇博客中找到有关 Vega 工作原理的深入探索。
当你需要的不仅仅是 Kibana 标准可视化工具所提供的功能时,Vega 就会大放异彩。它允许你构建适合你特定需求的自定义可视化,无论你是在处理复杂的数据关系还是想要独特的视觉风格。
几年前,我们分享了一篇关于如何在 Kibana 中创建 Sankey 图的博客。Sankey 图非常适合说明两个数据字段之间的关系。虽然图表运行良好,但随着 Kibana 新功能的不断增加,一个限制也变得明显:无法直接从图表创建 Kibana 过滤器。

在这篇博文中,我们将了解如何启用上一篇博文中的 Sankey 可视化来创建 Kibana 过滤器。
注意 :将代码复制到 Kibana 时,可能会出现一条警告消息,指出:URL 太大,Kibana 可能会停止工作。要解决此错误,请转到 Kibana 高级设置并启用"存储在会话中(enable Store in Session)"。
调整 Vega 代码
Kibana 过滤器
在 Kibana 中使用 Vega 时,你可以访问特殊功能,这些功能允许你直接从 Vega 可视化中调整 Kibana 的设置。这些功能允许你修改 Kibana 上下文设置,从而增强仪表板的交互性。
在这里,我们将重点介绍如何使用 kibanaAddFilter 函数。此功能允许你向显示可视化的 Kibana 仪表板添加过滤器。请记住,这些功能是 Vega 独有的,在 Vega-Lite 中不可用。
单击时过滤
我们使用 kibanaAddFilter 函数在可视化中单击堆栈时向 Kibana 添加过滤器。由于两个堆栈都基于不同的字段,因此我们需要确保我们实际上是在正确的字段上进行过滤。这需要一个条件表达式来确定单击了哪个堆栈。

在 Vega 中,你可以使用以下模式的条件表达式:{ condition ? if value : else value }。对于我们的条件,我们检查单击的堆栈是否为 stk1。此 stk1 已在我们的 Vega 代码的数据部分中定义,并用于图表中的左侧堆栈。如果条件为真,则表示单击了左侧堆栈,我们应该在 geo.src 字段上进行过滤。如果为假,我们将在与右侧堆栈相对应的 geo.dest 字段上进行过滤。使用此逻辑,我们可以更新信号部分中的 groupSelector 以反映正确的过滤行为。
{
name: groupSelector
value: false
on: [
{
// Clicking groupMark sets this signal to the filter values
events: @groupMark:click!
update: '''{stack:datum.stack == "stk1" ? kibanaAddFilter({"match_phrase": {"machine.os.keyword":datum.grpId}}) : kibanaAddFilter({"match_phrase": {"geo.dest":datum.grpId}}) }'''
}
]
}
删除未使用的代码
现在过滤已在 Kibana 级别处理,我们可以通过删除一些不必要的逻辑来简化 Vega 可视化。首先,我们可以从 Vega 规范的数据部分中删除过滤逻辑。
// when a country is selected, filter out unrelated data
{
type: filter
expr: !groupSelector || groupSelector.stk1 == datum.stk1 || groupSelector.stk2 == datum.stk2
}
其次,我们可以从信号中删除显示 "show all" 按钮的逻辑。
{
// Clicking "show all" button, or double-clicking anywhere resets it
events: [
{type: "click", markname: "groupReset"}
{type: "dblclick"}
]
update: "false"
}
最后,"show all" 按钮本身也可以被删除。
{
// Create a "show all" button. Shown only when a country is selected.
type: group
data: [
// We need to make the button show only when groupSelector signal is true.
// Each mark is drawn as many times as there are elements in the backing data.
// Which means that if values list is empty, it will not be drawn.
// Here I create a data source with one empty object, and filter that list
// based on the signal value. This can only be done in a group.
{
name: dataForShowAll
values: [{}]
transform: [{type: "filter", expr: "groupSelector"}]
}
]
// Set button size and positioning
encode: {
enter: {
xc: {signal: "width/2"}
y: {value: 30}
width: {value: 80}
height: {value: 30}
}
}
marks: [
{
// This group is shown as a button with rounded corners.
type: group
// mark name allows signal capturing
name: groupReset
// Only shows button if dataForShowAll has values.
from: {data: "dataForShowAll"}
encode: {
enter: {
cornerRadius: {value: 6}
fill: {value: "#f5f5f5"}
stroke: {value: "#c1c1c1"}
strokeWidth: {value: 2}
// use parent group's size
height: {
field: {group: "height"}
}
width: {
field: {group: "width"}
}
}
update: {
// groups are transparent by default
opacity: {value: 1}
}
hover: {
opacity: {value: 0.7}
}
}
marks: [
{
type: text
// if true, it will prevent clicking on the button when over text.
interactive: false
encode: {
enter: {
// center text in the parent group
xc: {
field: {group: "width"}
mult: 0.5
}
yc: {
field: {group: "height"}
mult: 0.5
offset: 2
}
align: {value: "center"}
baseline: {value: "middle"}
fontWeight: {value: "bold"}
text: {value: "Show All"}
}
}
}
]
}
]
}
更改数据集
要充分利用 Sankey 可视化,你需要将其应用于你自己的数据集。在本指南中,我们将调整可视化以与 Logs Kibana 示例数据集配合使用。首先确保已加载示例 Web 日志。然后,通过将索引更改为 kibana_sample_data_logs 来修改 Vega 代码以适应新数据集。
如果 @timestamp 未用作数据集的时间戳字段,则需要更新 %timefield% 设置。设置 %timefield% 设置可确保我们能够使用 Kibana 时间范围。因此,Kibana 时间范围应与你的数据集的时间范围相对应。要更改用于其中一个堆栈的字段,请在两个方面进行调整:数据检索和过滤逻辑。由于 Logs Kibana 示例数据集只有一个 geo.src 值,我们将该字段更改为 machine.os.keyword。

结论
Lens 是 Kibana 中首选的可视化编辑器,因为它既灵活又易于使用。但是,对于某些可视化类型,Vega 提供了创建 Lens 不支持的视觉效果的灵活性,例如我们在本博客中讨论的 Sankey 图表。最初,Sankey 可视化无法创建 Kibana 过滤器,这是 Lens 中可用的一项功能。本博客展示了如何使用 kibanaAddFilter 函数使用 Vega 创建 Kibana 过滤器。
Vega 代码
生成的 Vega 配置可以在 Github 存储库中找到。
注意:我们已将 vega 版本更新为版本 5,因为这是撰写本文时的最新版本。
想要获得 Elastic 认证?了解下一次 Elasticsearch 工程师培训的时间!
Elasticsearch 包含许多新功能,可帮助你为你的用例构建最佳搜索解决方案。深入了解我们的示例笔记本以了解更多信息,开始免费云试用,或立即在你的本地机器上试用 Elastic。
原文:Adding filter capabilities to Vega Sankey visualizations in Kibana - Elasticsearch Labs