跳转到主要内容

可视化

您可以通过使用场景对象类 VizPanel 将可视化添加到场景中。

简单的 VizPanel 示例

new VizPanel({
pluginId: 'timeseries',
title: 'Time series',
options: {
legend: {
showLegend: false,
}
},
fieldConfig: {
defaults: {
unit: 'bytes',
min: 0,
custom: { lineWidth: 2 fillOpacity: 6 },
},
overrides: [],
}
})
注意

前面示例中使用的插件 ID,timeseries,指的是 Grafana 核心面板插件,这是时间索引数据的标准图表可视化。optionsfieldConfig 是在面板检查器抽屉中查看 JSON 选项卡时在典型仪表板面板中看到的相同选项。要访问此选项卡,请在面板编辑菜单中单击 检查 > 面板 JSON

数据

VizPanel 使用 sceneGraph.getData(model) 调用来查找并订阅具有 SceneDataProvider 对象的最接近的父对象。这意味着如果任何父级别设置了 $data,则 VizPanel 使用其自身级别上的 $data 或与其他兄弟和场景对象共享数据。

页眉操作

VizPanel 有一个名为 headerActions 的属性,可以是 React.ReactNode 或自定义 SceneObject。此属性在您想在面板页眉的右上角放置链接或按钮时非常有用。例如

VizPanelMenu 类型的菜单属性是可选的,当设置时,它定义了面板右上角的菜单。菜单对象仅在下拉菜单本身渲染时才被激活。因此,添加动态菜单操作和链接的最佳方法是通过将它们添加到菜单附件的 行为 中。

new VizPanel({
pluginId: 'timeseries',
title: 'Time series',
headerActions: (
<LinkButton size="sm" variant="secondary" href="scenes/drilldown/url">
Drilldown
</LinkButton>
),
});

面板标题右上角的按钮可用于

  • 链接到其他场景
  • 更改当前场景的按钮(例如添加钻取页面)
  • 一个 RadioButtonGroup,用于更改可视化设置

对于 LinkButtonButtonRadioButtonGroup,当您将它们放置在面板标题中时,请使用 size="sm"。

标准 Grafana 可视化

场景附带一个辅助 API,PanelBuilders,用于构建 标准 Grafana 可视化。这些包括

  • 条形图
  • 柱形仪表
  • 数据网格
  • 火焰图
  • 仪表
  • 地理地图
  • 热图
  • 直方图
  • 日志
  • 新闻
  • 节点图
  • 饼图
  • 统计
  • 状态时间线
  • 状态历史
  • 表格
  • 文本
  • 时间序列
  • 趋势
  • 跟踪
  • XY 图表

PanelBuilders API 为构建列出的可视化 VizPanel 对象提供支持,支持面板选项和字段配置。

第 1 步。导入 PanelBuilders API

import { PanelBuilders } from '@grafana/scenes';

第 2 步。配置标准可视化 VizPanel 对象

const myTimeSeriesPanel = PanelBuilders.timeseries().setTitle('My first panel');

第 3 步。配置数据和时间范围

const data = new SceneQueryRunner({
datasource: {
type: 'prometheus',
uid: '<PROVIDE_GRAFANA_DS_UID>',
},
queries: [
{
refId: 'A',
expr: 'rate(prometheus_http_requests_total{}[5m])',
},
],
$timeRange: new SceneTimeRange({ from: 'now-5m', to: 'now' }),
});

myTimeSeriesPanel.setData(data);

第 4 步。配置面板选项

myTimeSeriesPanel.setOption('legend', { asTable: true }).setOption('tooltip', { mode: TooltipDisplayMode.Single });

第 5 步。配置标准选项

所有 Grafana 可视化都附带标准选项。PanelBuilders 提供了设置每个标准选项的方法。有关标准选项的更多信息,请参阅官方 Grafana 文档

myTimeSeriesPanel.setDecimals(2).setUnit('ms');

第 6 步。配置自定义字段配置

Grafana 可视化提供自定义的、针对特定可视化的配置选项,称为 字段配置。有关字段配置的更多信息,请参阅官方 Grafana 文档

使用 setCustomFieldConfig 方法设置所需的字段配置属性值。

myTimeSeriesPanel.setCustomFieldConfig('lineInterpolation', LineInterpolation.Smooth);

第 7 步。配置覆盖

Grafana 可视化允许您为特定字段或系列自定义可视化设置。这是通过添加一个针对特定字段集的重写规则来实现的,每个规则可以定义多个选项。有关重写的更多信息,请参阅官方Grafana 文档

使用 setOverrides 方法设置所需的字段配置重写。对于标准选项,使用 override<OptionName> 方法。对于自定义字段配置,使用 overrideCustomConfigProperty 方法。

myTimeSeriesPanel.setOverrides((b) =>
b.matchFieldsWithNameByRegex('/metrics/').overrideDecimals(4).overrideCustomFieldConfig('lineWidth', 5)
);

单个重写配置从 匹配器 配置开始。多亏了匹配器,Grafana 才知道应该将重写应用于结果的哪个部分。以下是一些可用的匹配器:

matchFieldsWithName(name: string)

根据提供的字段名选择一个字段。使用此选择器添加到规则中的属性仅应用于此单个字段。

matchFieldsWithNameByRegex(regex: string)

使用正则表达式指定要重写的字段。使用此选择器添加到规则中的属性应用于所有字段名与正则表达式匹配的字段。

matchFieldsByType(fieldType: FieldType)

通过类型选择字段,例如字符串、数值等。使用此选择器添加到规则中的属性应用于所有匹配所选类型的字段。

matchFieldsByQuery(refId: string)

选择特定查询返回的所有字段,例如 A、B 或 C。使用此选择器添加到规则中的属性应用于所选查询返回的所有字段。

matchFieldsByValue(options: FieldValueMatcherConfig)

选择所有与提供的值条件配置匹配的字段。此匹配器允许基于对系列减少值的条件执行重写配置。例如,您可以配置平均值高于提供的值的系列的重写。

matchComparisonQuery(refId: string)

选择比较查询返回的所有字段。使用此选择器添加到规则中的属性应用于为所选查询执行的比较查询返回的所有字段。有关时间范围比较的更多信息。

步骤 8. 构建可视化

使用 build 方法生成配置的 VizPanel 对象

const myPanel = myTimeSeriesPanel.build();

步骤9. 将可视化添加到场景

创建一个包含布局的场景,并将可视化作为布局子项添加

const scene = new EmbeddedScene({
body: new SceneFlexLayout({
children: [
new SceneFlexItem({
body: myPanel,
}),
],
}),
});

此构建的面板现在可以用于场景中。

将通用可视化配置提取到mixin函数中

function latencyGraphMixin(builder: ReturnType<typeof PanelBuilders["timeseries"]>) {
builder.setMin(0);
builder.setOption('legend', { showLegend: false: true })
}

const panel = PanelBuilders.timeseries().applyMixin(latencyGraphMixin).setData(...)

自定义可视化

如果您想确定Grafana应用程序插件中数据是如何可视化的,您可以通过两种方式实现。您始终可以选择创建自定义的SceneObject,但您将不会获得VizPanel提供的带有加载状态和其他功能。如果您想在面板框架内创建自定义可视化,并且它应该看起来与场景中的其他面板相似,那么最好注册一个运行时面板插件。

步骤1. 定义自定义面板选项和字段配置

interface CustomVizOptions {
mode: string;
}

interface CustomVizFieldOptions {
numericOption: number;
}

interface Props extends PanelProps<CustomVizOptions> {}

步骤2. 定义渲染自定义PanelPlugin的react组件

export function CustomVizPanel(props: Props) {
const { options, data } = props;

return (
<div>
<h4>
CustomVizPanel options: <pre>{JSON.stringify(options)}</pre>
</h4>
<div>
CustomVizPanel field config: <pre>{JSON.stringify(data.series[0]?.fields[0]?.config)}</pre>
</div>
</div>
);
}

步骤3. 创建PanelPlugin实例并将其注册到场景库中

import { sceneUtils } from '@grafana/scenes';

const myCustomPanel = new PanelPlugin<CustomVizOptions, CustomVizFieldOptions>(CustomVizPanel).useFieldConfig({
useCustomConfig: (builder) => {
builder.addNumberInput({
path: 'numericOption',
name: 'Numeric option',
description: 'A numeric option',
defaultValue: 1,
});
},
});

sceneUtils.registerRuntimePanelPlugin({ pluginId: 'my-scene-app-my-custom-viz', plugin: myCustomPanel });

步骤4. 在场景中使用自定义面板

现在您可以在任何VizPanel中使用此pluginId。请确保您指定的pluginId包含场景应用程序名称,并且不太可能与其他场景应用程序冲突。

const data = new SceneQueryRunner({
datasource: {
type: 'prometheus',
uid: 'gdev-prometheus',
},
queries: [
{
refId: 'A',
expr: 'rate(prometheus_http_requests_total{}[5m])',
},
],
$timeRange: new SceneTimeRange({ from: 'now-5m', to: 'now' }),
});

return new EmbeddedScene({
$data: data,
body: new SceneFlexLayout({
children: [
new SceneFlexItem({
body: new VizPanel({
pluginId: 'my-scene-app-my-custom-viz',
options: { mode: 'my-custom-mode' },
fieldConfig: {
defaults: {
unit: 'ms',
custom: {
numericOption: 100,
},
},
overrides: [],
},
}),
}),
],
}),
});

有关更多信息,请参阅官方构建面板插件的教程。只需记住,对于场景运行时面板插件,您不需要为面板插件创建plugin.json文件,因为它不会是一个可以用于仪表板的独立插件。您只能将插件引用到您的场景应用程序中。

源代码

查看示例源代码