Este es un tutorial paso a paso que muestra cómo crear un widget de panel simple. Puede descargar todos los archivos de este widget como un archivo ZIP: lesson_gauge_chart.zip.
Durante este tutorial, primero crearás un widget básico de "¡Hola, mundo!" y luego lo convertirás en un widget más avanzado que muestra el valor de una métrica como un gráfico de tipo gauge. Así es como se verá el widget terminado:
En esta sección aprenderá cómo crear los elementos mínimos requeridos de un widget y añadir un nuevo widget al frontend de Zabbix.
Todos los widgets personalizados se tratan como módulos externos y deben añadirse al directorio modules de su instalación de la interfaz de Zabbix (por ejemplo, zabbix/ui/modules). El directorio zabbix/ui/widgets está reservado para los widgets integrados de Zabbix y se actualiza junto con la interfaz de Zabbix.
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"
}
El archivo view del widget debe estar ubicado en el directorio views (para este tutorial, ui/modules/lesson_gauge_chart/views/). Si el archivo tiene el nombre por defecto widget.view.php, no es necesario registrarlo en el archivo manifest.json. Si el archivo tiene un nombre diferente, especifíquelo en la sección actions/widget.lesson_gauge_chart.view del archivo manifest.json.
Cree un directorio views en el directorio lesson_gauge_chart.
Cree un archivo widget.view.php en el directorio views.
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Vista del widget de gráfico de indicadores.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, '¡Hola, mundo!')
)
->show();
En esta sección, aprenderá cómo añadir un campo de configuración de widget y mostrar el valor introducido en la vista del widget como texto.
La configuración del widget consiste en un formulario (Zabbix\Widgets\CWidgetForm) y una vista de formulario de widget (widget.edit.php). Para añadir campos (Zabbix\Widgets\CWidgetField), debe crear una clase WidgetForm, que extenderá Zabbix\Widgets\CWidgetForm.
El formulario contiene el conjunto de campos (Zabbix\Widgets\CWidgetField) de varios tipos, que se utilizan para validar los valores introducidos por el usuario. El campo del formulario (Zabbix\Widgets\CWidgetField) para cada tipo de elemento de entrada convierte el valor en un formato único para almacenarlo en la base de datos.
El archivo form del widget debe estar ubicado en el directorio includes (para este tutorial, ui/modules/lesson_gauge_chart/includes/). Si el archivo tiene el nombre por defecto WidgetForm.php, no necesita registrarlo en el archivo manifest.json. Si el archivo tiene un nombre diferente, especifíquelo en la sección widget/form_class del archivo manifest.json.
Cree un nuevo directorio includes en el directorio lesson_gauge_chart.
Cree un archivo WidgetForm.php en el directorio 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', _('Description'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Vista de formulario del widget de gráfico de indicador.
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
Vaya al panel y haga clic en el icono de engranaje en el widget para abrir el formulario de configuración del widget.
El formulario de configuración del widget ahora contiene un nuevo campo de texto Description. Introduzca cualquier valor, por ejemplo, Gauge chart description.
Para que la nueva descripción aparezca en el widget, el valor del campo Description debe recuperarse de la base de datos y pasarse a la vista del widget. Para ello, debe crear una clase de acción.
Cree un nuevo directorio actions en el directorio lesson_gauge_chart.
Cree un archivo WidgetView.php en el directorio actions. La clase de acción WidgetView extenderá la clase CControllerDashboardWidgetView.
Los valores de los campos de configuración del widget se almacenan en la propiedad $fields_values de la clase de acción.
ui/modules/lesson_gauge_chart/actions/WidgetView.php
<?php
namespace Modules\LessonGaugeChart\Actions;
use CControllerDashboardWidgetView,
CControllerResponseData;
class WidgetView extends CControllerDashboardWidgetView {
protected function doAction(): void {
$this->setResponse(new CControllerResponseData([
'name' => $this->getInput('name', $this->widget->getName()),
'description' => $this->fields_values['description'],
'user' => [
'debug_mode' => $this->getDebugMode()
]
]));
}
}
ui/modules/lesson_gauge_chart/manifest.json
{
"manifest_version": 2.0,
"id": "lesson_gauge_chart",
"type": "widget",
"name": "Gauge chart",
"namespace": "LessonGaugeChart",
"version": "1.0",
"author": "Zabbix",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
}
}
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Vista del widget de gráfico de indicador.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, $data['description'])
)
->show();
El widget debe mostrar el último valor de una métrica elegida por el usuario. Para ello, es necesario añadir la capacidad de seleccionar métricas en la configuración del widget.
En esta sección, aprenderá cómo añadir un campo de selección de métricas al formulario del widget y cómo añadir la parte visual de este campo a la vista de configuración. A continuación, el controlador del widget podrá recuperar los datos de la métrica y su valor mediante una solicitud a la API. Una vez recibido, el valor puede mostrarse en la vista del 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
};
/**
* Formulario del widget de gráfico de indicador.
*/
class WidgetForm extends CWidgetForm {
public function addFields(): self {
return $this
->addField(
(new CWidgetFieldMultiSelectItem('itemid', _('Métrica')))
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
->setMultiple(false)
)
->addField(
new CWidgetFieldTextBox('description', _('Descripción'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Vista del formulario del widget de gráfico de indicador.
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldMultiSelectItemView($data['fields']['itemid'])
)
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
Vuelva al panel y haga clic en el icono de engranaje en el widget para abrir el formulario de configuración del widget.
El formulario de configuración del widget ahora contiene un nuevo campo de entrada Métrica. Seleccione el equipo "Zabbix server" y la métrica "Load average (1m avg)".
Haga clic en Aplicar en el formulario de configuración del widget. Luego haga clic en Guardar cambios en la esquina superior derecha para guardar el panel.
Abra y modifique actions/WidgetView.php.
A partir de ahora, el ID de la métrica estará disponible en el controlador del widget en $this->fields_values['itemid']. El método doAction() del controlador recopila los datos de la métrica (nombre, tipo de valor, unidades) utilizando el método de la API item.get y el último valor de la métrica utilizando el método de la 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
/**
* Vista del widget de gráfico de indicador.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem([
new CTag('h1', true, $data['description']),
new CDiv($data['value'] !== null ? $data['value']['value'] : _('Sin datos'))
])
->show();
En esta sección, aprenderá cómo añadir una sección Configuración avanzada expandible/colapsable con parámetros opcionales, como color, valores mínimo y máximo, unidades y el campo Descripción creado anteriormente.
La clase Widget extenderá la clase base CWidget para añadir/sobrescribir los ajustes por defecto del widget (en este caso, las traducciones). El JavaScript, proporcionado a continuación, muestra la cadena "Sin datos" en caso de que falten datos. La cadena "Sin datos" está presente en los archivos de traducción de la interfaz de Zabbix.
Si hay alguna constante del widget, también se recomienda especificarlas en la clase Widget.
ui/modules/lesson_gauge_chart/Widget.php
<?php
namespace Modules\LessonGaugeChart;
use Zabbix\Core\CWidget;
class Widget extends CWidget {
public const UNIT_AUTO = 0;
public const UNIT_STATIC = 1;
public function getTranslationStrings(): array {
return [
'class.widget.js' => [
'No data' => _('No data')
]
];
}
}
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Modules\LessonGaugeChart\Widget;
use Zabbix\Widgets\{
CWidgetField,
CWidgetForm
};
use Zabbix\Widgets\Fields\{
CWidgetFieldColor,
CWidgetFieldMultiSelectItem,
CWidgetFieldNumericBox,
CWidgetFieldSelect,
CWidgetFieldTextBox
};
/**
* Formulario del widget de gráfico de indicador.
*/
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', _('Métrica')))
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
->setMultiple(false)
)
->addField(
(new CWidgetFieldColor('chart_color', _('Color')))->setDefault('FF0000')
)
->addField(
(new CWidgetFieldNumericBox('value_min', _('Mín')))
->setDefault(0)
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
)
->addField(
(new CWidgetFieldNumericBox('value_max', _('Máx')))
->setDefault(100)
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
)
->addField(
(new CWidgetFieldSelect('value_units', _('Unidades'), [
Widget::UNIT_AUTO => _x('Auto', 'history source selection method'),
Widget::UNIT_STATIC => _x('Estático', 'history source selection method')
]))->setDefault(Widget::UNIT_AUTO)
)
->addField(
(new CWidgetFieldTextBox('value_static_units'))
)
->addField(
new CWidgetFieldTextBox('description', _('Descripción'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Vista del formulario del widget de gráfico de indicador.
*
* @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(_('valor'))
->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
(new CWidgetFormView($data))
->addField(
(new CWidgetFieldMultiSelectItemView($data['fields']['itemid']))
->setPopupParameter('numeric', true)
)
->addFieldset(
(new CWidgetFormFieldsetCollapsibleView(_('Configuración avanzada')))
->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();
El método addField() de la clase CWidgetFormView acepta una cadena de clase CSS como segundo parámetro.
En esta sección, aprenderá cómo añadir un gráfico de tipo gauge, realizado con JavaScript, que muestra si el valor más reciente es normal o demasiado alto/bajo.
JavaScript será responsable de inicializar el selector de color en la vista de configuración.
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
/**
* Vista del formulario del widget de gráfico gauge.
*
* @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(_('Configuración avanzada')))
->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();
Haga clic en Aplicar en el formulario de configuración del widget. Luego haga clic en Guardar cambios en la esquina superior derecha para guardar el panel.
Abra actions/WidgetView.php y actualice el controlador.
La propiedad $this->fields_values ahora contiene los valores de todos los campos de Configuración avanzada. Finalice el controlador para permitir pasar la configuración y el valor de la métrica seleccionada a la vista del 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()
]
]));
}
}
Debe crear un contenedor para el gráfico gauge, que dibujará en los siguientes pasos, y un contenedor para la descripción.
Para pasar valores a JavaScript como un objeto JSON, utilice el método setVar().
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Vista del widget de gráfico gauge.
*
* @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();
Cree un nuevo directorio assets en el directorio lesson_gauge_chart. Este directorio se utilizará para almacenar JavaScript, CSS y potencialmente cualquier otro recurso, como fuentes o imágenes.
Para el JavaScript de la vista del widget, cree un directorio js en el directorio assets.
Cree un archivo class.widget.js en el directorio assets/js.
Esta clase JavaScript del widget extenderá la clase base JavaScript de todos los widgets del panel - CWidget.
El panel depende de una implementación correcta de un widget y comunica cualquier información relevante al widget llamando a los respectivos métodos JavaScript. El panel también espera que el widget genere eventos cuando se produce alguna interacción. Por lo tanto, la clase CWidget contiene un conjunto de métodos con la implementación por defecto del comportamiento del widget, que puede personalizarse extendiendo la clase.
En este caso, es necesaria cierta personalización, por lo tanto se implementará lógica personalizada para el siguiente comportamiento del widget:
Para otros aspectos del widget de gráfico gauge, se utilizará la implementación por defecto del comportamiento del widget. Para obtener más información sobre los métodos JavaScript de la clase CWidget, consulte: JavaScript.
Dado que este JavaScript es necesario para la vista del widget, debe cargarse con la página del panel. Para habilitar la carga de JavaScript, deberá actualizar los parámetros assets/js y js_class en el archivo manifest.json como se muestra en el paso 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);
}
}
La clase WidgetLessonGaugeChart ahora se cargará automáticamente con el panel.
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"]
}
}
En esta sección aprenderá cómo añadir estilos CSS personalizados para que el widget tenga un aspecto más atractivo.
Para los estilos del widget, cree un nuevo directorio css en el directorio assets.
Cree un archivo widget.css en el directorio assets/css. Para dar estilo a los elementos del widget, utilice el selector div.dashboard-widget-{widget id}. Para configurar el CSS para todo el widget, utilice el selector 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": "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"]
}
}