Створення віджета (інструкція)

Це покрокова інструкція, яка показує, як створити простий віджет інформаційної панелі.

Мінімальна необхідна версія Zabbix для цієї інструкції – 6.4.4.

Ви можете завантажити всі файли цього віджета як ZIP-архів: lesson_gauge_chart.zip.

Що ви створите

У цьому посібнику ви спочатку створите базовий віджет "Hello, world!", а потім перетворите його на більш просунутий віджет, який відображає значення елемента даних у вигляді гістограми.Ось як виглядатиме готовий віджет:

Частина I - "Hello, world!"

У цьому розділі ви дізнаєтесь, як створити мінімально необхідні елементи віджета та додати новий віджет до інтерфейсу Zabbix.

Додайте порожній віджет до інтерфейсу Zabbix

  1. Створіть каталог lesson_gauge_chart у каталозі modules там де у вас встановлено web-інтерфейс Zabbix (наприклад, zabbix/ui/modules).

Усі користувальницькі віджети розглядаються як зовнішні модулі та мають бути додані до каталогу modules вашого інтерфейсу Zabbix (наприклад, zabbix/ui/modules). Каталог zabbix/ui/widgets зарезервовано для вбудованих віджетів Zabbix і оновлюється разом із Zabbix UI.

  1. Створіть файл manifest.json із базовими метаданими віджетів (перегляньте опис підтримуваних параметрів).

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"
       }
  1. У інтерфейсі Zabbix перейдіть до розділу Адміністрування → Загальні → Модулі та натисніть кнопку Сканувати директорію.

  1. Знайдіть новий модуль Gauge chart у списку та клацніть гіперпосилання «Дезактивовано», щоб змінити статус модуля з «Дезактивовано» на «Активовано».

  1. Відкрийте інформаційну панель, переведіть її в режим редагування та додайте новий віджет. У полі Тип виберіть «Калібрувальна діаграма».

  1. На цьому етапі конфігурація віджета Gauge chart містить лише загальні поля віджета Name і Refresh interval. Натисніть Додати, щоб додати віджет на інформаційну панель.

  1. На інформаційній панелі має з’явитися порожній віджет. Натисніть Зберегти зміни у верхньому правому куті, щоб зберегти інформаційну панель.

Додавання view віджету

Файл view віджета має бути розташований у каталозі views (для цієї інструкції ui/modules/lesson_gauge_chart/views/). Якщо файл має назву за замовчуванням widget.view.php, вам не потрібно реєструвати його у файлі manifest.json. Якщо файл має іншу назву, укажіть її в розділі actions/widget.lesson_gauge_chart.view файлу manifest.json.

  1. Створіть каталог views у каталозі lesson_gauge_chart.

  2. Створіть файл widget.view.php у каталозі views.

ui/modules/lesson_gauge_chart/views/widget.view.php

<?php
       
       /**
        * View віджета Gauge chart.
        *
       * @var CView $this
        * @var array $data
        */
       
       (new CWidgetView($data))
           ->additem(
               new CTag('h1', true, 'Hello, world!')
           )
           ->show();
  1. Оновіть інформаційну панель. Віджет Gauge chart тепер відображає «Hello, world!».

Частина II - Калібрувальна діаграма (Gauge chart)

Додайте налаштування до конфігурації view та використовуйте їх у view віджетів

У цьому розділі ви дізнаєтесь, як додати поле конфігурації віджета та показати введене значення у вигляді тексту у вікні віджета.

Конфігурація віджета складається з форми (Zabbix\Widgets\CWidgetForm) і view форми віджета (widget.edit.php). Щоб додати поля (Zabbix\Widgets\CWidgetField), вам потрібно створити клас WidgetForm, який буде розширювати Zabbix\Widgets\CWidgetForm.

Форма містить набір полів (Zabbix\Widgets\CWidgetField) різних типів, які використовуються для перевірки введених користувачем значень. Поле форми (Zabbix\Widgets\CWidgetField) для кожного типу елемента вводу перетворює значення в єдиний формат для зберігання в базі даних.

Файл форми віджета має бути розташований у каталозі includes (для цієї інструкції ui/modules/lesson_gauge_chart/includes/). Якщо файл має назву за замовчуванням WidgetForm.php, вам не потрібно реєструвати його у файлі manifest.json. Якщо файл має іншу назву, укажіть її в розділі widget/form_class файлу manifest.json.

  1. Створіть новий каталог includes у каталозі lesson_gauge_chart.

  2. Створіть файл WidgetForm.php у каталозі includes.

ui/modules/lesson_gauge_chart/includes/WidgetForm.php

<?php
       
       namespace Modules\LessonGaugeChart\Includes;
       
       use Zabbix\Widgets\CWidgetForm;
       
       class WidgetForm extends CWidgetForm {
       }
  1. Додайте поле Опис до форми конфігурації віджета. Це звичайне текстове поле, куди користувач може ввести будь-який набір символів. Для цього можна використовувати клас CWidgetFieldTextBox.

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'))
                   );
          }
       }
  1. У каталозі views створіть файл конфігурації view віджета widget.edit.php і додайте view для нового поля Description. Для класу полів CWidgetFieldTextBox view має вигляд CWidgetFieldTextBoxView.

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();
  1. Перейдіть на інформаційну панель і клацніть значок шестірні у віджеті, щоб відкрити форму налаштування віджета.

  2. Форма конфігурації віджета тепер містить нове текстове поле Опис. Введіть будь-яке значення, наприклад, Опис gauge chart.

  1. Натисніть Застосувати у формі налаштування віджета. Потім натисніть Зберегти зміни у верхньому правому куті, щоб зберегти інформаційну панель. Зауважте, що новий опис ніде не видно, а віджет все ще відображає «Hello, world!».

Щоб новий опис з’явився у віджеті, потрібно отримати значення поля Опис із бази даних і передати його у view віджета. Для цього вам потрібно створити клас дій.

  1. Створіть новий каталог actions у каталозі lesson_gauge_chart.

  2. Створіть файл WidgetView.php у каталозі actions. Клас дій WidgetView розширить клас CControllerDashboardWidgetView.

Значення полів конфігурації віджета зберігаються у властивості $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()
                   ]
               ]));
           }
       }
  1. Відкрийте manifest.json і зареєструйте WidgetView як клас дій у розділі actions/widget.lesson_gauge_chart.view.

ui/modules/lesson_gauge_chart/manifest.json

{
           "manifest_version": 2.0,
           "id": "leson_gauge_chart",
           "type": "widget",
           "name": "Gauge chart",
           "namespace": "LessonGaugeChart",
           "version": "1.0",
           "author": "Zabbix SIA",
           "actions": {
               "widget.lesson_gauge_chart.view": {
                   "class": "WidgetView"
               }
           }
       }
  1. Тепер ви можете використовувати значення поля опису, що міститься в $data['description'], у view віджетів. Відкрийте views/widget.view.php і замініть статичний текст «Hello, world!» на $data['description'].

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();
  1. Оновіть сторінку інформаційної панелі. Тепер ви маєте побачити текст опису віджета замість «Hello, world!».

Отримати значення елемента даних через API

Віджет має відображати останнє значення елемента за вибором користувача. Для цього вам потрібно додати можливість вибору елементів у конфігурації віджета.

У цьому розділі ви дізнаєтесь, як додати поле вибору елемента до форми віджета та як додати візуальну частину цього поля до view конфігурації. Тоді контролер віджетів зможе отримати дані елемента та його значення через запит API. Після отримання значення може бути відображене у вікні віджетів.

  1. Відкрийте includes/WidgetForm.php і додайте поле CWidgetFieldMultiSelectItem. Це дозволить вибрати пункт у формі конфігурації.

ui/modules/lesson_gauge_chart/includes/WidgetForm.php

<?php
       
       amespace 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'))
         );
           }
       }
  1. Відкрийте views/widget.edit.php і додайте візуальний компонент поля до view конфігурації.

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'], $data['captions']['items']['itemid'])
           )
           ->addField(
           new CWidgetFieldTextBoxView($data['fields']['description'])
           )
           ->show();
  1. Поверніться на інформаційну панель і клацніть значок шестірні у віджеті, щоб відкрити форму налаштування віджета.

  2. Форма конфігурації віджета тепер містить нове поле введення Елемент. Виберіть хост «Zabbix сервер» і елемент даних "Load average (1m avg)".

  1. Натисніть Застосувати у формі налаштування віджета. Потім натисніть Зберегти зміни у верхньому правому куті, щоб зберегти інформаційну панель.

  2. Відкрийте та змініть actions/WidgetView.php.

Відтепер ідентифікатор елемента буде доступний у контролері віджетів у $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()
                ]
               ]));
               }
       }
  1. Відкрийте views/widget.view.php і додайте значення елемента до view віджета.

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();
  1. Оновіть сторінку інформаційної панелі. Віджет відображатиме останнє значення елемента.

Додайте JavaScript до віджету

У цьому розділі ви дізнаєтеся, як додати до віджету елементи Javascript:

Ви додасте:

  • Діаграма, створена за допомогою JavaScript, щоб відразу показати, чи є останнє значення нормальним або занадто високим/низьким.
  • Розділ Розширена конфігурація для додаткових параметрів, таких як колір, мінімальне і максимальне значення, одиниці виміру і поле Опис, створене раніше.
  1. Створіть файл widget.edit.js.php в каталозі views.

JavaScript відповідатиме за приховування необов'язкових полів за чекбоксом Розширена конфігурація та ініціалізацію піпетки кольорів у view конфігурації. Ви можете додати його до тієї самої директорії, що й view конфігурації.

Оскільки JavaScript для view конфігурації повинен завантажуватися разом з формою, вам потрібно включити його в файл widget.edit.php, як показано на наступних кроках

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 ?>;
       }
       };
  1. Створіть файл Widget.php у головному каталозі віджетів lesson_gauge_chart для створення нового класу Widget.

Клас Widget розширює базовий клас CWidget для додавання/перевизначення налаштувань віджету за замовчуванням (у цьому випадку - перекладів).JavaScript, наведений нижче, виводить рядок "Немає даних" у разі відсутності даних.Рядок "Немає даних" присутній у файлах перекладу інтерфейсу користувача Zabbix.

Якщо є якісь константи віджета, рекомендується також вказати їх у класі 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')
       ]
       ];
       }
       }
  1. Відкрийте includes/WidgetForm.php і додайте нові поля: Додаткова конфігурація (чекбокс), Колір (перемикач кольорів), Мін (числове поле), Макс (числове поле) і Одиниці виміру (вибір).

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
       };
       /** 
       * 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)
       ->setFilterParameter('numeric', true)
       )
       ->addField(
       new CWidgetFieldCheckBox('adv_conf', _('Advanced configuration'))
       )
       ->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'))
       );
       }
       }
  1. Відкрийте views/widget.edit.php і додайте візуальні компоненти полів до view конфігурації.

Метод addField() класу CWidgetFormView приймає рядок класу CSS як другий параметр. Додайте рядок js-advanced-configuration до цих полів та їхніх міток, які мають бути приховані, якщо не вибрано Advanced configuration.

Щоб додати файл JavaScript до view конфігурації, використовуйте метод includeJsFile(). Щоб додати вбудований JavaScript, використовуйте метод addJavaScript().

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'])
       )
       ->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();
  1. Поверніться до інформаційної панелі, натисніть на іконку шестерні у віджеті, щоб відкрити форму конфігурації віджету. Форма конфігурації віджету тепер містить новий чекбокс Розширена конфігурація.

  1. Встановіть чекбокс Розширена конфігурація, щоб побачити додаткові поля конфігурації віджету. Заповніть поля значеннями та виберіть колір віджету.

  1. Натисніть на Застосувати у формі конфігурації віджету. Потім натисніть на Зберегти зміни у верхньому правому куті, щоб зберегти дашборд.

  2. Відкрийте actions/WidgetView.php і оновіть контролер.

Властивість $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()
       ]
       ]));
       }
       }
  1. Відкрийте та відредактуйте views/widget.view.php.

Вам потрібно створити контейнер для колійної діаграми, яку ви намалюєте в наступних кроках, і контейнер для опису.

Щоб передати значення в JavaScript як JSON-об'єкт, використовуйте метод setVar().

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();
  1. Створіть новий каталог assets у каталозі lesson_gauge_chart. Цей каталог буде використовуватися для зберігання JavaScript, CSS і, можливо, будь-яких інших ресурсів, таких як шрифти або зображення.

  2. Для перегляду JavaScript віджетів створіть каталог js у каталозі assets.

  3. Створіть файл class.widget.js в каталозі assets/js.

Цей клас JavaScript-віджету розширює базовий JavaScript-клас усіх віджетів інформаційної панелі - CWidget.

Інформаційна панель покладається на коректну реалізацію віджета і передає будь-яку відповідну інформацію віджету через виклик відповідних методів JavaScript. Інформаційна панель також очікує, що віджет буде генерувати події, коли відбувається певна взаємодія. Таким чином, клас CWidget містить набір методів з реалізацією поведінки віджета за замовчуванням, яку можна налаштувати, розширивши клас.

У цьому випадку необхідна певна кастомізація, тому буде реалізовано кастомну логіку для наступної поведінки віджету:

-ініціалізація віджету, яка відповідає за визначення початкового стану віджету (див. метод _init()); -відображення вмісту віджету (тобто малювання графіку), якщо процес оновлення віджету пройшов успішно та без помилок (див. метод _processUpdateResponse(response) та пов'язані з ним методи _resizeChart() та _updatedChart()); - зміна розміру віджету (див. метод resize() та пов'язаний з ним метод _resizeChart()).

Для інших аспектів віджету колійної діаграми буде використано реалізацію за замовчуванням для поведінки віджету.Щоб дізнатися більше про методи JavaScript класу CWidget, див: JavaScript.

Оскільки цей JavaScript необхідний для відображення віджету, його слід завантажити разом зі сторінкою дашборду. Щоб увімкнути завантаження JavaScript, вам потрібно оновити параметри assets/js і js_class у manifest.json, як показано в наступному кроці.

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);
       }
       }
  1. Відкрийте manifest.json і додайте:
  • ім'я файлу (class.widget.js) до масиву в секції assets/js;
  • ім'я класу (WidgetLessonGaugeChart) до параметра js_class в секції widget.

Клас 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 SIA",
       "actions": {
       "widget.lesson_gauge_chart.view": {
       "class": "WidgetView"
       }
       },
       "widget": {
       "js_class": "WidgetLessonGaugeChart"
       },
       "assets": {
       "js": ["class.widget.js"]
       }
       }

Додайте CSS стилі до віджету

У цьому розділі ви дізнаєтеся, як додати власні стилі CSS, щоб зробити віджет більш привабливим.

  1. Для стилів віджетів створіть новий каталог css у каталозі assets.

  2. Створіть файл widget.css у каталозі assets/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; 
       }
  1. Відкрийте manifest.json і додайте назву файлу CSS (widget.css) до масиву в розділі assets/css. Це дозволить стилям CSS, визначеним у widget.css, завантажуватись зі сторінкою інформаційної панелі.

ui/modules/lesson_gauge_chart/manifest.json

{
           "manifest_version": 2.0,
           "id": "leson_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"]
           }
       }
  1. Оновіть сторінку інформаційної панелі, щоб побачити готову версію віджета.