Commit 762c6dae558e0d25ebffd3b54222801a2a977560

Authored by Serhii Mikhnytskyi
Committed by Andrew Shvayka
1 parent 1eccfcc7

improved performance of table widgets - removed unused ngZone.run and detectChan…

…ges, changed functions trackByRowIndex - now is used index, not id, minor improvements for functions, used after data updating.
... ... @@ -61,7 +61,7 @@
61 61 </div>
62 62 </mat-toolbar>
63 63 <div fxFlex class="table-container">
64   - <table mat-table [dataSource]="alarmsDatasource"
  64 + <table mat-table [dataSource]="alarmsDatasource" [trackBy]="trackByRowIndex"
65 65 matSort [matSortActive]="sortOrderProperty" [matSortDirection]="pageLinkSortDirection()" matSortDisableClear>
66 66 <ng-container matColumnDef="select" sticky>
67 67 <mat-header-cell *matHeaderCellDef style="width: 30px;">
... ...
... ... @@ -247,11 +247,8 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
247 247 }
248 248
249 249 public onDataUpdated() {
250   - this.ngZone.run(() => {
251   - this.updateTitle(true);
252   - this.alarmsDatasource.updateAlarms();
253   - this.ctx.detectChanges();
254   - });
  250 + this.updateTitle(true);
  251 + this.alarmsDatasource.updateAlarms();
255 252 }
256 253
257 254 public pageLinkSortDirection(): SortDirection {
... ... @@ -565,6 +562,10 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
565 562 return column.def;
566 563 }
567 564
  565 + public trackByRowIndex(index: number) {
  566 + return index;
  567 + }
  568 +
568 569 public headerStyle(key: EntityColumn): any {
569 570 const columnWidth = this.columnWidth[key.def];
570 571 return widthStyle(columnWidth);
... ... @@ -606,7 +607,19 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
606 607 } else {
607 608 content = this.defaultContent(key, contentInfo, value);
608 609 }
609   - return isDefined(content) ? this.domSanitizer.bypassSecurityTrustHtml(content) : '';
  610 +
  611 + if (!isDefined(content)) {
  612 + return '';
  613 +
  614 + } else {
  615 + switch (typeof content) {
  616 + case 'string':
  617 + return this.domSanitizer.bypassSecurityTrustHtml(content);
  618 + default:
  619 + return content;
  620 + }
  621 + }
  622 +
610 623 } else {
611 624 return '';
612 625 }
... ...
... ... @@ -38,7 +38,7 @@
38 38 </div>
39 39 </mat-toolbar>
40 40 <div fxFlex class="table-container">
41   - <table mat-table [dataSource]="entityDatasource"
  41 + <table mat-table [dataSource]="entityDatasource" [trackBy]="trackByRowIndex"
42 42 matSort [matSortActive]="sortOrderProperty" [matSortDirection]="pageLinkSortDirection()" matSortDisableClear>
43 43 <ng-container [matColumnDef]="column.def" *ngFor="let column of columns; trackBy: trackByColumnDef;">
44 44 <mat-header-cell [ngStyle]="headerStyle(column)" *matHeaderCellDef mat-sort-header> {{ column.title }} </mat-header-cell>
... ...
... ... @@ -206,11 +206,8 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
206 206 }
207 207
208 208 public onDataUpdated() {
209   - this.ngZone.run(() => {
210   - this.updateTitle(true);
211   - this.entityDatasource.dataUpdated();
212   - this.ctx.detectChanges();
213   - });
  209 + this.updateTitle(true);
  210 + this.entityDatasource.dataUpdated();
214 211 }
215 212
216 213 public pageLinkSortDirection(): SortDirection {
... ... @@ -488,6 +485,10 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
488 485 return column.def;
489 486 }
490 487
  488 + public trackByRowIndex(index: number) {
  489 + return index;
  490 + }
  491 +
491 492 public headerStyle(key: EntityColumn): any {
492 493 const columnWidth = this.columnWidth[key.def];
493 494 return widthStyle(columnWidth);
... ... @@ -529,7 +530,19 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
529 530 } else {
530 531 content = this.defaultContent(key, contentInfo, value);
531 532 }
532   - return isDefined(content) ? this.domSanitizer.bypassSecurityTrustHtml(content) : '';
  533 +
  534 + if (!isDefined(content)) {
  535 + return '';
  536 +
  537 + } else {
  538 + switch (typeof content) {
  539 + case 'string':
  540 + return this.domSanitizer.bypassSecurityTrustHtml(content);
  541 + default:
  542 + return content;
  543 + }
  544 + }
  545 +
533 546 } else {
534 547 return '';
535 548 }
... ...
... ... @@ -40,7 +40,7 @@ import {
40 40 } from '@shared/models/widget.models';
41 41 import { UtilsService } from '@core/services/utils.service';
42 42 import { TranslateService } from '@ngx-translate/core';
43   -import { hashCode, isDefined, isNumber } from '@core/utils';
  43 +import {hashCode, isDefined, isDefinedAndNotNull, isNumber} from '@core/utils';
44 44 import cssjs from '@core/css/css';
45 45 import { PageLink } from '@shared/models/page/page-link';
46 46 import { Direction, SortOrder, sortOrderFromString } from '@shared/models/page/sort-order';
... ... @@ -197,11 +197,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
197 197 }
198 198
199 199 public onDataUpdated() {
200   - this.ngZone.run(() => {
201   - this.sources.forEach((source) => {
202   - source.timeseriesDatasource.dataUpdated(this.data);
203   - });
204   - this.ctx.detectChanges();
  200 + this.sources.forEach((source) => {
  201 + source.timeseriesDatasource.dataUpdated(this.data);
205 202 });
206 203 }
207 204
... ... @@ -410,7 +407,18 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
410 407 const units = contentInfo.units || this.ctx.widgetConfig.units;
411 408 content = this.ctx.utils.formatValue(value, decimals, units, true);
412 409 }
413   - return isDefined(content) ? this.domSanitizer.bypassSecurityTrustHtml(content) : '';
  410 +
  411 + if (!isDefined(content)) {
  412 + return '';
  413 +
  414 + } else {
  415 + switch (typeof content) {
  416 + case 'string':
  417 + return this.domSanitizer.bypassSecurityTrustHtml(content);
  418 + default:
  419 + return content;
  420 + }
  421 + }
414 422 }
415 423 }
416 424
... ... @@ -515,26 +523,22 @@ class TimeseriesDatasource implements DataSource<TimeseriesRow> {
515 523 row[d + 1] = cellData[1];
516 524 });
517 525 }
  526 +
518 527 const rows: TimeseriesRow[] = [];
519   - for (const t of Object.keys(rowsMap)) {
520   - if (this.hideEmptyLines) {
521   - let hideLine = true;
522   - for (let c = 0; (c < data.length) && hideLine; c++) {
523   - if (rowsMap[t][c + 1]) {
524   - hideLine = false;
525   - }
526   - }
527   - if (!hideLine) {
528   - rows.push(rowsMap[t]);
529   - }
  528 +
  529 + for (const value of Object.values(rowsMap)) {
  530 + this.hideEmptyLines = true;
  531 +
  532 + if (this.hideEmptyLines && isDefinedAndNotNull(value[1])) {
  533 + rows.push(value);
530 534 } else {
531   - rows.push(rowsMap[t]);
  535 + rows.push(value);
532 536 }
533 537 }
  538 +
534 539 return rows;
535 540 }
536 541
537   -
538 542 isEmpty(): Observable<boolean> {
539 543 return this.rowsSubject.pipe(
540 544 map((rows) => !rows.length)
... ...