构建自定义面板选项编辑器
Grafana 插件平台提供一系列编辑器,允许您的用户自定义面板。标准编辑器涵盖了最常见的选项类型,例如文本输入和布尔开关。如果您找不到所需的编辑器,可以构建自己的编辑器。
面板选项编辑器基础知识
最简单的编辑器是一个接受两个属性的 React 组件
value
:选项的当前值onChange
:更新选项的值
以下示例中的编辑器允许用户通过单击按钮来切换布尔值
src/SimpleEditor.tsx
import React from 'react';
import { Button } from '@grafana/ui';
import { StandardEditorProps } from '@grafana/data';
export const SimpleEditor = ({ value, onChange }: StandardEditorProps<boolean>) => {
return <Button onClick={() => onChange(!value)}>{value ? 'Disable' : 'Enable'}</Button>;
};
要使用自定义面板选项编辑器,请在 module.ts
文件中的 OptionsUIBuilder
对象上使用 addCustomEditor
,并将 editor
属性设置为您的自定义编辑器组件的名称。
src/module.ts
export const plugin = new PanelPlugin<SimpleOptions>(SimplePanel).setPanelOptions((builder) => {
return builder.addCustomEditor({
id: 'label',
path: 'label',
name: 'Label',
editor: SimpleEditor,
});
});
向面板选项编辑器添加设置
您可以使用自定义编辑器来自定义多个可能的设置。要向编辑器添加设置,请将 StandardEditorProps
的第二个模板变量设置为包含您要配置的设置的接口。通过 item
属性访问编辑器设置。
这是一个编辑器示例,该编辑器使用一系列数字填充下拉列表。Settings
接口定义了 from
和 to
属性的范围。
src/SimpleEditor.tsx
interface Settings {
from: number;
to: number;
}
type Props = StandardEditorProps<number, Settings>;
export const SimpleEditor = ({ item, value, onChange }: Props) => {
const options: Array<SelectableValue<number>> = [];
// Default values
const from = item.settings?.from ?? 1;
const to = item.settings?.to ?? 10;
for (let i = from; i <= to; i++) {
options.push({
label: i.toString(),
value: i,
});
}
return <Select options={options} value={value} onChange={(selectableValue) => onChange(selectableValue.value)} />;
};
您现在可以通过配置 settings
属性来调用 addCustomEditor
,从而为每个选项配置编辑器
src/module.ts
export const plugin = new PanelPlugin<SimpleOptions>(SimplePanel).setPanelOptions((builder) => {
return builder.addCustomEditor({
id: 'index',
path: 'index',
name: 'Index',
editor: SimpleEditor,
settings: {
from: 1,
to: 10,
},
});
});
在面板选项编辑器中使用查询结果
选项编辑器可以访问上次查询的结果。这使您可以根据数据源返回的数据动态更新编辑器。
编辑器上下文通过 context
属性可用。数据源返回的数据帧在 context.data
下可用。
src/SimpleEditor.tsx
export const SimpleEditor = ({ item, value, onChange, context }: StandardEditorProps<string>) => {
const options: SelectableValue<string>[] = [];
if (context.data) {
const frames = context.data;
for (let i = 0; i < frames.length; i++) {
options.push({
label: frames[i].name,
value: frames[i].name,
});
}
}
return <Select options={options} value={value} onChange={(selectableValue) => onChange(selectableValue.value)} />;
};