这是一个分步教程,演示如何create一个简单的仪表板小部件。 您可以将此widget的所有文件下载为ZIP压缩包:lesson_gauge_chart.zip。
在本教程中,您将首先构建一个基础的“Hello, world!” widget,然后将其转换为一个更高级的 widget,以仪表图的形式显示一个 监控项 值。 以下是最终完成的 widget 的外观:
在本节中,您将学习如何create最低要求的widget元素,并向Zabbix前端添加一个新的widget。
1。在 Zabbix 前端安装目录的 modules 目录中(例如,zabbix/ui/modules)创建一个目录,名为 lesson_gauge_chart。
所有自定义小部件均被视为外部模块,且必须添加到 Zabbix 前端安装目录的 modules 目录中(例如,zabbix/ui/modules)。 目录 zabbix/ui/widgets 专用于 Zabbix 内置小部件,并会随着 Zabbix UI 一同更新。
2。创建一个 manifest.json file 文件,包含基本的小部件 get 元数据(请参阅支持的 parameters 描述)。
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"
}
3。在 Zabbix 前端中,进入 Administration → General → Modules 页面,然后点击 Scan directory 按钮。
4。在列表中找到新模块 Gauge chart,点击 "Disabled" 超链接,将模块状态从 "Disabled" 更改为 "Enabled"(如果模块未列出,请参阅 安装 章节)。
5。打开一个仪表板,切换到编辑模式并添加一个新的小部件。在 Type 字段中,选择 "Gauge chart"。
6。此时,Gauge chart 小部件 get 的配置仅包含通用小部件 get 字段 Name 和 Refresh interval。点击 Add 将该小部件 get 添加到仪表板。
7。一个空白的小部件 get 应该会出现在仪表板上。点击右上角的 Top 的 Save changes 按钮以保存仪表板更改。
该小部件的视图file应位于views目录中(本教程中为ui/modules/lesson_gauge_chart/views/)。 如果file使用默认名称widget.view.php,则无需在manifest.json file中注册。 如果file使用其他名称,请在manifest.json file的actions/widget.lesson_gauge_chart.view部分指定。
在lesson_gauge_chart目录中创建views目录。
在views目录中创建widget.view.php file。
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Gauge chart widget view.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, 'Hello, world!')
)
->show();
在本节中,您将学习如何添加一个 widget 配置字段,并将输入的值以文本形式显示在 widget 视图中。
widget 配置由一个表单(Zabbix\Widgets\CWidgetForm)和一个 widget 表单视图(widget.edit.php)组成。
要添加字段(Zabbix\Widgets\CWidgetField),您需要 create 一个 WidgetForm 类,该类将继承 Zabbix\Widgets\CWidgetForm。
表单包含一组各种类型的字段(Zabbix\Widgets\CWidgetField),用于验证用户输入的值。
每种输入元素类型的表单字段(Zabbix\Widgets\CWidgetField)会将值转换为统一格式,以便存储在数据库中。
小部件的 表单 file 应位于 includes 目录中(对于本教程,即 ui/modules/lesson_gauge_chart/includes/)。
如果 file 使用默认名称 WidgetForm.php,则无需在 manifest.json 文件中注册它。
如果 file 使用了其他名称,请在 manifest.json 文件的 widget/form_class 部分指定该名称。
在 lesson_gauge_chart 目录中创建一个新的 includes 目录。
在 includes 目录中创建一个 WidgetForm.php file。
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
/**
* Gauge chart widget form view.
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
转到仪表板,点击 widget 上的齿轮图标以打开 widget 配置表单。
此时 widget 配置表单中包含了一个新的 Description 文本字段。
输入任意值,例如 Gauge chart description。
为了让新描述显示在小部件中,需要从数据库中检索 Description 字段的值,并将其传递给 widget 视图。
为此,您需要 create 一个动作类。
在 lesson_gauge_chart 目录中创建一个新的 actions 目录。
在 actions 目录中创建一个 WidgetView.php file。
WidgetView 动作类将继承 CControllerDashboardWidgetView 类。
widget 配置字段的值存储在动作类的 $fields_values 属性中。
ui/modules/lesson_gauge_chart/actions/WidgetView.php
<?php
namespace Modules\LessonGaugeChart\Actions;
use 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"
}
}
}
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Gauge chart widget view.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, $data['description'])
)
->show();
该widget应显示用户选择的监控项的最新值。为此,你需要在widget配置中添加选择监控项的功能。
在本节中,你将学习如何向widget表单中添加监控项选择字段,以及如何将该字段的可视化部分添加到配置视图中。然后,widget控制器将能够通过API请求检索监控项数据及其值。接收到该值后,可以在widget视图中显示。
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Zabbix\Widgets\{
CWidgetField,
CWidgetForm
};
use Zabbix\Widgets\Fields\{
CWidgetFieldMultiSelectItem,
CWidgetFieldTextBox
};
/**
* Gauge chart widget form.
*/
class WidgetForm extends 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
/**
* Gauge chart widget form view.
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldMultiSelectItemView($data['fields']['itemid'])
)
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
返回仪表板并点击widget中的齿轮图标以打开widget配置表单。
widget配置表单现在包含一个新的输入字段监控项。选择主机 "Zabbix server" 以及监控项 "Load average (1m avg)"。
在widget配置表单中点击 Apply。然后点击Top右上角的 Save changes 以保存仪表板。
打开并修改 actions/WidgetView.php。
从现在开始,监控项的ID将在widget控制器中通过 $this->fields_values['itemid'] 获取。doAction() 控制器方法将使用API方法 item.get 收集监控项数据(名称、值类型、单位),并使用API方法 history.get 收集监控项的最新值。
ui/modules/lesson_gauge_chart/actions/WidgetView.php
<?php
namespace Modules\LessonGaugeChart\Actions;
use API,
CControllerDashboardWidgetView,
CControllerResponseData;
class WidgetView extends CControllerDashboardWidgetView {
protected function 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
/**
* Gauge chart widget view.
*
* @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会在数据缺失时显示string“无数据”。 “无数据”string存在于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
namespace Modules\LessonGaugeChart\Includes;
use Modules\LessonGaugeChart\Widget;
use Zabbix\Widgets\{
CWidgetField,
CWidgetForm
};
use Zabbix\Widgets\Fields\{
CWidgetFieldColor,
CWidgetFieldMultiSelectItem,
CWidgetFieldNumericBox,
CWidgetFieldSelect,
CWidgetFieldTextBox
};
/**
* Gauge chart widget form.
*/
class WidgetForm extends 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'
];
public function addFields(): self {
return $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', 'history source selection method'),
Widget::UNIT_STATIC => _x('Static', 'history source selection method')
]))->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
/**
* Gauge chart widget form view.
*
* @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);
(new CWidgetFormView($data))
->addField(
(new CWidgetFieldMultiSelectItemView($data['fields']['itemid']))
->setPopupParameter('numeric', true)
)
->addFieldset(
(new CWidgetFormFieldsetCollapsibleView(_('Advanced configuration')))
->addField(
new CWidgetFieldColorView($data['fields']['chart_color'])
)
->addField(
new CWidgetFieldNumericBoxView($data['fields']['value_min'])
)
->addField(
new CWidgetFieldNumericBoxView($data['fields']['value_max'])
)
->addItem([
$lefty_units->getLabel(),
(new CFormField([
$lefty_units->getView()->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
$lefty_static_units->getView()
]))
])
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
)
->show();
CWidgetFormView类的addField()方法将CSS类string作为第二个参数。
在本节中,您将学习如何添加一个使用JavaScript制作的仪表盘图表,用于显示最新值是正常、过高还是过低。
JavaScript将负责在配置视图中初始化颜色选择器。
ui/modules/lesson_gauge_chart/views/widget.edit.js.php
<?php
use Modules\LessonGaugeChart\Widget;
?>
window.widget_lesson_gauge_chart_form = new class {
init({color_palette}) {
this._unit_select = document.getElementById('value_units');
this._unit_value = document.getElementById('value_static_units');
this._unit_select.addEventListener('change', () => this.updateForm());
colorPalette.setThemeColors(color_palette);
for (const colorpicker of jQuery('.<?= ZBX_STYLE_COLOR_PICKER ?> input')) {
jQuery(colorpicker).colorpicker();
}
const overlay = overlays_stack.getById('widget_properties');
for (const event of ['overlay.reload', 'overlay.close']) {
overlay.$dialogue[0].addEventListener(event, () => { jQuery.colorpicker('hide'); });
}
this.updateForm();
}
updateForm() {
this._unit_value.disabled = this._unit_select.value == <?= Widget::UNIT_AUTO ?>;
}
};
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Gauge chart widget form view.
*
* @var CView $this
* @var array $data
*/
use Modules\LessonGaugeChart\Includes\WidgetForm;
$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);
(new CWidgetFormView($data))
->addField(
(new CWidgetFieldMultiSelectItemView($data['fields']['itemid']))
->setPopupParameter('numeric', true)
)
->addFieldset(
(new CWidgetFormFieldsetCollapsibleView(_('Advanced configuration')))
->addField(
new CWidgetFieldColorView($data['fields']['chart_color'])
)
->addField(
new CWidgetFieldNumericBoxView($data['fields']['value_min'])
)
->addField(
new CWidgetFieldNumericBoxView($data['fields']['value_max'])
)
->addItem([
$lefty_units->getLabel(),
(new CFormField([
$lefty_units->getView()->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
$lefty_static_units->getView()
]))
])
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
)
->includeJsFile('widget.edit.js.php')
->addJavaScript('widget_lesson_gauge_chart_form.init('.json_encode([
'color_palette' => WidgetForm::DEFAULT_COLOR_PALETTE
], JSON_THROW_ON_ERROR).');')
->show();
在部件配置表单中点击应用。然后在Top右上角点击保存更改以保存仪表盘。
打开actions/WidgetView.php并update控制器。
$this->fields_values属性现在包含所有高级配置字段的值。 完善控制器以实现将配置和选定的监控项值传递给部件视图。
ui/modules/lesson_gauge_chart/actions/WidgetView.php
<?php
namespace Modules\LessonGaugeChart\Actions;
use API,
CControllerDashboardWidgetView,
CControllerResponseData;
class WidgetView extends CControllerDashboardWidgetView {
protected function 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]
]
]);
$history_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) {
$history_value = convertUnitsRaw([
'value' => $history[0]['value'],
'units' => $item['units']
]);
}
}
$this->setResponse(new CControllerResponseData([
'name' => $this->getInput('name', $this->widget->getName()),
'history' => $history_value,
'fields_values' => $this->fields_values,
'user' => [
'debug_mode' => $this->getDebugMode()
]
]));
}
}
您需要create一个用于仪表盘图表的容器(将在后续步骤中绘制)以及一个描述文本容器。
要使用setVar()方法将值作为JSONobject传递给JavaScript。
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Gauge chart widget view.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem([
(new CDiv())->addClass('chart'),
$data['fields_values']['description']
? (new CDiv($data['fields_values']['description']))->addClass('description')
: null
])
->setVar('history', $data['history'])
->setVar('fields_values', $data['fields_values'])
->show();
在lesson_gauge_chart目录中新建assets目录。 该目录将用于存储JavaScript、CSS以及可能需要的其他资源(如字体或图像)。
为部件视图JavaScript,在assets目录下createjs子目录。
在assets/js目录中创建class.widget.jsfile。
此JavaScript部件类将扩展所有仪表盘部件的基类——CWidget。
仪表盘依赖于部件的正确实现,并通过调用相应的JavaScript方法与部件通信相关信息。 仪表盘还期望部件在发生交互时generate事件。 因此,CWidget类包含一组具有默认部件行为实现的方法,可通过扩展该类进行自定义。
本例中需要对以下部件行为实现自定义逻辑:
对于仪表盘图表部件的其他方面,将使用部件行为的默认实现。 要了解CWidget类的JavaScript方法详情,请参阅:JavaScript。
由于此JavaScript是部件视图所必需的,应随仪表盘页面加载。 要实现JavaScript加载,您需要在manifest.jsonfile中updateassets/js和js_class参数,如步骤10.所示
ui/modules/lesson_gauge_chart/assets/js/class.widget.js
class WidgetLessonGaugeChart extends CWidget {
static UNIT_AUTO = 0;
static UNIT_STATIC = 1;
onInitialize() {
super.onInitialize();
this._refresh_frame = null;
this._chart_container = null;
this._canvas = null;
this._chart_color = null;
this._min = null;
this._max = null;
this._value = null;
this._last_value = null;
this._units = '';
}
processUpdateResponse(response) {
if (response.history === null) {
this._value = null;
this._units = '';
}
else {
this._value = Number(response.history.value);
this._units = response.fields_values.value_units == WidgetLessonGaugeChart.UNIT_AUTO
? response.history.units
: response.fields_values.value_static_units;
}
this._chart_color = response.fields_values.chart_color;
this._min = Number(response.fields_values.value_min);
this._max = Number(response.fields_values.value_max);
super.processUpdateResponse(response);
}
setContents(response) {
if (this._canvas === null) {
super.setContents(response);
this._chart_container = this._body.querySelector('.chart');
this._chart_container.style.height =
`${this._getContentsSize().height - this._body.querySelector('.description').clientHeight}px`;
this._canvas = document.createElement('canvas');
this._chart_container.appendChild(this._canvas);
this._resizeChart();
}
this._updatedChart();
}
onResize() {
super.onResize();
if (this._state === WIDGET_STATE_ACTIVE) {
this._resizeChart();
}
}
_resizeChart() {
const ctx = this._canvas.getContext('2d');
const dpr = window.devicePixelRatio;
this._canvas.style.display = 'none';
const size = Math.min(this._chart_container.offsetWidth, this._chart_container.offsetHeight);
this._canvas.style.display = '';
this._canvas.width = size * dpr;
this._canvas.height = size * dpr;
ctx.scale(dpr, dpr);
this._canvas.style.width = `${size}px`;
this._canvas.style.height = `${size}px`;
this._refresh_frame = null;
this._updatedChart();
}
_updatedChart() {
if (this._last_value === null) {
this._last_value = this._min;
}
const start_time = Date.now();
const end_time = start_time + 400;
const animate = () => {
const time = Date.now();
if (time <= end_time) {
const progress = (time - start_time) / (end_time - start_time);
const smooth_progress = 0.5 + Math.sin(Math.PI * (progress - 0.5)) / 2;
let value = this._value !== null ? this._value : this._min;
value = (this._last_value + (value - this._last_value) * smooth_progress - this._min) / (this._max - this._min);
const ctx = this._canvas.getContext('2d');
const size = this._canvas.width;
const char_weight = size / 12;
const char_shadow = 3;
const char_x = size / 2;
const char_y = size / 2;
const char_radius = (size - char_weight) / 2 - char_shadow;
const font_ratio = 32 / 100;
ctx.clearRect(0, 0, size, size);
ctx.beginPath();
ctx.shadowBlur = char_shadow;
ctx.shadowColor = '#bbb';
ctx.strokeStyle = '#eee';
ctx.lineWidth = char_weight;
ctx.lineCap = 'round';
ctx.arc(char_x, char_y, char_radius, Math.PI * 0.749, Math.PI * 2.251, false);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = `#${this._chart_color}`;
ctx.lineWidth = char_weight - 2;
ctx.lineCap = 'round';
ctx.arc(char_x, char_y, char_radius, Math.PI * 0.75,
Math.PI * (0.75 + (1.5 * Math.min(1, Math.max(0, value)))), false
);
ctx.stroke();
ctx.shadowBlur = 2;
ctx.fillStyle = '#1f2c33';
ctx.font = `${(char_radius * font_ratio)|0}px Arial`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(`${this._value !== null ? this._value : t('No data')}${this._units}`,
char_x, char_y, size - char_shadow * 4 - char_weight * 2
);
ctx.fillStyle = '#768d99';
ctx.font = `${(char_radius * font_ratio * .5)|0}px Arial`;
ctx.textBaseline = 'top';
ctx.textAlign = 'left';
ctx.fillText(`${this._min}${this._min != '' ? this._units : ''}`,
char_weight * .75, size - char_weight * 1.25, size / 2 - char_weight
);
ctx.textAlign = 'right';
ctx.fillText(`${this._max}${this._max != '' ? this._units : ''}`,
size - char_weight * .75, size - char_weight * 1.25, size / 2 - char_weight
);
requestAnimationFrame(animate);
}
else {
this._last_value = this._value;
}
};
requestAnimationFrame(animate);
}
}
WidgetLessonGaugeChart类现在将随仪表盘自动加载。
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": {
"js": ["class.widget.js"]
}
}
在本节中,您将学习如何添加自定义 CSS 样式,以使 widget 看起来更加美观。
1。针对 widget 样式,在 assets 目录中 create 一个名为 css 的新目录。
2。在 assets/css 目录中创建一个 widget.css file 文件。
为 widget 元素设置样式,请使用选择器 div.dashboard-widget-{widget id}。
为整个 widget 配置 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;
}
3。打开 manifest.json 并将 CSS file 名称(widget.css)添加到 assets/css 部分的 array 中。
这样就可以在仪表板页面加载时同时加载 widget.css 中定义的 CSS 样式。
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"]
}
}
4。刷新仪表板页面,以查看 widget 的最终 version 效果。