Aquest ¨¦s un tutorial passa a passa que ensenyacom crear un giny de tauler senzill.
La versi¨® m¨ªnima requerida de Áú»¢¶Ä²© per a aquest tutorial ¨¦s la 6.4.4.
Podeu descarregar tots els fitxers d'aquest giny en un arxiu ZIP: lesson_gauge_chart.zip.
Durant aquest tutorial, primer creareu un giny ²ú¨¤²õ¾±³¦ "Hola, m¨®n!" i, a tot seguit, el convertireu a un giny m¨¦s avan?at que ensenya el valor d'un element com a gr¨¤fic gauge. Aix¨ª ¨¦s com es veur¨¤ el giny enllestit:
En aquesta secci¨® aprendreu a crear els elements m¨ªnims de giny necessaris i afegir un nou giny a la interf¨ªcie Áú»¢¶Ä²©.
Tots els ginys personalitzats es tracten com a ³¾¨°»å³Ü±ô²õ externs i s'han d'afegir al directori de ³¾¨°»å³Ü±ô²õ de Áú»¢¶Ä²© (per exemple, zabbix/ui/modules). El directori zabbix/ui/widgets ¨¦s reservat per als ginys integrats de Áú»¢¶Ä²© i s'actualitza juntament amb la interf¨ªcie d'usuari de Áú»¢¶Ä²©.
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": "Áú»¢¶Ä²© SIA"
}
El fitxer view del giny s'ha d'ubicar al directori views (per a aquest tutorial, ui/modules/lesson_gauge_chart/views/). Si el fitxer t¨¦ un nom predeterminat widget.view.php, no cal que el registreu a manifest.json. Si el fitxer t¨¦ un nom diferent, especifiqueu-lo a la secci¨® actions/widget.lesson_gauge_chart.view de manifest.json.
Afegiu un directori views al leson_gauge_chart.
Creeu el fitxer widget.view.php dins del directori views.
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Visualitzaci¨® del giny del gr¨¤fic de mesura.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, 'Hello, world!')
)
->show();
En aquesta secci¨®, aprendr¨¤s a afegir un camp de configuraci¨® del giny i a mostrar el valor introdu?t a la vista del giny com a text.
La configuraci¨® del giny consta d'un formulari (Áú»¢¶Ä²©\Widgets\CWidgetForm) i d'una vista de formulari de giny (widget.edit.php). Per afegir camps (Áú»¢¶Ä²©\Widgets\CWidgetField), heu de crear una classe WidgetForm, que ampliar¨¤ Áú»¢¶Ä²©\Widgets\CWidgetForm.
El formulari cont¨¦ el conjunt de camps (Áú»¢¶Ä²©\Widgets\CWidgetField) de diversos tipus, que s'empren per validar els valors introdu?ts per l'usuari. El camp de formulari (Áú»¢¶Ä²©\Widgets\CWidgetField) per a cada tipus d'element d'entrada converteix el valor en un format ¨²nic per emmagatzemar-lo a la base de dades.
El fitxer formulari del giny s'ha d'ubicar al directori includes (per a aquest tutorial, ui/modules/lesson_gauge_chart/includes/). Si el fitxer t¨¦ un nom predeterminat WidgetForm.php, no cal que el registreu a manifest.json. Si el fitxer t¨¦ un nom diferent, especifiqueu-lo a la secci¨® widget/form_class de manifest.json.
Afegiu un directori includes al lesson_gauge_chart.
Creeu el fitxer WidgetForm.php dins del directori includes.
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Áú»¢¶Ä²©\Widgets\CWidgetForm;
class WidgetForm extends CWidgetForm {
}
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Áú»¢¶Ä²©\Widgets\CWidgetForm;
use Áú»¢¶Ä²©\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
/**
* Visualitzaci¨® del formulari del giny del gr¨¤fic de mesura.
*
* @var CView $this
* @var array $data
*/
(new CWidgetFormView($data))
->addField(
new CWidgetFieldTextBoxView($data['fields']['description'])
)
->show();
Aneu al Tauler i premeu la icona d'engranatge per obrir la configuraci¨® del giny.
La configuraci¨® del giny ara cont¨¦ un camp nou de text (¶Ù±ð²õ³¦°ù¾±±è³¦¾±¨®). Introdu?u qualsevol valor, per exemple, ¶Ù±ð²õ³¦°ù¾±±è³¦¾±¨® del gr¨¤fic de calibre.
Per veure-ho al giny, cal recuperar el valor del camp ¶Ù±ð²õ³¦°ù¾±±è³¦¾±¨® de la base de dades i passar a la vista del giny. Per fer-ho, heu de crear una classe d'acci¨®.
Afegiu un directori actions al lesson_gauge_chart.
Creeu un fitxer WidgetView.php dins del directori actions. La classe d'acci¨® WidgetView ampliar¨¤ la classe CControllerDashboardWidgetView.
Els valors dels camps de configuraci¨® del giny s'emmagatzemen a la propietat $fields_values de la classe d'acci¨®.
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": "giny",
"name": "³Ò°ù¨¤´Ú¾±³¦ de mesura",
"namespace": "LessonGaugeChart",
"version": "1.0",
"author": "Áú»¢¶Ä²© SIA",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
}
}
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Visualitzaci¨® del giny del gr¨¤fic de mesura.
*
* @var CView $this
* @var array $data
*/
(nou CWidgetView($data))
->addItem(
new CTag('h1', true, $data['description'])
)
->show();
El giny hauria de mostrar el darrer valor d'un element triat per l'usuari. Per aix¨°, heu d'afegir la possibilitat de triar elements a la configuraci¨® del giny.
En aquesta secci¨® aprendreu a afegir un camp de selecci¨® d'elements al formulari del giny i a afegir la part visual d'aquest camp a la vista de configuraci¨®. Aleshores, el controlador de ginys podr¨¤ recuperar les dades de lelement i el seu valor mitjan?ant una petici¨® d'API. Un cop rebuda, el valor es pot mostrar a la vista del giny.
ui/modules/lesson_gauge_chart/includes/WidgetForm.php
<?php
namespace Modules\LessonGaugeChart\Includes;
use Áú»¢¶Ä²©\Widgets\{
CWidgetField,
CWidgetForm
};
use Áú»¢¶Ä²©\Widgets\Fields\{
CWidgetFieldMultiSelectItem,
CWidgetFieldTextBox
};
/**
* Formulari de giny de gr¨¤fic de calibre.
*/
classe WidgetForm amplia CWidgetForm {
public function addFields(): self {
return $this
->addField(
(newCWidgetFieldMultiSelectItem('itemid', _('Item')))
->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
->setMultiple (false)
)
->addField(
new CWidgetFieldTextBox('»å±ð²õ³¦°ù¾±±è³¦¾±¨®', _('¶Ù±ð²õ³¦°ù¾±±è³¦¾±¨®'))
);
}
}
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Visualitzaci¨® del formulari del giny del gr¨¤fic de mesura.
*
* @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();
Torneu al tauler i feu clic a la icona d'engranatge del giny per obrir el formulari de configuraci¨® del giny.
El formulari de configuraci¨® del giny ara cont¨¦ un camp d'entrada nou Element. Trieu l'equip "Servidor Áú»¢¶Ä²©" i l'element "C¨¤rrega mitjana (1 m de mitjana)".
Feu clic a Aplicar al formulari de configuraci¨® del gint. Tot seguit, feu clic a Desar els canvis a l'extrem superior dret per desar el tauler.
Obriu i modifiqueu actions/WidgetView.php.
A partir d'ara, l'identificador de l'element ser¨¤ disponible al controlador del giny a $this->fields_values['itemid']. El m¨¨tode del controlador doAction() recopila les dades de l'element (nom, tipus de valor, unitats) mitjan?ant el m¨¨tode API item.get i l'¨²ltim valor de l'element mitjan?ant el M¨¨tode de l'API history.get.
ui/modules/lesson_gauge_chart/actions/WidgetView.php
<?php
namespace Modules\LessonGaugeChart\Actions;
use API,
CControllerDashboardWidgetView,
CCollerResponseData;
class WidgetView extendsCControllerDashboardWidgetView {
protected function doAction(): void {
$db_items = API::Item()->get([
'output' => ['itemid', 'value_type', 'nom', 'unitats'],
'itemids' => $this->fields_values['itemid'],
'webitems' => true,
'filtre' => [
'value_type' => [ITEM_VALUE_TYPE_UINT64, ITEM_VALUE_TYPE_FLOAT]
]
]);
$value = nul;
if ($db_items) {
$element = $db_items[0];
$³ó¾±²õ³Ù¨°°ù¾±²¹ = API::History()->get([
'output' => API_OUTPUT_EXTEND,
'itemids' => $item['itemid'],
'history' => $item['value_type'],
'sortfield' => 'rellotge',
'sortorder' => ZBX_SORT_DOWN,
'±ô¨ª³¾¾±³Ù' => 1
]);
si ($history) {
$value = convertUnitsRaw([
'valor' => $history[0]['valor'],
'unitats' => $item['unitats']
]);
}
}
$this->setResponse(new CControllerResponseData([
'name' => $this->getInput('name', $this->widget->getName()),
'valor' => $value,
'description' => $this->fields_values['»å±ð²õ³¦°ù¾±±è³¦¾±¨®'],
'usuari' => [
'debug_mode' => $this->getDebugMode()
]
]));
}
}
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Visualitzaci¨® del giny del gr¨¤fic de mesura.
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem([
new CTag('h1', true, $data['»å±ð²õ³¦°ù¾±±è³¦¾±¨®']),
CDiv new($data['valor'] !== nul ? $data['valor']['valor'] : _('Sense dades'))
])
->show();
En aquesta secci¨®, aprendreu a afegir elements Javascript al giny.
Afegirem:
JavaScript ser¨¤ responsable d'amagar els camps opcionals darrere de la casella de selecci¨® °ä´Ç²Ô´Ú¾±²µ³Ü°ù²¹³¦¾±¨® avan?ada i d'inicialitzar el selector de colors a la vista de configuraci¨®. Podeu afegir-lo al mateix directori que la vista de configuraci¨®.
Com que el JavaScript per a la vista de configuraci¨® s'ha de carregar amb el formulari, haureu d'incloure-lo a widget.edit.php tal com es mostra a les passes seg¨¹ents.
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 ?>;
}
};
La classe Giny ampliar¨¤ la classe base CWidget per afegir/substituir la configuraci¨® predeterminada del giny (en aquest cas - traduccions).
JavaScript, que es proporciona tot seguit, mostra la cadena "Sense dades" en cas que manquin dades. La cadena "Sense dades" ¨¦s present als fitxers de traducci¨® de la interf¨ªcie d'usuari de Áú»¢¶Ä²©.
Si hi ha constants de giny, es recomana especificar-les tamb¨¦ a la classe Giny.
ui/modules/lesson_gauge_chart/Widget.php
<?php
namespace Modules\LessonGaugeChart;
use Áú»¢¶Ä²©\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 Áú»¢¶Ä²©\Widgets\CWidgetField;
use Áú»¢¶Ä²©\Widgets\CWidgetForm;
use Áú»¢¶Ä²©\Widgets\Fields\CWidgetFieldCheckBox;
use Áú»¢¶Ä²©\Widgets\Fields\CWidgetFieldColor;
use Áú»¢¶Ä²©\Widgets\Fields\CWidgetFieldMultiSelectItem;
use Áú»¢¶Ä²©\Widgets\Fields\CWidgetFieldNumericBox;
use Áú»¢¶Ä²©\Widgets\Fields\CWidgetFieldSelect;
use Áú»¢¶Ä²©\Widgets\Fields\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('666666')
)
->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'))
);
}
}
El m¨¨tode addField() de la classe CWidgetFormView pren una cadena de classe CSS com a segon par¨¤metre. Afegiu la cadena js-advanced-configuration a aquests camps i les seves etiquetes, que s'haurien d'amagar si no es tria °ä´Ç²Ô´Ú¾±²µ³Ü°ù²¹³¦¾±¨® avan?ada.
Per afegir un fitxer JavaScript a la vista de configuraci¨®, empreu el m¨¨tode includeJsFile(). Per afegir JavaScript en l¨ªnia, empreu el m¨¨tode addJavaScript().
ui/modules/lesson_gauge_chart/views/widget.edit.php
<?php
/**
* Visualitzaci¨® del formulari del giny del gr¨¤fic de mesura.
*
* @var CView $this
* @var array $data
*/
use Áú»¢¶Ä²©\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();
Premeu Aplicar a la configuraci¨® del giny. A continuaci¨®, premeu Desar els canvis per desar el tauler.
Obriu actions/WidgetView.php i actualitzeu el controlador.
La propietat $this->fields_values ara cont¨¦ els valors de tots els camps °ä´Ç²Ô´Ú¾±²µ³Ü°ù²¹³¦¾±¨® avan?ada. Finalitzeu el controlador per permetre passar la configuraci¨® i el valor de l'element triat a la vista del giny.
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()
]
]));
}
}
Heu de crear un contenidor per al gr¨¤fic de mesura, que dibuixareu a les passes seg¨¹ents, i un contenidor per a la descripci¨®.
Per passar valors a JavaScript com a objecte JSON, empreu el m¨¨tode setVar().
ui/modules/lesson_gauge_chart/views/widget.view.php
<?php
/**
* Visualitzaci¨® del giny del gr¨¤fic de mesura.
*
* @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();
Creeu un directori actius al gr¨¤fic_indicador de lli?ons. Aquest directori s'emprar¨¤ per emmagatzemar Javascript, CSS i, potencialment, qualsevol altre actiu, com fonts o imatges.
Per a JavaScript de visualitzaci¨® de ginys, creeu un directori js dins del directori assets.
Creeu un fitxer widget.js al directori assets/js.
Aquesta classe de widget de JavaScript ampliar¨¤ la classe de JavaScript base de tots els ginys del tauler - CWidget.
El tauler de control es basa en una implementaci¨® correcta d'un giny i comunica qualsevol informaci¨® rellevant al giny mitjan?ant la crida als m¨¨todes JavaScript respectius. El tauler tamb¨¦ espera que el giny generi esdeveniments quan es produeixi alguna interacci¨®. Aix¨ª, la classe CWidget cont¨¦ un conjunt de m¨¨todes amb la implementaci¨® predeterminada del comportament del giny, que es pot personalitzar ampliant la classe.
En aquest cas, cal una mica de personalitzaci¨®; per tant, s'implementar¨¤ una l¨°gica personalitzada per al comportament del giny seg¨¹ent:
-inicialitzaci¨® del giny que s'encarrega de definir l'estat inicial del giny (veieu el m¨¨tode _init()); -mostrar el contingut del giny (¨¦s a dir, dibuixar el gr¨¤fic de l'indicador) si el proc¨¦s d'actualitzaci¨® del giny ha estat satisfactori i sense errors (veieu el m¨¨tode _processUpdateResponse(response) i els m¨¨todes _resizeChart() i _updatedChart() relacionats) -canviar la mida del giny (veieu el m¨¨tode resize() i el m¨¨tode _resizeChart() relacionat)
Per a altres aspectes del giny del gr¨¤fic gauge, s'utilitzar¨¤ la implementaci¨® predeterminada del comportament del giny. Per obtenir m¨¦s informaci¨® sobre els m¨¨todes JavaScript de la classe CWidget, consulteu: JavaScript.
Com que aquest JavaScript ¨¦s necessari per a la vista del widget, s'hauria de carregar amb la p¨¤gina del tauler. Per habilitar la c¨¤rrega de JavaScript, haureu d'actualitzar els ±è²¹°ù¨¤³¾±ð³Ù°ù±ð²õ assets/js i js_class de manifest.json tal com es veu a la passa seg¨¹ent.
ui/modules/lesson_gauge_chart/assets/js/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);
}
}
La classe WidgetLessonGaugeChart ara es carregar¨¤ autom¨¤ticament amb el tauler.
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": "Áú»¢¶Ä²© SIA",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
},
"widget": {
"js_class": "WidgetLessonGaugeChart"
},
"assets": {
"js": ["class.widget.js"]
}
}
En aquesta secci¨® aprendreu a afegir estils CSS personalitzats per fer que el giny sembli m¨¦s atractiu.
Per als estils de giny, creeu un nou directori css dins del directori assets.
Afegiu el fitxer widget.css a assets/css. Per estilitzar els elements del giny, empreu el selector div.dashboard-widget-{widget id}. Per configurar CSS per a tot el giny, empreu 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": "Áú»¢¶Ä²© SIA",
"actions": {
"widget.lesson_gauge_chart.view": {
"class": "WidgetView"
}
},
"widget": {
"js_class": "WidgetLessonGaugeChart"
},
"assets": {
"css": ["widget.css"],
"js": ["widget.js"]
}
}