使用 Vega 创建自定义可视化效果
Elastic Stack Serverless
Vega 和 Vega-Lite 都是用于创建自定义可视化效果的语法。 建议具有手动编写 Elasticsearch 查询经验的高级用户使用。 对于刚接触这两种语法的用户,Vega-Lite 是一个不错的起点,但它们不兼容。
Vega 和 Vega-Lite 面板可以显示一个或多个数据源,包括 Elasticsearch、Elastic Map Service、URL 或静态数据,并支持 Kibana 扩展,允许您将面板嵌入到仪表盘中并添加交互式工具。
当您想要创建具有以下特性的可视化效果时,请使用 Vega 或 Vega-Lite:
- 使用
nested
或parent/child
映射的聚合 - 没有数据视图的聚合
- 使用自定义时间过滤器的查询
- 复杂的计算
- 从 _source 而不是聚合中提取的数据
- 散点图、桑基图和自定义地图
- 不受支持的可视主题
这些语法有一些限制:它们不支持表格,并且不能有条件地运行查询。

Vega 和 Vega-Lite 都使用 JSON,但 Kibana 通过集成 HJSON,使键入更加简单。 HJSON 支持以下功能:
- 可选引号
- 双引号或单引号
- 可选逗号
- 使用 // 或 /* 语法的注释
- 多行字符串
了解如何将 Vega-Lite 与 Kibana 过滤器和 Elasticsearch 数据连接,然后了解如何使用 Vega 创建更多 Kibana 交互。
在编辑规范时,分小步骤工作,并经常保存您的工作。 微小的更改可能会导致意想不到的结果。 要保存,请单击工具栏中的 保存。
在开始之前,添加您将在规范中使用的电子商务示例数据,然后创建仪表盘。
- 安装电子商务示例数据集.
- 转到 仪表盘。
- 在 仪表盘 页面上,单击 创建仪表盘。
打开 Vega-Lite 并更改时间范围。
在仪表盘上,单击 选择类型,然后选择 自定义可视化效果。
预先填充的折线图显示文档总数。
确保 时间过滤器 为 过去 7 天。
了解如何从 Vega-Lite 查询 Elasticsearch,并在堆叠面积图中显示结果。
- 在 Vega-Lite 规范中,将
index: _all
替换为以下内容,然后单击 更新
index: kibana_sample_data_ecommerce
出现一条带有零结果的平线。
要从 kibana_sample_data_ecommerce 数据视图添加数据字段,请替换以下内容,然后单击 更新
- 将
%timefield%: @timestamp
替换为%timefield%: order_date
- 将
field: @timestamp
替换为field: order_date
要创建堆叠面积图,请添加聚合。
要检查您的工作,请在单独的浏览器选项卡上打开并使用 控制台。
- 在新标签页上打开 Kibana。
- 使用导航菜单或 全局搜索字段 转到 开发工具 页面。
- 在 控制台 编辑器上,输入聚合,然后单击 单击以发送请求
POST kibana_sample_data_ecommerce/_search
{
"query": {
"range": {
"order_date": {
"gte": "now-7d"
}
}
},
"aggs": {
"time_buckets": {
"date_histogram": {
"field": "order_date",
"fixed_interval": "1d",
"extended_bounds": {
"min": "now-7d"
},
"min_doc_count": 0
}
}
},
"size": 0
}
添加 terms 聚合,然后单击 单击以发送请求
POST kibana_sample_data_ecommerce/_search
{
"query": {
"range": {
"order_date": {
"gte": "now-7d"
}
}
},
"aggs": {
"categories": {
"terms": { "field": "category.keyword" },
"aggs": {
"time_buckets": {
"date_histogram": {
"field": "order_date",
"fixed_interval": "1d",
"extended_bounds": {
"min": "now-7d"
},
"min_doc_count": 0
}
}
}
}
},
"size": 0
}
响应格式与第一个聚合查询不同
{
"aggregations" : {
"categories" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [{
"key" : "Men's Clothing",
"doc_count" : 1661,
"time_buckets" : {
"buckets" : [{
"key_as_string" : "2020-06-30T00:00:00.000Z",
"key" : 1593475200000,
"doc_count" : 19
}, {
"key_as_string" : "2020-07-01T00:00:00.000Z",
"key" : 1593561600000,
"doc_count" : 71
}]
}
}]
}
}
}
在 Vega-Lite 规范中,输入聚合,然后单击 更新
data: {
url: {
%context%: true
%timefield%: order_date
index: kibana_sample_data_ecommerce
body: {
aggs: {
categories: {
terms: { field: "category.keyword" }
aggs: {
time_buckets: {
date_histogram: {
field: order_date
interval: {%autointerval%: true}
extended_bounds: {
min: {%timefilter%: "min"}
max: {%timefilter%: "max"}
}
min_doc_count: 0
}
}
}
}
}
size: 0
}
}
format: {property: "aggregations.categories.buckets" }
}
有关查询的信息,请参阅 在 Vega 中编写 Elasticsearch 查询的参考。
要生成数据,Vega-Lite 使用 source_0
和 data_0
。 source_0
包含来自 Elasticsearch 查询的结果,data_0
包含显示在图表上的视觉编码结果。 要调试警告,请比较 source_0
和 data_0
。
在工具栏中,单击 检查。
从 视图 下拉列表中,选择 Vega 调试。
从下拉列表中,选择 source_0。
要与视觉编码数据进行比较,请从下拉列表中选择 data_0。
key 无法转换,因为该属性是类别(
Men's Clothing
、Women's Clothing
等),而不是时间戳。
在 Vega-Lite 规范中,添加 encoding
块
encoding: {
x: {
field: time_buckets.buckets.key
type: temporal
axis: { title: null }
}
y: {
field: time_buckets.buckets.doc_count
type: quantitative
axis: { title: "Document count" }
}
}
Vega-Lite 无法提取 time_buckets.buckets
内部数组。
在 Kibana 7.9 及更高版本中,使用 Vega-Lite flatten transformation 提取 time_buckets.buckets
内部数组。
如果您使用的是 Kibana 7.8 及更早版本,则 flatten transformation 仅在 Vega 中可用。
在 Vega-Lite 规范中,添加 transform
块,然后单击 更新
transform: [{
flatten: ["time_buckets.buckets"]
}]
单击 检查,然后从 视图 下拉列表中选择 Vega 调试。
从下拉列表中,选择 data_0。
Vega-Lite 显示 未定义 值,因为存在重复名称。
要解决重复名称,请添加
transform
和encoding
块,然后单击 更新
transform: [{
flatten: ["time_buckets.buckets"],
as: ["buckets"]
}]
mark: area
encoding: {
x: {
field: buckets.key
type: temporal
axis: { title: null }
}
y: {
field: buckets.doc_count
type: quantitative
axis: { title: "Document count" }
}
color: {
field: key
type: nominal
}
}
使用 Vega-Lite 规范,您可以将悬停状态和工具提示添加到带有 selection
块的堆叠面积图。
在 Vega-Lite 规范中,添加 encoding
块,然后单击 更新
encoding: {
tooltip: [{
field: buckets.key
type: temporal
title: "Date"
}, {
field: key
type: nominal
title: "Category"
}, {
field: buckets.doc_count
type: quantitative
title: "Count"
}]
}
当您将鼠标悬停在堆叠面积图上的面积序列上时,会出现一个多行工具提示,但无法指示最近的点。 要指示最近的点,请添加第二个图层。
添加复合标记,然后单击 更新
layer: [{
mark: area
}, {
mark: point
}]
这些点无法堆叠并与堆叠面积图对齐。
更改 y encoding
y: {
field: buckets.doc_count
type: quantitative
axis: { title: "Document count" }
stack: true
}
在 mark: point
内部添加 selection
块
layer: [{
mark: area
}, {
mark: point
selection: {
pointhover: {
type: single
on: mouseover
clear: mouseout
empty: none
fields: ["buckets.key", "key"]
nearest: true
}
}
encoding: {
size: {
condition: {
selection: pointhover
value: 100
}
value: 5
}
fill: {
condition: {
selection: pointhover
value: white
}
}
}
}]
在堆叠面积图周围移动光标。 这些点能够指示最近的点。

选择由信号控制。 要查看信号,请单击工具栏中的 检查。
展开最终 Vega-Lite 规范
{
$schema: https://vega.github.io/schema/vega-lite/v4.json
title: Event counts from ecommerce
data: {
url: {
%context%: true
%timefield%: order_date
index: kibana_sample_data_ecommerce
body: {
aggs: {
categories: {
terms: { field: "category.keyword" }
aggs: {
time_buckets: {
date_histogram: {
field: order_date
interval: {%autointerval%: true}
extended_bounds: {
min: {%timefilter%: "min"}
max: {%timefilter%: "max"}
}
min_doc_count: 0
}
}
}
}
}
size: 0
}
}
format: {property: "aggregations.categories.buckets" }
}
transform: [{
flatten: ["time_buckets.buckets"]
as: ["buckets"]
}]
encoding: {
x: {
field: buckets.key
type: temporal
axis: { title: null }
}
y: {
field: buckets.doc_count
type: quantitative
axis: { title: "Document count" }
stack: true
}
color: {
field: key
type: nominal
title: "Category"
}
tooltip: [{
field: buckets.key
type: temporal
title: "Date"
}, {
field: key
type: nominal
title: "Category"
}, {
field: buckets.doc_count
type: quantitative
title: "Count"
}]
}
layer: [{
mark: area
}, {
mark: point
selection: {
pointhover: {
type: single
on: mouseover
clear: mouseout
empty: none
fields: ["buckets.key", "key"]
nearest: true
}
}
encoding: {
size: {
condition: {
selection: pointhover
value: 100
}
value: 5
}
fill: {
condition: {
selection: pointhover
value: white
}
}
}
}]
}
要使用 Elasticsearch 搜索查询构建面积图,请编辑 Vega 规范,然后添加单击并拖动处理程序以更新 Kibana 过滤器。
在 Vega 规范中,输入以下内容,然后单击 更新
{
$schema: "https://vega.github.io/schema/vega/v5.json"
data: [{
name: source_0
}]
scales: [{
name: x
type: time
range: width
}, {
name: y
type: linear
range: height
}]
axes: [{
orient: bottom
scale: x
}, {
orient: left
scale: y
}]
marks: [
{
type: area
from: {
data: source_0
}
encode: {
update: {
}
}
}
]
}
使用 data
块添加 Elasticsearch 搜索查询,然后单击 更新
data: [
{
name: source_0
url: {
%context%: true
%timefield%: order_date
index: kibana_sample_data_ecommerce
body: {
aggs: {
time_buckets: {
date_histogram: {
field: order_date
fixed_interval: "3h"
extended_bounds: {
min: {%timefilter%: "min"}
max: {%timefilter%: "max"}
}
min_doc_count: 0
}
}
}
size: 0
}
}
format: { property: "aggregations.time_buckets.buckets" }
}
]
显示 x 轴和 y 轴的标签。
在 Vega 规范中,添加 scales
块,然后单击更新
scales: [{
name: x
type: time
range: width
domain: {
data: source_0
field: key
}
}, {
name: y
type: linear
range: height
domain: {
data: source_0
field: doc_count
}
}]
添加 key
和 doc_count
字段作为 X 轴和 Y 轴的值,然后单击更新
marks: [
{
type: area
from: {
data: source_0
}
encode: {
update: {
x: {
scale: x
field: key
}
y: {
scale: y
value: 0
}
y2: {
scale: y
field: doc_count
}
}
}
}
]

在面积图上显示可点击的点,以过滤特定日期。
在 Vega 规范中,添加到 marks
块,然后单击更新
{
name: point
type: symbol
style: ["point"]
from: {
data: source_0
}
encode: {
update: {
x: {
scale: x
field: key
}
y: {
scale: y
field: doc_count
}
size: {
value: 100
}
fill: {
value: black
}
}
}
}
要使点可点击,请创建一个 Vega 信号。 您可以在用于更新的表达式中访问点击的 datum
。
在 Vega 规范中,添加一个 signals
块,以指定光标点击添加具有三小时间隔的时间过滤器,然后单击更新
signals: [
{
name: point_click
on: [{
events: {
source: scope
type: click
markname: point
}
update: '''kibanaSetTimeFilter(datum.key, datum.key + 3 * 60 * 60 * 1000)'''
}]
}
]
该事件使用 kibanaSetTimeFilter
自定义函数来生成一个过滤器,该过滤器应用于整个仪表板上的点击。
要使面积图具有交互性,请找到 marks
块,然后更新 point
并将 cursor: { value: "pointer" }
添加到 encoding
{
name: point
type: symbol
style: ["point"]
from: {
data: source_0
}
encode: {
update: {
...
cursor: { value: "pointer" }
}
}
}
要允许用户基于时间范围进行过滤,请添加一个拖动交互,这需要额外的信号和一个矩形叠加层。

在 Vega 规范中,添加一个 signal
以跟踪光标的 X 位置
{
name: currentX
value: -1
on: [{
events: {
type: mousemove
source: view
},
update: "clamp(x(), 0, width)"
}, {
events: {
type: mouseout
source: view
}
update: "-1"
}]
}
要指示当前光标位置,请添加一个 mark
块
{
type: rule
interactive: false
encode: {
update: {
y: {value: 0}
y2: {signal: "height"}
stroke: {value: "gray"}
strokeDash: {
value: [2, 1]
}
x: {signal: "max(currentX,0)"}
defined: {signal: "currentX > 0"}
}
}
}
要跟踪选定的时间范围,请添加一个信号,该信号将更新,直到用户释放其光标或按 Return
{
name: selected
value: [0, 0]
on: [{
events: {
type: mousedown
source: view
}
update: "[clamp(x(), 0, width), clamp(x(), 0, width)]"
}, {
events: {
type: mousemove
source: window
consume: true
between: [{
type: mousedown
source: view
}, {
merge: [{
type: mouseup
source: window
}, {
type: keydown
source: window
filter: "event.key === 'Escape'"
}]
}]
}
update: "[selected[0], clamp(x(), 0, width)]"
}, {
events: {
type: keydown
source: window
filter: "event.key === 'Escape'"
}
update: "[0, 0]"
}]
}
有一个信号跟踪用户的时间范围。
要以可视方式指示范围,请添加一个仅在有条件时才显示的标记
{
type: rect
name: selectedRect
encode: {
update: {
height: {signal: "height"}
fill: {value: "#333"}
fillOpacity: {value: 0.2}
x: {signal: "selected[0]"}
x2: {signal: "selected[1]"}
defined: {signal: "selected[0] !== selected[1]"}
}
}
}
添加一个信号,该信号在拖动时释放光标时更新 Kibana 时间过滤器
{
name: applyTimeFilter
value: null
on: [{
events: {
type: mouseup
source: view
}
update: '''selected[0] !== selected[1] ? kibanaSetTimeFilter(
invert('x',selected[0]),
invert('x',selected[1])) : null'''
}]
}
展开最终的 Vega 规范
{
$schema: "https://vega.github.io/schema/vega/v5.json"
data: [
{
name: source_0
url: {
%context%: true
%timefield%: order_date
index: kibana_sample_data_ecommerce
body: {
aggs: {
time_buckets: {
date_histogram: {
field: order_date
fixed_interval: "3h"
extended_bounds: {
min: {%timefilter%: "min"}
max: {%timefilter%: "max"}
}
min_doc_count: 0
}
}
}
size: 0
}
}
format: { property: "aggregations.time_buckets.buckets" }
}
]
scales: [{
name: x
type: time
range: width
domain: {
data: source_0
field: key
}
}, {
name: y
type: linear
range: height
domain: {
data: source_0
field: doc_count
}
}]
axes: [{
orient: bottom
scale: x
}, {
orient: left
scale: y
}]
marks: [
{
type: area
from: {
data: source_0
}
encode: {
update: {
x: {
scale: x
field: key
}
y: {
scale: y
value: 0
}
y2: {
scale: y
field: doc_count
}
}
}
},
{
name: point
type: symbol
style: ["point"]
from: {
data: source_0
}
encode: {
update: {
x: {
scale: x
field: key
}
y: {
scale: y
field: doc_count
}
size: {
value: 100
}
fill: {
value: black
}
cursor: { value: "pointer" }
}
}
},
{
type: rule
interactive: false
encode: {
update: {
y: {value: 0}
y2: {signal: "height"}
stroke: {value: "gray"}
strokeDash: {
value: [2, 1]
}
x: {signal: "max(currentX,0)"}
defined: {signal: "currentX > 0"}
}
}
},
{
type: rect
name: selectedRect
encode: {
update: {
height: {signal: "height"}
fill: {value: "#333"}
fillOpacity: {value: 0.2}
x: {signal: "selected[0]"}
x2: {signal: "selected[1]"}
defined: {signal: "selected[0] !== selected[1]"}
}
}
}
]
signals: [
{
name: point_click
on: [{
events: {
source: scope
type: click
markname: point
}
update: '''kibanaSetTimeFilter(datum.key, datum.key + 3 * 60 * 60 * 1000)'''
}]
}
{
name: currentX
value: -1
on: [{
events: {
type: mousemove
source: view
},
update: "clamp(x(), 0, width)"
}, {
events: {
type: mouseout
source: view
}
update: "-1"
}]
}
{
name: selected
value: [0, 0]
on: [{
events: {
type: mousedown
source: view
}
update: "[clamp(x(), 0, width), clamp(x(), 0, width)]"
}, {
events: {
type: mousemove
source: window
consume: true
between: [{
type: mousedown
source: view
}, {
merge: [{
type: mouseup
source: window
}, {
type: keydown
source: window
filter: "event.key === 'Escape'"
}]
}]
}
update: "[selected[0], clamp(x(), 0, width)]"
}, {
events: {
type: keydown
source: window
filter: "event.key === 'Escape'"
}
update: "[0, 0]"
}]
}
{
name: applyTimeFilter
value: null
on: [{
events: {
type: mouseup
source: view
}
update: '''selected[0] !== selected[1] ? kibanaSetTimeFilter(
invert('x',selected[0]),
invert('x',selected[1])) : null'''
}]
}
]
}
了解有关 Kibana 扩展、其他 Vega 资源和示例的更多信息。
Kibana 扩展了 Vega 和 Vega-Lite,以支持
- 自动调整大小
- 默认主题以匹配 Kibana
- 使用来自仪表板的时间范围和过滤器编写 Elasticsearch 查询
- [预览] 在 Vega 地图中使用 Elastic Map Service
- 其他工具提示样式
- 启用从任何域加载 URL 的高级设置
- 使用 Kibana 检查器或浏览器控制台进行调试支持
- (仅 Vega) 可以更新时间范围和仪表板过滤器的表达式函数
大多数用户都希望他们的 Vega 可视化效果占据所有可用空间,因此与 Vega 示例不同,width
和 height
在 Kibana 中不是必需的参数,因为在大多数情况下,你的规范将与默认的 Kibana 设置合并
autosize: {
type: fit
contains: padding
}
width: container
height: container
以下情况下,不应用这些默认设置
- 你的规范使用
type=map
- 你的规范是 Vega-Lite,并且包含 facet、row、column、repeat 或 concat 运算符。 在这些情况下,提供
width
和height
将影响子大小。
要手动设置宽度或高度,请设置 autosize: none
并提供精确的像素大小,包括标题、图例和轴的填充。
autosize: none
width: 600
height: 200
padding: {
top: 20
bottom: 20
left: 55
right: 150
}
要了解更多信息,请阅读关于 Vega autosize 和 Vega-Lite autosize。
Vega-Lite 中的自动调整大小具有 一些限制,这些限制会影响你的可视化效果的高度和宽度,但这些限制在 Vega 中不存在。 如果你需要完全控制,请使用 浏览器控制台 VEGA_DEBUG.vega_spec
输出将你的规范转换为 Vega。 要禁用这些警告,你可以 将额外的选项添加到你的规范。
Kibana 注册了一个带有 id elastic
的默认 Vega 颜色方案,并为每种 mark
类型设置了默认颜色。 通过提供不同的 stroke
、fill
或 color
(Vega-Lite) 值来覆盖它。
Kibana 扩展了 Vega data 元素,支持直接将 Elasticsearch 查询指定为 url
。
Kibana 无法支持动态加载的数据,否则它将在 Vega 中工作。 所有数据都在传递给 Vega 渲染器之前获取。
要在 Vega 中定义 Elasticsearch 查询,请将 url
设置为一个对象。 Kibana 会解析该对象,查找允许你的查询与 Kibana 集成的特殊令牌。
令牌包括以下内容
%context%: true
:在顶层设置,并将query
部分替换为来自仪表板的过滤器%timefield%: <name>
:在顶层设置,将查询与仪表板时间过滤器集成{%timefilter%: true}
:替换为具有上限和下限的 Elasticsearch 范围查询{%timefilter%: "min" | "max"}
:仅被上限或下限替换{%timefilter: true, shift: -1, unit: 'hour'}
:生成过去一小时的时间范围查询{%autointerval%: true}
:替换为包含自动 Kibana 时间间隔的字符串,例如1h
{%autointerval%: 10}
:替换为一个字符串,该字符串将时间大致分为 10 个范围,允许你影响自动间隔"%dashboard_context-must_clause%"
:字符串被包含过滤器的对象替换"%dashboard_context-filter_clause%"
:字符串被包含过滤器的对象替换"%dashboard_context-must_not_clause%"
:字符串被包含过滤器的对象替换
Vega 支持 interval
参数,该参数不受 Elasticsearch 8.0.0 及更高版本的支持。 要使用间隔,请改用 fixed_interval
或 calendar_interval
。
例如,以下查询计算特定索引中的文档数
// An object instead of a string for the URL value
// is treated as a context-aware Elasticsearch query.
url: {
// Specify the time filter.
%timefield%: @timestamp
// Apply dashboard context filters when set
%context%: true
// Which indexes to search
index: kibana_sample_data_logs
// The body element may contain "aggs" and "query" keys
body: {
aggs: {
time_buckets: {
date_histogram: {
// Use date histogram aggregation on @timestamp field
field: @timestamp
// interval value will depend on the time filter
// Use an integer to set approximate bucket count
interval: { %autointerval%: true }
// Make sure we get an entire range, even if it has no data
extended_bounds: {
min: { %timefilter%: "min" }
max: { %timefilter%: "max" }
}
// Use this for linear (e.g. line, area) graphs
// Without it, empty buckets will not show up
min_doc_count: 0
}
}
}
// Speed up the response by only including aggregation results
size: 0
}
}
@timestamp
— 过滤时间范围并将其分解为直方图存储桶。
完整结果包括以下结构
{
"aggregations": {
"time_buckets": {
"buckets": [{
"key_as_string": "2015-11-30T22:00:00.000Z",
"key": 1448920800000,<1>
"doc_count": 28
}, {
"key_as_string": "2015-11-30T23:00:00.000Z",
"key": 1448924400000,
"doc_count": 330
}, ...
"key"
— 你可以使用的 unix 时间戳,而无需 Vega 日期表达式进行转换。
对于大多数可视化效果,你只需要存储桶值列表。 要只关注你所需要的数据,请使用 format: {property: "aggregations.time_buckets.buckets"}
。
指定具有单独范围和仪表板上下文的查询。 该查询等效于 "%context%": true, "%timefield%": "@timestamp"
,不同之处在于时间范围向后移动 10 分钟
{
body: {
query: {
bool: {
must: [
// This string will be replaced
// with the auto-generated "MUST" clause
"%dashboard_context-must_clause%"
{
range: {
// apply timefilter (upper right corner)
// to the @timestamp variable
@timestamp: {
// "%timefilter%" will be replaced with
// the current values of the time filter
// (from the upper right corner)
"%timefilter%": true
// Only work with %timefilter%
// Shift current timefilter by 10 units back
shift: 10
// week, day (default), hour, minute, second
unit: minute
}
}
}
]
must_not: [
// This string will be replaced with
// the auto-generated "MUST-NOT" clause
"%dashboard_context-must_not_clause%"
]
filter: [
// This string will be replaced
// with the auto-generated "FILTER" clause
"%dashboard_context-filter_clause%"
]
}
}
}
}
当使用 "%context%": true
或为 "%timefield%"
定义值时,正文不能包含查询。 要自定义 VEGA 规范中的查询(例如,添加其他过滤器或移动时间过滤器),请定义你的查询并使用占位符,如以上示例所示。 占位符将在解析后被仪表板或可视化效果的实际上下文替换。
"%timefilter%"
也可以用于指定单个最小值或最大值。 date_histogram 的 extended_bounds
可以设置为两个值 - 最小值和最大值。 你可以使用 "min": {"%timefilter%": "min"}
,而不是硬编码一个值,它将被当前时间范围的开始时间替换。 shift
和 unit
值也受支持。 还可以动态设置 "interval"
,具体取决于当前选择的范围:"interval": {"%autointerval%": 10}
将尝试获取大约 10-15 个数据点(存储桶)。
[预览] 通过相同机制访问 Elastic Map Service 文件
url: {
// "type" defaults to "elasticsearch" otherwise
%type%: emsfile
// Name of the file, exactly as in https://maps.elastic.co
name: World Countries
}
// The result is either a topojson file or a geojson file.
// Refer to the Default format for the file at https://maps.elastic.co
// Get its features to use this data source with the "shape" marks
// https://vega.github.io/vega/docs/marks/shape/
// For a topojson file use
format: {type: "topojson", feature: "data"}
// For a geojson file use
format: {property: "features"}
[预览] 要启用 地图,图形必须在主机配置中指定 type=map
{
"config": {
"kibana": {
"type": "map",
// Initial map position
"latitude": 40.7,
"longitude": -74,
"zoom": 7,
// Defaults to 'true', disables the base map layer.
"mapStyle": false,
// When 'mapStyle' is 'undefined' or 'true', sets the EMS-layer for the map.
// May either be: "road_map", "road_map_desaturated", "dark_map", "road_map_desaturated_v9", "dark_map_v9".
// If 'emsTileServiceId' is 'undefined', it falls back to the auto-switch-dark-light behavior.
"emsTileServiceId": "road_map",
// default 0
"minZoom": 5,
// defaults to the maximum for the given style,
// or 25 when base is disabled
"maxZoom": 13,
// Defaults to 'true', shows +/- buttons to zoom in/out
"zoomControl": false,
// Defaults to 'false', disables mouse wheel zoom. If set to
// 'true', map may zoom unexpectedly while scrolling dashboard
"scrollWheelZoom": false,
// When false, repaints on each move frame.
// Makes the graph slower when moving the map
"delayRepaint": true,
}
},
/* the rest of Vega JSON */
}
- 默认值 0
- 默认值 0
- 默认值 2
- 默认值为 true
可视化效果会自动注入一个 "projection"
,你可以使用它来计算所有地理感知标记的位置。 此外,你可以使用 latitude
、longitude
和 zoom
信号。 这些信号可以在图形中使用,或者可以更新以修改地图的位置。
[预览] 你可以使用 Vega data 元素通过将 url.data
设置为 emsFile
来访问你的 Vega 地图中管理边界的 Elastic Maps Service (EMS) 矢量形状
"data": [
{
"name": "countries",
"url": {
// "type" defaults to "elasticsearch" otherwise
%type%: emsfile
// Name of the file, exactly as in the Region map visualization
name: World Countries
},
// The result is a topojson file, get its features to use
// this data source with the "shape" marks
// https://vega.github.io/vega/docs/marks/shape/
"format": {"type": "topojson", "feature": "data"},
}
],
"marks": [
{
"type": "shape",
"from": {"data": "countries"},
"transform": [{"type": "geoshape", "projection": "projection"}]
}
]
Kibana 已经安装了 Vega 工具提示插件,因此可以在那里记录的方式定义工具提示。 除此之外,Kibana 还支持用于更改工具提示位置和填充的配置选项
{
config: {
kibana: {
tooltips: {
position: 'top',
padding: 15,
textTruncate: true,
}
}
}
}
Vega 可以从任何 URL 加载数据。 要启用,请在 kibana.yml
中设置 vis_type_vega.enableExternalUrls: true
,然后重新启动 Kibana。
外部 URL 加载的文件必须允许 CORS。 远程 URL 必须包含 Access-Control-Allow-Origin
,它允许来自 Kibana URL 的请求。
你可以通过使用占位符 %timefilter_min%
和 %timefilter_max%
使当前时间范围成为外部时间范围的一部分,作为毫秒时间戳,例如 http://example.com?min=%timefilter_min%
。
使用上下文 检查 工具来深入了解不同的元素。
Vega 使用 Elasticsearch 搜索 API 从 Elasticsearch 获取文档和聚合结果。要解决这些请求的问题,请单击检查,它会显示最新的请求。如果您的规范包含多个请求,您可以使用视图下拉列表在视图之间切换。

通过 Vega 调试视图,您可以检查数据集和信号值运行时数据。
运行时数据是从 运行时作用域 读取的。

要调试更复杂的规范,请访问 view
变量。有关更多信息,请参阅 Vega 浏览器调试过程。
由于 Elasticsearch 中数据的动态特性,除非您可以共享数据集,否则很难帮助您解决 Vega 规范的问题。为此,请单击检查,选择 Vega 调试视图,然后选择规范。

要复制响应,请单击复制到剪贴板。将复制的数据粘贴到 gist.github.com,可以选择使用 .json 扩展名。使用 [raw] 按钮,并在请求帮助时共享它。
[预览] 使用浏览器调试工具(例如,Chrome 中的 F12 或 Ctrl+Shift+J)来检查 VEGA_DEBUG
变量
view
— 访问 Vega View 对象。请参阅 Vega 调试指南,了解如何在运行时检查数据和信号。对于 Vega-Lite,VEGA_DEBUG.view.data('source_0')
获取预转换的数据,而VEGA_DEBUG.view.data('data_0')
获取编码的数据。对于 Vega,它使用在 Vega 规范中定义的数据名称。vega_spec
— Kibana 修改后的 Vega JSON 图形规范。对于 Vega-Lite,这是 Vega-Lite 编译器的输出。vegalite_spec
— 如果这是一个 Vega-Lite 图形,这是 Vega-Lite 编译之前的图形 JSON 规范。
Kibana 已使用这些函数扩展了 Vega 表达式语言。这些函数将触发获取新数据,默认情况下,这将重置 Vega 信号。要保持信号值不变,请在 Vega 配置中设置 restoreSignalValuesOnRefresh: true
。
/**
* @param {object} query Elastic Query DSL snippet, as used in the query DSL editor
* @param {string} [index] as defined in Kibana, or default if missing
* @param {string} Custom label of the filter shown in the filter bar
*/
kibanaAddFilter(query, index, alias)
/**
* @param {object} query Elastic Query DSL snippet, as used in the query DSL editor
* @param {string} [index] as defined in Kibana, or default if missing
*/
kibanaRemoveFilter(query, index)
kibanaRemoveAllFilters()
/**
* Update dashboard time filter to the new values
* @param {number|string|Date} start
* @param {number|string|Date} end
*/
kibanaSetTimeFilter(start, end)
{
config: {
kibana: {
// Placement of the Vega-defined signal bindings.
// Can be `left`, `right`, `top`, or `bottom` (default).
controlsLocation: top
// Can be `vertical` or `horizontal` (default).
controlsDirection: vertical
// If true, hides most of Vega and Vega-Lite warnings
hideWarnings: true
// Vega renderer to use: `svg` or `canvas` (default)
renderer: canvas
// Defaults to 'false', restores Vega signal values on refresh
restoreSignalValuesOnRefresh: false
}
}
}
要了解有关 Vega 和 Vega-Lite 的更多信息,请参阅资源和示例。
Vega Editor 包含 Vega 和 Vega-Lite 的示例,但不支持任何 Kibana 特定的功能,例如 Elasticsearch 请求和交互式底图。
当您在 Kibana 中使用示例时,您可能需要修改 “data” 部分以使用绝对 URL。例如,将 "url": "data/world-110m.json"
替换为 "url": "https://vega.github.io/editor/data/world-110m.json"
。