构建自定义面板选项编辑器
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)} />;
};