构建自定义面板选项编辑器
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
文件中使用 addCustomEditor
方法在 OptionsUIBuilder
对象上,并将 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)} />;
};