[comment]: # aside:2

[comment]: # ({04e47dfc-fa26c138})

# Create a widget (tutorial)

[comment]: # ({/04e47dfc-fa26c138})

[comment]: # ({14b8f451-386f5763})
Šī ir soli pa solim apmācība, kurā parādīts, kā izveidot vienkāršu paneļa logrīku.
Jūs varat lejupielādēt visus šī logrīka failus kā ZIP arhīvu: [lesson_gauge_chart.zip](../../../../assets/en/devel/modules/examples/lesson_gauge_chart.zip).

[comment]: # ({/14b8f451-386f5763})

[comment]: # ({096b9349-dead8e1e})
## Ko jūs izveidosiet

Šīs pamācības laikā jūs vispirms izveidosiet [pamata](#part-i--hello-world) "Hello, world!" logrīku un pēc tam pārveidosiet to par [modernāku](#part-ii--gauge-chart) logrīku, kas attēlo vienuma vērtību kā mērinstrumenta diagrammu.
Lūk, kā izskatīsies pabeigtais logrīks:

![](../../../../assets/en/devel/modules/tutorials/widget/widget_view_finished.png){width="600"}

[comment]: # ({/096b9349-dead8e1e})

[comment]: # ({156649db-03fc601d})

## Part I - "Hello, world!" 

In this section you will learn how to create the minimum required widget elements and add a new widget to Zabbix frontend.

[comment]: # ({/156649db-03fc601d})

[comment]: # ({33e23fc9-ac51379a})
### Pievienojiet tukšu logrīku Zabbix lietotāja saskarnei

1. Izveidojiet direktoriju *lesson_gauge_chart* direktorijā *modules* savā Zabbix lietotāja saskarnes instalācijā (piemēram, *zabbix/ui/modules*).

::: noteclassic
Visi pielāgotie logrīki tiek uzskatīti par ārējiem moduļiem, un tie ir jāpievieno Zabbix lietotāja saskarnes instalācijas direktorijai *modules* (piemēram, *zabbix/ui/modules*).
Direktorija *zabbix/ui/widgets* ir rezervēta Zabbix iebūvētajiem logrīkiem un tiek atjaunināta kopā ar Zabbix lietotāja saskarni.
:::

2. Izveidojiet failu *manifest.json* ar pamata logrīka metadatiem (skatiet atbalstīto [parametru](../file_structure/manifest) aprakstu).

**ui/modules/lesson_gauge_chart/manifest.json**

```json
{
    "manifest_version": 2.0,
    "id": "lesson_gauge_chart",
    "type": "widget",
    "name": "Gauge chart",
    "namespace": "LessonGaugeChart",
    "version": "1.1",
    "author": "Zabbix"
}
```

3. Zabbix lietotāja saskarnē dodieties uz sadaļu *Administration → General → Modules* un noklikšķiniet uz pogas *Scan directory*.

![](../../../../assets/en/devel/modules/tutorials/widget/scan_dir.png)

4. Sarakstā atrodiet jauno moduli *Gauge chart* un noklikšķiniet uz hipersaites "Disabled", lai mainītu moduļa statusu no "Disabled" uz "Enabled" (ja modulis nav sarakstā, skatiet sadaļu [troubleshooting](/manual/extensions/frontendmodules#installation)).

![](../../../../assets/en/devel/modules/tutorials/widget/widget_register.png){width="600"}

5. Atveriet paneli, pārslēdziet to rediģēšanas režīmā un pievienojiet jaunu logrīku.
Laukā *Type* atlasiet "Gauge chart".

![](../../../../assets/en/devel/modules/tutorials/widget/widget_add.png){width="600"}

6. Šajā brīdī *Gauge chart* logrīka konfigurācijā ir tikai kopīgie logrīka lauki *Name* un *Refresh interval*.
Noklikšķiniet uz *Add*, lai pievienotu logrīku panelim.

![](../../../../assets/en/devel/modules/tutorials/widget/widget_conf_b.png){width="600"}

7. Panelī jāparādās tukšam logrīkam.
Augšējā labajā stūrī noklikšķiniet uz *Save changes*, lai saglabātu paneli.

![](../../../../assets/en/devel/modules/tutorials/widget/widget_blank_b.png){width="600"}

[comment]: # ({/33e23fc9-ac51379a})

[comment]: # ({6ca1b1e7-a953cd01})
### Pievienojiet logrīka skatu

:::noteclassic
Logrīka **skata** failam jāatrodas direktorijā *views* (šajā pamācībā — *ui/modules/lesson_gauge_chart/views/*).
Ja failam ir noklusējuma nosaukums *widget.view.php*, tas nav jāreģistrē failā *manifest.json*.
Ja failam ir cits nosaukums, norādiet to faila [manifest.json](/devel/modules/file_structure/manifest) sadaļā *actions/widget.lesson_gauge_chart.view*.
:::

1. Izveidojiet direktoriju *views* direktorijā *lesson_gauge_chart*.

2. Izveidojiet failu *widget.view.php* direktorijā *views*.

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

```php
<?php

/**
 * Gauge chart logrīka skats.
 *
 * @var CView $this
 * @var array $data
 */

(new CWidgetView($data))
    ->addItem(
        new CTag('h1', true, 'Hello, world!')
    )
    ->show();
```

3. Atsvaidziniet paneli.
Logrīks *Gauge chart* tagad attēlo "Hello, world!".

![](../../../../assets/en/devel/modules/tutorials/widget/widget_hello_world.png){width="600"}

[comment]: # ({/6ca1b1e7-a953cd01})

[comment]: # ({f5b50cf9-b89998cf})

## Part II - Gauge chart

[comment]: # ({/f5b50cf9-b89998cf})

[comment]: # ({d1da3c35-b23d5e39})
### Pievienojiet iestatījumus konfigurācijas skatam un izmantojiet tos logrīka skatā

Šajā sadaļā jūs uzzināsiet, kā pievienot logrīka konfigurācijas lauku un parādīt ievadīto vērtību logrīka skatā kā tekstu.

Logrīka konfigurācija sastāv no formas (*Zabbix\\Widgets\\CWidgetForm*) un logrīka formas skata (*widget.edit.php*).
Lai pievienotu laukus (*Zabbix\\Widgets\\CWidgetField*), jums jāizveido *WidgetForm* klase, kas paplašinās *Zabbix\\Widgets\\CWidgetForm*.

Forma satur dažādu tipu lauku kopu (*Zabbix\\Widgets\\CWidgetField*), kas tiek izmantoti lietotāja ievadīto vērtību validēšanai.
Formas lauks (*Zabbix\\Widgets\\CWidgetField*) katram ievades elementa tipam pārveido vērtību vienotā formātā, lai to saglabātu datubāzē.

:::noteclassic
Logrīka **formas** failam jāatrodas direktorijā *includes* (šajā pamācībā — *ui/modules/lesson_gauge_chart/includes/*).
Ja failam ir noklusējuma nosaukums *WidgetForm.php*, tas nav jāreģistrē failā *manifest.json*.
Ja failam ir cits nosaukums, norādiet to faila [manifest.json](/devel/modules/file_structure/manifest) sadaļā *widget/form_class*.
:::

1. Izveidojiet jaunu direktoriju *includes* direktorijā *lesson_gauge_chart*.

2. Izveidojiet failu *WidgetForm.php* direktorijā *includes*.

**ui/modules/lesson_gauge_chart/includes/WidgetForm.php**

```php
<?php

namespace Modules\LessonGaugeChart\Includes;

use Zabbix\Widgets\CWidgetForm;

class WidgetForm extends CWidgetForm {
}
```

3. Pievienojiet logrīka konfigurācijas formai lauku *Description*.
Tas ir parasts teksta lauks, kurā lietotājs var ievadīt jebkuru rakstzīmju kopu.
Tam var izmantot klasi *CWidgetFieldTextBox*.

**ui/modules/lesson_gauge_chart/includes/WidgetForm.php**

```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'))
            );
   }
}
```

4. Direktorijā *views* izveidojiet logrīka konfigurācijas skata failu *widget.edit.php* un pievienojiet skatu jaunajam laukam *Description*.
Lauka klasei *CWidgetFieldTextBox* skats ir *CWidgetFieldTextBoxView.*

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

```php
<?php

/**
 * Gauge chart widget form view.
 *
 * @var CView $this
 * @var array $data
 */

(new CWidgetFormView($data))
    ->addField(
        new CWidgetFieldTextBoxView($data['fields']['description'])
    )
    ->show();
```

5. Dodieties uz paneli un noklikšķiniet uz zobrata ikonas logrīkā, lai atvērtu logrīka konfigurācijas formu.

6. Logrīka konfigurācijas forma tagad satur jaunu teksta lauku *Description*.
Ievadiet jebkuru vērtību, piemēram, *Gauge chart description*.

![](../../../../assets/en/devel/modules/tutorials/widget/widget_conf_descr.png){width="600"}

7. Logrīka konfigurācijas formā noklikšķiniet uz *Apply*.
Pēc tam augšējā labajā stūrī noklikšķiniet uz *Save changes*, lai saglabātu paneli.
Ņemiet vērā, ka jaunais apraksts nekur nav redzams un logrīks joprojām attēlo "Hello, world!".

Lai jaunais apraksts tiktu parādīts logrīkā, lauka *Description* vērtība ir jāiegūst no datubāzes un jānodod logrīka skatam.
Lai to izdarītu, jums jāizveido darbības klase.

8. Izveidojiet jaunu direktoriju *actions* direktorijā *lesson_gauge_chart*.

9. Izveidojiet failu *WidgetView.php* direktorijā *actions*.
Darbības klase *WidgetView* paplašinās klasi *CControllerDashboardWidgetView*.

Logrīka konfigurācijas lauku vērtības tiek glabātas darbības klases īpašībā **$fields_values**.

**ui/modules/lesson_gauge_chart/actions/WidgetView.php**

```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()
            ]
        ]));
    }
}
```

10. Atveriet *manifest.json* un reģistrējiet *WidgetView* kā darbības klasi sadaļā *actions/widget.lesson_gauge_chart.view*.

**ui/modules/lesson_gauge_chart/manifest.json**

```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"
        }
    }
}
```

11. Tagad logrīka skatā varat izmantot apraksta lauka vērtību, kas atrodas *$data['description']*.
Atveriet *views/widget.view.php* un aizstājiet statisko tekstu "Hello, world!" ar *$data['description']*.

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

```php
<?php

/**
 * Gauge chart widget view.
 *
 * @var CView $this
 * @var array $data
 */

(new CWidgetView($data))
    ->addItem(
        new CTag('h1', true, $data['description'])
    )
    ->show();
```

12. Atsvaidziniet paneļa lapu.
Tagad jums vajadzētu redzēt logrīka apraksta tekstu "Hello, world!" vietā.

![](../../../../assets/en/devel/modules/tutorials/widget/widget_view_descr.png){width="600"}

[comment]: # ({/d1da3c35-b23d5e39})

[comment]: # ({c52f5522-3f0e28b2})
### Iegūt vienuma vērtību, izmantojot API

Logrīkam jāparāda lietotāja izvēlēta vienuma pēdējā vērtība.
Lai to izdarītu, logrīka konfigurācijai jāpievieno iespēja atlasīt vienumus.

Šajā sadaļā jūs uzzināsiet, kā logrīka formai pievienot vienuma atlases lauku un kā pievienot šī lauka vizuālo daļu konfigurācijas skatā.
Pēc tam logrīka kontrolieris varēs iegūt vienuma datus un tā vērtību, izmantojot API pieprasījumu.
Pēc saņemšanas vērtību varēs attēlot logrīka skatā.

1. Atveriet *includes/WidgetForm.php* un pievienojiet lauku *CWidgetFieldMultiSelectItem*.
Tas ļaus konfigurācijas formā atlasīt vienumu.

**ui/modules/lesson_gauge_chart/includes/WidgetForm.php**

```php
<?php

namespace Modules\LessonGaugeChart\Includes;

use Zabbix\Widgets\{
    CWidgetField,
    CWidgetForm
};

use Zabbix\Widgets\Fields\{
    CWidgetFieldMultiSelectItem,
    CWidgetFieldTextBox
};

/**
 * Mērinstrumenta diagrammas logrīka forma.
 */
class WidgetForm extends CWidgetForm {
    
    public function addFields(): self {
        return $this
            ->addField(
                (new CWidgetFieldMultiSelectItem('itemid', _('Vienums')))
                    ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK)
                    ->setMultiple(false)
            )
            ->addField(
                new CWidgetFieldTextBox('description', _('Apraksts'))
            );
    }
}
```

2. Atveriet *views/widget.edit.php* un pievienojiet lauka vizuālo komponenti konfigurācijas skatam.

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

```php
<?php

/**
 * Mērinstrumenta diagrammas logrīka formas skats.
 *
 * @var CView $this
 * @var array $data
 */

(new CWidgetFormView($data))
    ->addField(
        new CWidgetFieldMultiSelectItemView($data['fields']['itemid'])
    )
    ->addField(
        new CWidgetFieldTextBoxView($data['fields']['description'])
    )
    ->show();
```

3. Atgriezieties panelī un noklikšķiniet uz zobrata ikonas logrīkā, lai atvērtu logrīka konfigurācijas formu.

4. Logrīka konfigurācijas forma tagad satur jaunu ievades lauku *Vienums*.
Atlasiet hostu "Zabbix server" un vienumu "Load average (1m avg)".

![](../../../../assets/en/devel/modules/tutorials/widget/widget_conf_item.png){width=600}

5. Logrīka konfigurācijas formā noklikšķiniet uz *Piemērot*.
Pēc tam augšējā labajā stūrī noklikšķiniet uz *Saglabāt izmaiņas*, lai saglabātu paneli.

6. Atveriet un modificējiet *actions/WidgetView.php*.

Turpmāk vienuma ID būs pieejams logrīka kontrolierī *$this->fields\_values\['itemid'\]*.
Kontroliera metode *doAction()* apkopo vienuma datus (nosaukumu, vērtības tipu, mērvienības), izmantojot API metodi *[item.get](/manual/api/reference/item/get)*, un vienuma pēdējo vērtību, izmantojot API metodi *[history.get](/manual/api/reference/history/get)*.

**ui/modules/lesson_gauge_chart/actions/WidgetView.php**

```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()
            ]
        ]));
    }
}
```

7. Atveriet *views/widget.view.php* un pievienojiet vienuma vērtību logrīka skatam.

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

```php
<?php

/**
 * Mērinstrumenta diagrammas logrīka skats.
 *
 * @var CView $this
 * @var array $data
 */

(new CWidgetView($data))
    ->addItem([
        new CTag('h1', true, $data['description']),
        new CDiv($data['value'] !== null ? $data['value']['value'] : _('Nav datu'))
    ])
    ->show();
```

8. Atsvaidziniet paneļa lapu.
Logrīks attēlos jaunāko vienuma vērtību.

![](../../../../assets/en/devel/modules/tutorials/widget/widget_view_item.png){width="600"}

[comment]: # ({/c52f5522-3f0e28b2})

[comment]: # ({aa1b47ba-8f001ece})
### Pievienot papildu konfigurācijas iestatījumus konfigurācijas skatā

Šajā sadaļā jūs uzzināsiet, kā pievienot izvēršamu/sakļaujamu *Papildu konfigurācija* sadaļu ar izvēles parametriem, piemēram, krāsu, minimālajām un maksimālajām vērtībām, vienībām un iepriekš izveidoto *Apraksts* lauku.

1. Izveidojiet *Widget.php* failu galvenajā logrīka direktorijā *lesson_gauge_chart*, lai izveidotu jaunu klasi *Widget*.

Klase *Widget* paplašinās bāzes klasi *CWidget*, lai pievienotu/pārrakstītu noklusējuma logrīka iestatījumus (šajā gadījumā - tulkojumus).
Tālāk norādītais JavaScript parāda virkni "No data", ja dati nav pieejami.
Virkne "No data" ir pieejama Zabbix lietotāja saskarnes tulkojumu failos.

Ja ir kādas logrīka konstantes, ieteicams tās norādīt arī klasē *Widget*.

**ui/modules/lesson_gauge_chart/Widget.php**

```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')
            ]
        ];
    }
}
```

2. Atveriet *includes/WidgetForm.php* un pievienojiet jaunus laukus *Color* (krāsu izvēlne), *Min* (skaitlisks lauks), *Max* (skaitlisks lauks) un *Units* (izvēlne), kā arī definējiet noklusējuma krāsu paleti krāsu izvēlnei, lai to varētu izmantot nākamajās darbībās.

**ui/modules/lesson_gauge_chart/includes/WidgetForm.php**

```php
<?php

namespace Modules\LessonGaugeChart\Includes;

use Modules\LessonGaugeChart\Widget;

use Zabbix\Widgets\{
    CWidgetField,
    CWidgetForm
};

use Zabbix\Widgets\Fields\{
    CWidgetFieldColor,
    CWidgetFieldMultiSelectItem,
    CWidgetFieldNumericBox,
    CWidgetFieldSelect,
    CWidgetFieldTextBox
};

/**
 * Gauge chart widget form.
 */
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'))
            );
    }
}
```

3. Atveriet *views/widget.edit.php* un pievienojiet lauku vizuālos komponentus konfigurācijas skatam.

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

```php
<?php

/**
 * Gauge chart widget form view.
 *
 * @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();
```

::: noteclassic
Metodes *addField()* klasei *CWidgetFormView* kā otro parametru pieņem CSS klases virkni.
:::

4. Atgriezieties informācijas panelī, pārslēdzieties rediģēšanas režīmā un noklikšķiniet uz zobrata ikonas logrīkā, lai atvērtu logrīka konfigurācijas formu.
Tagad logrīka konfigurācijas forma satur jaunu izvēršamu/sakļaujamu sadaļu *Papildu konfigurācija*.

![](../../../../assets/en/devel/modules/tutorials/widget/widget_conf_advanced.png){width="600"}

5. Izvēršiet sadaļu *Papildu konfigurācija*, lai redzētu papildu logrīka konfigurācijas laukus.
Ņemiet vērā, ka laukam *Color* vēl nav krāsu izvēlnes.
Tas ir tāpēc, ka krāsu izvēlne ir jāinicializē ar JavaScript, kas tiks pievienots nākamajā sadaļā - [*Pievienot JavaScript logrīkam*](#add-javascript-to-the-widget).

![](../../../../assets/en/devel/modules/tutorials/widget/widget_conf_advanced_a.png){width="600"}

[comment]: # ({/aa1b47ba-8f001ece})

[comment]: # ({175c9f96-c573cc71})
### JavaScript pievienošana logrīkam

Šajā sadaļā jūs uzzināsiet, kā pievienot mērinstrumenta diagrammu (gauge chart), kas izveidota, izmantojot JavaScript, un parāda, vai jaunākā vērtība ir normāla vai pārāk augsta/zema.

1. Izveidojiet failu *widget.edit.js.php* direktorijā *views*.

JavaScript būs atbildīgs par krāsu izvēlētāja inicializēšanu konfigurācijas skatā.

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

```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 ?>;
    }
};
```

2. Atveriet *views/widget.edit.php* un pievienojiet failu *widget.edit.js.php* ar JavaScript konfigurācijas skatam.
Lai to izdarītu, izmantojiet metodi *includeJsFile()*.
Lai pievienotu iekļauto JavaScript, izmantojiet metodi *addJavaScript()*.

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

```php
<?php

/**
 * Gauge chart logrīka formas skats.
 *
 * @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();
```

3. Atgriezieties panelī, noklikšķiniet uz zobrata ikonas logrīkā, lai atvērtu logrīka konfigurācijas formu.
Tagad izvērsiet sadaļu *Advanced configuration*, lai redzētu inicializēto krāsu izvēlētāju.
Aizpildiet laukus ar vērtībām un izvēlieties krāsu mērinstrumenta diagrammai.

![](../../../../assets/en/devel/modules/tutorials/widget/widget_conf_advanced_b.png){width="600"}

4. Logrīka konfigurācijas formā noklikšķiniet uz *Apply*.
Pēc tam augšējā labajā stūrī noklikšķiniet uz *Save changes*, lai saglabātu paneli.

5. Atveriet *actions/WidgetView.php* un atjauniniet kontrolieri.

Īpašība **$this->fields_values** tagad satur visu *Advanced configuration* lauku vērtības.
Pabeidziet kontrolieri, lai iespējotu konfigurācijas un atlasītā vienuma vērtības nodošanu logrīka skatam.

**ui/modules/lesson_gauge_chart/actions/WidgetView.php**

```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()
            ]
        ]));
    }
}
```

6. Atveriet un modificējiet *views/widget.view.php*.

Jums jāizveido konteiners mērinstrumenta diagrammai, kuru zīmēsiet nākamajos soļos, un konteiners aprakstam.

Lai nodotu vērtības JavaScript kā JSON objektu, izmantojiet metodi *setVar()*.

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

```php
<?php

/**
 * Gauge chart logrīka skats.
 *
 * @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();
```

7. Izveidojiet jaunu direktoriju *assets* direktorijā *lesson_gauge_chart*.
Šī direktorija tiks izmantota JavaScript, CSS un, iespējams, citu resursu, piemēram, fontu vai attēlu, glabāšanai.

8. Logrīka skata JavaScript vajadzībām izveidojiet direktoriju *js* direktorijā *assets*.

9. Izveidojiet failu *class.widget.js* direktorijā *assets/js*.

Šī JavaScript logrīka klase paplašinās visu paneļa logrīku pamata JavaScript klasi — *CWidget*.

Panelis paļaujas uz korektu logrīka implementāciju un nodod visu attiecīgo informāciju logrīkam, izsaucot atbilstošās JavaScript metodes.
Panelis arī sagaida, ka logrīks ģenerēs notikumus, kad notiks kāda mijiedarbība.
Tādēļ klase *CWidget* satur metožu kopu ar noklusēto logrīka darbības implementāciju, kuru var pielāgot, paplašinot šo klasi.

Šajā gadījumā ir nepieciešama zināma pielāgošana, tāpēc tiks ieviesta pielāgota loģika šādai logrīka darbībai:

-   logrīka inicializācija, kas ir atbildīga par logrīka sākotnējā stāvokļa noteikšanu (skatiet metodi *onInitialize()*);
-   logrīka satura attēlošana (tas ir, mērinstrumenta diagrammas zīmēšana), ja logrīka atjaunināšanas process ir bijis veiksmīgs un bez kļūdām (skatiet metodi *processUpdateResponse(response)* un saistītās metodes *\_resizeChart()* un *\_updatedChart()*)
-   logrīka izmēra maiņa (skatiet metodi *onResize()* un saistīto metodi *\_resizeChart()*)

Citos mērinstrumenta diagrammas logrīka aspektos tiks izmantota noklusētā logrīka darbības implementācija.
Lai uzzinātu vairāk par klases *CWidget* JavaScript metodēm, skatiet: [JavaScript](/devel/modules/widgets/presentation/javascript).

Tā kā šis JavaScript ir nepieciešams logrīka skatam, tas jāielādē kopā ar paneļa lapu.
Lai iespējotu JavaScript ielādi, jums būs jāatjaunina parametri *assets/js* un *js_class* failā ***manifest.json***, kā parādīts 10. solī.

**ui/modules/lesson_gauge_chart/assets/js/class.widget.js**

```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);
    }
}
```

10. Atveriet *manifest.json* un pievienojiet:

- faila nosaukumu (*class.widget.js*) masīvam sadaļā *assets/js*;
- klases nosaukumu (*WidgetLessonGaugeChart*) parametram *js_class* sadaļā *widget*.

Klase *WidgetLessonGaugeChart* tagad tiks automātiski ielādēta kopā ar paneli.

**ui/modules/lesson_gauge_chart/manifest.json**

```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"]
    }
}
```

[comment]: # ({/175c9f96-c573cc71})

[comment]: # ({6ea664c3-71184963})
### Pievienojiet logrīkam CSS stilus

Šajā sadaļā jūs uzzināsiet, kā pievienot pielāgotus CSS stilus, lai logrīks izskatītos pievilcīgāk.

1. Logrīka stiliem izveidojiet jaunu direktoriju *css* direktorijā *assets*.

2. Izveidojiet failu *widget.css* direktorijā *assets/css*.
Lai stilizētu logrīka elementus, izmantojiet selektoru *div.dashboard-widget-{widget id}*.
Lai konfigurētu CSS visam logrīkam, izmantojiet selektoru *form.dashboard-widget-{widget id}*

**ui/modules/lesson_gauge_chart/assets/css/widget.css**

```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;
}
```

3. Atveriet *manifest.json* un pievienojiet CSS faila nosaukumu (*widget.css*) masīvam sadaļā *assets/css*.
Tas ļaus failā *widget.css* definētajiem CSS stiliem ielādēties kopā ar paneļa lapu.

**ui/modules/lesson_gauge_chart/manifest.json**

```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"]
    }
}
```

4. Atsvaidziniet paneļa lapu, lai redzētu pabeigto logrīka versiju.

![](../../../../assets/en/devel/modules/tutorials/widget/widget_view_finished.png){width="600"}

[comment]: # ({/6ea664c3-71184963})
