Você está visualizando a documentação da versão de desenvolvimento, que pode estar incompleta.
Esta página foi traduzida automaticamente. Se você notar um erro, selecione-o e pressione Ctrl+Enter para reportá-lo aos editores.

Criar um widget (tutorial)

Este é um tutorial passo a passo que mostra como criar um widget de dashboard simples. Você pode baixar todos os arquivos deste widget como um arquivo ZIP: lesson_gauge_chart.zip.

O que você irá construir

Durante este tutorial, você irá primeiro construir um widget básico "Hello, world!" e depois convertê-lo em um widget mais avançado que exibe o valor de um item como um gráfico de gauge. Veja como o widget finalizado ficará:

Parte I - "Olá, mundo!"

Nesta seção, você aprenderá como criar os elementos mínimos necessários de um widget e adicionar um novo widget ao frontend do Zabbix.

Adicionar um widget em branco ao frontend do Zabbix

  1. Crie um diretório lesson_gauge_chart no diretório modules da instalação do frontend do Zabbix (por exemplo, zabbix/ui/modules).

Todos os widgets personalizados são tratados como módulos externos e devem ser adicionados ao diretório modules da instalação do frontend do Zabbix (por exemplo, zabbix/ui/modules). O diretório zabbix/ui/widgets é reservado para widgets nativos do Zabbix e é atualizado junto com a interface do Zabbix.

  1. Crie um arquivo manifest.json com os metadados básicos do widget (veja a descrição dos parâmetros suportados).

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"
       }
  1. No frontend do Zabbix, vá para a seção Administração → Geral → Módulos e clique no botão Procurar diretório.

  1. Localize o novo módulo Gauge chart na lista e clique no hiperlink "Desabilitado" para alterar o status do módulo de "Desabilitado" para "Habilitado" (se o módulo não estiver listado, consulte a seção de solução de problemas).

  1. Abra um dashboard, alterne para o modo de edição e adicione um novo widget. No campo Tipo, selecione "Gauge chart".

  1. Neste ponto, a configuração do widget Gauge chart contém apenas os campos comuns Nome e Intervalo de atualização. Clique em Adicionar para adicionar o widget ao dashboard.

  1. Um widget em branco deve aparecer no dashboard. Clique em Salvar alterações no canto superior direito para salvar o dashboard.

Adicionar uma visualização de widget

O arquivo de visualização do widget deve estar localizado no diretório views (para este tutorial, ui/modules/lesson_gauge_chart/views/). Se o arquivo tiver o nome padrão widget.view.php, você não precisa registrá-lo no arquivo manifest.json. Se o arquivo tiver um nome diferente, especifique-o na seção actions/widget.lesson_gauge_chart.view do arquivo manifest.json.

  1. Crie um diretório views no diretório lesson_gauge_chart.

  2. Crie um arquivo widget.view.php no diretório views.

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

<?php
       
       /**
        * Visualização do widget de gráfico de gauge.
        *
        * @var CView $this
        * @var array $data
        */
       
       (new CWidgetView($data))
           ->addItem(
               new CTag('h1', true, 'Hello, world!')
           )
           ->show();
  1. Atualize o dashboard. O widget Gauge chart agora exibe "Hello, world!".

Parte II - Gráfico de Gauge

Adicione configurações a uma visualização de configuração e use-as em uma visualização de widget

Nesta seção, você aprenderá como adicionar um campo de configuração de widget e exibir o valor inserido na visualização do widget como texto.

A configuração do widget consiste em um formulário (Zabbix\Widgets\CWidgetForm) e uma visualização de formulário de widget (widget.edit.php). Para adicionar campos (Zabbix\Widgets\CWidgetField), você precisa criar uma classe WidgetForm, que irá estender Zabbix\Widgets\CWidgetForm.

O formulário contém o conjunto de campos (Zabbix\Widgets\CWidgetField) de vários tipos, que são usados para validar os valores inseridos pelo usuário. O campo do formulário (Zabbix\Widgets\CWidgetField) para cada tipo de elemento de entrada converte o valor em um formato único para armazená-lo no banco de dados.

O arquivo form do widget deve estar localizado no diretório includes (para este tutorial, ui/modules/lesson_gauge_chart/includes/). Se o arquivo tiver o nome padrão WidgetForm.php, você não precisa registrá-lo no arquivo manifest.json. Se o arquivo tiver um nome diferente, especifique-o na seção widget/form_class do arquivo manifest.json.

  1. Crie um novo diretório includes no diretório lesson_gauge_chart.

  2. Crie um arquivo WidgetForm.php no diretório includes.

ui/modules/lesson_gauge_chart/includes/WidgetForm.php

<?php
       
       namespace Modules\LessonGaugeChart\Includes;
       
       use Zabbix\Widgets\CWidgetForm;
       
       class WidgetForm extends CWidgetForm {
       }
  1. Adicione um campo Description ao formulário de configuração do widget. Este é um campo de texto comum, onde o usuário pode inserir qualquer conjunto de caracteres. Você pode usar a classe CWidgetFieldTextBox para isso.

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. No diretório views, crie um arquivo de visualização de configuração do widget widget.edit.php e adicione uma visualização para o novo campo Description. Para a classe de campo CWidgetFieldTextBox, a visualização é 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. Vá para o dashboard e clique no ícone de engrenagem no widget para abrir o formulário de configuração do widget.

  2. O formulário de configuração do widget agora contém um novo campo de texto Description. Digite qualquer valor, por exemplo, Gauge chart description.

  1. Clique em Aplicar no formulário de configuração do widget. Em seguida, clique em Salvar alterações no canto superior direito para salvar o dashboard. Observe que a nova descrição não está visível em nenhum lugar e o widget ainda exibe "Hello, world!".

Para que a nova descrição apareça no widget, o valor do campo Description precisa ser recuperado do banco de dados e passado para a visualização do widget. Para isso, você precisa criar uma classe de ação.

  1. Crie um novo diretório actions no diretório lesson_gauge_chart.

  2. Crie um arquivo WidgetView.php no diretório actions. A classe de ação WidgetView irá estender a classe CControllerDashboardWidgetView.

Os valores dos campos de configuração do widget são armazenados na propriedade $fields_values da classe de ação.

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. Abra o manifest.json e registre WidgetView como uma classe de ação na seção actions/widget.lesson_gauge_chart.view.

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"
               }
           }
       }
  1. Agora você pode usar o valor do campo description, contido em $data['description'], na visualização do widget. Abra views/widget.view.php e substitua o texto estático "Hello, world!" por $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. Atualize a página do dashboard. Agora você deve ver o texto da descrição do widget em vez de "Hello, world!".

Recuperar o valor de um item via API

O widget deve mostrar o último valor de um item à escolha do usuário. Para isso, é necessário adicionar a capacidade de selecionar items na configuração do widget.

Nesta seção, você aprenderá como adicionar um campo de seleção de item ao formulário do widget e como adicionar a parte visual desse campo à visualização de configuração. Em seguida, o controlador do widget poderá recuperar os dados do item e seu valor por meio de uma solicitação de API. Uma vez recebido, o valor pode ser exibido na visualização do widget.

  1. Abra includes/WidgetForm.php e adicione o campo CWidgetFieldMultiSelectItem. Isso permitirá selecionar um item no formulário de configuração.

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'))
                   );
           }
       }
  1. Abra views/widget.edit.php e adicione o componente visual do campo à visualização de configuração.

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();
  1. Volte ao dashboard e clique no ícone de engrenagem no widget para abrir o formulário de configuração do widget.

  2. O formulário de configuração do widget agora contém um novo campo de entrada Item. Selecione o host "Zabbix server" e o item "Load average (1m avg)".

  1. Clique em Aplicar no formulário de configuração do widget. Em seguida, clique em Salvar alterações no canto superior direito para salvar o dashboard.

  2. Abra e modifique actions/WidgetView.php.

A partir de agora, o ID do item estará disponível no controlador do widget em $this->fields_values['itemid']. O método do controlador doAction() coleta os dados do item (nome, tipo de valor, unidades) usando o método da API item.get e o último valor do item usando o método da 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. Abra views/widget.view.php e adicione o valor do item à visualização do widget.

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. Atualize a página do dashboard. O widget exibirá o valor mais recente do item.

Adicionar configurações avançadas à visualização de configuração

Nesta seção, você aprenderá como adicionar uma seção expansível/recolhível Configuração avançada com parâmetros opcionais, como cor, valores mínimo e máximo, unidades e o campo Descrição criado anteriormente.

  1. Crie um arquivo Widget.php no diretório principal do widget lesson_gauge_chart para criar uma nova classe Widget.

A classe Widget irá estender a classe base CWidget para adicionar/sobrescrever as configurações padrão do widget (neste caso - traduções). O JavaScript, fornecido abaixo, exibe a string "Sem dados" em caso de ausência de dados. A string "Sem dados" está presente nos arquivos de tradução da interface do Zabbix.

Se houver quaisquer constantes do widget, recomenda-se também especificá-las na classe 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. Abra includes/WidgetForm.php e adicione os novos campos Cor (seletor de cor), Mín (campo numérico), Máx (campo numérico) e Unidades (select), e defina a paleta de cores padrão para o seletor de cor, para que possa ser usada nos próximos passos.

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
       };
       
       /**
        * Formulário do widget de gráfico de gauge.
        */
       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'))
                   );
           }
       }
  1. Abra views/widget.edit.php e adicione os componentes visuais dos campos à visualização de configuração.

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

<?php
       
       /**
        * Visualização do formulário do widget de gráfico de gauge.
        *
        * @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();

O método addField() da classe CWidgetFormView recebe uma string de classe CSS como segundo parâmetro.

  1. Volte ao dashboard, alterne para o modo de edição e clique no ícone de engrenagem no widget para abrir o formulário de configuração do widget. O formulário de configuração do widget agora contém uma nova seção expansível/recolhível Configuração avançada.

  1. Expanda a seção Configuração avançada para ver os campos adicionais de configuração do widget. Observe que o campo Cor ainda não possui um seletor de cor. Isso ocorre porque o seletor de cor deve ser inicializado com JavaScript, que será adicionado na próxima seção - Adicionar JavaScript ao widget.

Adicionar JavaScript ao widget

Nesta seção, você aprenderá como adicionar um gráfico de gauge - feito usando JavaScript - que mostra se o valor mais recente está normal ou muito alto/baixo.

  1. Crie um arquivo widget.edit.js.php no diretório views.

O JavaScript será responsável por inicializar o seletor de cores na visualização de configuração.

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 ?>;
           }
       };
  1. Abra views/widget.edit.php e adicione o arquivo widget.edit.js.php com o JavaScript à visualização de configuração. Para isso, use o método includeJsFile(). Para adicionar JavaScript inline, use o método addJavaScript().

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();
  1. Volte ao dashboard, clique no ícone de engrenagem no widget para abrir o formulário de configuração do widget. Agora, expanda a seção Advanced configuration para ver o seletor de cores inicializado. Preencha os campos com valores e selecione uma cor para o gráfico de gauge.

  1. Clique em Aplicar no formulário de configuração do widget. Em seguida, clique em Salvar alterações no canto superior direito para salvar o dashboard.

  2. Abra actions/WidgetView.php e atualize o controller.

A propriedade $this->fields_values agora contém os valores de todos os campos de Advanced configuration. Finalize o controller para permitir o envio da configuração e do valor do item selecionado para a visualização do widget.

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. Abra e modifique views/widget.view.php.

Você precisa criar um container para o gráfico de gauge, que será desenhado nos próximos passos, e um container para a descrição.

Para passar valores para o JavaScript como um objeto JSON, use o método 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. Crie um novo diretório assets no diretório lesson_gauge_chart. Este diretório será usado para armazenar JavaScript, CSS e, potencialmente, quaisquer outros assets, como fontes ou imagens.

  2. Para o JavaScript da visualização do widget, crie um diretório js no diretório assets.

  3. Crie um arquivo class.widget.js no diretório assets/js.

Esta classe JavaScript do widget irá estender a classe base JavaScript de todos os widgets do dashboard - CWidget.

O dashboard depende de uma implementação correta de um widget e comunica qualquer informação relevante ao widget através da chamada dos respectivos métodos JavaScript. O dashboard também espera que o widget gere eventos quando alguma interação ocorrer. Assim, a classe CWidget contém um conjunto de métodos com a implementação padrão do comportamento do widget, que pode ser customizado estendendo a classe.

Neste caso, alguma customização é necessária, portanto, a lógica personalizada será implementada para o seguinte comportamento do widget:

  • inicialização do widget, que é responsável por definir o estado inicial do widget (veja o método onInitialize());
  • exibição do conteúdo do widget (ou seja, desenhar o gráfico de gauge) se o processo de atualização do widget foi bem-sucedido e sem erros (veja o método processUpdateResponse(response) e os métodos relacionados _resizeChart() e _updatedChart() )
  • redimensionamento do widget (veja o método onResize() e o método relacionado _resizeChart() )

Para outros aspectos do widget de gráfico de gauge, será usada a implementação padrão do comportamento do widget. Para saber mais sobre os métodos JavaScript da classe CWidget, veja: JavaScript.

Como este JavaScript é necessário para a visualização do widget, ele deve ser carregado junto com a página do dashboard. Para habilitar o carregamento do JavaScript, você precisará atualizar os parâmetros assets/js e js_class no arquivo manifest.json conforme mostrado no passo 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);
           }
       }
  1. Abra manifest.json e adicione:
  • o nome do arquivo (class.widget.js) ao array na seção assets/js;
  • o nome da classe (WidgetLessonGaugeChart) ao parâmetro js_class na seção widget.

A classe WidgetLessonGaugeChart agora será carregada automaticamente com o 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",
           "actions": {
               "widget.lesson_gauge_chart.view": {
                   "class": "WidgetView"
               }
           },
           "widget": {
               "js_class": "WidgetLessonGaugeChart"
           },
           "assets": {
               "js": ["class.widget.js"]
           }
       }

Adicionar estilos CSS ao widget

Nesta seção, você aprenderá como adicionar estilos CSS personalizados para tornar o widget mais atraente.

  1. Para os estilos do widget, crie um novo diretório css no diretório assets.

  2. Crie um arquivo widget.css no diretório assets/css. Para estilizar os elementos do widget, use o seletor div.dashboard-widget-{widget id}. Para configurar o CSS para todo o widget, use o seletor 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. Abra o manifest.json e adicione o nome do arquivo CSS (widget.css) ao array na seção assets/css. Isso permitirá que os estilos CSS definidos em widget.css sejam carregados junto com a página do 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",
           "actions": {
               "widget.lesson_gauge_chart.view": {
                   "class": "WidgetView"
               }
           },
           "widget": {
               "js_class": "WidgetLessonGaugeChart"
           },
           "assets": {
               "css": ["widget.css"],
               "js": ["class.widget.js"]
           }
       }
  1. Atualize a página do dashboard para ver a versão finalizada do widget.