diff --git a/ui-ngx/src/app/shared/components/device/gateway-statistics.component.html b/ui-ngx/src/app/shared/components/device/gateway-statistics.component.html
index 3c8b6818c4..01b25734a7 100644
--- a/ui-ngx/src/app/shared/components/device/gateway-statistics.component.html
+++ b/ui-ngx/src/app/shared/components/device/gateway-statistics.component.html
@@ -18,7 +18,7 @@
diff --git a/ui-ngx/src/app/shared/components/device/gateway-statistics.component.scss b/ui-ngx/src/app/shared/components/device/gateway-statistics.component.scss
index 2125391eea..3cc39890ca 100644
--- a/ui-ngx/src/app/shared/components/device/gateway-statistics.component.scss
+++ b/ui-ngx/src/app/shared/components/device/gateway-statistics.component.scss
@@ -37,5 +37,37 @@
height: 100%;
}
}
+
+ .statistic-legend {
+ flex-wrap: wrap;
+ width: 100%;
+ padding-top: 8px;
+ padding-bottom: 4px;
+
+ .statistic-legend-keys {
+ .statistic-legend-label {
+ padding: 2px 20px 2px 10px;
+ white-space: nowrap;
+
+ &.statistic-hidden-label {
+ text-decoration: line-through;
+ opacity: .6;
+ }
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ .statistic-legend-line {
+ display: inline-block;
+ width: 15px;
+ height: 3px;
+ text-align: left;
+ vertical-align: middle;
+ outline: none;
+ }
+ }
+ }
}
diff --git a/ui-ngx/src/app/shared/components/device/gateway-statistics.component.ts b/ui-ngx/src/app/shared/components/device/gateway-statistics.component.ts
index 7d19db4ecd..d91bc4a404 100644
--- a/ui-ngx/src/app/shared/components/device/gateway-statistics.component.ts
+++ b/ui-ngx/src/app/shared/components/device/gateway-statistics.component.ts
@@ -23,12 +23,18 @@ import { MatDialog } from '@angular/material/dialog';
import { AttributeService } from '@core/http/attribute.service';
import { DeviceService } from '@core/http/device.service';
import { TranslateService } from '@ngx-translate/core';
-import { AttributeScope, DataKeyType } from '@shared/models/telemetry/telemetry.models';
+import { AttributeData, AttributeScope } from '@shared/models/telemetry/telemetry.models';
import { PageComponent } from '@shared/components/page.component';
import { DialogService } from '@app/core/services/dialog.service';
import { WidgetContext } from '@home/models/widget-component.models';
import { TbFlot } from '@home/components/widget/lib/flot-widget';
-import { ResizeObserver } from "@juggle/resize-observer";
+import { ResizeObserver } from '@juggle/resize-observer';
+import { IWidgetSubscription, SubscriptionInfo, WidgetSubscriptionOptions } from '@core/api/widget-api.models';
+import { UtilsService } from '@core/services/utils.service';
+import { DatasourceType, LegendConfig, LegendData, LegendPosition, widgetType } from '@shared/models/widget.models';
+import { EntityType } from '@shared/models/entity-type.models';
+import { EntityId } from '@shared/models/id/entity-id';
+import { BaseData } from '@shared/models/base-data';
@Component({
@@ -44,13 +50,29 @@ export class GatewayStatisticsComponent extends PageComponent implements AfterVi
ctx: WidgetContext;
private flot: TbFlot;
-
+ private flotCtx;
public statisticForm: FormGroup;
-
public statisticsKeys = [];
public commands = [];
public commandObj: any;
private resize$: ResizeObserver;
+ private subscription: IWidgetSubscription;
+ private subscriptionOptions: WidgetSubscriptionOptions = {
+ callbacks: {
+ onDataUpdated: (subscription, detectChanges) => this.ctx.ngZone.run(() => {
+ this.onDataUpdated();
+ }),
+ onDataUpdateError: (subscription, e) => this.ctx.ngZone.run(() => {
+ this.onDataUpdateError(subscription, e);
+ })
+ },
+ useDashboardTimewindow: false,
+ legendConfig : {
+ position: LegendPosition.bottom
+ } as LegendConfig
+ };
+ private subscriptionInfo: SubscriptionInfo [];
+ public legendData: LegendData;
constructor(protected router: Router,
@@ -61,6 +83,7 @@ export class GatewayStatisticsComponent extends PageComponent implements AfterVi
protected deviceService: DeviceService,
protected dialogService: DialogService,
private cd: ChangeDetectorRef,
+ private utils: UtilsService,
public dialog: MatDialog) {
super(store);
this.statisticForm = this.fb.group({
@@ -72,43 +95,60 @@ export class GatewayStatisticsComponent extends PageComponent implements AfterVi
if (this.commands.length) {
this.commandObj = this.commands.find(command => command.attributeOnGateway === value);
}
- this.changeSubscription(true);
+ if (this.subscriptionInfo) this.createChartsSubscription(this.ctx.defaultSubscription.datasources[0].entity, value);
})
}
ngAfterViewInit() {
+ this.init();
if (this.ctx.defaultSubscription.datasources.length) {
+
const gatewayId = this.ctx.defaultSubscription.datasources[0].entity.id;
- this.attributeService.getEntityAttributes(gatewayId, AttributeScope.SHARED_SCOPE, ["general_configuration"]).subscribe(resp => {
+ this.attributeService.getEntityAttributes(gatewayId, AttributeScope.SHARED_SCOPE, ["general_configuration"]).subscribe((resp: AttributeData[]) => {
if (resp && resp.length) {
this.commands = resp[0].value.statistics.commands;
if (!this.statisticForm.get('statisticKey').value) {
this.statisticForm.get('statisticKey').setValue(this.commands[0].attributeOnGateway);
- this.changeSubscription(true);
+ this.createChartsSubscription(this.ctx.defaultSubscription.datasources[0].entity, this.commands[0].attributeOnGateway);
}
}
})
}
- this.ctx.defaultSubscription.onTimewindowChangeFunction = timeWindow => {
- this.ctx.defaultSubscription.options.timeWindowConfig = timeWindow;
- this.ctx.defaultSubscription.updateTimewindowConfig(timeWindow);
- // this.ctx.defaultSubscription.update();
- this.updateChart();
- return timeWindow;
- }
- this.changeSubscription(true);
- this.resize$ = new ResizeObserver(() => {
- this.resize();
- });
- this.resize$.observe(this.statisticChart.nativeElement)
+
+ }
+
+ public onLegendKeyHiddenChange(index: number) {
+ this.legendData.keys[index].dataKey.hidden = !this.legendData.keys[index].dataKey.hidden;
+ this.subscription.updateDataVisibility(index);
}
- initChart = () => {
- if (this.ctx.defaultSubscription.data.length && !this.flot) {
- this.ctx.$container = $(this.statisticChart.nativeElement);
- this.flot = new TbFlot(this.ctx, 'line');
- } else setTimeout(this.initChart, 500);
+ private createChartsSubscription(gateway: BaseData, attr: string) {
+ let subscriptionInfo = [{
+ type: DatasourceType.entity,
+ entityType: EntityType.DEVICE,
+ entityId: gateway.id.id,
+ entityName: gateway.name,
+ timeseries: []
+ }];
+
+ subscriptionInfo[0].timeseries = [{name: attr, label: attr}];
+ this.subscriptionInfo = subscriptionInfo;
+ this.changeSubscription(subscriptionInfo);
+
+ }
+
+ init = () => {
+ this.flotCtx = {
+ $scope: this.ctx.$scope,
+ $injector: this.ctx.$injector,
+ utils: this.ctx.utils,
+ isMobile: this.ctx.isMobile,
+ isEdit: this.ctx.isEdit,
+ subscriptionApi: this.ctx.subscriptionApi,
+ detectChanges: this.ctx.detectChanges,
+ settings: this.ctx.settings
+ };
}
updateChart = () => {
@@ -123,31 +163,52 @@ export class GatewayStatisticsComponent extends PageComponent implements AfterVi
}
}
+ private reset() {
+ if (this.resize$) {
+ this.resize$.disconnect();
+ }
+ if (this.subscription) {
+ this.subscription.unsubscribe();
+ }
+ if (this.flot) {
+ this.flot.destroy();
+ }
+ }
+
+ private onDataUpdateError(subscription: IWidgetSubscription, e: any) {
+ const exceptionData = this.utils.parseException(e);
+ let errorText = exceptionData.name;
+ if (exceptionData.message) {
+ errorText += ': ' + exceptionData.message;
+ }
+ }
+
+ private onDataUpdated() {
+ if (this.flot) {
+ this.flot.update();
+ }
+ }
+
- changeSubscription(init?: boolean) {
+ changeSubscription(subscriptionInfo: SubscriptionInfo[]) {
+ if (this.subscription) {
+ this.reset();
+ }
if (this.ctx.datasources[0].entity) {
- if (this.flot && init) {
- this.flot.destroy();
- delete this.flot;
- }
- this.ctx.defaultSubscription.options.datasources[0].dataKeys = [{
- name: this.statisticForm.get('statisticKey').value,
- type: DataKeyType.timeseries,
- settings: {},
- color: "#2196f3"
- }];
- this.ctx.defaultSubscription.unsubscribe();
- this.ctx.defaultSubscription.updateDataSubscriptions();
- this.ctx.defaultSubscription.options.callbacks.dataLoading = () => {
- };
- this.ctx.defaultSubscription.callbacks.onDataUpdated = () => {
- if (init) {
- this.initChart();
- } else {
- this.updateChart();
- }
- }
- this.cd.detectChanges();
+ this.ctx.subscriptionApi.createSubscriptionFromInfo(widgetType.timeseries, subscriptionInfo, this.subscriptionOptions, false, true).subscribe(subscription => {
+ this.subscription = subscription;
+ this.legendData = this.subscription.legendData;
+ this.flotCtx.defaultSubscription = subscription;
+ this.flotCtx.$container = $(this.statisticChart.nativeElement);
+ this.resize$ = new ResizeObserver(() => {
+ this.resize();
+ });
+ this.resize$.observe(this.statisticChart.nativeElement);
+ this.ctx.detectChanges();
+ this.flot = new TbFlot(this.flotCtx as WidgetContext, "line");
+ this.flot.update();
+ })
+
}
}