Примеры виджетов
Виджет с интервальным и текущим параметром
Комплексный виджет это виджет, отображающий друг под другом два блока данных:
- массив единичных значений;
- массив интервальных значений.
Внешний вид виджета
Внешний вид виджета показан на рисунке . В элементе svg можно предусматривается возможность поставить пользователю иконку. На виджете реализуются специальные элементы, такие как переход по ссылке на другой дашборд и просмотр границ контроля текущего параметра.
Состав файлов с кодом виджета
Поскольку виджет называется комплексным, введем следующие названия файлов:
- widget.complex.ts - содержит описание входных/выходных данных виджета, логику обмена данными с сервисами.
- widget.complex.html - содержит HTML представление виджета
- widget.complex.scss - стили виджета
- i18n\ru.json, i18n\en.json - локализация виджета для русского и англиского языка.
Импорт библиотеки-пакета (widget.complex.ts)
Любой код виджета требует импорт библиотек пакета **@inspark/widget-common/interface **.
Поэтому вначале выполним импорт:
import {
_,
WidgetPackage,
WidgetComponent,
ITEM_TYPE, ItemSingle, PARAM_TYPE, ParamConfigSingle,
WidgetParams, Component, WidgetComponentContainer
} from '@inspark/widget-common/interface';
Описание входных данных виджета (widget.complex.ts)
Для того, чтобы конфигуратор виджета, а также сервис, знали о том какие данные нужны виджету и как они должны передаваться, необходимо описать входные параметры.
Для комплексного виджета они такие:
const PARAMS: WidgetParams = {
instant: {
title: 'Список мгновенных значений',
item_type: ITEM_TYPE.single,
items: [{
max: 8,
}]
},
interval: {
title: 'Список интервальных значений',
item_type: ITEM_TYPE.interval,
items: [{
max: 8,
}]
}
};
Для того, чтобы в шаблоне виджета правильно работала система автодополнения кода, а также студия могла осуществлять поиск ошибок следует добавить интерфейс входных параметров. InputParameters зависит от описания WidgetParams и является той структурой, которая будет передана виджету для отображения.
interface InputParameters {
instant: {
config: ParamConfigSingle,
items: Array<ItemSingle>
};
interval: {
config: ParamConfigInterval,
items: Array<ItemInterval>
};
}
Как вы видите instant и interval есть как в описании WidgetParams, так и в InputParameters.
Типы config и items зависят от тех типов, которые были указаны в WidgetParams у поля item_type. InputParameters в комплексном виджете состоит из двух элементов:
config | Настройки, задаваемые в конфигураторе виджета |
---|---|
items | Массив значений ItemInterval |
Описание класса получения данных в виджет (widget.complex.ts)
Каждый виджет представляет из себя класс, в который разработчик может добавить собственный код. Для получения данных, опишем функцию onUpdate, которая вызывается каждый раз при передаче данных от сервиса виджету. Данные виджета доступны в параметре values, интерфейс InputParameters которого мы описали выше.
Добавим в комплексный виджет график-пирог для интервальных значений. Для этого нам нужно подготовить их для передачи в компонент chart (prepareDataPie).
class WidgetComplex extends WidgetComponent {
values: InputParameters;
dataPie: any;
configs: any;
onUpdate(values) {
if (values.interval && values.interval && values.interval.items && values.interval.items.length > 0) {
this.prepareDataPie(values);
}
}
private prepareDataPie(values) {
this.dataPie = values.interval.items.map((item, index) => {
if (item.data.stateMap && item.data.stateMap.length > 0) {
return {'value': '', 'data': item.data.stateMap.map(state => ({'key': state.state.statename, 'value': state.interval}))};
}
return null;
});
this.configs = {
charttype: ChartTypes.intervalPieChart
};
}
}
Подсветка синтаксиса в виджете (widget.complex.ts)
Блок ниже необходим для того, чтобы внутренняя система среды разработки поняла, что шаблон виджета относится к этому виджету и правильно передавала в него данные. Функционально данный блок не несет никакой нагрузки и не является обязательным, но строго рекомендуемым.
@Component({
templateUrl: './widget.complex.html', // Связывает наш код виджета с html шаблоном
})
class WidgetContainer extends WidgetComponentContainer {
values: InputParameters;
component = new WidgetComplex(); // Если необходимо использовать функции или данные нашего виджета внутри шаблона.
}
Описание выходных данных виджета WidgetPackage (widget.complex.ts)
Для того, чтобы виджет можно было загрузить в магазин его необходимо экспортировать с типом WidgetPackage.WidgetPackage это пакет виджета, включающий в себя информацию о данных, шаблоне, переводах, размерах и стилях.
const component: WidgetPackage = {
template: require('./widget.complex.html'),
component: new WidgetComplex(),
params: PARAMS,
size: {'sm': {'x': 0, 'y': 0, 'w': 3, 'h': 6}, 'lg': {'x': 0, 'y': 0, 'w': 5, 'h': 7}, 'mobile': {'x': 0, 'y': 0, 'w': 2, 'h': 7}},
styles: require('./widget.complex.scss'),
};
export default component;
После того, как мы подготовили ts файл, нам необходимо описать шаблон виджета.
Шаблон-html виджета (widget.complex.html)
Настоящий шаблон виджета довольно большой и в основном состоит из html кода, поэтому мы остановимся только на важных моментах.
В соответствии с описанной структурой мы можем использовать в виджете переменные values и component. Кроме того в виджете также доступны другие данные и функции контейнера.
<div *ngIf="values.instant.items.length > 0">
<div *ngFor="let par of values.instant.items">
<span>{{par.config.duration | periodFromDate : par.config.valueType}}</span>
<ng-container *ngIf="par.config.valueType == VALUE_TYPE.signal">
<div *ngIf="par.title">
{{par.title}}
</div>
<div *ngIf="(par.device.object.shortname || par.device.controller.serialnumber)"
class="u-h4 u-text_word-wrap_break-word">
{{par.device.object.shortname}} {{par.device.controller.serialnumber}}
</div>
<div *ngIf="par.data.switchCount" class="">
Количество переключений: {{par.data.switchCount}}
</div>
</ng-container>
<div *ngIf="component.dataPie && component.dataPie.length && component.configs"
class="u-text_center u-centring-ver">
<app-pie-chart [config]="component.configs"
[values]="component.dataPie[idx]"
class="chart"></app-pie-chart>
</div>
</div>
</div>
Стилизация виджета (widget.complex.scss)
Стили виджета являются обособленной структурой. В Angular это реализуется использованием encapsulation: ViewEncapsulation.Emulated,
В стилях виджета можно использовать цвета приложения, применяя соответствующие css переменные. В данном примере не вводятся никаких дополнительных стилей, файл пуст, стили будут применены платформенные (по умолчанию три темы: светлая, темная, контрастная).
Локализация
В классе widgetPackage не используется файл локализации
locales: [{code: 'en', file: require('./i18n/en.json')}, {code: 'ru', file: require('./i18n/ru.json')}]
Добавление своих медиа файлов в виджет
В виджетах есть возможность добавлять собственные медиафайлы(картинки, видео, шрифты, звуки) в сборку.
Для того нужно:
- скопировать его в папку виджета, например в подкаталог media.
- В коде виджета, загрузить файл, а точнее его url, в переменную с помощью require
class WidgetInfoBoardComponent extends WidgetComponent {
media = {
img: require('./media/tableExample0.svg')
};
}
- В шаблоне виджета использовать урл с помощью component.media.img или просто media.img
<img width="100px" height="100px" [src]="component.media.img" alt="Москва-Сити">
Пример виджета:
https://github.com/inspark/web-widget-container/tree/master/src/app/widgets/widget-info-board
Размеры виджета
Для разработчика доступно использование размеров виджета для отображения компактного размера или адаптации под большие экраны.
При изменении окна браузера, размеры виджета или формата отображения(мобильный, планшет, десктоп) вызывается функция onResize(width, height).
Если не требуется дополнительной обработки событий, то по-умолчанию она обновляет переменные ширины и высоты виджета.
onResize(width, height) {
this.width = width;
this.height = height;
}
Если вам необходимо переопределить событие onResize, не забудьте обновить переменные width и height.
Пример переопределения функции https://github.com/inspark/web-widget-container/blob/master/src/app/widgets/widget-chart/widget.chart.ts
Использование в шаблоне
Вы можете использовать размеры виджета, для отображения и скрытия различных классов, как это делается с помощью css @media.
Например, в следующем примере надпись видно только если ширина виджета более 500 пикселей.
<div [ngClass]="{small: component.width< 500}">Это большой размер</div>
<div *ngIf="component.width>=500">Альтернативный вариант использования</div>
css код
.small {display:none;}