Dit is een stapsgewijze handleiding die laat zien hoe je een eenvoudige dashboardwidget kunt maken.
De vereiste minimale Zabbix-versie voor deze tutorial is 6.4.4.
Je kunt alle bestanden van deze widget downloaden als een ZIP-archief: lesson_gauge_chart.zip.
Tijdens deze tutorial ga je eerst een basis "Hallo, wereld!" widget maken en vervolgens deze omzetten naar een geavanceerdere widget die een itemwaarde weergeeft als een metergrafiek. Zo ziet de afgewerkte widget eruit:
In deze sectie leert u hoe u de minimaal vereiste widget-elementen maakt en een nieuwe widget toevoegt aan de Zabbix-frontend.
Alle aangepaste widgets worden behandeld als externe modules en moeten worden toegevoegd aan de map ui/modules. De map ui/widgets is gereserveerd voor de ingebouwde widgets van Zabbix en wordt bijgewerkt samen met de Zabbix-UI.
ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Metergrafiek",
"namespace": "LessonGaugeChart",
"version": "1.0",
"author": "Zabbix SIA"
}
Het weergave-bestand van de widget moet zich bevinden in de views-map (voor deze tutorial ui/modules/lesson_gauge_chart/views/). Als het bestand de standaardnaam widget.view.php heeft, hoef je het niet te registreren in het manifest.json-bestand. Als het bestand een andere naam heeft, specificeer deze dan in de sectie actions/widget.lesson_gauge_chart.view van het manifest.json-bestand.
Maak een map genaamd views aan in de lesson_gauge_chart-map.
Maak een bestand genaamd widget.view.php aan in de views-map.
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Weergave van de metergrafiek-widget.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, 'Hallo, wereld!')
)
->show();
In dit gedeelte leer je hoe je een configuratieveld aan een widget kunt toevoegen en de ingevoerde waarde in de widgetweergave kunt tonen als tekst.
De configuratie van de widget bestaat uit een formulier (Zabbix\Widgets\CWidgetForm) en een weergave voor het widgetformulier (widget.edit.php). Om velden (Zabbix\Widgets\CWidgetField) toe te voegen, moet je een klasse WidgetForm maken, die Zabbix\Widgets\CWidgetForm uitbreidt.
Het formulier bevat een reeks velden (Zabbix\Widgets\CWidgetField) van verschillende typen, die worden gebruikt om de door de gebruiker ingevoerde waarden te valideren. Het formulierveld (Zabbix\Widgets\CWidgetField) voor elk invoerelementtype converteert de waarde naar een enkel formaat om deze op te slaan in de database.
Het formulier-bestand van de widget moet zich bevinden in de includes-map (voor deze tutorial ui/modules/lesson_gauge_chart/includes/). Als het bestand de standaardnaam WidgetForm.php heeft, hoef je het niet te registreren in het manifest.json-bestand. Als het bestand een andere naam heeft, specificeer deze dan in de sectie widget/form_class van het manifest.json-bestand.
Maak een nieuwe map genaamd includes aan in de lesson_gauge_chart-map.
Maak een bestand genaamd WidgetForm.php aan in de includes-map.
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', _('Beschrijving'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Weergave van het formulier voor de metergrafiek-widget.
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
Ga naar het dashboard en klik op het tandwielicoon in de widget om het configuratieformulier van het widget te openen.
Het configuratieformulier van het widget bevat nu een nieuw tekstveld Beschrijving. Voer een willekeurige waarde in, bijvoorbeeld Beschrijving van de metergrafiek.
Om de nieuwe beschrijving in het widget te laten verschijnen, moet de waarde van het veld Beschrijving uit de database worden opgehaald en doorgegeven aan de weergave van het widget. Hiervoor moet je een actieklasse maken.
Maak een nieuwe map genaamd actions aan in de lesson_gauge_chart-map.
Maak een bestand genaamd WidgetView.php aan in de actions-map. De actieklasse WidgetView zal de klasse CControllerDashboardWidgetView uitbreiden.
Waarden van de velden in de configuratie van het widget worden opgeslagen in de eigenschap $fields_values van de actieklasse.
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": "Metergrafiek",
"namespace": "LessonGaugeChart",
"version": "1.0",
"author": "Zabbix SIA",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
}
}
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Weergave van de metergrafiek-widget.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, $data['description'])
)
->show();
Het widget zou de laatste waarde van een item naar keuze van de gebruiker moeten tonen. Hiervoor moet je de mogelijkheid toevoegen om items te selecteren in de configuratie van het widget.
In dit gedeelte leer je hoe je een itemselectieveld aan het widgetformulier kunt toevoegen en hoe je het visuele deel van dit veld kunt toevoegen aan de configuratieweergave. Daarna kan de widgetcontroller itemgegevens en de waarde van het item ophalen via een API-aanvraag. Zodra deze ontvangen is, kan de waarde worden weergegeven in de widgetweergave.
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Zabbix\Widgets\{
CWidgetField,
CWidgetForm
};
use Zabbix\Widgets\Fields\{
CWidgetFieldMultiSelectItem,
CWidgetFieldTextBox
};
/**
* Formulier van de metergrafiek-widget.
*/
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', _('Beschrijving'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Weergave van het formulier voor de metergrafiek-widget.
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldMultiSelectItemView($data['fields']['itemid'], $data['captions']['items']['itemid'])
)
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
Ga terug naar het dashboard en klik op het tandwielicoon in de widget om het configuratieformulier van het widget te openen.
Het configuratieformulier van het widget bevat nu een nieuw invoerveld Item. Selecteer de host "Zabbix server" en het item "Load average (1m avg)".
Klik op Toepassen in het configuratieformulier van het widget. Klik vervolgens op Wijzigingen opslaan in de rechterbovenhoek om het dashboard op te slaan.
Open actions/WidgetView.php en pas dit aan.
Vanaf nu zal het item-ID beschikbaar zijn in de widgetcontroller in $this->fields_values['itemid']. De methode doAction() van de controller verzamelt de itemgegevens (naam, waarde type, eenheden) met behulp van de API-methode item.get en de laatste itemwaarde met behulp van de API-methode 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
/**
* Weergave van de metergrafiek-widget.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem([
new CTag('h1', true, $data['description']),
new CDiv($data['value'] !== null ? $data['value']['value'] : _('Geen gegevens'))
])
->show();
In this section, you will learn how to add an expandable/collapsible Advanced configuration section with optional parameters, such as color, minimum and maximum values, units and the Description field created earlier.
The Widget class will extend the CWidget base class to add/override the default widget settings (in this case - translations). JavaScript, provided below, displays the string "No data" in case of missing data. The "No data" string is present in the Zabbix UI translation files.
If there are any widget constants, it is recommended to also specify them in the Widget class.
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 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
*/
use Zabbix\Widgets\Fields\CWidgetFieldGraphDataSet;
$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'], $data['captions']['items']['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();
The addField() method of the CWidgetFormView class takes a CSS class string as the second parameter.
In deze sectie leer je hoe je JavaScript-elementen aan de widget kunt toevoegen.
Je voegt het volgende toe:
JavaScript zal verantwoordelijk zijn voor het verbergen van optionele velden achter de Geavanceerde configuratie checkbox en voor het initialiseren van de kleurkiezer in de configuratie weergave. Je kunt het toevoegen aan dezelfde map als de configuratie weergave.
Aangezien de JavaScript voor de configuratie weergave geladen moet worden met het formulier, dien je het op te nemen in het widget.edit.php bestand zoals getoond in de volgende stappen.
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._form = document.getElementById('widget-dialogue-form');
this._advanced_configuration = document.getElementById('adv_conf');
this._unit_select = document.getElementById('value_units');
this._unit_value = document.getElementById('value_static_units');
this._advanced_configuration.addEventListener('change', () => this.updateForm());
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() {
const show_advanced_configuration = this._advanced_configuration.checked;
for (const element of this._form.querySelectorAll('.js-advanced-configuration')) {
element.style.display = show_advanced_configuration ? '' : 'none';
}
this._unit_value.disabled = this._unit_select.value == <?= Widget::UNIT_AUTO ?>;
}
};
De Widget klasse zal de basis klasse CWidget uitbreiden om de standaard widgetinstellingen toe te voegen/te overschrijven (in dit geval - vertalingen). De onderstaande JavaScript toont de string "Geen gegevens" in het geval van ontbrekende data. De string "Geen gegevens" is aanwezig in de Zabbix UI vertalingsbestanden.
Als er widgetconstanten zijn, wordt het ook aanbevolen om ze in de Widget klasse te specificeren.
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' => _('Geen gegevens')
]
];
}
}
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\{
CWidgetFieldCheckBox,
CWidgetFieldColor,
CWidgetFieldMultiSelectItem,
CWidgetFieldNumericBox,
CWidgetFieldSelect,
CWidgetFieldTextBox
};
/**
* Formulier voor de metergrafiek widget.
*/
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)
->setFilterParameter('numeric', true)
)
->addField(
new CWidgetFieldCheckBox('adv_conf', _('Geavanceerde configuratie'))
)
->addField(
(new CWidgetFieldColor('chart_color', _('Kleur')))->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', _('Eenheden'), [
Widget::UNIT_AUTO => _x('Automatisch', 'methode voor selectie van geschiedenisbron'),
Widget::UNIT_STATIC => _x('Statisch', 'methode voor selectie van geschiedenisbron')
]))->setDefault(Widget::UNIT_AUTO)
)
->addField(
(new CWidgetFieldTextBox('value_static_units'))
)
->addField(
new CWidgetFieldTextBox('description', _('Beschrijving'))
);
}
}
De addField()-methode van de klasse CWidgetFormView neemt een CSS-klassenreeks als tweede parameter. Voeg de tekenreeks js-advanced-configuration toe aan die velden en hun labels die verborgen moeten zijn als Geavanceerde configuratie niet is geselecteerd.
Om een JavaScript-bestand aan de configuratieweergave toe te voegen, gebruik je de methode includeJsFile(). Gebruik de methode addJavaScript() voor inline JavaScript.
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Weergaveformulier voor de metergrafiek widget.
*
* @var CView $this
* @var array $data
*/
use Zabbix\Widgets\Fields\CWidgetFieldGraphDataSet;
$lefty_units = new CWidgetFieldSelectView($data['fields']['value_units']);
$lefty_static_units = (new CWidgetFieldTextBoxView($data['fields']['value_static_units']))
->setPlaceholder(_('waarde'))
->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
(new CWidgetFormView($data))
->addField(
new CWidgetFieldMultiSelectItemView($data['fields']['itemid'], $data['captions']['items']['itemid'])
)
->addField(
new CWidgetFieldCheckBoxView($data['fields']['adv_conf'])
)
->addField(
new CWidgetFieldColorView($data['fields']['chart_color']),
'js-advanced-configuration'
)
->addField(
new CWidgetFieldNumericBoxView($data['fields']['value_min']),
'js-advanced-configuration'
)
->addField(
new CWidgetFieldNumericBoxView($data['fields']['value_max']),
'js-advanced-configuration'
)
->addItem([
$lefty_units->getLabel()->addClass('js-advanced-configuration'),
(new CFormField([
$lefty_units->getView()->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
$lefty_static_units->getView()
]))->addClass('js-advanced-configuration')
])
->addField(
new CWidgetFieldTextBoxView($data['fields']['description']),
'js-advanced-configuration'
)
->includeJsFile('widget.edit.js.php')
->addJavaScript('widget_lesson_gauge_chart_form.init('.json_encode([
'color_palette' => CWidgetFieldGraphDataSet::DEFAULT_COLOR_PALETTE
], JSON_THROW_ON_ERROR).');')
->show();
Klik op Toepassen in het widget configuratieformulier. Klik vervolgens rechtsboven op Wijzigingen opslaan om het dashboard op te slaan.
Open actions/WidgetView.php en update de controller.
De $this->fields_values eigenschap bevat nu de waarden van alle Geavanceerde configuratie velden. Rond de controller af om het doorgeven van de configuratie en de geselecteerde itemwaarde naar de widget weergave mogelijk te maken.
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()
]
]));
}
}
Je moet een container maken voor de metergrafiek die je in de volgende stappen zult tekenen, en een container voor de beschrijving.
Om waarden door te geven aan JavaScript als een JSON-object, gebruik de setVar()-methode.
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Weergave van de metergrafiek widget.
*
* @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();
Maak een nieuwe map assets aan in de lesson_gauge_chart map. Deze map wordt gebruikt voor het opslaan van JavaScript, CSS en mogelijk andere bronnen, zoals lettertypen of afbeeldingen.
Maak voor de JavaScript van de widgetweergave een map js aan in de assets map.
Maak een class.widget.js bestand aan in de assets/js map.
Deze JavaScript-widgetklasse zal de basis JavaScript-klasse van alle dashboardwidgets uitbreiden - CWidget.
Het dashboard vertrouwt op een juiste implementatie van een widget en communiceert alle relevante informatie naar de widget door de respectievelijke JavaScript-methoden aan te roepen. Het dashboard verwacht ook dat de widget gebeurtenissen genereert wanneer er interactie plaatsvindt. Daarom bevat de CWidget klasse een reeks methoden met de standaardimplementatie van widgetgedrag, die kan worden aangepast door de klasse uit te breiden.
In dit geval is enige aanpassing nodig, daarom zal aangepaste logica worden geïmplementeerd voor het volgende widgetgedrag:
Voor andere aspecten van de metergrafiek widget zal de standaardimplementatie voor widgetgedrag worden gebruikt. Om meer te weten te komen over de JavaScript-methoden van de CWidget klasse, zie: JavaScript.
Aangezien deze JavaScript vereist is voor de widgetweergave, moet deze worden geladen met de dashboardpagina. Om het laden van JavaScript mogelijk te maken, moet je de assets/js en js_class parameters van manifest.json bijwerken, zoals getoond in de volgende stap.
ui/modules/lesson_gauge_chart/assets/js/class.widget.js
class WidgetLessonGaugeChart extends CWidget {
static UNIT_AUTO = 0;
static UNIT_STATIC = 1;
_init() {
super._init();
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);
if (this._canvas === null) {
super._processUpdateResponse(response);
this._chart_container = this._content_body.querySelector('.chart');
this._canvas = document.createElement('canvas');
this._chart_container.appendChild(this._canvas);
this._resizeChart();
}
else {
this._updatedChart();
}
}
resize() {
super.resize();
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);
}
}
De WidgetLessonGaugeChart klasse wordt nu automatisch geladen met het dashboard.
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 SIA",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
},
"widget": {
"js_class": "WidgetLessonGaugeChart"
},
"assets": {
"js": ["class.widget.js"]
}
}
In dit gedeelte leer je hoe je aangepaste CSS-stijlen kunt toevoegen om de widget er aantrekkelijker uit te laten zien.
Maak voor widget-stijlen een nieuwe map genaamd css aan in de assets directory.
Maak een bestand genaamd widget.css in de assets/css directory. Gebruik de selector div.dashboard-widget-{widget id} om elementen van de widget te stylen. Gebruik de selector form.dashboard-widget-{widget id} om CSS voor de hele widget te configureren.
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 SIA",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
},
"widget": {
"js_class": "WidgetLessonGaugeChart"
},
"assets": {
"css": ["widget.css"],
"js": ["class.widget.js"]
}
}