Aqui está 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] (../../../../assets/en/devel/modules/examples/lesson_gauge_chart.zip).
Durante este tutorial, você construirá primeiro um widget básico "Olá, mundo!" e, em seguida, o converterá em um widget mais avançado que exibe o valor de um item como um gráfico de medidor. Veja como o widget final ficará:

Nesta seção você aprenderá como criar os elementos mínimos necessários do widget e adicionar um novo widget ao frontend do Zabbix.
::: nota clássica 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 integrados ao Zabbix e é atualizado junto com a UI do Zabbix. :::
ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Gráfico de medidor",
"namespace": "LessonGaugeChart",
"version": "1.1",
"author": "Zabbix"
}




O arquivo view 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, não será necessário 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] (devel/modules/file_structure/manifest).
Crie um diretório views no diretório lesson_gauge_chart.
Crie um arquivo widget.view.php no diretório views.
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Visualização do widget do gráfico de medidores.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, 'Olá, mundo!')
)
->show();
Nesta seção, você aprenderá a adicionar um campo de configuração de widget e a mostrar 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\), você precisa criar uma classe WidgetForm, que 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\) para cada tipo de elemento de entrada converte o valor em um único formato para armazená-lo no banco de dados.
O arquivo de formulário (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, não será necessário 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] (devel/modules/file_structure/manifest).
Crie um novo diretório includes no diretório lesson_gauge_chart.
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 {
}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', _('Descrição'))
);
}
}ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Visualização do formulário do widget do gráfico de medidores.
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();Vá para o painel 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 um novo campo de texto Descrição. Insira qualquer valor, por exemplo, Descrição do gráfico de medidor.

Para que a nova descrição apareça no widget, o valor do campo Descrição 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.
Crie um novo diretório actions no diretório lesson_gauge_chart.
Crie um arquivo WidgetView.php no diretório actions. A classe de ação WidgetView 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()
]
]));
}
}ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Gráfico de medidor",
"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
/**
* Gauge chart widget view.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, $data['description'])
)
->show();
O widget deve mostrar o último valor de um item da escolha do usuário. Para isso, você precisa adicionar a capacidade de selecionar itens 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 à exibiçã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 poderá ser exibido na visualização do widget.
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Zabbix\Widgets\{
CWidgetField,
CWidgetForm
};
use Zabbix\Widgets\Fields\{
CWidgetFieldMultiSelectItem,
CWidgetFieldTextBox
};
/**
* Gauge chart widget form.
*/
class WidgetForm extends CWidgetForm {
public function addFields(): self {
return $this
->addField(
(new CWidgetFieldMultiSelectItem('itemid', _('Item')))
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
->setMultiple(false)
)
->addField(
new CWidgetFieldTextBox('description', _('Descrição'))
);
}
}ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Visualização do formulário do widget do gráfico do medidor.
*
* @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();Volte ao painel 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 um novo campo de entrada Item. Selecione o host "Zabbix server" e o item "Load average (1m avg)".

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 painel.
Abra e modifique o arquivo actions/WidgetView.php.
De agora em diante, 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()
]
]));
}
}ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Visualização do widget do gráfico do medidor.
*
* @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();
Nesta seção, você aprenderá a como adicionar uma seção de Configurações avançadas expansível com parâmetros opcionais, tais como cor, valores mínimos e máximos, unidades e o campo Descrição criado anteriormente.
A classe Widget estenderá a classe base CWidget para adicionar/sobrepor as configurações padrão do widget (neste caso - traduções). @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 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
};
/**
* Formulário do widget de gráfico de medidor.
*/
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', _('Cor')))->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', _('Unidades'), [
Widget::UNIT_AUTO => _x('Auto', 'seleção por histórico'),
Widget::UNIT_STATIC => _x('Static', 'seleção por histórico')
]))->setDefault(Widget::UNIT_AUTO)
)
->addField(
(new CWidgetFieldTextBox('value_static_units'))
)
->addField(
new CWidgetFieldTextBox('description', _('Descrição'))
);
}
}ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* View de formulário do widget de gráfico de medidor.
*
* @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(_('Configuração avançada')))
->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 classe CSS de string como segundo parâmetro.


Nesta seção, você aprenderá a como adicionar um gráfico de medidor - criado usando JavaScript - que mostra se o último valor está normal ou muito alto/baixo.
JavaScript será responsável pela inicialização do seletor de cor na view 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 ?>;
}
};ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* View de formulário do widget de gráfico de medidor.
*
* @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(_('Configuração avançada')))
->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();
Clique em Aplicar no formulário de configuração do widget. Então, clique em Salvar alterações no canto superior direito para salvar o painel.
Abra o arquivo actions/WidgetView.php e atualize o controlador.
A propriedade $this->fields_values agora contém os valores de todos os campos da Configuração avançada. Finalize o controlador para habilitar a passagem da configuração e valor de item selecionado à view 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()
]
]));
}
}Você precisa criar um contêiner para o gráfico de medidor, o qual você vai desenhar nos próximos passos, e um contêiner para a descrição.
Para passar valores ao 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();Crie um novo diretório assets em lesson_gauge_chart. Este diretório será usado para arquivar JavaScript, CSS, e potencialmente quaisquer outros recursos, como fontes ou imagens.
Para JavaScript de view do widget, crie um diretório js dentro de assets.
Crie um arquivo class.widget.js no diretório assets/js.
Esta classe JavaScript do widget estenderá a classe Javascript base de todos os widgets de painel - CWidget.
O painel depende de uma correta implementação de um widget e comunica qualquer informação relevante ao widget através da chamada dos respectivos métodos JavaScript. O painel também espera que o widget gere eventos quando algumas interações ocorrerem. Assim, a classe CWidget contém um conjunto de métodos com a implementação padrão de comportamento do widget, que pode ser customizada estendendo essa classe.
Neste caso, alguma customização é necessária, portanto uma lógica customizada será implementada para o seguinte comportamento do widget:
Para outros aspectos do widget de gráfico de medidor, a implementação padrão para o comportamento do widget será usada. Para aprender mais sobre métodos JavaScript da classe CWidget, veja: JavaScript.
Desde que JavaScript é necessário para a visualização do widget, ele deve ser carregado junto com a página do painel. Para habilitar a carga do JavaScript, você terá que atualizar os parâmetros assets/js e js_class no arquivo manifest.json como 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);
}
}A classe WidgetLessonGaugeChart será agora carregada automaticamente com o painel.
ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Gráfico de medidor",
"namespace": "LessonGaugeChart",
"version": "1.0",
"author": "Zabbix",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
},
"widget": {
"js_class": "WidgetLessonGaugeChart"
},
"assets": {
"js": ["class.widget.js"]
}
}Nesta seção, você aprenderá a adicionar estilos CSS personalizados para tornar o widget mais atraente.
Para estilos de widget, crie um novo diretório css dentro de assets.
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;
}ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Gráfico de medidor",
"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"]
}
}