Комплексный виджет это виджет, отображающий друг под другом два блока данных:
Внешний вид виджета показан на рисунке . В элементе svg можно предусматривается возможность поставить пользователю иконку. На виджете реализуются специальные элементы, такие как переход по ссылке на другой дашборд и просмотр границ контроля текущего параметра.
Поскольку виджет называется комплексным, введем следующие названия файлов:
Любой код виджета требует импорт библиотек пакета **@inspark/widget-common/interface **.
Поэтому вначале выполним импорт:
import {
_,
WidgetPackage,
WidgetComponent,
ITEM_TYPE, ItemSingle, PARAM_TYPE, ParamConfigSingle,
WidgetParams, Component, WidgetComponentContainer
} from '@inspark/widget-common/interface';
Для того, чтобы конфигуратор виджета, а также сервис, знали о том какие данные нужны виджету и как они должны передаваться, необходимо описать входные параметры.
Для комплексного виджета они такие:
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 |
Каждый виджет представляет из себя класс, в который разработчик может добавить собственный код. Для получения данных, опишем функцию 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
};
}
}
Блок ниже необходим для того, чтобы внутренняя система среды разработки поняла, что шаблон виджета относится к этому виджету и правильно передавала в него данные. Функционально данный блок не несет никакой нагрузки и не является обязательным, но строго рекомендуемым.
@Component({
templateUrl: './widget.complex.html', // Связывает наш код виджета с html шаблоном
})
class WidgetContainer extends WidgetComponentContainer {
values: InputParameters;
component = new WidgetComplex(); // Если необходимо использовать функции или данные нашего виджета внутри шаблона.
}
Для того, чтобы виджет можно было загрузить в магазин его необходимо экспортировать с типом 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 кода, поэтому мы остановимся только на важных моментах.
В соответствии с описанной структурой мы можем использовать в виджете переменные 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>
Стили виджета являются обособленной структурой. В Angular это реализуется использованием encapsulation: ViewEncapsulation.Emulated,
В стилях виджета можно использовать цвета приложения, применяя соответствующие css переменные. В данном примере не вводятся никаких дополнительных стилей, файл пуст, стили будут применены платформенные (по умолчанию три темы: светлая, темная, контрастная).
В классе widgetPackage не используется файл локализации
locales: [{code: 'en', file: require('./i18n/en.json')}, {code: 'ru', file: require('./i18n/ru.json')}]
В виджетах есть возможность добавлять собственные медиафайлы(картинки, видео, шрифты, звуки) в сборку.
Для того нужно:
class WidgetInfoBoardComponent extends WidgetComponent {
media = {
img: require('./media/tableExample0.svg')
};
}
<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;}