这是一个分步教程,展示了如何创建一个简单的仪表板小部件。 您可以将此小部件的所有文件下载为 ZIP 存档:lesson_gauge_chart.zip。
在本教程中,您将首先构建一个 基本“Hello, world!”小部件,然后将其转换为一个 更高级 小部件,该小部件将项目值显示为仪表图。 完成的小部件将如下所示:
在本部分中,您将学习如何创建所需的最小小部件元素并向 Zabbix 前端添加新小部件。
所有自定义小部件都被视为外部模块,必须添加到 Zabbix 前端安装的 modules 目录中(例如,zabbix/ui/modules)。 目录 zabbix/ui/widgets 为 Zabbix 内置小部件保留,并与 Zabbix UI 一起更新。
ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Gauge chart",
"namespace": "LessonGaugeChart",
"version": "1.1",
"author": "Zabbix"
}
单击“添加”将小部件添加到仪表板。
小部件的 view 文件应位于 views 目录中(本教程中为 ui/modules/lesson_gauge_chart/views/)。 如果文件具有默认名称 widget.view.php,则无需在 manifest.json 文件中注册它。 如果文件具有不同的名称,请在 manifest.json 文件的 actions/widget.lesson_gauge_chart.view 部分中指定它。
在 lesson_gauge_chart 目录中创建目录 views。
在 views 目录中创建 widget.view.php 文件。
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* 仪表盘小部件视图。
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, 'Hello, world!')
)
->show();
在本节中,您将了解如何添加小部件配置字段,并在小部件视图中将输入的值显示为文本。
小部件配置由表单 (Zabbix\Widgets\CWidgetForm) 和小部件表单视图 (widget.edit.php) 组成。
要添加字段 (Zabbix\Widgets\CWidgetField),您需要创建一个 WidgetForm 类,它将扩展 Zabbix\Widgets\CWidgetForm。
表单包含各种类型的字段集 (Zabbix\Widgets\CWidgetField),用于验证用户输入的值。
每个输入元素类型的表单字段 (Zabbix\Widgets\CWidgetField) 将值转换为单一格式以将其存储在数据库中。
小部件的 form 文件应位于 includes 目录中(本教程中为 ui/modules/lesson_gauge_chart/includes/)。 如果文件具有默认名称 WidgetForm.php,则无需在 manifest.json 文件中注册它。 如果文件具有不同的名称,请在 manifest.json 文件的 widget/form_class 部分中指定它。
在 lesson_gauge_chart 目录中创建一个新目录 includes。
在 includes 目录中创建一个 WidgetForm.php 文件。
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Zabbix\Widgets\CWidgetForm;
class WidgetForm extends CWidgetForm {
}
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Zabbix\Widgets\CWidgetForm;
use Zabbix\Widgets\Fields\CWidgetFieldTextBox;
class WidgetForm extends CWidgetForm {
public function addFields(): self {
return $this
->addField(
new CWidgetFieldTextBox('description', _('Description'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* 仪表图小部件表单视图。
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
转到仪表板并单击小部件中的齿轮图标以打开小部件配置表单。
小部件配置表单现在包含一个新的 Description 文本字段。 输入任何值,例如 Gauge chart description。
要使新描述显示在小部件中,需要从数据库中检索 Description 字段值并将其传递给小部件视图。
为此,您需要创建一个操作类。
在 lesson_gauge_chart 目录中创建一个新目录 actions。
在 actions 目录中创建一个 WidgetView.php 文件。
WidgetView 操作类将扩展 CControllerDashboardWidgetView 类。
小部件配置字段的值存储在操作类的 $fields_values 属性中。
ui/modules/lesson_gauge_chart/actions/WidgetView.php
<?php
命名空间 Modules\LessonGaugeChart\Actions;
使用 CControllerDashboardWidgetView,
CControllerResponseData;
class WidgetView extends CControllerDashboardWidgetView {
protected function doAction(): void {
$this->setResponse(new CControllerResponseData([
'name' => $this->getInput('name', $this->widget->getName()),
'description' => $this->fields_values['description'],
'user' => [
'debug_mode' => $this->getDebugMode()
]
]));
}
}
ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Gauge chart",
"namespace": "LessonGaugeChart",
"version": "1.0",
"author": "Zabbix",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
}
}
打开 views/widget.view.php 并将静态文本“Hello, world!”替换为 $data['description']。
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* 仪表盘小部件视图。
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, $data['description'])
)
->show();
小部件应显示用户选择的项目的最后一个值。 为此,您需要在小部件配置中添加选择项目的功能。
在本节中,您将了解如何向小部件表单添加项目选择字段以及如何将此字段的可视部分添加到配置视图。 然后,小部件控制器将能够通过 API 请求检索项目数据及其值。 收到后,该值可显示在小部件视图中。
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
命名空间 Modules\LessonGaugeChart\Includes;
使用 Zabbix\Widgets\{
CWidgetField,
CWidgetForm
};
使用 Zabbix\Widgets\Fields\{
CWidgetFieldMultiSelectItem,
CWidgetFieldTextBox
};
/**
* 仪表图表小部件表单。
*/
class WidgetForm 扩展 CWidgetForm {
public function addFields(): self {
return $this
->addField(
(new CWidgetFieldMultiSelectItem('itemid', _('Item')))
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
->setMultiple(false)
)
->addField(
new CWidgetFieldTextBox('description', _('Description'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* 仪表盘小部件表单视图。
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldMultiSelectItemView($data['fields']['itemid'])
)
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
返回仪表板并单击小部件中的齿轮图标以打开小部件配置表单。
小部件配置表单现在包含一个新的输入字段 Item。 选择主机“Zabbix 服务器”和项目“平均负载(1 分钟平均值)”。
在小部件配置表单中单击 应用。然后单击右上角的 保存更改 以保存仪表板。
打开并修改 actions/WidgetView.php。
从现在开始,项目 ID 将在小部件控制器中的 $this->fields_values['itemid'] 中可用。 doAction() 控制器方法使用 API 方法 item.get 收集项目数据(名称、值类型、单位),并使用 API 方法 history.get 收集项目的最后一个值。
ui/modules/lesson_gauge_chart/actions/WidgetView.php
<?php
命名空间 Modules\LessonGaugeChart\Actions;
使用 API,
CControllerDashboardWidgetView,
CControllerResponseData;
类 WidgetView 扩展了 CControllerDashboardWidgetView {
受保护的函数 doAction():void {
$db_items = API::Item()->get([
'output' => ['itemid', 'value_type', 'name', 'units'],
'itemids' => $this->fields_values['itemid'],
'webitems' => true,
'filter' => [
'value_type' => [ITEM_VALUE_TYPE_UINT64, ITEM_VALUE_TYPE_FLOAT]
]
]);
$value = null;
if ($db_items) {
$item = $db_items[0];
$history = API::History()->get([
'output' => API_OUTPUT_EXTEND,
'itemids' => $item['itemid'],
'history' => $item['value_type'],
'sortfield' => 'clock',
'sortorder' => ZBX_SORT_DOWN,
'limit' => 1
]);
if ($history) {
$value = convertUnitsRaw([
'value' => $history[0]['value'],
'units' => $item['units']
]);
}
}
$this->setResponse(new CControllerResponseData([
'name' => $this->getInput('name', $this->widget->getName()),
'value' => $value,
'description' => $this->fields_values['description'],
'user' => [
'debug_mode' => $this->getDebugMode()
]
]));
}
}
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* 仪表图小部件视图。
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem([
new CTag('h1', true, $data['description']),
new CDiv($data['value'] !== null ? $data['value']['value'] : _('No data'))
])
->show();
在本节中,您将了解如何添加可扩展/可折叠的 高级配置 部分,其中包含可选参数,例如颜色、最小值和最大值、单位以及之前创建的 描述 字段。
Widget 类将扩展 CWidget 基类以添加/覆盖默认窗口小部件设置(在本例中为翻译)。
如果缺少数据,下面提供的 JavaScript 将显示字符串“无数据”。
“无数据”字符串存在于 Zabbix UI 翻译文件中。
如果有任何窗口小部件常量,建议也在 Widget 类中指定它们。
ui/modules/lesson_gauge_chart/Widget.php
<?php
namespace Modules\LessonGaugeChart;
use Zabbix\Core\CWidget;
class Widget extends CWidget {
public const UNIT_AUTO = 0;
public const UNIT_STATIC = 1;
public function getTranslationStrings(): array {
return [
'class.widget.js' => [
'No data' => _('No data')
]
];
}
}
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
命名空间 Modules\LessonGaugeChart\Includes;
使用 Modules\LessonGaugeChart\Widget;
使用 Zabbix\Widgets\{
CWidgetField,
CWidgetForm
};
使用 Zabbix\Widgets\Fields\{
CWidgetFieldColor,
CWidgetFieldMultiSelectItem,
CWidgetFieldNumericBox,
CWidgetFieldSelect,
CWidgetFieldTextBox
};
/**
* 仪表图表小部件表单。
*/
类 WidgetForm 扩展了 CWidgetForm {
public const DEFAULT_COLOR_PALETTE = [
'FF465C', 'B0AF07', '0EC9AC', '524BBC', 'ED1248', 'D1E754', '2AB5FF', '385CC7', 'EC1594', 'BAE37D',
'6AC8FF', 'EE2B29', '3CA20D', '6F4BBC', '00A1FF', 'F3601B', '1CAE59', '45CFDB', '894BBC', '6D6D6D'
];
公共函数 addFields(): self {
返回 $this
->addField(
(new CWidgetFieldMultiSelectItem('itemid', _('Item')))
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
->setMultiple(false)
)
->addField(
(new CWidgetFieldColor('chart_color', _('Color')))->setDefault('FF0000')
)
->addField(
(new CWidgetFieldNumericBox('value_min', _('Min')))
->setDefault(0)
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
)
->addField(
(new CWidgetFieldNumericBox('value_max', _('Max')))
->setDefault(100)
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
)
->addField(
(new CWidgetFieldSelect('value_units', _('Units'), [
Widget::UNIT_AUTO => _x('Auto', '历史源选择方法'),
Widget::UNIT_STATIC => _x('Static', '历史源选择方法')
]))->setDefault(Widget::UNIT_AUTO)
)
->addField(
(new CWidgetFieldTextBox('value_static_units'))
)
->addField(
new CWidgetFieldTextBox('description', _('Description'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* 仪表图小部件表单视图。
*
* @var CView $this
* @var array $data
*/
$lefty_units = new CWidgetFieldSelectView($data['fields']['value_units']);
$lefty_static_units = (new CWidgetFieldTextBoxView($data['fields']['value_static_units']))
->setPlaceholder(_('value'))
->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
(新 CWidgetFormView($data))
->addField(
(新 CWidgetFieldMultiSelectItemView($data['fields']['itemid']))
->setPopupParameter('numeric', true)
)
->addFieldset(
(新 CWidgetFormFieldsetCollapsibleView(_('高级配置')))
->addField(
新 CWidgetFieldColorView($data['fields']['chart_color'])
)
->addField(
新 CWidgetFieldNumericBoxView($data['fields']['value_min'])
)
->addField(
新 CWidgetFieldNumericBoxView($data['fields']['value_max'])
)
->addItem([
$lefty_units->getLabel(),
(新 CFormField([
$lefty_units->getView()->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
$lefty_static_units->getView()
]))
])
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
)
->show();
CWidgetFormView 类的 addField() 方法将 CSS 类字符串作为第二个参数。
在本节中,您将学习如何添加自定义 CSS 样式以使小部件看起来更具吸引力。
对于小部件样式,请在 assets 目录中创建一个新目录 css。
在 assets/css 目录中创建一个 widget.css 文件。 要设置小部件元素的样式,请使用选择器 div.dashboard-widget-{widget id}。 要为整个小部件配置 CSS,请使用选择器 form.dashboard-widget-{widget id}
ui/modules/lesson_gauge_chart/assets/css/widget.css
div.dashboard-widget-lesson_gauge_chart {
display: grid;
grid-template-rows: 1fr;
padding: 0;
}
div.dashboard-widget-lesson_gauge_chart .chart {
display: grid;
align-items: center;
justify-items: center;
}
div.dashboard-widget-lesson_gauge_chart .chart canvas {
background: white;
}
div.dashboard-widget-lesson_gauge_chart .description {
padding-bottom: 8px;
font-size: 1.750em;
line-height: 1.2;
text-align: center;
}
.dashboard-grid-widget-hidden-header div.dashboard-widget-lesson_gauge_chart .chart {
margin-top: 8px;
}
ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Gauge chart",
"namespace": "LessonGaugeChart",
"version": "1.0",
"author": "Zabbix",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
},
"widget": {
"js_class": "WidgetLessonGaugeChart"
},
"assets": {
"css": ["widget.css"],
"js": ["class.widget.js"]
}
}